From 7641bb7876fc87c9344ce44c68e211f334d59ace Mon Sep 17 00:00:00 2001 From: xCrystal Date: Wed, 20 Dec 2023 19:14:28 +0100 Subject: [PATCH] Implement the engine to backup disabled map spaces (#33) --- constants/space_constants.asm | 6 +- data/maps/setup_script_pointers.asm | 1 + data/maps/setup_scripts.asm | 9 ++ engine/board/spaces.asm | 145 +++++++++++++++++++++++++++- engine/menus/save.asm | 35 +++++++ engine/overworld/events.asm | 23 ++++- home/map.asm | 6 +- layout.link | 2 + ram/sram.asm | 5 + ram/wram.asm | 12 +++ 10 files changed, 237 insertions(+), 7 deletions(-) diff --git a/constants/space_constants.asm b/constants/space_constants.asm index 293c5cb5e..73f45c407 100755 --- a/constants/space_constants.asm +++ b/constants/space_constants.asm @@ -4,7 +4,7 @@ DEF FIRST_GREY_SPACE_METATILE EQU $e0 DEF UNIQUE_SPACE_METATILES_MASK EQU %11111 ; Branch Space special direction values - const_def -1, -1 + const_def 255, -1 const BRANCH_DIRECTION_INVALID ; -1 const BRANCH_DIRECTION_UNAVAILABLE ; -2 @@ -15,3 +15,7 @@ DEF UNIQUE_SPACE_METATILES_MASK EQU %11111 const GO_LEFT ; 251 const GO_RIGHT ; 250 DEF NEXT_SPACE_IS_ANCHOR_POINT EQU const_value + 1 + +DEF MAX_SPACES_PER_MAP EQU const_value + 1 + +DEF NUM_DISABLED_SPACES_BACKUPS EQU 10 diff --git a/data/maps/setup_script_pointers.asm b/data/maps/setup_script_pointers.asm index 40dcb66f5..975804f01 100644 --- a/data/maps/setup_script_pointers.asm +++ b/data/maps/setup_script_pointers.asm @@ -55,3 +55,4 @@ MapSetupCommands: add_mapsetup ResetLevelScopedEventFlags ; 30 add_mapsetup AnchorPointAfterWarp ; 31 add_mapsetup BackupMapObjects ; 32 + add_mapsetup LoadDisabledSpaces ; 33 diff --git a/data/maps/setup_scripts.asm b/data/maps/setup_scripts.asm index 06fd56b1b..188a3c470 100644 --- a/data/maps/setup_scripts.asm +++ b/data/maps/setup_scripts.asm @@ -66,6 +66,7 @@ MapSetupScript_Warp: mapsetup RefreshPlayerCoords mapsetup GetMapScreenCoords mapsetup LoadBlockData + mapsetup LoadDisabledSpaces mapsetup BufferScreen mapsetup LoadMapGraphics mapsetup LoadMapTimeOfDay @@ -91,6 +92,7 @@ MapSetupScript_BadWarp: mapsetup RefreshPlayerCoords mapsetup GetMapScreenCoords mapsetup LoadBlockData + mapsetup LoadDisabledSpaces mapsetup BufferScreen mapsetup DisableLCD mapsetup LoadMapGraphics @@ -116,6 +118,7 @@ MapSetupScript_Connection: mapsetup HandleNewMap mapsetup RefreshPlayerCoords mapsetup LoadBlockData + mapsetup LoadDisabledSpaces mapsetup LoadMapTileset mapsetup SaveScreen mapsetup LoadMapObjects @@ -139,6 +142,7 @@ MapSetupScript_Train: mapsetup HandleNewMap mapsetup RefreshPlayerCoords mapsetup LoadBlockData + mapsetup LoadDisabledSpaces mapsetup BufferScreen mapsetup DisableLCD mapsetup LoadMapGraphics @@ -163,6 +167,7 @@ MapSetupScript_ReloadMap: mapsetup InitSound mapsetup LoadBlockData mapsetup LoadConnectionBlockData + mapsetup LoadDisabledSpaces mapsetup LoadMapGraphics mapsetup LoadMapTimeOfDay mapsetup EnableOverworldHUD @@ -184,6 +189,7 @@ MapSetupScript_ExitViewMap: mapsetup RefreshPlayerCoords mapsetup GetMapScreenCoords mapsetup LoadBlockData + mapsetup LoadDisabledSpaces mapsetup BufferScreen mapsetup LoadMapGraphics mapsetup LoadMapTimeOfDay @@ -204,6 +210,7 @@ MapSetupScript_LinkReturn: mapsetup InitSound mapsetup HandleNewMap mapsetup LoadBlockData + mapsetup LoadDisabledSpaces mapsetup BufferScreen mapsetup LoadMapGraphics mapsetup LoadMapTimeOfDay @@ -225,6 +232,7 @@ MapSetupScript_Continue: mapsetup HandleContinueMap mapsetup LoadBlockData mapsetup LoadConnectionBlockData + mapsetup LoadDisabledSpaces mapsetup BufferScreen mapsetup LoadMapGraphics mapsetup LoadMapTimeOfDay @@ -241,4 +249,5 @@ MapSetupScript_Continue: MapSetupScript_Submenu: mapsetup LoadBlockData mapsetup LoadConnectionBlockData + mapsetup LoadDisabledSpaces db -1 ; end diff --git a/engine/board/spaces.asm b/engine/board/spaces.asm index e5374debe..d732fc94c 100755 --- a/engine/board/spaces.asm +++ b/engine/board/spaces.asm @@ -131,6 +131,8 @@ LandedInRegularSpaceScript_AfterSpaceEffect: and UNIQUE_SPACE_METATILES_MASK add FIRST_GREY_SPACE_METATILE ld [hl], a +; backup the disabled space to preserve it on map reload + call BackupDisabledSpace ; trigger end of turn ld a, BOARDEVENT_END_TURN ldh [hCurBoardEvent], a @@ -309,4 +311,145 @@ UnionSpaceScript:: ld a, [wCurSpaceNextSpace] ld [wCurSpace], a call LoadCurSpaceData - end + ret + +BackupDisabledSpace:: +; unlike map objects which are backed up when leaving a map, +; a disabled space is backed up immediately when it is disabled. + ld a, [wCurSpace] + push af + + ld hl, wMapGroup + ld d, [hl] + inc hl ; wMapNumber + ld e, [hl] + + ld a, BANK(wDisabledSpacesBackups) + ld [rSVBK], a + + ld hl, wMap1DisabledSpacesBackup + ld bc, wMap2DisabledSpacesBackup - wMap1DisabledSpacesBackup - 2 +.loop + ld a, [hl] + cp GROUP_N_A + jr z, .found_available_entry + and a ; cp $00 (terminator found at wDisabledSpacesBackupsEnd, no more room) + jr z, .done_pop_af + cp d ; wMapDisabledSpacesMapGroup == wMapGroup? + jr nz, .next + inc hl + ld a, [hl] + cp e ; wMapDisabledSpacesMapNumber == wMapNumber? + jr nz, .next2 + inc hl + jr .found_matching_entry +.next + inc hl +.next2 + inc hl + add hl, bc + jr .loop + +.found_available_entry + ld [hl], d ; wMapGroup + inc hl + ld [hl], e ; wMapNumber + inc hl +.found_matching_entry +; mark the space at wCurSpace as disabled in the entry with + pop af + ld e, a + ld d, 0 + ld b, SET_FLAG + call FlagAction + jr .done + +.done_pop_af + pop af +.done + ld a, 1 + ld [rSVBK], a + ret + +LoadDisabledSpaces: +; map setup command (called after the map setup command LoadBlockData) + ld hl, wMapGroup + ld d, [hl] + inc hl + ld e, [hl] ; wMapNumber + ld a, BANK(wDisabledSpacesBackups) + ld [rSVBK], a + + ld hl, wMap1DisabledSpacesBackup + ld bc, wMap2DisabledSpacesBackup - wMap1DisabledSpacesBackup - 2 +.find_loop + ld a, [hl] + cp GROUP_N_A + jr z, .no_match + and a ; cp $00 (terminator found at wDisabledSpacesBackupsEnd) + jr z, .no_match + cp d + jr nz, .next + inc hl + ld a, [hl] + cp e + jr nz, .next2 + inc hl + jr .found_matching_entry +.next + inc hl +.next2 + inc hl + add hl, bc + jr .find_loop + +.found_matching_entry +; loop through all MAX_SPACES_PER_MAP flags and call .ApplyDisabledSpace in the disabled spaces. + xor a +.apply_loop_2 + ld e, [hl] + inc hl +.apply_loop_1 + srl e + call c, .ApplyDisabledSpace + inc a + cp MAX_SPACES_PER_MAP + jr z, .done ; return when all MAX_SPACES_PER_MAP flags checked + ld d, a + and %111 + ld a, d + jr z, .apply_loop_2 ; jump if done with current batch of 8 flags + jr .apply_loop_1 + +.done +.no_match + ld a, 1 + ld [rSVBK], a + ret + +.ApplyDisabledSpace: + push af + push de + push hl + ld e, a + ld a, 1 + ld [rSVBK], a + ld a, e ; a = space to apply as disabled + call LoadTempSpaceData + ld a, [wTempSpaceXCoord] + add 4 + ld d, a + ld a, [wTempSpaceYCoord] + add 4 + ld e, a + call GetBlockLocation + ld a, [hl] + and UNIQUE_SPACE_METATILES_MASK + add FIRST_GREY_SPACE_METATILE + ld [hl], a + ld a, BANK(wDisabledSpacesBackups) + ld [rSVBK], a + pop hl + pop de + pop af + ret diff --git a/engine/menus/save.asm b/engine/menus/save.asm index b156a266d..8c0b489d1 100644 --- a/engine/menus/save.asm +++ b/engine/menus/save.asm @@ -289,6 +289,7 @@ SaveGameData: call SaveOptions call SavePlayerData call SavePokemonData + call SaveDisabledSpacesBackupsData call SaveMapObjectsBackupsData call SaveBox call SaveChecksum @@ -447,6 +448,22 @@ SavePokemonData: call CloseSRAM ret +SaveDisabledSpacesBackupsData: + ldh a, [rSVBK] + push af + ld a, BANK(wDisabledSpacesBackups) + ldh [rSVBK], a + ld a, BANK(sDisabledSpacesBackups) + call OpenSRAM + ld hl, wDisabledSpacesBackups + ld de, sDisabledSpacesBackups + ld bc, wDisabledSpacesBackupsEnd - wDisabledSpacesBackups + call CopyBytes + call CloseSRAM + pop af + ldh [rSVBK], a + ret + SaveMapObjectsBackupsData: ldh a, [rSVBK] push af @@ -543,6 +560,7 @@ TryLoadSaveFile: jr nz, .backup call LoadPlayerData call LoadPokemonData + call LoadDisabledSpacesBackupsData call LoadMapObjectsBackupsData call LoadBox farcall RestorePartyMonMail @@ -559,6 +577,7 @@ TryLoadSaveFile: jr nz, .corrupt call LoadBackupPlayerData call LoadBackupPokemonData + call LoadDisabledSpacesBackupsData call LoadMapObjectsBackupsData call LoadBox farcall RestorePartyMonMail @@ -696,6 +715,22 @@ LoadPokemonData: call CloseSRAM ret +LoadDisabledSpacesBackupsData: + ldh a, [rSVBK] + push af + ld a, BANK(wDisabledSpacesBackups) + ldh [rSVBK], a + ld a, BANK(sDisabledSpacesBackups) + call OpenSRAM + ld hl, sDisabledSpacesBackups + ld de, wDisabledSpacesBackups + ld bc, wDisabledSpacesBackupsEnd - wDisabledSpacesBackups + call CopyBytes + call CloseSRAM + pop af + ldh [rSVBK], a + ret + LoadMapObjectsBackupsData: ldh a, [rSVBK] push af diff --git a/engine/overworld/events.asm b/engine/overworld/events.asm index 2b2ee2d4a..88e1db0cd 100644 --- a/engine/overworld/events.asm +++ b/engine/overworld/events.asm @@ -165,18 +165,37 @@ StartMap: ld [hli], a ; wPrevWarp ld [hli], a ; wPrevMapGroup ld [hl], a ; wPrevMapNumber + + ld a, BANK(wDisabledSpacesBackups) + ld [rSVBK], a + ld hl, wDisabledSpacesBackups + ld bc, wDisabledSpacesBackupsEnd - wDisabledSpacesBackups + xor a + call ByteFill + ld e, NUM_DISABLED_SPACES_BACKUPS + ld hl, wDisabledSpacesBackups + ld bc, wMap2DisabledSpacesBackup - wMap1DisabledSpacesBackup +.loop1 + ld a, GROUP_N_A + ld [hl], a + add hl, bc + dec e + jr nz, .loop1 + ld [hl], $00 ; list terminator + ld a, BANK(wMapObjectsBackups) ld [rSVBK], a ld e, NUM_MAP_OBJECTS_BACKUPS ld hl, wMapObjectsBackups ld bc, wMap2ObjectsBackup - wMap1ObjectsBackup -.loop +.loop2 ld a, GROUP_N_A ld [hl], a add hl, bc dec e - jr nz, .loop + jr nz, .loop2 ld [hl], $00 ; list terminator + ld a, 1 ld [rSVBK], a diff --git a/home/map.asm b/home/map.asm index 3d7e5da6e..78bdb1042 100644 --- a/home/map.asm +++ b/home/map.asm @@ -359,10 +359,10 @@ CheckIndoorMap:: ret ; z BackupMapObjects:: -; this setup script is called just before the EnterMap* setup script, +; this map setup command is called just before the EnterMap* map setup command, ; when wMapGroup and wMapNumber still contain the about-to-leave map. ; there is no need to backup map objects when going through connections during View Map mode, -; as during this mode there is no possible interaction that leads to a map objec changing status. +; as during this mode there is no possible interaction that leads to a map object changing status. ; BackupMapObjectsOnEnterViewMapMode is called when entering View Map mode. ldh a, [hCurBoardEvent] cp BOARDEVENT_VIEW_MAP_MODE @@ -730,7 +730,7 @@ CopyMapObjectEvents:: ret .FindMapObjectsBackup: -; this is called from the LoadMapAttributes map setup script. +; this is called from the LoadMapAttributes map map setup command. ; at this point wMapGroup and wMapNumber contain the about-to-enter map. ; if map is found in wMapObjectsBackups, copy object data from there and return carry. ; return nc otherwise. diff --git a/layout.link b/layout.link index 481a2a0b3..abfba3af4 100644 --- a/layout.link +++ b/layout.link @@ -263,6 +263,7 @@ WRAMX 1 "Party" WRAMX 2 "Pic Animations" + "Disabled Spaces Backups" WRAMX 3 "Map Objects Backups" WRAMX 5 @@ -289,6 +290,7 @@ SRAM $01 "Active Box" "Link Battle Data" "SRAM Hall of Fame" + "SRAM Disabled Spaces Backups" SRAM $02 "Boxes 1-7" SRAM $03 diff --git a/ram/sram.asm b/ram/sram.asm index 1624edb4c..86e6e3e04 100644 --- a/ram/sram.asm +++ b/ram/sram.asm @@ -137,6 +137,11 @@ SECTION "Boxes 8-14", SRAM "boxes: Expected {d:NUM_BOXES} total boxes, got {d:box_n}" +SECTION "SRAM Disabled Spaces Backups", SRAM + +sDisabledSpacesBackups:: ds wDisabledSpacesBackupsEnd - wDisabledSpacesBackups + + SECTION "SRAM Map Objects Backups", SRAM sMapObjectsBackups:: ds wMapObjectsBackupsEnd - wMapObjectsBackups diff --git a/ram/wram.asm b/ram/wram.asm index 238d439fa..ab0107677 100644 --- a/ram/wram.asm +++ b/ram/wram.asm @@ -2687,6 +2687,18 @@ wPokeAnimBitmaskBuffer:: ds 7 wPokeAnimStructEnd:: +SECTION "Disabled Spaces Backups", WRAMX + +wDisabledSpacesBackups:: +for n, 1, NUM_DISABLED_SPACES_BACKUPS + wMap{d:n}DisabledSpacesBackup:: + wMap{d:n}DisabledSpacesBackupMapGroup:: db + wMap{d:n}DisabledSpacesBackupMapNumber:: db + wMap{d:n}DisabledSpacesBackupData:: flag_array MAX_SPACES_PER_MAP +endr +wDisabledSpacesBackupsEnd:: db ; list terminator + + SECTION "Map Objects Backups", WRAMX wMapObjectsBackups::