From 2f1608576a411602ba8730643e13858b0520a388 Mon Sep 17 00:00:00 2001 From: xCrystal Date: Mon, 19 Feb 2024 17:10:33 +0100 Subject: [PATCH] Add support for more than 8 techniques (#34) (#28) --- README.md | 2 +- constants/technique_constants.asm | 27 ++++++----- data/levels/levels.asm | 2 +- docs/develop/ram_addresses.md | 4 +- docs/usage/index.md | 2 +- engine/board/spaces.asm | 21 +++++---- macros/scripts/maps.asm | 74 ++++++++++++++++++++++++++----- maps/DebugLevel2_Map1.asm | 4 +- maps/DebugLevel5_Map1.asm | 8 ++-- ram/wram.asm | 2 +- 10 files changed, 103 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index fe6764c03..b34386ce4 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,6 @@ Compared to pokecrystal and the Pokemon Crystal ROM, the ROM built by pokecrysta pokecrystal-board requires RGBDS 0.7.0 to build. It has two build targets: *crystal*, and *crystal_debug*. The former builds a ROM with the *_DEBUG* symbol undefined, and the latter builds a ROM with the *_DEBUG* symbol defined. *crystal_debug* is meant to include additional content and configurations to facilitate testing during development, while *crystal* builds the ROM meant to be hypothetically released to the public. Other than that, refer to the [install docs from pokecrystal](INSTALL.md) for detailed instructions on how to setup and build pokecrystal-board. -If you have specific questions about the usage of pokecrystal-board or how to contribute to it, feel free to open an issue or to contact me on Discord. But please, do not do this for questions that are rather in the domain of pokecrystal. +If you have specific questions about the usage of pokecrystal-board or how to contribute to it, or to report a bug, feel free to open an issue or to contact me on Discord. But please, do not do this for questions that are rather in the domain of pokecrystal. If you are interested on developing on top of pokecrystal-board, [docs/usage/index.md](docs/usage/index.md) details the different features. For generic changes made in pokecrystal-board (adaptations, cleaning up, etc.) refer to issues #1, #2, #7, #8. You can also navigate issues tagged with a "Feature" label to see commits pertaining specific features. Additionally, a rough list of new RAM addresses can be found in [docs/develop/ram_addresses.md](docs/develop/ram_addresses.md). \ No newline at end of file diff --git a/constants/technique_constants.asm b/constants/technique_constants.asm index ac1522d99..7d00fd83c 100755 --- a/constants/technique_constants.asm +++ b/constants/technique_constants.asm @@ -1,14 +1,19 @@ +MACRO technique + const \1_B + DEF \1_F EQU \1_B % 8 + DEF \1 EQU 1 << \1_F +ENDM + ; technique constants const_def - const TECHNIQUE_CUT_F - const TECHNIQUE_FLASH_F - const TECHNIQUE_SURF_F - const TECHNIQUE_ROCK_SMASH_F - const TECHNIQUE_WATERFALL_F + technique TECHNIQUE_CUT + technique TECHNIQUE_FLASH + technique TECHNIQUE_SURF + technique TECHNIQUE_ROCK_SMASH + technique TECHNIQUE_WATERFALL + technique TECHNIQUE_DUMMY_5 + technique TECHNIQUE_DUMMY_6 + technique TECHNIQUE_DUMMY_7 + technique TECHNIQUE_DUMMY_8 + technique TECHNIQUE_DUMMY_9 DEF NUM_TECHNIQUES EQU const_value - -DEF TECHNIQUE_CUT EQU 1 << TECHNIQUE_CUT_F -DEF TECHNIQUE_FLASH EQU 1 << TECHNIQUE_FLASH_F -DEF TECHNIQUE_SURF EQU 1 << TECHNIQUE_SURF_F -DEF TECHNIQUE_ROCK_SMASH EQU 1 << TECHNIQUE_ROCK_SMASH_F -DEF TECHNIQUE_WATERFALL EQU 1 << TECHNIQUE_WATERFALL_F diff --git a/data/levels/levels.asm b/data/levels/levels.asm index 121463cc6..bd005bf11 100755 --- a/data/levels/levels.asm +++ b/data/levels/levels.asm @@ -39,6 +39,6 @@ if DEF(_DEBUG) ; level_unlock_req LEVELS_CLEARED, DEBUGLEVEL_3, STAGE_1_F ; DEBUGLEVEL_4 ; level_unlock_req LEVELS_CLEARED, DEBUGLEVEL_4, STAGE_1_F ; DEBUGLEVEL_5 level_unlock_req NUMBER_OF_LEVELS_CLEARED, 3 ; DEBUGLEVEL_4 - level_unlock_req TECHNIQUES_CLEARED, TECHNIQUE_FLASH | TECHNIQUE_WATERFALL ; DEBUGLEVEL_5 + level_unlock_req TECHNIQUES_CLEARED, TECHNIQUE_FLASH | TECHNIQUE_WATERFALL, 0 ; DEBUGLEVEL_5 endc assert x == NUM_LEVELS diff --git a/docs/develop/ram_addresses.md b/docs/develop/ram_addresses.md index 4f3894dbb..e32e78864 100755 --- a/docs/develop/ram_addresses.md +++ b/docs/develop/ram_addresses.md @@ -19,7 +19,7 @@ - Addresses within *wPlayerData* ~ *wPlayerDataEnd*: preserved on save. Includes: - **wUnlockedLevels**: flag array that tracks progression regarding which levels have been unlocked. - - **wClearedLevelsStage**: flag array that tracks progression regarding which levels have been cleared. Each level can have up to four clearable endings (N). + - **wClearedLevelsStage\**: flag array that tracks progression regarding which levels have been cleared. Each level can have up to four stages (clearable endings). - **wUnlockedTechniques**: flag array that tracks progression regarding which techniques have been unlocked. - **wCurLevel**: initialized in LevelSelectionMenu (where it is also used), and stays static during the level. - **wDefaultLevelSelectionMenuLandmark**: used to know in which landmark to place the player when entering level selection menu. @@ -28,7 +28,7 @@ - These addresses share memory region with string buffers from *wStringBuffer3* onwards. They are placed in memory in the following order. - **wTempSpaceStruct**: Temporary scope. Same structure as *wCurSpaceStruct* - - **wTempSpaceBranchStruct**: Temporary scope. The structure is four bytes for next space for each direction (R/L/U/D; -1 if unavailable direction) followed by four bytes for required techniques for each direction (R/L/U/D) + - **wTempSpaceBranchStruct**: Temporary scope. The structure is four bytes for next space for each direction (R/L/U/D; -1 if unavailable direction) followed by at least four bytes (depending on *NUM_TECHNIQUES*) for required techniques for each direction (R/L/U/D) - **wViewMapModeRange**, **wViewMapModeDisplacementY**, **wViewMapModeDisplacementX**: Temporary scope during a Vew Map mode session. - **wBeforeViewMapYCoord**, **wBeforeViewMapXCoord**, **wBeforeViewMapMapGroup**, **wBeforeViewMapMapNumber**, **wBeforeViewMapDirection**: Temporary scope during a Vew Map mode session. Used to preserve player state before entering View Map mode. diff --git a/docs/usage/index.md b/docs/usage/index.md index 758e80ed5..0c0c07f27 100755 --- a/docs/usage/index.md +++ b/docs/usage/index.md @@ -79,7 +79,7 @@ In a branch space, the last two bytes of the *space* macro are repurposed as a p endbranch ``` -Each *branchdir* entry includes: direction, next space id, techniques required. The order of entries is irrelevant, but do not put the same direction more than once in the same branch struct (all but the last entry using that direction will be ignored). +Each *branchdir* entry includes: direction, next space id, required techniques. The order of entries is irrelevant, but do not put the same direction more than once in the same branch struct (all but the last entry using that direction will be ignored). The number of arguments occupied by required techniques in each *branchdir* entry is equal to the number of techniques you have defined divided by eight. ### End space diff --git a/engine/board/spaces.asm b/engine/board/spaces.asm index bb67fb56b..d709702bf 100755 --- a/engine/board/spaces.asm +++ b/engine/board/spaces.asm @@ -195,19 +195,24 @@ ArriveToBranchSpaceScript: .DisableDirectionsRequiringLockedTechniques: ; set to BRANCH_DIRECTION_UNAVAILABLE each next space byte of the branch struct ; that has an unavailable direction due to required techniques not yet unlocked. - ld hl, wTempSpaceBranchStruct + NUM_DIRECTIONS - ld de, wTempSpaceBranchStruct +for curdir, 0, NUM_DIRECTIONS + ld e, (NUM_TECHNIQUES + 7) / 8 + ld hl, wTempSpaceBranchStruct + NUM_DIRECTIONS + curdir * (NUM_TECHNIQUES + 7) / 8 ld bc, wUnlockedTechniques -rept NUM_DIRECTIONS +.loop\@ ld a, [bc] and [hl] cp [hl] - jr z, .next\@ - ld a, BRANCH_DIRECTION_UNAVAILABLE - ld [de], a -.next\@ + jr nz, .unavailable_next\@ + dec e + jr z, .available_next\@ + inc bc inc hl - inc de + jr .loop\@ +.unavailable_next\@ + ld a, BRANCH_DIRECTION_UNAVAILABLE + ld [wTempSpaceBranchStruct + curdir], a +.available_next\@ endr ret diff --git a/macros/scripts/maps.asm b/macros/scripts/maps.asm index 5e0778a2c..a0cbf837b 100644 --- a/macros/scripts/maps.asm +++ b/macros/scripts/maps.asm @@ -163,18 +163,40 @@ endc ENDM MACRO branchdir +assert (_NARG - 2) == (NUM_TECHNIQUES + 7) / 8 +DEF techniques_byte = 0 if !STRCMP("\1", "RIGHT") DEF _NEXT_SPACE_RIGHT = \2 - DEF _TECHNIQUES_RIGHT = \3 + DEF _TECHNIQUES_RIGHT = TRUE + rept _NARG - 2 + DEF _TECHNIQUES_RIGHT_{d:techniques_byte} = \3 + shift + DEF techniques_byte += 1 + endr elif !STRCMP("\1", "LEFT") DEF _NEXT_SPACE_LEFT = \2 - DEF _TECHNIQUES_LEFT = \3 + DEF _TECHNIQUES_LEFT = TRUE + rept _NARG - 2 + DEF _TECHNIQUES_LEFT_{d:techniques_byte} = \3 + shift + DEF techniques_byte += 1 + endr elif !STRCMP("\1", "UP") DEF _NEXT_SPACE_UP = \2 - DEF _TECHNIQUES_UP = \3 + DEF _TECHNIQUES_UP = TRUE + rept _NARG - 2 + DEF _TECHNIQUES_UP_{d:techniques_byte} = \3 + shift + DEF techniques_byte += 1 + endr elif !STRCMP("\1", "DOWN") DEF _NEXT_SPACE_DOWN = \2 - DEF _TECHNIQUES_DOWN = \3 + DEF _TECHNIQUES_DOWN = TRUE + rept _NARG - 2 + DEF _TECHNIQUES_DOWN_{d:techniques_byte} = \3 + shift + DEF techniques_byte += 1 + endr endc ENDM @@ -204,28 +226,56 @@ else db -1 endc if DEF(_TECHNIQUES_RIGHT) - db {_TECHNIQUES_RIGHT} + DEF techniques_byte = 0 + rept (NUM_TECHNIQUES + 7) / 8 + db {_TECHNIQUES_RIGHT_{d:techniques_byte}} + PURGE _TECHNIQUES_RIGHT_{d:techniques_byte} + DEF techniques_byte += 1 + endr PURGE _TECHNIQUES_RIGHT else - db 0 + rept (NUM_TECHNIQUES + 7) / 8 + db 0 + endr endc if DEF(_TECHNIQUES_LEFT) - db {_TECHNIQUES_LEFT} + DEF techniques_byte = 0 + rept (NUM_TECHNIQUES + 7) / 8 + db {_TECHNIQUES_LEFT_{d:techniques_byte}} + PURGE _TECHNIQUES_LEFT_{d:techniques_byte} + DEF techniques_byte += 1 + endr PURGE _TECHNIQUES_LEFT else - db 0 + rept (NUM_TECHNIQUES + 7) / 8 + db 0 + endr endc if DEF(_TECHNIQUES_UP) - db {_TECHNIQUES_UP} + DEF techniques_byte = 0 + rept (NUM_TECHNIQUES + 7) / 8 + db {_TECHNIQUES_UP_{d:techniques_byte}} + PURGE _TECHNIQUES_UP_{d:techniques_byte} + DEF techniques_byte += 1 + endr PURGE _TECHNIQUES_UP else - db 0 + rept (NUM_TECHNIQUES + 7) / 8 + db 0 + endr endc if DEF(_TECHNIQUES_DOWN) - db {_TECHNIQUES_DOWN} + DEF techniques_byte = 0 + rept (NUM_TECHNIQUES + 7) / 8 + db {_TECHNIQUES_DOWN_{d:techniques_byte}} + PURGE _TECHNIQUES_DOWN_{d:techniques_byte} + DEF techniques_byte += 1 + endr PURGE _TECHNIQUES_DOWN else - db 0 + rept (NUM_TECHNIQUES + 7) / 8 + db 0 + endr endc ENDM diff --git a/maps/DebugLevel2_Map1.asm b/maps/DebugLevel2_Map1.asm index cdf7fe046..63be0069f 100755 --- a/maps/DebugLevel2_Map1.asm +++ b/maps/DebugLevel2_Map1.asm @@ -54,6 +54,6 @@ DebugLevel2_Map1_MapSpaces: space 0, 12, $0, GO_LEFT ; 15 .BS1: - branchdir LEFT, 13, 0 - branchdir UP, 3, 0 + branchdir LEFT, 13, 0, 0 + branchdir UP, 3, 0, 0 endbranch diff --git a/maps/DebugLevel5_Map1.asm b/maps/DebugLevel5_Map1.asm index 66c328f6f..9835d287e 100755 --- a/maps/DebugLevel5_Map1.asm +++ b/maps/DebugLevel5_Map1.asm @@ -118,11 +118,11 @@ DebugLevel5_Map1_MapSpaces: space 16, 4, $0, 8 ; 43 .BS2: - branchdir RIGHT, 3, 0 - branchdir UP, 35, 0 + branchdir RIGHT, 3, 0, 0 + branchdir UP, 35, 0, 0 endbranch .BS36: - branchdir RIGHT, 37, 0 - branchdir UP, GO_UP, 0 + branchdir RIGHT, 37, 0, 0 + branchdir UP, GO_UP, 0, 0 endbranch diff --git a/ram/wram.asm b/ram/wram.asm index 8f0c7884b..0944c90ff 100644 --- a/ram/wram.asm +++ b/ram/wram.asm @@ -1715,7 +1715,7 @@ wStringBuffer5:: ds STRING_BUFFER_LENGTH NEXTU wTempSpaceStruct:: space_struct wTempSpace wTempSpaceStructEnd:: -wTempSpaceBranchStruct:: ds NUM_DIRECTIONS * 2 +wTempSpaceBranchStruct:: ds NUM_DIRECTIONS * (1 + ((NUM_TECHNIQUES) + 7) / 8) wTempSpaceBranchStructEnd:: wViewMapModeRange:: db