summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Add-a-new-Pack-pocket.md115
1 files changed, 63 insertions, 52 deletions
diff --git a/Add-a-new-Pack-pocket.md b/Add-a-new-Pack-pocket.md
index 01d8c84..999500d 100644
--- a/Add-a-new-Pack-pocket.md
+++ b/Add-a-new-Pack-pocket.md
@@ -1,4 +1,8 @@
-This tutorial is for how to add a new Pack pocket. As an example, we'll add a Berry Pocket.
+This tutorial is for how to add a new Pack pocket. Before starting, you'll need to install a Tilemap editor for Game Boy and GBC; [Tilemap Studio](https://github.com/Rangi42/tilemap-studio) is highly recommended for this (and will be the one used to illustrate one of the steps).
+
+As an example, we'll add a Berry Pocket in the third slot of our bag.
+
+
## Contents
@@ -12,9 +16,10 @@ This tutorial is for how to add a new Pack pocket. As an example, we'll add a Be
7. [Update `HasNoItems` and `CheckRegisteredItem` to check the new pocket](#7-update-hasnoitems-and-checkregistereditem-to-check-the-new-pocket)
8. [Update standard inventory routines](#8-update-standard-inventory-routines)
9. [Update the Pack engine](#9-update-the-pack-engine)
-10. [Update the Crystal-only Pack engine](#10-update-the-crystal-only-pack-engine)
-11. [Update Kurt's Apricorn script](#11-update-kurts-apricorn-script)
-12. [Fix build errors](#12-fix-build-errors)
+10. [Create/Edit pack_menu.tilemap](#10-create-edit-pack-menu-tilemap)
+11. [Update the Crystal-only Pack engine](#10-update-the-crystal-only-pack-engine)
+12. [Update Kurt's Apricorn script](#11-update-kurts-apricorn-script)
+13. [Fix build errors](#12-fix-build-errors)
## 1. Define pocket-related constants
@@ -36,9 +41,10 @@ Edit [constants/item_data_constants.asm](../blob/master/constants/item_data_cons
const_def
const ITEM_POCKET ; 0
const BALL_POCKET ; 1
++ const BERRY_POCKET
const KEY_ITEM_POCKET ; 2
const TM_HM_POCKET ; 3
-+ const BERRY_POCKET ; 4
+
NUM_POCKETS EQU const_value
MAX_ITEMS EQU 20
@@ -48,7 +54,7 @@ Edit [constants/item_data_constants.asm](../blob/master/constants/item_data_cons
+MAX_BERRIES EQU 17
```
-Notice that the "item types" constants are in a different order than the "pack pockets" constants. So don't mix them up. Also we name the item type "`BERRIES`" because "`BERRY`" is an item, so don't mix those up either.
+Notice that the "item types" constants are in a different order than the "pack pockets" constants, so don't mix them up. Also we name the item type "`BERRIES`" because "`BERRY`" is an item, so don't mix those up either.
The `MAX_*` constants are the storage capacities of their respective pockets. We defined `MAX_BERRIES` as 17 because there are 17 items that will go in the Berry pocket, as we'll see later; that way you can conveniently carry one stack of each Berry. (Likewise, `MAX_BALLS` is 12, and 12 items belong in the Ball pocket.)
@@ -136,7 +142,7 @@ Edit [wram.asm](../blob/master/wram.asm):
+wBerryPocketCursor:: db
wPCItemsScrollPosition:: db
- wPartyMenuScrollPosition:: db ; unused
+ ds 1
wItemsPocketScrollPosition:: db
wKeyItemsPocketScrollPosition:: db
wBallsPocketScrollPosition:: db
@@ -146,9 +152,8 @@ Edit [wram.asm](../blob/master/wram.asm):
...
+wDudeNumBerries::
- wDudeNumKeyItems:: db ; d292
- wDudeKeyItems:: ds 18
- wDudeKeyItemsEnd:: db
+ wDudeNumKeyItems:: db
+ wDudeKeyItems:: ds 18 + 1
...
@@ -158,13 +163,11 @@ Edit [wram.asm](../blob/master/wram.asm):
...
- wNumBalls:: db ; d8d7
- wBalls:: ds MAX_BALLS * 2 + 1 ; d8d8
- wBallsEnd::
+ wNumBalls:: db
+ wBalls:: ds MAX_BALLS * 2 + 1
+wNumBerries:: db
+wBerries:: ds MAX_BERRIES * 2 + 1
-+wBerriesEnd::
```
Every pocket has a <code>w<i>Name</i>PocketCursor</code> and a <code>w<i>Name</i>PocketScrollPosition</code> byte for scrolling through it, a <code>wNum<i>Names</i></code> byte that stores how many items are in it, and a <code>w<i>Names</i></code>–<code>w<i>Names</i>End</code> array for storing its items. `wTMsHMs` and `wKeyItems` are special, but normal item-storage pockets like `wItems` and `wBalls` have two bytes per possible item (one for the ID, one for the quantity) plus a byte for the end-of-list marker.
@@ -238,9 +241,9 @@ Now edit [engine/overworld/select_menu.asm](../blob/master/engine/overworld/sele
; entries correspond to *_POCKET constants
dw .CheckItem
dw .CheckBall
++ dw .CheckBerry
dw .CheckKeyItem
dw .CheckTMHM
-+ dw .CheckBerry
...
@@ -391,12 +394,12 @@ We've saved editing the longest file for last: [engine/items/pack.asm](../blob/m
const PACKSTATE_ITEMSPOCKETMENU ; 2
const PACKSTATE_INITBALLSPOCKET ; 3
const PACKSTATE_BALLSPOCKETMENU ; 4
++ const PACKSTATE_INITBERRYPOCKET
++ const PACKSTATE_BERRYPOCKETMENU
const PACKSTATE_INITKEYITEMSPOCKET ; 5
const PACKSTATE_KEYITEMSPOCKETMENU ; 6
const PACKSTATE_INITTMHMPOCKET ; 7
const PACKSTATE_TMHMPOCKETMENU ; 8
-+ const PACKSTATE_INITBERRYPOCKET
-+ const PACKSTATE_BERRYPOCKETMENU
const PACKSTATE_QUITNOSCRIPT ; 9
const PACKSTATE_QUITRUNSCRIPT ; 10
```
@@ -416,12 +419,12 @@ Notice the pattern to this table: for each pocket, there's a `PACKSTATE_INIT*POC
dw .ItemsPocketMenu ; 2
dw .InitBallsPocket ; 3
dw .BallsPocketMenu ; 4
++ dw .InitBerryPocket
++ dw .BerryPocketMenu
dw .InitKeyItemsPocket ; 5
dw .KeyItemsPocketMenu ; 6
dw .InitTMHMPocket ; 7
dw .TMHMPocketMenu ; 8
-+ dw .InitBerryPocket
-+ dw .BerryPocketMenu
dw Pack_QuitNoScript ; 9
dw Pack_QuitRunScript ; 10
```
@@ -516,12 +519,12 @@ Two, we actually write the subroutines that we just added pointers to in the jum
dw .ItemsPocketMenu ; 2
dw .InitBallsPocket ; 3
dw .BallsPocketMenu ; 4
++ dw .InitBerryPocket
++ dw .BerryPocketMenu
dw .InitKeyItemsPocket ; 5
dw .KeyItemsPocketMenu ; 6
dw .InitTMHMPocket ; 7
dw .TMHMPocketMenu ; 8
-+ dw .InitBerryPocket
-+ dw .BerryPocketMenu
dw Pack_QuitNoScript ; 9
dw Pack_QuitRunScript ; 10
```
@@ -609,9 +612,9 @@ Just like before, we insert the Berry pocket between the Ball and Key Item pocke
; entries correspond to *_POCKET constants
dw .ItemsPocket
dw .BallsPocket
++ dw .BerryPocket
dw .KeyItemsPocket
dw .TMHMPocket
-+ dw .BerryPocket
...
@@ -694,9 +697,9 @@ This is somewhat tricky to notice. Here the code is decrementing or incrementing
; entries correspond to *_POCKET constants
dw .Items
dw .Balls
++ dw .Berries
dw .KeyItems
dw .TMHM
-+ dw .Berries
...
@@ -747,38 +750,14 @@ Another jumptable, this time used by the catch tutorial dude. Once again, we jus
PackGFXPointers:
dw PackGFX + (15 tiles) * 1 ; ITEM_POCKET
dw PackGFX + (15 tiles) * 3 ; BALL_POCKET
++ dw PackGFX + (15 tiles) * 4 ; BERRY_POCKET
dw PackGFX + (15 tiles) * 0 ; KEY_ITEM_POCKET
dw PackGFX + (15 tiles) * 2 ; TM_HM_POCKET
-+ dw PackGFX + (15 tiles) * 4 ; BERRY_POCKET
```
This is a table of pointers to the individual highlighted pocket pictures in pack.png and pack_f.png. Remember how they were out of order compared to the constants? That's why this table is necessary. For example, the first (#0) picture was of the Key Item pocket, and `KEY_ITEM_POCKET` is 2, so the third (#2) entry here points to the first picture. Anyway, all we have to do is add a pointer for the Berry pocket again.
-```diff
- .tilemap
- ; ITEM_POCKET
- db $00, $04, $04, $04, $01 ; top border
- db $06, $07, $08, $09, $0a ; Items
- db $02, $05, $05, $05, $03 ; bottom border
- ; BALL_POCKET
- db $00, $04, $04, $04, $01 ; top border
- db $15, $16, $17, $18, $19 ; Balls
- db $02, $05, $05, $05, $03 ; bottom border
- ; KEY_ITEM_POCKET
- db $00, $04, $04, $04, $01 ; top border
- db $0b, $0c, $0d, $0e, $0f ; Key Items
- db $02, $05, $05, $05, $03 ; bottom border
- ; TM_HM_POCKET
- db $00, $04, $04, $04, $01 ; top border
- db $10, $11, $12, $13, $14 ; TM/HM
- db $02, $05, $05, $05, $03 ; bottom border
-+; BERRY_POCKET
-+ db $00, $04, $04, $04, $01 ; top border
-+ db $1a, $1b, $1c, $1d, $1e ; Berries
-+ db $02, $05, $05, $05, $03 ; bottom border
-```
-These are tilemaps for the pocket name labels in pack_menu.png. Each one is three rows of five tiles each, with tile indexes starting at 0. Take a look at pack_menu.png and notice how the hexadecimal indexes here correspond to tiles that form sensible pictures.
```diff
BallsPocketMenuHeader:
@@ -845,7 +824,39 @@ These are tilemaps for the pocket name labels in pack_menu.png. Each one is thre
We saw `BallsPocketMenuHeader` used in the subroutines for the Start Menu Pack and the battle Pack, and `PC_Mart_BallsPocketMenuHeader` in the subroutine for the Pack when depositing or selling. Here they're finally being defined. And since we created the corresponding names `BerryPocketMenuHeader` and `PC_Mart_BerryPocketMenuHeader`, they need defining too; as usual, we can just copy whatever the Ball pocket does and substitute "Berry" for "Ball".
-## 10. Update the Crystal-only Pack engine
+## 10. Create/Edit páck_menu.tilemap
+
+![gfx/pack/pack_menu.tilemap](https://imgur.com/a/qluhv7j)
+
+Remember that at the start of this tutorial you were told to install a tilemap editor? This is why you need it. Open Tilemap Studio, select Tilemap > Open and, in your local repo, select [gfx/pack/pack_menu.tilemap](.../blob/master/gfx/pack/pack_menu.tilemap). In the Tilemap Options window, select "Plain Tiles" as the format. From there, resize the Tilemap to 5x15 and edit it so that "Berries" is the third box in the tilemap, just like in the image presented above.
+
+**NOTE**: In case you're using an old version of this repo, you'll have to select Tileset > Load and then your new [gfx/pack/pack_menu.png](.../blob/master/gfx/pack/pack_menu.png). After that, select Tilemap > New and, in the New Tilemap window, adjust the tilemap size to 5x15, with the Plain Tiles format. Also, change this in [engine/items/pack.asm](.../blob/master/engine/items/pack.asm):
+
+```diff
+-.tilemap: ; 5x12
++.tilemap: ; 5x15
+- ; ITEM_POCKET
+- db $00, $04, $04, $04, $01 ; top border
+- db $06, $07, $08, $09, $0a ; Items
+- db $02, $05, $05, $05, $03 ; bottom border
+- ; BALL_POCKET
+- db $00, $04, $04, $04, $01 ; top border
+- db $15, $16, $17, $18, $19 ; Balls
+- db $02, $05, $05, $05, $03 ; bottom border
+- ; KEY_ITEM_POCKET
+- db $00, $04, $04, $04, $01 ; top border
+- db $0b, $0c, $0d, $0e, $0f ; Key Items
+- db $02, $05, $05, $05, $03 ; bottom border
+- ; TM_HM_POCKET
+- db $00, $04, $04, $04, $01 ; top border
+- db $10, $11, $12, $13, $14 ; TM/HM
+- db $02, $05, $05, $05, $03 ; bottom border-
++; the 5x3 pieces correspond to *_POCKET constants
++INCBIN "gfx/pack/pack_menu.tilemap"
+```
+
+
+## 11. Update the Crystal-only Pack engine
Edit [engine/items/pack_kris.asm](../blob/master/engine/items/pack_kris.asm):
@@ -853,15 +864,15 @@ Edit [engine/items/pack_kris.asm](../blob/master/engine/items/pack_kris.asm):
PackFGFXPointers:
dw PackFGFX + (15 tiles) * 1 ; ITEM_POCKET
dw PackFGFX + (15 tiles) * 3 ; BALL_POCKET
++ dw PackFGFX + (15 tiles) * 4 ; BERRY_POCKET
dw PackFGFX + (15 tiles) * 0 ; KEY_ITEM_POCKET
dw PackFGFX + (15 tiles) * 2 ; TM_HM_POCKET
-+ dw PackFGFX + (15 tiles) * 4 ; BERRY_POCKET
```
This is just like `PackGFXPointers`, but for the Crystal-only girl's Pack.
-## 11. Update Kurt's Apricorn script
+## 12. Update Kurt's Apricorn script
If you did not change the Apricorns' pocket, then skip this step.
@@ -881,7 +892,7 @@ Kurt's script to turn Apricorns into Balls assumes they're still in the Item poc
Just use your text editor to find all five occurrences of "`wNumItems`" in the file, and make that one-line change to all of them.
-## 12. Fix build errors
+## 13. Fix build errors
We're almost finished, but if you run `make` now, it gives an error: