pret / pokecrystal Goto Github PK
View Code? Open in Web Editor NEWDisassembly of Pokémon Crystal
Home Page: https://pret.github.io/pokecrystal/
Disassembly of Pokémon Crystal
Home Page: https://pret.github.io/pokecrystal/
Reverse engineer the trading protocol and whatever related functions in the ROM.
Sym files are tremendously helpful when using bgb, and there should be python tools to support this.
Have a way to replace the Suicune/Unown movie with the intro from G/S.
All of the python should be packaged up into an egg, possibly in its own repository (keeping the git history in tact). Unit tests should be moved into extras/tests/
or whatever module name it ends up being.
bank 44
3626dde started preprocessing all included files. This makes preprocessing files in text/ redundant, and actually wasteful since they are preprocessed twice.
Later fleshing out of preprocessing will deal with this. What will it entail?
These use their own command macros. There are $b0 commands in all ($01-$af, plus $ff (end)).
command pointers @ $3fd28
move effect pointers @ $271f4
move effects @ $2732e
effect_commands = {
0x01: 'checkturn', # (automatically used at the beginning of every turn. not found in move effects)
0x02: 'checkobedience',
0x03: 'usedmovetext',
0x04: 'doturn', # (bide, dig, struggle etc)
0x14: 'sleeptarget',
0x15: 'draintarget',
0x16: 'drainsleep',
0x17: 'burntarget',
0x18: 'freezetarget',
0x19: 'paralyzetarget',
0x1a: 'halvetargetdefense',
0x1b: 'mirrormove',
# 1c: unknown
0x27: 'recoil',
0x3a: 'charge',
0x54: 'curse',
0x55: 'protect',
0x56: 'spikes',
0x57: 'foresight',
0x58: 'perishsong',
0x59: 'startsandstorm',
0x5a: 'endure',
0x5b: 'checkcurl',
0x5c: 'rolloutpower',
0x5d: 'effect0x5d', # unused
0x5e: 'furycutter',
0x5f: 'attract',
0x60: 'checkhappiness',
0x61: 'present',
0x63: 'checkfrustration',
0x64: 'safeguard',
0x66: 'getmagnitude',
0x67: 'batonpass',
0x68: 'pursuit',
0x69: 'clearhazards',
0x6a: 'healmorn',
0x6b: 'healday',
0x6c: 'healnite',
0x6d: 'hiddenpower',
0x6e: 'startrain',
0x6f: 'startsun',
0x70: 'attackup',
0x71: 'defenseup',
0x72: 'speedup',
0x73: 'specialattackup',
0x74: 'specialdefenseup',
0x75: 'accuracyup',
0x76: 'evasionup',
0x77: 'attackup2',
0x78: 'defenseup2',
0x79: 'speedup2',
0x7a: 'specialattackup2',
0x7b: 'specialdefenseup2',
0x7c: 'accuracyup2',
0x7d: 'evasionup2',
0x7e: 'attackdown',
0x7f: 'defensedown',
0x80: 'speeddown',
0x81: 'specialattackdown',
0x82: 'specialdefensedown',
0x83: 'accuracydown',
0x84: 'evasiondown',
0x85: 'attackdown2',
0x86: 'defensedown2',
0x87: 'speeddown2',
0x88: 'specialattackdown2',
0x89: 'specialdefensedown2',
0x8a: 'accuracydown2',
0x8b: 'evasiondown2',
0x8c: 'statmessageuser',
0x8d: 'statmessagetarget',
0x8e: 'applystatuser',
0x8f: 'applystattarget',
0x92: 'checkstat',
0x94: 'fakeout',
0x95: 'bellydrum',
0x96: 'psychup',
0x99: 'checkdig',
0x9a: 'mirrorcoat',
0x9c: 'delayhit',
0x9d: 'checkminimize',
0x9e: 'skipsuncharge',
0x9f: 'thunderaccuracy',
0xa0: 'teleport',
0xa4: 'allstatsup',
0xaa: 'wait',
0xab: 'hittarget',
0xaf: 'curl',
0xff: 'endmove',
}
Extract and decompress the tilesets. Include them in main.asm
.
There should be a few comments pointing to where the encounter/wilds tables are used.
The build should fail almost immediately if there's no baserom.gbc file present. There's no reason to take two or three seconds.
The existing main.asm is hard to follow. Formatting conventions are inconsistent and content is disorganized.
Proposed:
Example bank:
; ========================= B A N K 3 A =========================
; Sound engine and music/sound effect pointers
SECTION "bank3A", DATA, BANK[$3A]
; The entire sound engine. Interfaces are in bank 0
INCLUDE "audio/engine.asm"
; List of what music plays when a trainer notices you
INCLUDE "audio/music_encounters.asm"
; Pointer table for all the music in the game
INCLUDE "audio/music_pointers.asm"
; Empty song
INCLUDE "audio/music/nothing.s"
; Pointer table for all the cries in the game
INCLUDE "audio/cry_pointers.asm"
; Pointer table for all the sound effects in the game
INCLUDE "audio/sfx_pointers.asm"
; The remainder of the bank is taken up by music
Music_Route36: INCLUDE "audio/music/route36.s"
Music_RivalBattle: INCLUDE "audio/music/rivalbattle.s"
Music_RocketBattle: INCLUDE "audio/music/rocketbattle.s"
Music_ElmsLab: INCLUDE "audio/music/elmslab.s"
Music_DarkCave: INCLUDE "audio/music/darkcave.s"
Music_JohtoLeader: INCLUDE "audio/music/johtoleader.s"
Music_Champion: INCLUDE "audio/music/champion.s"
Music_SSAqua: INCLUDE "audio/music/ssaqua.s"
Music_NewBarkTown: INCLUDE "audio/music/newbarktown.s"
Music_GoldenrodCity: INCLUDE "audio/music/goldenrodcity.s"
Music_VermilionCity: INCLUDE "audio/music/vermilioncity.s"
Music_TitleScreen: INCLUDE "audio/music/titlescreen.s"
Music_RuinsOfAlphInside: INCLUDE "audio/music/ruinsofalphinside.s"
Music_LookPokemaniac: INCLUDE "audio/music/lookpokemaniac.s"
Music_TrainerVictory: INCLUDE "audio/music/trainervictory.s"
; ========================= B A N K 3 B =========================
; Songs
SECTION "bank3B", DATA, BANK[$3B]
; ...
A map editor would be nice to have.
Since I wrote a custom preprocessor, I suppose I should also make some explicit documentation on how to add new python-based macros to the preprocessor.
The original reason for making our own preprocessor was the textpre.awk
script in pokered. When making pokered, textpre.awk
was used to convert quotes in main.asm
to bytes before passing the input on to rgbds
.
To reduce the number of dependencies, textpre.awk
was rewritten into python as preprocessor.py
. The preprocessor grew to accommodate macros because of the stability issues in rgbds
. Adding macros in asm seems to cause rgbds to want to crash more frequently, so avoiding extra load on rgbds as much as possible is a high priority.
Unfortunately, this means that we have written our own custom preprocessor and must support it with documentation and testing.
parse and dump base stats into main.asm
$1f60 bytes ($20 * 251) from $51424 to $53384
struct: http://bulbapedia.bulbagarden.net/wiki/Pok%C3%A9mon_base_stats_data_structure_in_Generation_II
Parse/dump
Oops, looks like we're missing trainer money. See #48.
< padz> 1.1 is basically a bug list so its more interesting than some incbinned boilerplate
SRAM-related code should be disassembled. It will help understand the WRAM layout for sure.
./dl-libs.sh
Otherwise the ant
build step will fail.
When comparing red/crystal ROMs in comparator.py, it would be nice to allow for a percent variation to account for different pointers.
The docstring in vba.py is currently missing information about mercurial/hg for grabbing vba-clojure.
Extract the frontpics and include them from main.asm
.
Figure out the animations and insert them.
# structure:
# the actual animation (top-level)
# commands come in pairs of bytes:
# frame #, duration: frame 0 is the original pic (no change)
# setrepeat #: sets the number of times to repeat the loop defined by dorepeat
# dorepeat #: repeats from command # (starting from 0)
# end
# main animations (played everywhere)
anim_table = 0xd0695
unown_anims = 0xd2229
egg_anim = 0xd1696
# there are extra animations, appended to the main animation
# used for the status screen (usually blinks and tail wags)
extra = 0xd16a3
unown_extra = 0xd23d1
egg_extra = 0xd2222
# affected tile locations use bitmasks
# a bitstream is layered over the pic
# the stream is read from the least-significant bit,
# and applied the same way the base pic is drawn (descending, left->right)
bitmasks = 0xd24ef
unown_bitmasks = 0xd3ad3
egg_bitmasks = 0xd3acf
# tiles used in each frame
# frame definition structure:
# first byte is the bitmask used for this frame
# following bytes are tile ids mapped to each bit in the mask
# all pointers are in bank $35 (besides unowns)
kanto_tiles = 0xd4000
# kanto mons are directly after, but johto mons are in bank $36
johto_tiles = 0xd412e
unown_tiles = 0xd99a9
egg_tiles = 0xd998b
Expected behavior: Automatically compress modified uncompressed files. Otherwise, use existing lz files.
Traceback (most recent call last):
File "prequeue.py", line 16, in <module>
preprocessor.preprocess(preprocessor.macros)
File "/home/kanzure/code/pokecrystal3/preprocessor.py", line 639, in preprocess
read_line(l, skippable_macros, macro_table)
File "/home/kanzure/code/pokecrystal3/preprocessor.py", line 615, in read_line
macro_translator(macro, token, asm, skippable_macros)
File "/home/kanzure/code/pokecrystal3/preprocessor.py", line 541, in macro_translator
raise Exception("line is: " + str(line) + " and macro is: " + str(macro))
Exception: line is: db $0, $56, $51 and macro is: extras.pokemontools.crystal.ItemFragment
make: *** [pokecrystal.o] Error 1
Temporary fix: 8fe7f4c
The label processing code in extras/
is getting ridiculous. There are a few separate locations where label processing code is implemented:
class Label
in crystal.py
crystal.py
crystal.py
labels.py
class RomStr
in romstr.py
These should be consolidated and merged into one location. I bet there might even be one or two functions that are conceptually similar.
$ python dump_sections.py
Traceback (most recent call last):
File "dump_sections.py", line 126, in <module>
output = dump_sections(baserom)
File "dump_sections.py", line 83, in dump_sections
last_bank = calculate_bank_quantity(path, bank_size=bank_size)
File "dump_sections.py", line 46, in calculate_bank_quantity
return float(os.lstat(path).st_size) / bank_size
OSError: [Errno 2] No such file or directory: 'baserom.gbc'
and then:
$ python dump_sections.py
Traceback (most recent call last):
File "dump_sections.py", line 126, in <module>
output = dump_sections(baserom)
File "dump_sections.py", line 92, in dump_sections
banks = range(initial_bank, last_bank)
TypeError: range() integer end argument expected, got float.
wtf?
The Makefile's image conversion targets are unreasonably long.
Custom image handling (such as transposing tile arrangements) is file-specific and inconsistent. The existing implementation doesn't come close to covering even all existing cases, and isn't scalable.
A filesystem abstraction like storing image metadata as yaml, json or similar in the same directory as the image risks fragmentation and adds a layer of complexity.
One metadata file at the top level would be sufficient. Existing makefile logic
gfx/pics/%/back.lz:: gfx/pics/%/back.png
$(PYTHON) $(POKEMONTOOLS)/gfx.py png-to-lz --vert $<
gfx/pics/%/back.png:: gfx/pics/%/back.lz
$(PYTHON) $(POKEMONTOOLS)/gfx.py lz-to-png --vert $<
could be condensed to
back:
transpose: lz
which python could then interpret as
any image file named back.% will be transposed in conversion to and from lz
Writing something like:
db "Farfetch'","d"
will cause the text processor to check the character after the apostrophe to see what letter it is which will load a different text tile ('d, 's etc) but it does not check to see if the apostrophe is the last character of the string, and if the apostrophe is the last character of the string, compiling results in "IndexError: string index out of range".
Make installation more reasonable on all platforms.
Precautionary.
Proposed:
audio/
music/
ssaqua.s
sfx/
001.s
cry/
001.s
cry_pointers.asm
engine.asm
music_pointers.asm
music_encounters.asm
sfx_pointers.asm
gfx/
attacks/
credits/
pics/
backpics/
001.2bpp
001.lz
frontpics/
001.2bpp
001.lz
001a.2bpp
trainers/
falkner.2bpp
falkner.lz
intro/
tilemaps/
01.bin
01.lz
suicune_closeup.2bpp
suicune_closeup.lz
misc/
ow/
tilesets/
01.2bpp
01.lz
title/
maps/
newbarktown.blk
tilesets/
01/
blocks.bin
collision.bin
palettes.bin
text/
sweethoney.tx
extras/
same as before
Parse/dump
Figure out link battles.
http://nocash.emubase.de/pandocs.htm#serialdatatransferlinkcable
Extract the backpics and include them from main.asm
.
When random people call you for no reason, they say things like:
“My [$d0ac] and I are getting more in sync with each other.”
The text of the phone calls needs to be added, and the code defining the $d0ac variables does also.
I forked the repo, do adding or changing entries create new pokemon?
https://github.com/kanzure/pokecrystal/tree/master/stats/pokedex/entries
A MIDI importer would be a boon to anyone looking to edit music sanely.
maps/BattleTower1F.asm:INCBIN "baserom.gbc",$9e4be,$9e4e4 - $9e4be
maps/BattleTowerBattleRoom.asm:INCBIN "baserom.gbc",$9f50b,$9f52e-$9f50b
maps/BattleTowerHallway.asm:INCBIN "baserom.gbc",$9f5cb,$9f5dc - $9f5cb
maps/BlackthornGym2F.asm:INCBIN "baserom.gbc",$19572b,$33
maps/CeladonDeptStore6F.asm:INCBIN "baserom.gbc",$71203,$47
maps/CeladonDeptStoreElevator.asm:INCBIN "baserom.gbc",$713d0,$713d8 - $713d0
maps/CeladonGameCorner.asm:INCBIN "baserom.gbc",$721cd,$721d0 - $721cd
maps/CeladonGameCornerPrizeRoom.asm:INCBIN "baserom.gbc",$72790,$38
maps/CeladonGameCornerPrizeRoom.asm:INCBIN "baserom.gbc",$72877,$41
maps/DragonsDenB1F.asm:INCBIN "baserom.gbc",$18c932,$14
maps/DragonShrine.asm:INCBIN "baserom.gbc",$18d215,$aa
maps/EarlsPokemonAcademy.asm:INCBIN "baserom.gbc",$68ae1,$2a
maps/GoldenrodCity.asm:INCBIN "baserom.gbc",$198967,$33
maps/GoldenrodDeptStore6F.asm:INCBIN "baserom.gbc",$56478,$564bf - $56478
maps/GoldenrodDeptStoreElevator.asm:INCBIN "baserom.gbc",$566e0,$566fe - $566e0
maps/GoldenrodGameCorner.asm:INCBIN "baserom.gbc",$56cc9,$38
maps/GoldenrodGameCorner.asm:INCBIN "baserom.gbc",$56db0,$56df1 - $56db0
maps/GoldenrodPokeComCenter2FMobile.asm:INCBIN "baserom.gbc",$62602,$62624 - $62602
maps/GoldenrodPokeComCenter2FMobile.asm:INCBIN "baserom.gbc",$6264c,$25
maps/IcePathB1F.asm:INCBIN "baserom.gbc",$7e4c2,$7e50a - $7e4c2
maps/IcePathB1F.asm:INCBIN "baserom.gbc",$7e512,$1b
maps/KrissHouse2F.asm:INCBIN "baserom.gbc",$7abc9,$7abcc - $7abc9
In Pokémon stats, use a macro for TM/HM. See the “; learnset” under BulbasaurBaseStats in pokéred for an example of what we want to replace. Instead, it should be something like “TMHM 1, 2, 4, 7, 55”.
The README says https://github.com/bentley/rgbds/ is needed to assemble and on rgdbs's README is says Windows builds are available here: http://anthony.bentley.name/rgbds/
however that link is dead.
Any clues on how to get this assembling on Windows?
The only part of this that's been touched is the surf check.
There should just be a comment about preprocessing asm to tx, instead of dumping out that huge line.
See http://hax.iimarck.us/files/scriptingcodes_eng.htm#Marke1C
This list is not complete and is also wrong for Crystal.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.