diff --git a/.gitignore b/.gitignore index a6351deb..1985ae96 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ *.sw[op] build/ tools/*.exe +tools/asar .vscode/launch.json .vscode/tasks.json /names/custom_names.txt diff --git a/src/cutscenes.asm b/src/cutscenes.asm index 6b977cf7..adc3f622 100644 --- a/src/cutscenes.asm +++ b/src/cutscenes.asm @@ -7,12 +7,12 @@ endif JSR cutscenes_load_ceres_arrival if !FEATURE_PAL -org $8B92B5 +org $8B9287 else -org $8B930C +org $8B92DE endif - JSL cutscenes_nintendo_splash - NOP : NOP + JSR cutscenes_nintendo_logo_hijack + NOP org $80AE5C @@ -108,16 +108,23 @@ endif org $8BF800 print pc, " cutscenes start" -cutscenes_nintendo_splash: +cutscenes_nintendo_logo_hijack: { - LDX #$0078 - LDA !sram_cutscenes - AND !CUTSCENE_SKIP_SPLASH - BEQ .done - LDX #$0001 - .done - STX $0DE2 - RTL + JSL $80834B ; hijacked code + + LDA !sram_cutscenes : AND !CUTSCENE_QUICKBOOT : BNE .quickboot + STA !ram_quickboot_spc_state ; A is 0 + RTS + +.quickboot + PLA ; pop return address + PLB + PLA ; saved processor status and 1 byte of next return address + PLA ; remainder of next return address + + LDA #$0001 : STA !ram_quickboot_spc_state + + JML $808482 ; finish boot code; another hijack will launch the menu } cutscenes_add_elevator_speed: diff --git a/src/defines.asm b/src/defines.asm index 338048b3..95f54e13 100644 --- a/src/defines.asm +++ b/src/defines.asm @@ -157,6 +157,11 @@ !ram_itempickups_hidden = !WRAM_PERSIST_START+$62 !ram_frames_held = !WRAM_PERSIST_START+$64 +!ram_quickboot_spc_state = !WRAM_PERSIST_START+$66 + ; 0: SPC load completed/not requested + ; 1: SPC load requested + ; ROM address: routine to perform next initialization step + ; ^ FREE SPACE ^ up to +$7A (!WRAM_START+$FC - !WRAM_PERSIST_START) ; ----------------------- @@ -702,6 +707,7 @@ endif !CUTSCENE_FAST_PHANTOON = #$0200 !CUTSCENE_FAST_KRAID = #$0400 !CUTSCENE_SKIP_SPLASH = #$0800 +!CUTSCENE_QUICKBOOT = #$0800 !CUTSCENE_SKIP_GAMEOVER = #$1000 !CUTSCENE_FAST_BOWLING = #$2000 !CUTSCENE_KRAID_DEATH_CAMERA = #$4000 diff --git a/src/init.asm b/src/init.asm index 847b907d..e6eece9c 100644 --- a/src/init.asm +++ b/src/init.asm @@ -6,7 +6,8 @@ org $808455 ; hijack when clearing bank 7E org $808490 - PHA + ; Save quickboot state since it needs to distinguish between a soft and hard reset + LDY.w !ram_quickboot_spc_state LDX #$3FFE .clear_bank_loop STZ $0000,X @@ -16,14 +17,19 @@ org $808490 DEX : DEX BPL .clear_bank_loop JSL init_nonzero_wram - PLA + + STY.w !ram_quickboot_spc_state BRA .end_clear_bank + warnpc $8084AF org $8084AF .end_clear_bank +org $80856E + JML init_post_boot + org $81F000 print pc, " init start" @@ -94,7 +100,12 @@ init_sram: TDC : STA !sram_top_display_mode STA !sram_room_layout INC : STA !sram_healthalarm + +if !FEATURE_DEV + LDA !CUTSCENE_QUICKBOOT|$0003 : STA !sram_cutscenes +else LDA #$0003 : STA !sram_cutscenes +endif .sram_upgrade_CtoD TDC : STA !sram_preset_options @@ -217,30 +228,30 @@ init_menu_customization: RTL } -init_controller_bindings: +init_post_boot: { - ; check if any non-dpad bindings are set - LDX #$000A - LDA.w !IH_INPUT_SHOT+$0C - .loopBindings - ORA.w !IH_INPUT_SHOT,X - DEX #2 : BPL .loopBindings - AND #$FFF0 : BNE .done - - ; load default dpad bindings - LDA #$0800 : STA.w !INPUT_BIND_UP - LSR : STA.w !INPUT_BIND_DOWN - LSR : STA.w !INPUT_BIND_LEFT - LSR : STA.w !INPUT_BIND_RIGHT - - ; load default non-dpad bindings - LDX #$000C - .loopTable - LDA.l ControllerLayoutTable,X : STA.w !IH_INPUT_SHOT,X - DEX #2 : BPL .loopTable + ; Load the last selected file slot (so that the user's controller + ; bindings will apply if they load a preset without loading a save file) + LDA $701FEC ; Selected save slot + STA !CURRENT_SAVE_FILE + CMP #$0003 : BCC .valid_index + LDA #$0000 + .valid_index + JSL $818085 ; Load save file + BCC .check_quickboot + + ; No valid save; load a new file (for default controller bindings) + JSR $B2CB + + .check_quickboot + ; Is quickboot enabled? + LDA !sram_cutscenes : AND !CUTSCENE_QUICKBOOT : BEQ .done + + ; Boot to the infohud menu + JML cm_boot .done - RTL + JML $82893D ; hijacked code: start main game loop } print pc, " init end" diff --git a/src/mainmenu.asm b/src/mainmenu.asm index 34173291..28821651 100644 --- a/src/mainmenu.asm +++ b/src/mainmenu.asm @@ -1817,7 +1817,6 @@ action_teleport: STZ $0E18 ; Set elevator to inactive STZ $1C1F ; Clear message box index - JSL init_controller_bindings LDA !SAMUS_HP_MAX : BNE .branch LDA #$001F : STA !SAMUS_HP @@ -2934,7 +2933,7 @@ game_debugfixscrolloffsets: ; --------------- CutscenesMenu: - dw #cutscenes_skip_splash + dw #cutscenes_quickboot dw #cutscenes_skip_intro dw #cutscenes_skip_ceres_arrival dw #cutscenes_skip_g4 @@ -2955,8 +2954,8 @@ CutscenesMenu: dw #$0000 %cm_header("CUTSCENES AND EFFECTS") -cutscenes_skip_splash: - %cm_toggle_bit("Fast Nintendo splash", !sram_cutscenes, !CUTSCENE_SKIP_SPLASH, #0) +cutscenes_quickboot: + %cm_toggle_bit("Boot to Menu", !sram_cutscenes, !CUTSCENE_QUICKBOOT, #0) cutscenes_skip_intro: %cm_toggle_bit("Skip Intro", !sram_cutscenes, !CUTSCENE_SKIP_INTRO, #0) diff --git a/src/menu.asm b/src/menu.asm index e54f2247..35deca9d 100644 --- a/src/menu.asm +++ b/src/menu.asm @@ -2,10 +2,6 @@ org $85FD00 print pc, " menu bank85 start" -wait_for_lag_frame_long: - JSR $8136 - RTL - initialize_ppu_long: PHP : %a16() LDA $7E33EA : STA !ram_cgram_cache+$2E @@ -41,6 +37,8 @@ cm_start: PHB : PHX : PHY PHK : PLB + LDA #$0000 : STA !ram_quickboot_spc_state + ; Ensure sound is enabled when menu is open LDA !DISABLE_SOUNDS : PHA STZ !DISABLE_SOUNDS @@ -94,6 +92,41 @@ cm_start: RTL } +cm_boot: +{ + PHK : PLB + LDA !ram_quickboot_spc_state : BEQ .skip_spc + LDA #cm_spc_init : STA !ram_quickboot_spc_state + + ; Disable sounds until we boot the SPC + LDA #$0001 : STA !DISABLE_SOUNDS +.skip_spc + + %a8() + LDA #$5A : STA $2109 ; BG3 tilemap base address + LDA #$04 : STA $212C ; Enable BG3; disable all else + %a16() + JSR cm_init + JSL cm_draw + JSR cm_loop + + .spc_loop + JSR cm_wait_for_lag_frame + LDA !ram_quickboot_spc_state : BMI .spc_loop + + .done + LDA !ram_custom_preset : BNE .preset_load + LDA !ram_load_preset : BEQ .main_game_loop + + .preset_load + JSL preset_load + + .main_game_loop + PEA $8282 : PLB : PLB + %a8() + JML $828944 +} + cm_init: { ; Setup registers @@ -134,6 +167,28 @@ cm_set_etanks_and_reserve: RTL } +cm_wait_for_lag_frame: +{ + PHP : %ai16() + LDA !ram_quickboot_spc_state : TAX + + LDA $05B8 ; lag frame counter + ; (it's only 8 bits, but it's OK if we mix it up with the variable after) + .loop + CMP $05B8 + BNE .done + + CPX #$0000 : BPL .loop + PHA : PHP : PHB : JSR cm_jump_x : PLB : PLP + LDA !ram_quickboot_spc_state : TAX : PLA + BRA .loop + + .done + PLP : RTS +} + +cm_jump_x: + DEX : PHX : RTS ; ---------- ; Drawing @@ -507,7 +562,7 @@ cm_tilemap_menu: cm_tilemap_transfer: { - JSL wait_for_lag_frame_long ; Wait for lag frame + JSR cm_wait_for_lag_frame ; Wait for lag frame %a16() LDA #$5800 : STA $2116 ; VRAM addr @@ -1560,7 +1615,7 @@ menu_ctrl_clear_input_display: cm_loop: { %ai16() - JSL wait_for_lag_frame_long + JSR cm_wait_for_lag_frame JSL $808F0C ; Music queue JSL $8289EF ; Sound fx queue JSL MenuRNG @@ -2021,7 +2076,7 @@ kb_main_loop: RTL .new_input - JSL wait_for_lag_frame_long + JSR cm_wait_for_lag_frame JSL $808F0C ; Music queue JSL $8289EF ; Sound fx queue JSR kb_handle_inputs @@ -3461,6 +3516,135 @@ MenuRNG2: RTL } +!cm_spc_db = $30 +!cm_spc_data = $31 +!cm_spc_index = $33 +!cm_spc_len = $34 + +cm_spc_init: { + ; wait for SPC to be ready + LDA #$BBAA : CMP $2140 : BNE .return + + LDA #$FFFF : STA $0617 ; disable soft rest + + %a8() + LDA #$CC + STA !cm_spc_index + + %a16() + LDA #$CFCF + STA !cm_spc_db + LDA #$8000 + STA !cm_spc_data + + LDA #cm_spc_next_block + STA !ram_quickboot_spc_state + +.return +RTS +} + +cm_spc_next_block: { + %a8() + PHB : LDA !cm_spc_db : PHA : PLB + LDY !cm_spc_data + + ; Get block size + LDA #$01 + LDX $0000, y + BNE .not_last : LDA #$00 + .not_last + INY : BNE + : JSR cm_spc_inc_bank + + INY : BNE + : JSR cm_spc_inc_bank + + STX !cm_spc_len + + ; Get block address + LDX $0000, y + INY : BNE + : JSR cm_spc_inc_bank + + INY : BNE + : JSR cm_spc_inc_bank + + PLB : STX $2142 + + STA $2141 + + %a16() + LDA #cm_spc_next_block_wait + STA !ram_quickboot_spc_state + + RTS +} + +cm_spc_inc_bank: { + PHA : LDA !cm_spc_db : INC A : STA !cm_spc_db + PHA : PLB : PLA + LDY #$8000 + RTS +} + +cm_spc_next_block_wait: { + %a8() + LDA !cm_spc_index : STA $2140 : CMP $2140 : BNE .return + + STZ !cm_spc_index + %a16() + LDA !cm_spc_len : BEQ .eof + LDA #cm_spc_transfer + STA !ram_quickboot_spc_state + STY !cm_spc_data + RTS + + .eof + LDA #$0000 : STA !ram_quickboot_spc_state + STZ !DISABLE_SOUNDS + STZ $0617 + + .return + RTS +} + +cm_spc_transfer: { + ; Determine how many bytes to transfer + LDA !cm_spc_len : TAX + SBC #$0040 : BCC .last + LDX #$0040 : STA !cm_spc_len + BRA .setup + .last + STZ !cm_spc_len + + .setup + %a8() + PHB : LDA !cm_spc_db : PHA : PLB + LDY !cm_spc_data + + LDA !cm_spc_index + + %a8() + .transfer_loop + XBA : LDA $0000, y : XBA + + %a16() : STA $002140 : %a8() + + .wait_loop + CMP $002140 : BNE .wait_loop + + INC A + INY : BNE + : JSR cm_spc_inc_bank + + + DEX : BNE .transfer_loop + + LDX !cm_spc_len : BNE .timeout + ; Done with the transfer! + CLC : ADC #$03 : STA !cm_spc_index : STY !cm_spc_data + %a16() : LDA #cm_spc_next_block : STA !ram_quickboot_spc_state + + PLB + RTS + + .timeout + STA !cm_spc_index : STY !cm_spc_data + + PLB + RTS +} ; ---------- ; Resources diff --git a/src/presets.asm b/src/presets.asm index 39aa1433..847ceba9 100644 --- a/src/presets.asm +++ b/src/presets.asm @@ -569,7 +569,6 @@ endif TDC : STA !ram_transition_flag JSL init_heat_damage_ram JSL init_physics_ram - JSL init_controller_bindings LDA #$E737 : STA $099C ; Pointer to next frame's room transition code = $82:E737 diff --git a/src/symbols.asm b/src/symbols.asm index 61c05c72..aedfcdb8 100644 --- a/src/symbols.asm +++ b/src/symbols.asm @@ -157,6 +157,8 @@ ram_itempickups_chozo = !ram_itempickups_chozo ; !WRAM_PERSIST_START+$60 ram_itempickups_hidden = !ram_itempickups_hidden ; !WRAM_PERSIST_START+$62 ram_frames_held = !ram_frames_held ; !WRAM_PERSIST_START+$64 +ram_quickboot_spc_state = !ram_quickboot_spc_state ; !WRAM_PERSIST_START+$66 + ; ^ FREE SPACE ^ up to +$7A (!WRAM_START+$FC - !WRAM_PERSIST_START) ; -----------------------