Skip to content

Commit

Permalink
Implement the newbox PC storage system (#608)
Browse files Browse the repository at this point in the history
(Squashed from the `newbox` branch)

Many thanks to FIQ for rewriting the backend to (a) navigate all the boxes without saving, and (b) store 16 boxes instead of 14 (320 Pokémon instead of 280)! Also for a Gen 3+-style frontend with colored icons and Menu/Swap/Item modes. And to darsh for writing BSP scripts so that Prism's `bspcomp` can patch old save files as far back as 2019.

The `box_struct` is no longer a subset of `party_struct`; instead, `party_struct` is encoded to `savemon_struct` on deposit and decoded on withdraw. (They still begin with mostly the same fields, but `savemon_struct` stores a single PP Up byte and has 7-bit encoded nickname and OT fields with a checksum in the 8th bits. This means that PP as well as HP and status will be restored on deposit.)

Long-term plans include using redrawn icons by choosh based on Crystal Clear, with the same palettes as full-size sprites; and rearranging more of the struct fields to allow 10-bit mon, move, and item IDs (up to 510 of each), 20-bit OT ID (6 digits, 000000-999999), or even 5-bit IVs (0-31 instead of 0-15).

Fixes #510

Co-authored-by: Fredrik Ljungdahl <[email protected]>
Co-authored-by: itsdarsh <[email protected]>
  • Loading branch information
3 people authored Mar 20, 2021
1 parent dbdc9c6 commit 6303b29
Show file tree
Hide file tree
Showing 111 changed files with 13,609 additions and 5,272 deletions.
12 changes: 12 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ jobs:
mv polishedcrystal-3.0.0-beta.gbc build/polishedcrystal-3.0.0-faithful-debug-beta.gbc
mv polishedcrystal-3.0.0-beta.sym build/polishedcrystal-3.0.0-faithful-debug-beta.sym
make tidy
make bsp
mv polishedcrystal-3.0.0-beta.bsp build/polishedcrystal-3.0.0-beta.bsp
popd
- name: Delete old release
id: delete_release
Expand Down Expand Up @@ -145,3 +147,13 @@ jobs:
asset_path: ./polishedcrystal/build/polishedcrystal-3.0.0-faithful-debug-beta.sym
asset_name: polishedcrystal-3.0.0-beta-${{ env.SHORT_SHA }}-faithful-debug.sym
asset_content_type: text/plain
- name: Upload BSP
id: upload-bsp
uses: actions/[email protected]
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./polishedcrystal/build/polishedcrystal-3.0.0-beta.bsp
asset_name: polishedcrystal-3.0.0-beta-${{ env.SHORT_SHA }}.bsp
asset_content_type: application/octet-stream
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*.map
*.sym
*.exe
*.bsp
*.h.gch
*.pyc
*$py.class
Expand Down
2 changes: 1 addition & 1 deletion CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Pokémon Polished Crystal would never have been finished without the help of man
* luckytyphlosion for performance optimizations to the game engine, and a 60FPS overworld.
* The TPP Anniversary Crystal 251 dev team for making their code publically usable (specifically: the Move Relearner, automatic box switching, Gen VI money loss, and caught data stats page code).
* Sanqui for the music player with piano roll visualization.
* ax6 for porting the xorshift+ PRNG from Prism.
* ax6 for porting the xorshift+ PRNG from Prism as well as developing bsp and related patching functions originally for Prism.
* MeroMero for the in-battle color inversion code, Smeargle color code, and some move animations.
* kroc for the no-RTC code.
* VictoriaLacroix for the Running Shoes routine.
Expand Down
16 changes: 12 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ gfx/misc.o


.SUFFIXES:
.PHONY: clean tidy crystal faithful nortc debug monochrome freespace tools
.PHONY: clean tidy crystal faithful nortc debug monochrome freespace tools bsp
.SECONDEXPANSION:
.PRECIOUS: %.2bpp %.1bpp
.SECONDARY:
Expand All @@ -82,15 +82,17 @@ clean: tidy
find gfx \( -name '*.[12]bpp' -o -name '*.2bpp.vram[012]' -o -name '*.2bpp.vram[012]p' \) -delete
find gfx/pokemon -mindepth 1 \( -name 'bitmask.asm' -o -name 'frames.asm' -o -name 'front.animated.tilemap' -o -name 'front.dimensions' \) -delete
find data/tilesets -name '*_collision.bin' -delete
$(MAKE) clean -C tools/

tidy:
rm -f $(crystal_obj) $(wildcard $(NAME)-*.gbc) $(wildcard $(NAME)-*.map) $(wildcard $(NAME)-*.sym)
$(MAKE) clean -C tools/
rm -f $(crystal_obj) $(wildcard $(NAME)-*.gbc) $(wildcard $(NAME)-*.map) $(wildcard $(NAME)-*.sym) $(wildcard $(NAME)-*.bsp)

freespace: ROM_NAME = $(NAME)-$(VERSION)
freespace: crystal
freespace: crystal tools/bankends
tools/bankends $(ROM_NAME).map > bank_ends.txt

bsp: $(NAME)-$(VERSION).bsp


define DEP
$1: $2 $$(shell tools/scan_includes $2)
Expand All @@ -109,6 +111,10 @@ endif
$(RGBDS_DIR)rgbfix $(RGBFIX_FLAGS) $@
tools/bankends -q $(ROM_NAME).map

.bsp: tools/bspcomp
%.bsp: $(wildcard bsp/*.txt)
cd bsp; ../tools/bspcomp patch.txt ../$@; cd ..


gfx/battle/lyra_back.2bpp: rgbgfx += -h

Expand Down Expand Up @@ -163,6 +169,8 @@ gfx/pokegear/pokegear_sprites.2bpp: tools/gfx += --trim-whitespace

gfx/pokemon/%/back.2bpp: rgbgfx += -h

gfx/pc/obj.2bpp: gfx/pc/modes.2bpp gfx/pc/bags.2bpp ; cat $^ > $@

gfx/slots/slots_1.2bpp: tools/gfx += --trim-whitespace
gfx/slots/slots_2.2bpp: tools/gfx += --interleave --png=$<
gfx/slots/slots_3.2bpp: tools/gfx += --interleave --png=$< --remove-duplicates --keep-whitespace --remove-xflip
Expand Down
5 changes: 5 additions & 0 deletions audio/music_player.asm
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ endc
MusicPlayer::
call ClearTileMap

ld a, LOW(LCDMusicPlayer)
ldh [hFunctionTargetLo], a
ld a, HIGH(LCDMusicPlayer)
ldh [hFunctionTargetHi], a

; Load palette
ld hl, rIE
set LCD_STAT, [hl]
Expand Down
93 changes: 93 additions & 0 deletions bsp/apply_party_patches.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
ApplyPartyPatches:
; #1: callback, will receive party pointer, nickname pointer, OT pointer, location (0 = party, 1 = box, 2 = daycare)
push #e
push #d
push #c
push #b
push #a
set #a, #1
set #1, 5
call GetGameDataOffsetConstant
set #1, #result
call GetGameDataPointer
seek #result
readbyte #temp
add #1, #result, 8
add #2, #result, 0x16a
add #3, #result, 0x128
set #4, #zero
callnz #temp, .apply_to_list
set #1, 6
call GetGameDataOffsetConstant
set #1, #result
call GetGameDataPointer
seek #result
readbyte #temp
shiftleft #temp, 31 ; nonzero if bit 0 is set
callnz #temp, .daycare_mon
set #1, 7
call GetGameDataOffsetConstant
set #1, #result
call GetGameDataPointer
seek #result
readbyte #temp
shiftleft #temp, 31
; there are two extra bytes for the daycare lady we need to skip
; (#1 should end up on sBreedmon2, not sBreedmon2Item)
readhalfword #result ; move file pointer ahead
pos #result
callnz #temp, .daycare_mon
set #b, sBox1_v6
call .boxes
set #b, sBox8_v6
call .boxes
pop #a
pop #b
pop #c
pop #d
pop #e
return

.boxes
set #c, 7
.box_loop
seek #b
readbyte #temp
add #1, #b, 22
add #2, #b, 882
add #3, #b, 662
set #4, 1
callnz #temp, .apply_to_list
add #b, BOX_SIZE_v6
decrement #c
jumpnz #c, .box_loop
return

.daycare_mon
add #1, #result, 23
add #2, #result, 1
add #3, #result, 12
set #4, 2
rotateleft #temp, 1
.apply_to_list
set #d, #temp
set #e, #4
.loop
push #3
push #2
push #1
set #4, #e
call #a
pop #1
set #4, PARTYMON_STRUCT_LENGTH
jumpz #e, .length_OK
set #4, BOXMON_STRUCT_LENGTH
.length_OK
add #1, #4
pop #2
add #2, NAME_LENGTH
pop #3
add #3, NAME_LENGTH
decrement #d
jumpnz #d, .loop
return
90 changes: 90 additions & 0 deletions bsp/constants.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
; size constants
define BANK_SIZE, 0x4000
define BANKS, 0x80
define ROM_SIZE, 0x200000
define HASH_SIZE, 20
define SAVE_SIZE, 0x8000

; SRAM pointers
define sPartyMail, 0x0600
define sMailbox, 0x0835
define sBackupMailbox, 0x0a0c
define sSaveVersion, 0x0be2
define sBackupOptions, 0x1200
define sBackupCheckValue1, 0x1207
define sBackupGameData, 0x1208
define sBackupChecksum, 0x1f0d
define sBackupCheckValue2, 0x1f0f
define sOptions, 0x2000
define sCheckValue1, 0x2007
define sGameData, 0x2008
define sChecksum, 0x2d0d
define sCheckValue2, 0x2d0f
define sNewBox1, 0x2d10
define sBackupNewBox1, 0x2f20
define sLinkBattleRecord, 0x3266
define sByteBeforeHallOfFame, 0x32bf
define sBoxMons1, 0x4000
define sBoxMons1UsedEntries, 0x5fc6
define sBoxMons2, 0x6000
define sBoxMons2UsedEntries, 0x7fc6

; game data offsets
define PLAYER_NAME_OFFSET, 0x003
define ITEMS_OFFSET, 0x38d
define MEDICINE_OFFSET, 0x425
define BALLS_OFFSET, 0x471
define BERRIES_OFFSET, 0x4a5
define PC_ITEMS_OFFSET, 0x4e5
define BOX_NAMES_OFFSET, 0x6e1
define MAP_GROUP_OFFSET, 0x834
define PARTY_COUNT_OFFSET, 0x856
define PARTY_MON_OT_OFFSET, 0x97e
define POKEDEX_CAUGHT_OFFSET, 0xa0b
define DAYCARE_MAN_OFFSET, 0xa6a
define BREED_MON_1_NICK_OFFSET, 0xa6b
define BREED_MON_1_OT_OFFSET, 0xa76
define DAYCARE_LADY_OFFSET, 0xaa1
define BREED_MON_2_NICK_OFFSET, 0xaa4
define BREED_MON_2_OT_OFFSET, 0Xaaf
define EGG_MON_NICK_OFFSET, 0xada
define MAGIKARP_RECORD_HOLDER_NAME_OFFSET, 0xb6b

; SRAM sizes
define GAME_DATA_SIZE, 0xb7b
define BOX_SIZE, 0x3d4

; struct lengths
define PARTYMON_STRUCT_LENGTH, 48
define BOXMON_STRUCT_LENGTH, 32
define NAME_LENGTH, 11
define BOX_NAME_LENGTH, 9
define PLAYER_NAME_LENGTH, 8

; pokemon struct offsets
define MOVES_OFFSET, 2
define FORM_OFFSET, 21
define PP_OFFSET, 22
define CAUGHTBALL_OFFSET, 28

; pokemon struct constants
define NUM_MOVES, 4
define PP_MASK, 0x3f
define PP_UP_MASK, 0xc0
define FORM_MASK, 0x1f

; pokemon constants
define GYARADOS, 0x82

; move constants
define RAGE, 0x63
define SELFDESTRUCT, 0x78 ; becomes Trick Room
define FRESH_SNACK, 0x87
define EXPLOSION, 0x99
define FACADE, 0xab
define MILK_DRINK, 0xd0 ; becomes Shell Smash
define RETURN, 0xd8

; event flags
define EVENT_GOT_SHUCKIE, 74
define EVENT_MANIA_TOOK_SHUCKIE_OR_LET_YOU_KEEP_HIM, 75
Loading

0 comments on commit 6303b29

Please sign in to comment.