summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--audio/engine.asm251
-rw-r--r--battle/magikarp_length.asm220
-rw-r--r--constants.asm23
-rw-r--r--credits.asm824
-rw-r--r--extras/crystal.py507
-rw-r--r--extras/disassemble_map_scripts.py151
-rw-r--r--extras/gbz80disasm.py17
-rw-r--r--extras/map_names.py486
-rw-r--r--extras/pksv.py1
-rw-r--r--extras/vba.py841
-rw-r--r--extras/vba_config.py15
-rw-r--r--gbhw.asm65
-rw-r--r--gfx/debug/color_test.2bppbin0 -> 368 bytes
-rw-r--r--gfx/evo/bubble.2bppbin0 -> 16 bytes
-rw-r--r--gfx/evo/bubble_large.2bppbin0 -> 64 bytes
-rw-r--r--gfx/misc/font.1bpp (renamed from gfx/font.1bpp)bin1024 -> 1024 bytes
-rw-r--r--gfx/misc/font_battle_extra.2bpp (renamed from gfx/font_battle_extra.2bpp)bin512 -> 512 bytes
-rw-r--r--gfx/misc/font_extra.2bpp (renamed from gfx/font_extra.2bpp)bin512 -> 512 bytes
-rw-r--r--gfx/misc/font_inversed.1bpp (renamed from gfx/font_inversed.1bpp)0
-rw-r--r--gfx/misc/pack_f.2bppbin0 -> 960 bytes
-rw-r--r--gfx/misc/unown_font.2bppbin0 -> 432 bytes
-rw-r--r--gfx/ow/misc.2bppbin0 -> 608 bytes
-rw-r--r--gfx/special/celebi/1.2bpp1
-rw-r--r--gfx/special/celebi/2.2bppbin0 -> 64 bytes
-rw-r--r--gfx/special/celebi/3.2bppbin0 -> 64 bytes
-rw-r--r--gfx/special/celebi/4.2bppbin0 -> 64 bytes
-rw-r--r--gfx/special/celebi/leaf.2bppbin0 -> 64 bytes
-rw-r--r--joypad.asm275
-rw-r--r--main.asm1370
-rw-r--r--maps/KrissHouse2F.asm69
-rw-r--r--maps/KurtsHouse.asm35
-rw-r--r--pokecrystal.asm1
-rw-r--r--preprocessor.py5
-rw-r--r--requirements.txt (renamed from requirement.txt)0
-rw-r--r--scripting.asm3127
-rw-r--r--vblank.asm78
-rw-r--r--wram.asm37
37 files changed, 6993 insertions, 1406 deletions
diff --git a/audio/engine.asm b/audio/engine.asm
index a45f6564c..e54bda967 100644
--- a/audio/engine.asm
+++ b/audio/engine.asm
@@ -16,27 +16,27 @@ SoundRestart: ; e8000
push bc
push af
call MusicOff
- ld hl, $ff24 ; channel control registers
+ ld hl, rNR50 ; channel control registers
xor a
- ld [hli], a ; ff24 ; volume/vin
- ld [hli], a ; ff25 ; sfx channels
+ ld [hli], a ; rNR50 ; volume/vin
+ ld [hli], a ; rNR51 ; sfx channels
ld a, $80 ; all channels on
ld [hli], a ; ff26 ; music channels
- ld hl, $ff10 ; sound channel registers
+ ld hl, rNR10 ; sound channel registers
ld e, $04 ; number of channels
.clearsound
; sound channel 1 2 3 4
xor a
- ld [hli], a ; $ff10, $ff15, $ff1a, $ff1f ; sweep = 0
+ ld [hli], a ; rNR10, $ff15, rNR30, $ff1f ; sweep = 0
- ld [hli], a ; $ff11, $ff16, $ff1b, $ff20 ; length/wavepattern = 0
+ ld [hli], a ; rNR11, rNR21, rNR31, rNR41 ; length/wavepattern = 0
ld a, $08
- ld [hli], a ; $ff12, $ff17, $ff1c, $ff21 ; envelope = 0
+ ld [hli], a ; rNR12, rNR22, rNR32, rNR42 ; envelope = 0
xor a
- ld [hli], a ; $ff13, $ff18, $ff1d, $ff22 ; frequency lo = 0
+ ld [hli], a ; rNR13, rNR23, rNR33, rNR43 ; frequency lo = 0
ld a, $80
- ld [hli], a ; $ff14, $ff19, $ff1e, $ff23 ; restart sound (freq hi = 0)
+ ld [hli], a ; rNR14, rNR24, rNR34, rNR44 ; restart sound (freq hi = 0)
dec e
jr nz, .clearsound
@@ -208,10 +208,10 @@ UpdateSound: ; e805c
call FadeMusic
; write volume to hardware register
ld a, [Volume]
- ld [$ff24], a
+ ld [rNR50], a
; write SO on/off to hardware register
ld a, [SoundOutput]
- ld [$ff25], a
+ ld [rNR51], a
ret
; e8125
@@ -251,7 +251,7 @@ UpdateChannels: ; e8125
jr z, .asm_e8159
;
ld a, [SoundInput]
- ld [$ff10], a
+ ld [rNR10], a
.asm_e8159
bit 5, [hl] ; rest
jr nz, .ch1rest
@@ -264,48 +264,48 @@ UpdateChannels: ; e8125
jr .asm_e8175
.asm_e816b
ld a, [$c294]
- ld [$ff13], a
+ ld [rNR13], a
ld a, [$c295]
- ld [$ff14], a
+ ld [rNR14], a
.asm_e8175
bit 0, [hl]
ret z
ld a, [$c292]
ld d, a
- ld a, [$ff11]
+ ld a, [rNR11]
and a, $3f ; sound length
or d
- ld [$ff11], a
+ ld [rNR11], a
ret
.asm_e8184
ld a, [$c292]
ld d, a
- ld a, [$ff11]
+ ld a, [rNR11]
and a, $3f ; sound length
or d
- ld [$ff11], a
+ ld [rNR11], a
ld a, [$c294]
- ld [$ff13], a
+ ld [rNR13], a
ret
.ch1rest
- ld a, [$ff26]
+ ld a, [rNR52]
and a, %10001110 ; ch1 off
- ld [$ff26], a
- ld hl, $ff10
+ ld [rNR52], a
+ ld hl, rNR10
call ClearChannel
ret
.asm_e81a2
ld hl, $c292
ld a, $3f ; sound length
or [hl]
- ld [$ff11], a
+ ld [rNR11], a
ld a, [$c293]
- ld [$ff12], a
+ ld [rNR12], a
ld a, [$c294]
- ld [$ff13], a
+ ld [rNR13], a
ld a, [$c295]
or a, $80
- ld [$ff14], a
+ ld [rNR14], a
ret
.Channel2
@@ -322,31 +322,31 @@ UpdateChannels: ; e8125
ret z
ld a, [$c292]
ld d, a
- ld a, [$ff16]
+ ld a, [rNR21]
and a, $3f ; sound length
or d
- ld [$ff16], a
+ ld [rNR21], a
ret
.asm_e81db ; unused
ld a, [$c294]
- ld [$ff18], a
+ ld [rNR23], a
ld a, [$c295]
- ld [$ff19], a
+ ld [rNR24], a
ret
.asm_e81e6
ld a, [$c292]
ld d, a
- ld a, [$ff16]
+ ld a, [rNR21]
and a, $3f ; sound length
or d
- ld [$ff16], a
+ ld [rNR21], a
ld a, [$c294]
- ld [$ff18], a
+ ld [rNR23], a
ret
.ch2rest
- ld a, [$ff26]
+ ld a, [rNR52]
and a, %10001101 ; ch2 off
- ld [$ff26], a
+ ld [rNR52], a
ld hl, $ff15
call ClearChannel
ret
@@ -354,14 +354,14 @@ UpdateChannels: ; e8125
ld hl, $c292
ld a, $3f ; sound length
or [hl]
- ld [$ff16], a
+ ld [rNR21], a
ld a, [$c293]
- ld [$ff17], a
+ ld [rNR22], a
ld a, [$c294]
- ld [$ff18], a
+ ld [rNR23], a
ld a, [$c295]
or a, $80 ; initial (restart)
- ld [$ff19], a
+ ld [rNR24], a
ret
.Channel3
@@ -377,34 +377,34 @@ UpdateChannels: ; e8125
ret
.asm_e822f ; unused
ld a, [$c294]
- ld [$ff1d], a
+ ld [rNR33], a
ld a, [$c295]
- ld [$ff1e], a
+ ld [rNR34], a
ret
.asm_e823a
ld a, [$c294]
- ld [$ff1d], a
+ ld [rNR33], a
ret
.ch3rest
- ld a, [$ff26]
+ ld a, [rNR52]
and a, %10001011 ; ch3 off
- ld [$ff26], a
- ld hl, $ff1a
+ ld [rNR52], a
+ ld hl, rNR30
call ClearChannel
ret
.asm_e824d
ld a, $3f
- ld [$ff1b], a
+ ld [rNR31], a
xor a
- ld [$ff1a], a
+ ld [rNR30], a
call .asm_e8268
ld a, $80
- ld [$ff1a], a
+ ld [rNR30], a
ld a, [$c294]
- ld [$ff1d], a
+ ld [rNR33], a
ld a, [$c295]
or a, $80
- ld [$ff1e], a
+ ld [rNR34], a
ret
.asm_e8268
push hl
@@ -458,7 +458,7 @@ UpdateChannels: ; e8125
ld a, [$c293]
and a, $f0
sla a
- ld [$ff1c], a
+ ld [rNR32], a
ret
.Channel4
@@ -472,24 +472,24 @@ UpdateChannels: ; e8125
ret
.asm_e82c1 ; unused
ld a, [$c294]
- ld [$ff22], a
+ ld [rNR43], a
ret
.ch4rest
- ld a, [$ff26]
+ ld a, [rNR52]
and a, %10000111 ; ch4 off
- ld [$ff26], a
+ ld [rNR52], a
ld hl, $ff1f
call ClearChannel
ret
.asm_e82d4
ld a, $3f ; sound length
- ld [$ff20], a
+ ld [rNR41], a
ld a, [$c293]
- ld [$ff21], a
+ ld [rNR42], a
ld a, [$c294]
- ld [$ff22], a
+ ld [rNR43], a
ld a, $80
- ld [$ff23], a
+ ld [rNR44], a
ret
; e82e7
@@ -535,15 +535,15 @@ Functione8307: ; e8307
ld hl, Tablee8350
.updatehw
xor a
- ld [$ff10], a ; sweep off
+ ld [rNR10], a ; sweep off
ld a, [hli]
- ld [$ff11], a ; sound length / duty cycle
+ ld [rNR11], a ; sound length / duty cycle
ld a, [hli]
- ld [$ff12], a ; ch1 volume envelope
+ ld [rNR12], a ; ch1 volume envelope
ld a, [hli]
- ld [$ff13], a ; ch1 frequency lo
+ ld [rNR13], a ; ch1 frequency lo
ld a, [hli]
- ld [$ff14], a ; ch1 frequency hi
+ ld [rNR14], a ; ch1 frequency hi
.asm_e8335
ld a, d
inc a
@@ -1192,7 +1192,7 @@ ParseMusic: ; e85e1
jr nz, .ok
; ????
xor a
- ld [$ff10], a ; sweep = 0
+ ld [rNR10], a ; sweep = 0
.ok
; stop playing
; turn channel off
@@ -2352,72 +2352,87 @@ LoadMusic: ; e8b30
; e8b79
PlayCry: ; e8b79
-; input: de = cry id
+; Play cry de using parameters:
+; CryPitch
+; CryEcho
+; CryLength
+
call MusicOff
- ; load cry id
+
+; Overload the music id with the cry id
ld hl, MusicID
ld [hl], e
inc hl
ld [hl], d
- ; seek pointer table
+
+; 3-byte pointers (bank, address)
ld hl, Cries
add hl, de
add hl, de
add hl, de
- ; get bank
+
ld a, [hli]
ld [MusicBank], a
- ; get address
+
ld e, [hl]
inc hl
ld d, [hl]
-; read cry header
- ; get byte at bank:address
+
+; Read the cry's sound header
call FarLoadMusicByte
- ; get top 2 bits (# chs)
+ ; Top 2 bits contain the number of channels
rlca
rlca
- and a, $03
- inc a ; ch count -> loop count
+ and a, 3
+
+; For each channel:
+ inc a
.loop
push af
call LoadChannel
+
ld hl, Channel1Flags - Channel1
add hl, bc
set 5, [hl]
+
ld hl, Channel1Flags2 - Channel1
add hl, bc
set 4, [hl]
- ld hl, $0027
+
+ ld hl, Channel1CryPitch - Channel1
add hl, bc
- ld a, [$c2b0]
+ ld a, [CryPitch]
ld [hli], a
- ld a, [$c2b1]
+ ld a, [CryEcho]
ld [hl], a
- ; are we on the last channel? (music & sfx)
+
+; No tempo for channel 4
ld a, [CurChannel]
- and a, $03
- cp a, $03
+ and a, 3
+ cp 3
jr nc, .start
- ; update tempo
+
+; Tempo is effectively length
ld hl, Channel1Tempo - Channel1
add hl, bc
- ld a, [$c2b2]
+ ld a, [CryLength]
ld [hli], a
- ld a, [$c2b3]
+ ld a, [CryLength+1]
ld [hl], a
.start
call StartChannel
ld a, [$c2bc]
and a
jr z, .next
-; play cry from the side of the monster it's coming from (stereo only)
-; outside of battles cries play on both tracks
- ; is stereo on?
+
+; Stereo only: Play cry from the monster's side.
+; This only applies in-battle.
+
ld a, [Options]
bit 5, a ; stereo
jr z, .next
- ; and [Tracks], [CryTracks]
+
+; [Tracks] &= [CryTracks]
ld hl, Channel1Tracks - Channel1
add hl, bc
ld a, [hl]
@@ -2426,21 +2441,25 @@ PlayCry: ; e8b79
ld hl, Channel1Tracks - Channel1
add hl, bc
ld [hl], a
+
.next
pop af
dec a
jr nz, .loop
- ; save current volume
+
+
+; Cries play at max volume, so we save the current volume for later.
ld a, [LastVolume]
and a
jr nz, .end
+
ld a, [Volume]
ld [LastVolume], a
- ; cries have max volume
ld a, $77
ld [Volume], a
+
.end
- ld a, $01 ; stop playing music
+ ld a, 1 ; stop playing music
ld [SFXPriority], a
call MusicOn
ret
@@ -2454,56 +2473,56 @@ LoadSFX: ; e8c04
jr z, .ch6
res 0, [hl] ; turn it off
xor a
- ld [$ff11], a ; length/wavepattern = 0
+ ld [rNR11], a ; length/wavepattern = 0
ld a, $08
- ld [$ff12], a ; envelope = 0
+ ld [rNR12], a ; envelope = 0
xor a
- ld [$ff13], a ; frequency lo = 0
+ ld [rNR13], a ; frequency lo = 0
ld a, $80
- ld [$ff14], a ; restart sound (freq hi = 0)
+ ld [rNR14], a ; restart sound (freq hi = 0)
xor a
ld [SoundInput], a ; global sound off
- ld [$ff10], a ; sweep = 0
+ ld [rNR10], a ; sweep = 0
.ch6
ld hl, $c1fe ; ch6 on?
bit 0, [hl]
jr z, .ch7
res 0, [hl] ; turn it off
xor a
- ld [$ff16], a ; length/wavepattern = 0
+ ld [rNR21], a ; length/wavepattern = 0
ld a, $08
- ld [$ff17], a ; envelope = 0
+ ld [rNR22], a ; envelope = 0
xor a
- ld [$ff18], a ; frequency lo = 0
+ ld [rNR23], a ; frequency lo = 0
ld a, $80
- ld [$ff19], a ; restart sound (freq hi = 0)
+ ld [rNR24], a ; restart sound (freq hi = 0)
.ch7
ld hl, $c230 ; ch7 on?
bit 0, [hl]
jr z, .ch8
res 0, [hl] ; turn it off
xor a
- ld [$ff1a], a ; sound mode #3 off
- ld [$ff1b], a ; length/wavepattern = 0
+ ld [rNR30], a ; sound mode #3 off
+ ld [rNR31], a ; length/wavepattern = 0
ld a, $08
- ld [$ff1c], a ; envelope = 0
+ ld [rNR32], a ; envelope = 0
xor a
- ld [$ff1d], a ; frequency lo = 0
+ ld [rNR33], a ; frequency lo = 0
ld a, $80
- ld [$ff1e], a ; restart sound (freq hi = 0)
+ ld [rNR34], a ; restart sound (freq hi = 0)
.ch8
ld hl, $c262 ; ch8 on?
bit 0, [hl]
jr z, .chscleared
res 0, [hl] ; turn it off
xor a
- ld [$ff20], a ; length/wavepattern = 0
+ ld [rNR41], a ; length/wavepattern = 0
ld a, $08
- ld [$ff21], a ; envelope = 0
+ ld [rNR42], a ; envelope = 0
xor a
- ld [$ff22], a ; frequency lo = 0
+ ld [rNR43], a ; frequency lo = 0
ld a, $80
- ld [$ff23], a ; restart sound (freq hi = 0)
+ ld [rNR44], a ; restart sound (freq hi = 0)
xor a
ld [NoiseSampleAddressLo], a
ld [NoiseSampleAddressHi], a
@@ -3126,13 +3145,13 @@ ChannelPointers: ; e8fd9
ClearChannels: ; e8fe9
; runs ClearChannel for all 4 channels
; doesn't seem to be used, but functionally identical to SoundRestart
- ld hl, $ff24
+ ld hl, rNR50
xor a
ld [hli], a
ld [hli], a
ld a, $80
ld [hli], a
- ld hl, $ff10
+ ld hl, rNR10
ld e, $04
.loop
call ClearChannel
@@ -3142,19 +3161,19 @@ ClearChannels: ; e8fe9
; e8ffe
ClearChannel: ; e8ffe
-; input: hl = beginning hw sound register ($ff10, $ff15, $ff1a, $ff1f)
+; input: hl = beginning hw sound register (rNR10, $ff15, rNR30, $ff1f)
; output: 00 00 80 00 80
; sound channel 1 2 3 4
xor a
- ld [hli], a ; $ff10, $ff15, $ff1a, $ff1f ; sweep = 0
+ ld [hli], a ; rNR10, $ff15, rNR30, $ff1f ; sweep = 0
- ld [hli], a ; $ff11, $ff16, $ff1b, $ff20 ; length/wavepattern = 0
+ ld [hli], a ; rNR11, rNR21, rNR31, rNR41 ; length/wavepattern = 0
ld a, $08
- ld [hli], a ; $ff12, $ff17, $ff1c, $ff21 ; envelope = 0
+ ld [hli], a ; rNR12, rNR22, rNR32, rNR42 ; envelope = 0
xor a
- ld [hli], a ; $ff13, $ff18, $ff1d, $ff22 ; frequency lo = 0
+ ld [hli], a ; rNR13, rNR23, rNR33, rNR43 ; frequency lo = 0
ld a, $80
- ld [hli], a ; $ff14, $ff19, $ff1e, $ff23 ; restart sound (freq hi = 0)
+ ld [hli], a ; rNR14, rNR24, rNR34, rNR44 ; restart sound (freq hi = 0)
ret
; e900a
diff --git a/battle/magikarp_length.asm b/battle/magikarp_length.asm
new file mode 100644
index 000000000..7b2d5e386
--- /dev/null
+++ b/battle/magikarp_length.asm
@@ -0,0 +1,220 @@
+CalcMagikarpLength: ; fbbfc
+; Return Magikarp's length (in mm) in MagikarpLength (big endian)
+;
+; input:
+; de: EnemyMonDVs
+; bc: PlayerID
+
+; This function is needlessly convoluted, and poorly commented.
+; Reading is discouraged.
+
+; In short, it generates a value between 190 and 1786 using
+; a Magikarp's DVs and its trainer ID. This value is further
+; scrutinized in GetEnemyMon to make longer Magikarp even rarer.
+
+; This is done by calculating the value using operands from
+; a conversion lookup table.
+
+; Our index is calculated by xoring DVs with the trainer ID:
+
+; bc = rrc(rrc(dvs)) xor rrc(id)
+
+; if bc < $a: MagikarpLength = c + 190
+; if bc >= $ff00: MagikarpLength = c + 1370
+; else: MagikarpLength = z*100 + (bc-x)/y
+
+; X, Y, and Z depend on the value of b as follows:
+
+; if b = 0: x = 310, y = 2, z = 3
+; if b = 1: x = 710, y = 4, z = 4
+; if b = 2-9: x = 2710, y = 20, z = 5
+; if b = 10-29: x = 7710, y = 50, z = 6
+; if b = 30-68: x = 17710, y = 100, z = 7
+; if b = 69-126: x = 32710, y = 150, z = 8
+; if b = 127-185: x = 47710, y = 150, z = 9
+; if b = 186-224: x = 57710, y = 100, z = 10
+; if b = 225-243: x = 62710, y = 50, z = 11
+; if b = 244-251: x = 64710, y = 20, z = 12
+; if b = 252-253: x = 65210, y = 5, z = 13
+; if b = 254: x = 65410, y = 2, z = 14
+
+; These values represent arbitrary conversion points.
+
+
+; b = rrcrrc(atkdefdv) xor rrc(id[0])
+
+; id
+ ld h, b
+ ld l, c
+ ld a, [hli]
+ ld b, a
+ ld c, [hl]
+ rrc b
+ rrc c
+
+; dvs
+ ld a, [de]
+ inc de
+ rrca
+ rrca
+ xor b
+ ld b, a
+
+; c = rrcrrc(spdspcdv) xor rrc(id[1])
+
+ ld a, [de]
+ rrca
+ rrca
+ xor c
+ ld c, a
+
+; if bc < $000a:
+ ld a, b
+ and a
+ jr nz, .loadtable
+ ld a, c
+ cp a, $a
+ jr nc, .loadtable
+
+; de = hl = bc + $be
+ ld hl, $be
+ add hl, bc
+ ld d, h
+ ld e, l
+ jr .endtable
+
+.loadtable
+ ld hl, .MagikarpLengthTable
+ ld a, $02
+ ld [$d265], a
+
+.readtable
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+ call .BLessThanD
+ jr nc, .advancetable
+
+; c = bc / [hl]
+ call .BCMinusDE
+ ld a, b
+ ld [$ffb3], a
+ ld a, c
+ ld [$ffb4], a
+ ld a, [hl]
+ ld [$ffb7], a
+ ld b, $02
+ call Divide
+ ld a, [$ffb6]
+ ld c, a
+
+; de = c + 100 * (2 + number of rows down the table)
+ xor a
+ ld [$ffb4], a
+ ld [$ffb5], a
+ ld a, $64
+ ld [$ffb6], a
+ ld a, [$d265]
+ ld [$ffb7], a
+ call Multiply
+ ld b, $00
+ ld a, [$ffb6]
+ add c
+ ld e, a
+ ld a, [$ffb5]
+ adc b
+ ld d, a
+ jr .endtable
+
+.advancetable
+ inc hl ; align to next triplet
+ ld a, [$d265]
+ inc a
+ ld [$d265], a
+ cp a, $10
+ jr c, .readtable
+
+ call .BCMinusDE
+ ld hl, $0640
+ add hl, bc
+ ld d, h
+ ld e, l
+
+.endtable
+ ld h, d
+ ld l, e
+ add hl, hl
+ add hl, hl
+ add hl, de
+ add hl, hl ; hl = de * 10
+
+ ld de, $ff02
+ ld a, $ff
+.loop
+ inc a
+ add hl, de ; - 254
+ jr c, .loop
+
+ ld d, $00
+
+; mod $0c
+.modloop
+ cp a, $0c
+ jr c, .done
+ sub a, $0c
+ inc d
+ jr .modloop
+
+.done
+ ld e, a
+ ld hl, MagikarpLength
+ ld [hl], d
+ inc hl
+ ld [hl], e
+ ret
+; fbc9a
+
+.BLessThanD ; fbc9a
+; return carry if b < d
+ ld a, b
+ cp d
+ ret c
+ ret nc
+; fbc9e
+
+.CLessThanE ; fbc9e
+; unused
+ ld a, c
+ cp e
+ ret
+; fbca1
+
+.BCMinusDE ; fbca1
+; bc -= de
+ ld a, c
+ sub e
+ ld c, a
+ ld a, b
+ sbc d
+ ld b, a
+ ret
+; fbca8
+
+.MagikarpLengthTable ; fbca8
+; ????, divisor
+ dwb $006e, $01
+ dwb $0136, $02
+ dwb $02c6, $04
+ dwb $0a96, $14
+ dwb $1e1e, $32
+ dwb $452e, $64
+ dwb $7fc6, $96
+ dwb $ba5e, $96
+ dwb $e16e, $64
+ dwb $f4f6, $32
+ dwb $fcc6, $14
+ dwb $feba, $05
+ dwb $ff82, $02
+; fbccf
+
diff --git a/constants.asm b/constants.asm
index ec45875d6..8a3d4d080 100644
--- a/constants.asm
+++ b/constants.asm
@@ -3417,15 +3417,20 @@ BATTLETYPE_SUICUNE EQU $0c
; joypad
-NO_INPUT EQU %00000000
-BUTTON_A EQU %00000001
-BUTTON_B EQU %00000010
-SELECT EQU %00000100
-START EQU %00001000
-D_RIGHT EQU %00010000
-D_LEFT EQU %00100000
-D_UP EQU %01000000
-D_DOWN EQU %10000000
+BUTTONS EQU %00010000
+D_PAD EQU %00100000
+
+AUTO_INPUT EQU $ff
+
+NO_INPUT EQU %00000000
+BUTTON_A EQU %00000001
+BUTTON_B EQU %00000010
+SELECT EQU %00000100
+START EQU %00001000
+D_RIGHT EQU %00010000
+D_LEFT EQU %00100000
+D_UP EQU %01000000
+D_DOWN EQU %10000000
; mbc
NUM_SRAM_BANKS EQU 4
diff --git a/credits.asm b/credits.asm
new file mode 100644
index 000000000..d5e4399b9
--- /dev/null
+++ b/credits.asm
@@ -0,0 +1,824 @@
+SATOSHI_TAJIRI EQU 00
+JUNICHI_MASUDA EQU 01
+TETSUYA_WATANABE EQU 02
+SHIGEKI_MORIMOTO EQU 03
+SOUSUKE_TAMADA EQU 04
+TAKENORI_OOTA EQU 05
+KEN_SUGIMORI EQU 06
+MOTOFUMI_FUJIWARA EQU 07
+ATSUKO_NISHIDA EQU 08
+MUNEO_SAITO EQU 09
+SATOSHI_OOTA EQU 10
+RENA_YOSHIKAWA EQU 11
+JUN_OKUTANI EQU 12
+HIRONOBU_YOSHIDA EQU 13
+ASUKA_IWASHITA EQU 14
+GO_ICHINOSE EQU 15
+MORIKAZU_AOKI EQU 16
+KOHJI_NISHINO EQU 17
+KENJI_MATSUSHIMA EQU 18
+TOSHINOBU_MATSUMIYA EQU 19
+SATORU_IWATA EQU 20
+NOBUHIRO_SEYA EQU 21
+KAZUHITO_SEKINE EQU 22
+TETSUJI_OOTA EQU 23
+NCL_SUPER_MARIO_CLUB EQU 24
+SARUGAKUCHO EQU 25
+AKITO_MORI EQU 26
+TAKAHIRO_HARADA EQU 27
+TOHRU_HASHIMOTO EQU 28
+NOBORU_MATSUMOTO EQU 29
+TAKEHIRO_IZUSHI EQU 30
+TAKASHI_KAWAGUCHI EQU 31
+TSUNEKAZU_ISHIHARA EQU 32
+HIROSHI_YAMAUCHI EQU 33
+KENJI_SAIKI EQU 34
+ATSUSHI_TADA EQU 35
+NAOKO_KAWAKAMI EQU 36
+HIROYUKI_ZINNAI EQU 37
+KUNIMI_KAWAMURA EQU 38
+HISASHI_SOGABE EQU 39
+KEITA_KAGAYA EQU 40
+YOSHINORI_MATSUDA EQU 41
+HITOMI_SATO EQU 42
+TORU_OSAWA EQU 43
+TAKAO_OHARA EQU 44
+YUICHIRO_ITO EQU 45
+TAKAO_SHIMIZU EQU 46
+PLANNING EQU 47
+KEITA_NAKAMURA EQU 48
+HIROTAKA_UEMURA EQU 49
+HIROAKI_TAMURA EQU 50
+NORIAKI_SAKAGUCHI EQU 51
+MIYUKI_SATO EQU 52
+GAKUZI_NOMOTO EQU 53
+AI_MASHIMA EQU 54
+MIKIHIRO_ISHIKAWA EQU 55
+HIDEYUKI_HASHIMOTO EQU 56
+SATOSHI_YAMATO EQU 57
+SHIGERU_MIYAMOTO EQU 58
+GAIL_TILDEN EQU 59
+NOB_OGASAWARA EQU 60
+SETH_MCMAHILL EQU 61
+HIROTO_ALEXANDER EQU 62
+TERESA_LILLYGREN EQU 63
+THOMAS_HERTZOG EQU 64
+ERIK_JOHNSON EQU 65
+HIRO_NAKAMURA EQU 66
+TERUKI_MURAKAWA EQU 67
+KAZUYOSHI_OSAWA EQU 68
+KIMIKO_NAKAMICHI EQU 69
+END EQU 70
+CREDITS_UNKNOWN EQU 71
+STAFF EQU 72
+DIRECTOR EQU 73
+CODIRECTOR EQU 74
+PROGRAMMERS EQU 75
+GRAPHICS_DIRECTOR EQU 76
+MONSTER_DESIGN EQU 77
+GRAPHICS_DESIGN EQU 78
+MUSIC EQU 79
+SOUND_EFFECTS EQU 80
+GAME_DESIGN EQU 81
+GAME_SCENARIO EQU 82
+TOOL_PROGRAMMING EQU 83
+PARAMETRIC_DESIGN EQU 84
+SCRIPT_DESIGN EQU 85
+MAP_DATA_DESIGN EQU 86
+MAP_DESIGN EQU 87
+PRODUCT_TESTING EQU 88
+SPECIAL_THANKS EQU 89
+PRODUCERS EQU 90
+EXECUTIVE_PRODUCER EQU 91
+POKEMON_ANIMATION EQU 92
+POKEDEX_TEXT EQU 93
+MOBILE_PRJ_LEADER EQU 94
+MOBILE_SYSTEM_AD EQU 95
+MOBILE_STADIUM_DIR EQU 96
+COORDINATION EQU 97
+COPYRIGHT EQU 98
+US_VERSION_STAFF EQU 99
+US_COORDINATION EQU 100
+TEXT_TRANSLATION EQU 101
+PAAD_TESTING EQU 102
+
+CREDITS_THEEND EQU $f9
+CREDITS_WAIT2 EQU $fa
+CREDITS_MUSIC EQU $fb
+CREDITS_CLEAR EQU $fc
+CREDITS_SCENE EQU $fd
+CREDITS_WAIT EQU $fe
+
+
+ParseCredits: ; 1099aa
+ ld hl, $cf63
+ bit 7, [hl]
+ jp nz, .done
+
+; Wait until the timer has run out to parse the next command.
+ ld hl, CreditsTimer
+ ld a, [hl]
+ and a
+ jr z, .parse
+
+; One tick has passed.
+ dec [hl]
+ jp .done
+
+.parse
+; First, let's clear the current text display,
+; starting from line 5.
+ xor a
+ ld [$ffd4], a
+ hlcoord 0, 5
+ ld bc, 20 * 12
+ ld a, " "
+ call ByteFill
+
+; Then read the script.
+
+.loop
+ call .get
+
+; Commands:
+ cp $ff
+ jp z, .end
+ cp CREDITS_WAIT
+ jr z, .wait
+ cp CREDITS_SCENE
+ jr z, .scene
+ cp CREDITS_CLEAR
+ jr z, .clear
+ cp CREDITS_MUSIC
+ jr z, .music
+ cp CREDITS_WAIT2
+ jr z, .wait2
+ cp CREDITS_THEEND
+ jr z, .theend
+
+; If it's not a command, it's a string identifier.
+
+ push af
+ ld e, a
+ ld d, 0
+ ld hl, CreditsStrings
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld d, [hl]
+ ld e, a
+ pop af
+
+; Strings spanning multiple lines have special cases.
+
+ cp COPYRIGHT
+ jr z, .copyright
+
+ cp STAFF
+ jr c, .staff
+
+; The rest start from line 6.
+
+ hlcoord 0, 6
+ jr .print
+
+.copyright
+ hlcoord 2, 6
+ jr .print
+
+.staff
+ hlcoord 0, 6
+
+.print
+; Print strings spaced every two lines.
+ call .get
+ ld bc, 20 * 2
+ call AddNTimes
+ call PlaceString
+ jr .loop
+
+.theend
+; Display "The End" graphic.
+ call $5c11
+ jr .loop
+
+.scene
+; Update the scene number and corresponding palette.
+ call .get
+ ld [$cf65], a ; scene
+ xor a
+ ld [$cf64], a ; frame
+ call GetCreditsPalette
+ call $32f9 ; update hw pal registers
+ jr .loop
+
+.clear
+; Clear the banner.
+ ld a, $ff
+ ld [$cf64], a ; frame
+ jr .loop
+
+.music
+; Play the credits music.
+ ld de, MUSIC_CREDITS
+ push de
+ ld de, MUSIC_NONE
+ call StartMusic
+ call DelayFrame
+ pop de
+ call StartMusic
+ jp .loop
+
+.wait2
+; Wait for some amount of ticks.
+ call .get
+ ld [CreditsTimer], a
+ jr .done
+
+.wait
+; Wait for some amount of ticks, and do something else.
+ call .get
+ ld [CreditsTimer], a
+
+ xor a
+ ld [$ffd5], a
+ ld a, 1
+ ld [$ffd4], a
+
+.done
+ jp $5951
+
+.end
+; Stop execution.
+ ld hl, $cf63
+ set 7, [hl]
+ ld a, $20
+ ld [$c2a7], a
+ ld a, $5c
+ ld [$c2a9], a
+ ld a, $00
+ ld [$c2aa], a
+ ret
+
+.get
+; Get byte CreditsPos from CreditsScript
+ push hl
+ push de
+ ld a, [CreditsPos]
+ ld e, a
+ ld a, [CreditsPos+1]
+ ld d, a
+ ld hl, CreditsScript
+ add hl, de
+
+ inc de
+ ld a, e
+ ld [CreditsPos], a
+ ld a, d
+ ld [CreditsPos+1], a
+ ld a, [hl]
+ pop de
+ pop hl
+ ret
+; 109a95
+
+
+INCBIN "baserom.gbc", $109a95, $109b2c - $109a95
+
+
+GetCreditsPalette: ; 109b2c
+ call .GetPalAddress
+
+ push hl
+ ld a, 0
+ call .UpdatePals
+ pop hl
+ ret
+
+.GetPalAddress
+; Each set of palette data is 24 bytes long.
+ ld a, [$cf65] ; scene
+ and 3
+ add a
+ add a ; * 8
+ add a
+ ld e, a
+ ld d, 0
+ ld hl, .CreditsPalettes
+ add hl, de
+ add hl, de ; * 3
+ add hl, de
+ ret
+
+.UpdatePals
+; Update the first three colors in both palette buffers.
+
+ push af
+ push hl
+ add $00 ; lo($d000)
+ ld e, a
+ ld a, 0
+ adc $d0 ; hi($d000)
+ ld d, a
+ ld bc, 24
+ call CopyBytes
+
+ pop hl
+ pop af
+ add $80 ; lo($d080)
+ ld e, a
+ ld a, 0
+ adc $d0 ; hi($d080)
+ ld d, a
+ ld bc, 24
+ call CopyBytes
+ ret
+
+
+.CreditsPalettes
+INCBIN "baserom.gbc",$109b6a,$18 ; pichu.pal
+INCBIN "baserom.gbc",$109b82,$18 ; smoochum.pal
+INCBIN "baserom.gbc",$109b9a,$18 ; ditto.pal
+INCBIN "baserom.gbc",$109bb2,$18 ; igglybuff.pal
+; 109bca
+
+INCBIN "baserom.gbc", $109bca, $109c24 - $109bca
+
+CreditsGFX:
+INCBIN "gfx/credits/border.2bpp"
+INCBIN "gfx/credits/pichu.2bpp"
+INCBIN "gfx/credits/smoochum.2bpp"
+INCBIN "gfx/credits/ditto.2bpp"
+INCBIN "gfx/credits/igglybuff.2bpp"
+
+
+CreditsScript: ; 10acb4
+
+; Clear the banner.
+ db CREDITS_CLEAR
+
+; Pokemon Crystal Version Staff
+ db STAFF, 01
+ db CREDITS_WAIT, 08
+
+; Play the credits music.
+ db CREDITS_MUSIC
+
+ db CREDITS_WAIT2, 10
+
+ db CREDITS_WAIT, 01
+
+; Update the banner.
+ db CREDITS_SCENE, 00 ; Pichu
+
+ db DIRECTOR, 01
+ db SATOSHI_TAJIRI, 02
+ db CREDITS_WAIT, 12
+
+ db CODIRECTOR, 01
+ db JUNICHI_MASUDA, 02
+ db CREDITS_WAIT, 12
+
+ db PROGRAMMERS, 00
+ db SOUSUKE_TAMADA, 01
+ db HISASHI_SOGABE, 02
+ db KEITA_KAGAYA, 03
+ db YOSHINORI_MATSUDA, 04
+ db CREDITS_WAIT, 12
+
+ db PROGRAMMERS, 00
+ db SHIGEKI_MORIMOTO, 01
+ db TETSUYA_WATANABE, 02
+ db TAKENORI_OOTA, 03
+ db CREDITS_WAIT, 12
+
+ db GRAPHICS_DIRECTOR, 01
+ db KEN_SUGIMORI, 02
+ db CREDITS_WAIT, 12
+
+ db MONSTER_DESIGN, 00
+ db KEN_SUGIMORI, 01
+ db MOTOFUMI_FUJIWARA, 02
+ db SHIGEKI_MORIMOTO, 03
+ db HIRONOBU_YOSHIDA, 04
+ db SATOSHI_OOTA, 05
+ db CREDITS_WAIT, 12
+
+ db MONSTER_DESIGN, 00
+ db ATSUKO_NISHIDA, 01
+ db MUNEO_SAITO, 02
+ db RENA_YOSHIKAWA, 03
+ db CREDITS_WAIT, 12
+
+ db POKEMON_ANIMATION, 01
+ db HIRONOBU_YOSHIDA, 02
+ db JUN_OKUTANI, 03
+ db CREDITS_WAIT, 12
+
+; Clear the banner.
+ db CREDITS_CLEAR
+
+ db CREDITS_WAIT, 01
+
+; Update the banner.
+ db CREDITS_SCENE, 01 ; Smoochum
+
+ db GRAPHICS_DESIGN, 00
+ db HIRONOBU_YOSHIDA, 01
+ db JUN_OKUTANI, 02
+ db ASUKA_IWASHITA, 03
+ db TETSUYA_WATANABE, 04
+ db CREDITS_WAIT, 12
+
+ db MUSIC, 00
+ db JUNICHI_MASUDA, 01
+ db MORIKAZU_AOKI, 02
+ db GO_ICHINOSE, 03
+ db CREDITS_WAIT, 12
+
+ db SOUND_EFFECTS, 00
+ db MORIKAZU_AOKI, 01
+ db JUNICHI_MASUDA, 02
+ db TETSUYA_WATANABE, 03
+ db CREDITS_WAIT, 12
+
+ db GAME_DESIGN, 00
+ db JUNICHI_MASUDA, 01
+ db SHIGEKI_MORIMOTO, 02
+ db KOHJI_NISHINO, 03
+ db CREDITS_WAIT, 12
+
+ db GAME_DESIGN, 00
+ db TETSUJI_OOTA, 01
+ db HITOMI_SATO, 02
+ db KENJI_MATSUSHIMA, 03
+ db CREDITS_WAIT, 12
+
+ db GAME_SCENARIO, 00
+ db JUNICHI_MASUDA, 01
+ db KOHJI_NISHINO, 02
+ db TOSHINOBU_MATSUMIYA, 03
+ db KENJI_MATSUSHIMA, 04
+ db CREDITS_WAIT, 12
+
+ db POKEDEX_TEXT, 01
+ db TOSHINOBU_MATSUMIYA, 02
+ db CREDITS_WAIT, 12
+
+ db TOOL_PROGRAMMING, 01
+ db SOUSUKE_TAMADA, 02
+ db TAKENORI_OOTA, 03
+ db CREDITS_WAIT, 12
+
+ db PARAMETRIC_DESIGN, 01
+ db KOHJI_NISHINO, 02
+ db CREDITS_WAIT, 12
+
+; Clear the banner.
+ db CREDITS_CLEAR
+
+ db CREDITS_WAIT, 01
+
+; Update the banner.
+ db CREDITS_SCENE, 02 ; Ditto
+
+ db SCRIPT_DESIGN, 01
+ db TETSUJI_OOTA, 02
+ db NOBUHIRO_SEYA, 03
+ db CREDITS_WAIT, 12
+
+ db MAP_DATA_DESIGN, 01
+ db TETSUJI_OOTA, 02
+ db KAZUHITO_SEKINE, 03
+ db CREDITS_WAIT, 12
+
+ db MAP_DESIGN, 00
+ db TETSUJI_OOTA, 01
+ db KOHJI_NISHINO, 02
+ db NOBUHIRO_SEYA, 03
+ db CREDITS_WAIT, 12
+
+ db COORDINATION, 01
+ db HIROYUKI_ZINNAI, 02
+ db CREDITS_WAIT, 12
+
+ db PRODUCERS, 00
+ db SATORU_IWATA, 01
+ db SATOSHI_YAMATO, 02
+ db SHIGERU_MIYAMOTO, 03
+ db CREDITS_WAIT, 12
+
+ db PRODUCERS, 01
+ db TSUNEKAZU_ISHIHARA, 02
+ db CREDITS_WAIT, 12
+
+; Clear the banner.
+ db CREDITS_CLEAR
+
+ db CREDITS_WAIT, 01
+
+; Update the banner.
+ db CREDITS_SCENE, 03 ; Igglybuff
+
+ db US_VERSION_STAFF, 02
+ db CREDITS_WAIT, 09
+
+ db US_COORDINATION, 01
+ db GAIL_TILDEN, 02
+ db HIRO_NAKAMURA, 03
+ db CREDITS_WAIT, 12
+
+ db US_COORDINATION, 01
+ db JUNICHI_MASUDA, 02
+ db SETH_MCMAHILL, 03
+ db CREDITS_WAIT, 12
+
+ db US_COORDINATION, 01
+ db HIROTO_ALEXANDER, 02
+ db TERESA_LILLYGREN, 03
+ db CREDITS_WAIT, 12
+
+ db TEXT_TRANSLATION, 01
+ db NOB_OGASAWARA, 02
+ db CREDITS_WAIT, 12
+
+ db PROGRAMMERS, 01
+ db TERUKI_MURAKAWA, 02
+ db KAZUYOSHI_OSAWA, 03
+ db CREDITS_WAIT, 12
+
+ db PAAD_TESTING, 01
+ db THOMAS_HERTZOG, 02
+ db ERIK_JOHNSON, 03
+ db CREDITS_WAIT, 12
+
+ db PRODUCT_TESTING, 00
+ db PLANNING, 01
+ db CREDITS_WAIT, 12
+
+ db PRODUCT_TESTING, 00
+ db KEITA_NAKAMURA, 01
+ db HIROTAKA_UEMURA, 02
+ db HIROAKI_TAMURA, 03
+ db NORIAKI_SAKAGUCHI, 04
+ db CREDITS_WAIT, 12
+
+ db PRODUCT_TESTING, 00
+ db NCL_SUPER_MARIO_CLUB, 01
+ db KENJI_SAIKI, 02
+ db ATSUSHI_TADA, 03
+ db MIYUKI_SATO, 04
+ db CREDITS_WAIT, 12
+
+ db SPECIAL_THANKS, 00
+ db KIMIKO_NAKAMICHI, 01
+ db AKITO_MORI, 02
+ db CREDITS_WAIT, 12
+
+ db SPECIAL_THANKS, 00
+ db GAKUZI_NOMOTO, 01
+ db AI_MASHIMA, 02
+ db KUNIMI_KAWAMURA, 03
+ db CREDITS_WAIT, 12
+
+ db SPECIAL_THANKS, 00
+ db MIKIHIRO_ISHIKAWA, 01
+ db HIDEYUKI_HASHIMOTO, 02
+ db CREDITS_WAIT, 12
+
+ db EXECUTIVE_PRODUCER, 01
+ db HIROSHI_YAMAUCHI, 02
+ db CREDITS_WAIT, 12
+
+ db COPYRIGHT, 01
+ db CREDITS_WAIT, 09
+
+; Display "The End" graphic.
+ db CREDITS_THEEND
+
+ db CREDITS_WAIT, 20
+
+ db $ff ; end
+; 10ae13
+
+
+CreditsStrings:
+ dw .SatoshiTajiri
+ dw .JunichiMasuda
+ dw .TetsuyaWatanabe
+ dw .ShigekiMorimoto
+ dw .SousukeTamada
+ dw .TakenoriOota
+ dw .KenSugimori
+ dw .MotofumiFujiwara
+ dw .AtsukoNishida
+ dw .MuneoSaito
+ dw .SatoshiOota
+ dw .RenaYoshikawa
+ dw .JunOkutani
+ dw .HironobuYoshida
+ dw .AsukaIwashita
+ dw .GoIchinose
+ dw .MorikazuAoki
+ dw .KohjiNishino
+ dw .KenjiMatsushima
+ dw .ToshinobuMatsumiya
+ dw .SatoruIwata
+ dw .NobuhiroSeya
+ dw .KazuhitoSekine
+ dw .TetsujiOota
+ dw .NclSuperMarioClub
+ dw .Sarugakucho
+ dw .AkitoMori
+ dw .TakahiroHarada
+ dw .TohruHashimoto
+ dw .NoboruMatsumoto
+ dw .TakehiroIzushi
+ dw .TakashiKawaguchi
+ dw .TsunekazuIshihara
+ dw .HiroshiYamauchi
+ dw .KenjiSaiki
+ dw .AtsushiTada
+ dw .NaokoKawakami
+ dw .HiroyukiZinnai
+ dw .KunimiKawamura
+ dw .HisashiSogabe
+ dw .KeitaKagaya
+ dw .YoshinoriMatsuda
+ dw .HitomiSato
+ dw .ToruOsawa
+ dw .TakaoOhara
+ dw .YuichiroIto
+ dw .TakaoShimizu
+ dw .Planning
+ dw .KeitaNakamura
+ dw .HirotakaUemura
+ dw .HiroakiTamura
+ dw .NoriakiSakaguchi
+ dw .MiyukiSato
+ dw .GakuziNomoto
+ dw .AiMashima
+ dw .MikihiroIshikawa
+ dw .HideyukiHashimoto
+ dw .SatoshiYamato
+ dw .ShigeruMiyamoto
+ dw .GailTilden
+ dw .NobOgasawara
+ dw .SethMcMahill
+ dw .HirotoAlexander
+ dw .TeresaLillygren
+ dw .ThomasHertzog
+ dw .ErikJohnson
+ dw .HiroNakamura
+ dw .TerukiMurakawa
+ dw .KazuyoshiOsawa
+ dw .KimikoNakamichi
+ dw .End
+ dw .Unknown
+ dw .Staff
+ dw .Director
+ dw .CoDirector
+ dw .Programmers
+ dw .GraphicsDirector
+ dw .MonsterDesign
+ dw .GraphicsDesign
+ dw .Music
+ dw .SoundEffects
+ dw .GameDesign
+ dw .GameScenario
+ dw .ToolProgramming
+ dw .ParametricDesign
+ dw .ScriptDesign
+ dw .MapDataDesign
+ dw .MapDesign
+ dw .ProductTesting
+ dw .SpecialThanks
+ dw .Producers
+ dw .ExecutiveProducer
+ dw .PokemonAnimation
+ dw .PokedexText
+ dw .MobilePrjLeader
+ dw .MobileSystemAd
+ dw .MobileStadiumDir
+ dw .Coordination
+ dw .Copyright
+ dw .UsVersionStaff
+ dw .UsCoordination
+ dw .TextTranslation
+ dw .PaadTesting
+
+.SatoshiTajiri: db " SATOSHI TAJIRI@" ; "たじり さとし@"
+.JunichiMasuda: db " JUNICHI MASUDA@" ; "ますだ じゅんいち@"
+.TetsuyaWatanabe: db " TETSUYA WATANABE@" ; "わたなべ てつや@"
+.ShigekiMorimoto: db " SHIGEKI MORIMOTO@" ; "もりもと しげき@"
+.SousukeTamada: db " SOUSUKE TAMADA@" ; "たまだ そうすけ@"
+.TakenoriOota: db " TAKENORI OOTA@" ; "おおた たけのり@"
+.KenSugimori: db " KEN SUGIMORI@" ; "すぎもり けん@"
+.MotofumiFujiwara: db " MOTOFUMI FUJIWARA@" ; "ふじわら もとふみ@"
+.AtsukoNishida: db " ATSUKO NISHIDA@" ; "にしだ あつこ@"
+.MuneoSaito: db " MUNEO SAITO@" ; "さいとう むねお@"
+.SatoshiOota: db " SATOSHI OOTA@" ; "おおた さとし@"
+.RenaYoshikawa: db " RENA YOSHIKAWA@" ; "よしかわ れな@"
+.JunOkutani: db " JUN OKUTANI@" ; "おくたに じゅん@"
+.HironobuYoshida: db " HIRONOBU YOSHIDA@" ; "よしだ ひろのぶ@"
+.AsukaIwashita: db " ASUKA IWASHITA@" ; "いわした あすか@"
+.GoIchinose: db " GO ICHINOSE@" ; "いちのせ ごう@"
+.MorikazuAoki: db " MORIKAZU AOKI@" ; "あおき もりかず@"
+.KohjiNishino: db " KOHJI NISHINO@" ; "にしの こうじ@"
+.KenjiMatsushima: db " KENJI MATSUSHIMA@" ; "まつしま けんじ@"
+.ToshinobuMatsumiya: db "TOSHINOBU MATSUMIYA@" ; "まつみや としのぶ@"
+.SatoruIwata: db " SATORU IWATA@" ; "いわた さとる@"
+.NobuhiroSeya: db " NOBUHIRO SEYA@" ; "せや のぶひろ@"
+.KazuhitoSekine: db " KAZUHITO SEKINE@" ; "せきね かずひと@"
+.TetsujiOota: db " TETSUJI OOTA@" ; "おおた てつじ@"
+.NclSuperMarioClub: db "NCL SUPER MARIO CLUB@" ; "スーパーマりォクラブ@"
+.Sarugakucho: db " SARUGAKUCHO@" ; "さるがくちょう@"
+.AkitoMori: db " AKITO MORI@" ; "もり あきと@"
+.TakahiroHarada: db " TAKAHIRO HARADA@" ; "はらだ たかひろ@"
+.TohruHashimoto: db " TOHRU HASHIMOTO@" ; "はしもと とおる@"
+.NoboruMatsumoto: db " NOBORU MATSUMOTO@" ; "まつもと のぼる@"
+.TakehiroIzushi: db " TAKEHIRO IZUSHI@" ; "いずし たけひろ@"
+.TakashiKawaguchi: db " TAKASHI KAWAGUCHI@" ; "かわぐち たかし@"
+.TsunekazuIshihara: db " TSUNEKAZU ISHIHARA@" ; "いしはら つねかず@"
+.HiroshiYamauchi: db " HIROSHI YAMAUCHI@" ; "やまうち ひろし@"
+.KenjiSaiki: db " KENJI SAIKI@" ; "さいき けんじ@"
+.AtsushiTada: db " ATSUSHI TADA@" ; "ただ あつし@"
+.NaokoKawakami: db " NAOKO KAWAKAMI@" ; "かわかみ なおこ@"
+.HiroyukiZinnai: db " HIROYUKI ZINNAI@" ; "じんない ひろゆき@"
+.KunimiKawamura: db " KUNIMI KAWAMURA@" ; "かわむら くにみ@"
+.HisashiSogabe: db " HISASHI SOGABE@" ; "そがべ ひさし@"
+.KeitaKagaya: db " KEITA KAGAYA@" ; "かがや けいた@"
+.YoshinoriMatsuda: db " YOSHINORI MATSUDA@" ; "まつだ よしのり@"
+.HitomiSato: db " HITOMI SATO@" ; "さとう ひとみ@"
+.ToruOsawa: db " TORU OSAWA@" ; "おおさわ とおる@"
+.TakaoOhara: db " TAKAO OHARA@" ; "おおはら たかお@"
+.YuichiroIto: db " YUICHIRO ITO@" ; "いとう ゆういちろう@"
+.TakaoShimizu: db " TAKAO SHIMIZU@" ; "しみず たかお@"
+.Planning: db " SPECIAL PRODUCTION", $4e
+ db " PLANNING", $4e ; "きかくかいはつぶ@"
+ db " & DEVELOPMENT DEPT.@"
+.KeitaNakamura: db " KEITA NAKAMURA@" ; "なかむら けいた@"
+.HirotakaUemura: db " HIROTAKA UEMURA@" ; "うえむら ひろたか@"
+.HiroakiTamura: db " HIROAKI TAMURA@" ; "たむら ひろあき@"
+.NoriakiSakaguchi: db " NORIAKI SAKAGUCHI@" ; "さかぐち のりあき@"
+.MiyukiSato: db " MIYUKI SATO@" ; "さとう みゆき@"
+.GakuziNomoto: db " GAKUZI NOMOTO@" ; "のもと がくじ@"
+.AiMashima: db " AI MASHIMA@" ; "ましま あい@"
+.MikihiroIshikawa: db " MIKIHIRO ISHIKAWA@" ; "いしかわ みきひろ@"
+.HideyukiHashimoto: db " HIDEYUKI HASHIMOTO@" ; "はしもと ひでゆき@"
+.SatoshiYamato: db " SATOSHI YAMATO@" ; "やまと さとし@"
+.ShigeruMiyamoto: db " SHIGERU MIYAMOTO@" ; "みやもと しげる@"
+.End: db " END@" ; "おしまい@"
+.Unknown: db " ????????@" ; "????????@"
+.GailTilden: db " GAIL TILDEN@"
+.NobOgasawara: db " NOB OGASAWARA@"
+.SethMcMahill: db " SETH McMAHILL@"
+.HirotoAlexander: db " HIROTO ALEXANDER@"
+.TeresaLillygren: db " TERESA LILLYGREN@"
+.ThomasHertzog: db " THOMAS HERTZOG@"
+.ErikJohnson: db " ERIK JOHNSON@"
+.HiroNakamura: db " HIRO NAKAMURA@"
+.TerukiMurakawa: db " TERUKI MURAKAWA@"
+.KazuyoshiOsawa: db " KAZUYOSHI OSAWA@"
+.KimikoNakamichi: db " KIMIKO NAKAMICHI@"
+.Staff: db " #MON", $4e ; "ポケットモンスター", $4e
+ db " CRYSTAL VERSION", $4e ; " クりスタル バージョン", $4e
+ db " STAFF@" ; " スタッフ@"
+.Director: db " DIRECTOR@" ; "エグゼクティブ ディレクター@"
+.CoDirector: db " CO-DIRECTOR@" ; "ディレクター@"
+.Programmers: db " PROGRAMMERS@" ; "プログラム@"
+.GraphicsDirector: db " GRAPHICS DIRECTOR@" ; "グラフィック ディレクター@"
+.MonsterDesign: db " MONSTER DESIGN@" ; "# デザイン@"
+.GraphicsDesign: db " GRAPHICS DESIGN@" ; "グラフィック デザイン@"
+.Music: db " MUSIC@" ; "おんがく@"
+.SoundEffects: db " SOUND EFFECTS@" ; "サウンド エフ→クト@"
+.GameDesign: db " GAME DESIGN@" ; "ゲームデザイン@"
+.GameScenario: db " GAME SCENARIO@" ; "シナりォ@"
+.ToolProgramming: db " TOOL PROGRAMMING@" ; "ツール プログラム@"
+.ParametricDesign: db " PARAMETRIC DESIGN@" ; "パラメーター せってい@"
+.ScriptDesign: db " SCRIPT DESIGN@" ; "スクりプト せってい@"
+.MapDataDesign: db " MAP DATA DESIGN@" ; "マップデータ せってい@"
+.MapDesign: db " MAP DESIGN@" ; "マップ デザイン@"
+.ProductTesting: db " PRODUCT TESTING@" ; "デバッグプレイ@"
+.SpecialThanks: db " SPECIAL THANKS@" ; "スぺシャルサンクス@"
+.Producers: db " PRODUCERS@" ; "プロデューサー@"
+.ExecutiveProducer: db " EXECUTIVE PRODUCER@" ; "エグゼクティブ プロデューサー@"
+.PokemonAnimation: db " #MON ANIMATION@" ; "# アニメーション@"
+.PokedexText: db " #DEX TEXT@" ; "ずかん テキスト@"
+.MobilePrjLeader: db " MOBILE PRJ. LEADER@" ; "モバイルプロジ→クト りーダー@"
+.MobileSystemAd: db " MOBILE SYSTEM AD.@" ; "モバイル システムアドバイザー@"
+.MobileStadiumDir: db "MOBILE STADIUM DIR.@" ; "モバイルスタジアム ディレクター@"
+.Coordination: db " COORDINATION@" ; "コーディネーター@"
+.UsVersionStaff: db " US VERSION STAFF@"
+.UsCoordination: db " US COORDINATION@"
+.TextTranslation: db " TEXT TRANSLATION@"
+.PaadTesting: db " PAAD TESTING@"
+
+.Copyright:
+; (C) 1 9 9 5 - 2 0 0 1 N i n t e n d o
+db $60,$61,$62,$63,$64,$65,$66, $67, $68, $69, $6a, $6b, $6c, $4e
+; (C) 1 9 9 5 - 2 0 0 1 C r e a t u r e s i n c .
+db $60,$61,$62,$63,$64,$65,$66, $6d, $6e, $6f, $70, $71, $72, $7a, $7b, $7c, $4e
+; (C) 1 9 9 5 - 2 0 0 1 G A M E F R E A K i n c .
+db $60,$61,$62,$63,$64,$65,$66, $73, $74, $75, $76, $77, $78, $79, $7a, $7b, $7c, "@"
+
diff --git a/extras/crystal.py b/extras/crystal.py
index 06d54ae22..b3f29a12f 100644
--- a/extras/crystal.py
+++ b/extras/crystal.py
@@ -2816,16 +2816,18 @@ pksv_crystal_more = {
0x9C: ["specialphonecall", ["call_id", MultiByteParam]],
0x9D: ["checkphonecall"],
0x9E: ["verbosegiveitem", ["item", ItemLabelByte], ["quantity", DecimalParam]],
- 0x9F: ["verbosegiveitem2", ["item", ItemLabelByte]],
+ 0x9F: ["verbosegiveitem2", ["item", ItemLabelByte], ["var", SingleByteParam]],
0xA0: ["loadwilddata", ["map_group", MapGroupParam], ["map_id", MapIdParam]],
0xA1: ["halloffame"],
0xA2: ["credits"],
0xA3: ["warpfacing", ["facing", SingleByteParam], ["map_group", MapGroupParam], ["map_id", MapIdParam], ["x", SingleByteParam], ["y", SingleByteParam]],
0xA4: ["storetext", ["pointer", PointerLabelBeforeBank], ["memory", SingleByteParam]],
0xA5: ["displaylocation", ["id", SingleByteParam]],
+ 0xA6: ["unknown0xa6"],
+ 0xA7: ["unknown0xa7"],
0xA8: ["unknown0xa8", ["unknown", SingleByteParam]],
- 0xB2: ["unknown0xb2", ["unknown", SingleByteParam]],
- 0xCC: ["unknown0xcc"],
+ 0xA9: ["unknown0xa9"],
+ 0xAA: ["unknown0xaa"],
}
def create_command_classes(debug=False):
"""creates some classes for each command byte"""
@@ -6322,489 +6324,9 @@ class PokedexEntry:
{4}""".format(self.species, self.weight, self.height, self.page1.to_asm(), self.page2.to_asm())
return output
-# map names with no labels will be generated at the end of the structure
-map_names = {
- 1: {
- 0x1: {"name": "Olivine Pokémon Center 1F",
- "label": "OlivinePokeCenter1F"},
- 0x2: {"name": "Olivine Gym"},
- 0x3: {"name": "Olivine Voltorb House"},
- 0x4: {"name": "Olivine House Beta"},
- 0x5: {"name": "Olivine Punishment Speech House"},
- 0x6: {"name": "Olivine Good Rod House"},
- 0x7: {"name": "Olivine Cafe"},
- 0x8: {"name": "Olivine Mart"},
- 0x9: {"name": "Route 38 Ecruteak Gate"},
- 0xA: {"name": "Route 39 Barn"},
- 0xB: {"name": "Route 39 Farmhouse"},
- 0xC: {"name": "Route 38"},
- 0xD: {"name": "Route 39"},
- 0xE: {"name": "Olivine City"},
- },
- 2: {
- 0x1: {"name": "Mahogany Red Gyarados Speech House"},
- 0x2: {"name": "Mahogany Gym"},
- 0x3: {"name": "Mahogany Pokémon Center 1F",
- "label": "MahoganyPokeCenter1F"},
- 0x4: {"name": "Route 42 Ecruteak Gate"},
- 0x5: {"name": "Route 42"},
- 0x6: {"name": "Route 44"},
- 0x7: {"name": "Mahogany Town"},
- },
- 3: {
- 0x1: {"name": "Sprout Tower 1F"},
- 0x2: {"name": "Sprout Tower 2F"},
- 0x3: {"name": "Sprout Tower 3F"},
- 0x4: {"name": "Tin Tower 1F"},
- 0x5: {"name": "Tin Tower 2F"},
- 0x6: {"name": "Tin Tower 3F"},
- 0x7: {"name": "Tin Tower 4F"},
- 0x8: {"name": "Tin Tower 5F"},
- 0x9: {"name": "Tin Tower 6F"},
- 0xA: {"name": "Tin Tower 7F"},
- 0xB: {"name": "Tin Tower 8F"},
- 0xC: {"name": "Tin Tower 9F"},
- 0xD: {"name": "Burned Tower 1F"},
- 0xE: {"name": "Burned Tower B1F"},
- 0xF: {"name": "National Park"},
- 0x10: {"name": "National Park Bug Contest"},
- 0x11: {"name": "Radio Tower 1F"},
- 0x12: {"name": "Radio Tower 2F"},
- 0x13: {"name": "Radio Tower 3F"},
- 0x14: {"name": "Radio Tower 4F"},
- 0x15: {"name": "Radio Tower 5F"},
- 0x16: {"name": "Ruins of Alph Outside"},
- 0x17: {"name": "Ruins of Alph Ho-oh Chamber"},
- 0x18: {"name": "Ruins of Alph Kabuto Chamber"},
- 0x19: {"name": "Ruins of Alph Omanyte Chamber"},
- 0x1A: {"name": "Ruins of Alph Aerodactyl Chamber"},
- 0x1B: {"name": "Ruins of Alph Inner Chamber"},
- 0x1C: {"name": "Ruins of Alph Research Center"},
- 0x1D: {"name": "Ruins of Alph Ho-oh Item Room"},
- 0x1E: {"name": "Ruins of Alph Kabuto Item Room"},
- 0x1F: {"name": "Ruins of Alph Omanyte Item Room"},
- 0x20: {"name": "Ruins of Alph Aerodactyl Item Room"},
- 0x21: {"name": "Ruins of Alph Ho-Oh Word Room"},
- 0x22: {"name": "Ruins of Alph Kabuto Word Room"},
- 0x23: {"name": "Ruins of Alph Omanyte Word Room"},
- 0x24: {"name": "Ruins of Alph Aerodactyl Word Room"},
- 0x25: {"name": "Union Cave 1F"},
- 0x26: {"name": "Union Cave B1F"},
- 0x27: {"name": "Union Cave B2F"},
- 0x28: {"name": "Slowpoke Well B1F"},
- 0x29: {"name": "Slowpoke Well B2F"},
- 0x2A: {"name": "Olivine Lighthouse 1F"},
- 0x2B: {"name": "Olivine Lighthouse 2F"},
- 0x2C: {"name": "Olivine Lighthouse 3F"},
- 0x2D: {"name": "Olivine Lighthouse 4F"},
- 0x2E: {"name": "Olivine Lighthouse 5F"},
- 0x2F: {"name": "Olivine Lighthouse 6F"},
- 0x30: {"name": "Mahogany Mart 1F"},
- 0x31: {"name": "Team Rocket Base B1F"},
- 0x32: {"name": "Team Rocket Base B2F"},
- 0x33: {"name": "Team Rocket Base B3F"},
- 0x34: {"name": "Ilex Forest"},
- 0x35: {"name": "Warehouse Entrance"},
- 0x36: {"name": "Underground Path Switch Room Entrances"},
- 0x37: {"name": "Goldenrod Dept Store B1F"},
- 0x38: {"name": "Underground Warehouse"},
- 0x39: {"name": "Mount Mortar 1F Outside"},
- 0x3A: {"name": "Mount Mortar 1F Inside"},
- 0x3B: {"name": "Mount Mortar 2F Inside"},
- 0x3C: {"name": "Mount Mortar B1F"},
- 0x3D: {"name": "Ice Path 1F"},
- 0x3E: {"name": "Ice Path B1F"},
- 0x3F: {"name": "Ice Path B2F Mahogany Side"},
- 0x40: {"name": "Ice Path B2F Blackthorn Side"},
- 0x41: {"name": "Ice Path B3F"},
- 0x42: {"name": "Whirl Island NW"},
- 0x43: {"name": "Whirl Island NE"},
- 0x44: {"name": "Whirl Island SW"},
- 0x45: {"name": "Whirl Island Cave"},
- 0x46: {"name": "Whirl Island SE"},
- 0x47: {"name": "Whirl Island B1F"},
- 0x48: {"name": "Whirl Island B2F"},
- 0x49: {"name": "Whirl Island Lugia Chamber"},
- 0x4A: {"name": "Silver Cave Room 1"},
- 0x4B: {"name": "Silver Cave Room 2"},
- 0x4C: {"name": "Silver Cave Room 3"},
- 0x4D: {"name": "Silver Cave Item Rooms"},
- 0x4E: {"name": "Dark Cave Violet Entrance"},
- 0x4F: {"name": "Dark Cave Blackthorn Entrance"},
- 0x50: {"name": "Dragon's Den 1F"},
- 0x51: {"name": "Dragon's Den B1F"},
- 0x52: {"name": "Dragon Shrine"},
- 0x53: {"name": "Tohjo Falls"},
- 0x54: {"name": "Diglett's Cave"},
- 0x55: {"name": "Mount Moon"},
- 0x56: {"name": "Underground"},
- 0x57: {"name": "Rock Tunnel 1F"},
- 0x58: {"name": "Rock Tunnel B1F"},
- 0x59: {"name": "Safari Zone Fuchsia Gate Beta"},
- 0x5A: {"name": "Safari Zone Beta"},
- 0x5B: {"name": "Victory Road"},
- },
- 4: {
- 0x1: {"name": "Ecruteak House"}, # passage to Tin Tower
- 0x2: {"name": "Wise Trio's Room"},
- 0x3: {"name": "Ecruteak Pokémon Center 1F",
- "label": "EcruteakPokeCenter1F"},
- 0x4: {"name": "Ecruteak Lugia Speech House"},
- 0x5: {"name": "Dance Theatre"},
- 0x6: {"name": "Ecruteak Mart"},
- 0x7: {"name": "Ecruteak Gym"},
- 0x8: {"name": "Ecruteak Itemfinder House"},
- 0x9: {"name": "Ecruteak City"},
- },
- 5: {
- 0x1: {"name": "Blackthorn Gym 1F"},
- 0x2: {"name": "Blackthorn Gym 2F"},
- 0x3: {"name": "Blackthorn Dragon Speech House"},
- 0x4: {"name": "Blackthorn Dodrio Trade House"},
- 0x5: {"name": "Blackthorn Mart"},
- 0x6: {"name": "Blackthorn Pokémon Center 1F",
- "label": "BlackthornPokeCenter1F"},
- 0x7: {"name": "Move Deleter's House"},
- 0x8: {"name": "Route 45"},
- 0x9: {"name": "Route 46"},
- 0xA: {"name": "Blackthorn City"},
- },
- 6: {
- 0x1: {"name": "Cinnabar Pokémon Center 1F",
- "label": "CinnabarPokeCenter1F"},
- 0x2: {"name": "Cinnabar Pokémon Center 2F Beta",
- "label": "CinnabarPokeCenter2FBeta"},
- 0x3: {"name": "Route 19 - Fuchsia Gate"},
- 0x4: {"name": "Seafoam Gym"},
- 0x5: {"name": "Route 19"},
- 0x6: {"name": "Route 20"},
- 0x7: {"name": "Route 21"},
- 0x8: {"name": "Cinnabar Island"},
- },
- 7: {
- 0x1: {"name": "Cerulean Gym Badge Speech House"},
- 0x2: {"name": "Cerulean Police Station"},
- 0x3: {"name": "Cerulean Trade Speech House"},
- 0x4: {"name": "Cerulean Pokémon Center 1F",
- "label": "CeruleanPokeCenter1F"},
- 0x5: {"name": "Cerulean Pokémon Center 2F Beta",
- "label": "CeruleanPokeCenter2FBeta"},
- 0x6: {"name": "Cerulean Gym"},
- 0x7: {"name": "Cerulean Mart"},
- 0x8: {"name": "Route 10 Pokémon Center 1F",
- "label": "Route10PokeCenter1F"},
- 0x9: {"name": "Route 10 Pokémon Center 2F Beta",
- "label": "Route10PokeCenter2FBeta"},
- 0xA: {"name": "Power Plant"},
- 0xB: {"name": "Bill's House"},
- 0xC: {"name": "Route 4"},
- 0xD: {"name": "Route 9"},
- 0xE: {"name": "Route 10 North"},
- 0xF: {"name": "Route 24"},
- 0x10: {"name": "Route 25"},
- 0x11: {"name": "Cerulean City"},
- },
- 8: {
- 0x1: {"name": "Azalea Pokémon Center 1F",
- "label": "AzaleaPokeCenter1F"},
- 0x2: {"name": "Charcoal Kiln"},
- 0x3: {"name": "Azalea Mart"},
- 0x4: {"name": "Kurt's House"},
- 0x5: {"name": "Azalea Gym"},
- 0x6: {"name": "Route 33"},
- 0x7: {"name": "Azalea Town"},
- },
- 9: {
- 0x1: {"name": "Lake of Rage Hidden Power House"},
- 0x2: {"name": "Lake of Rage Magikarp House"},
- 0x3: {"name": "Route 43 Mahogany Gate"},
- 0x4: {"name": "Route 43 Gate"},
- 0x5: {"name": "Route 43"},
- 0x6: {"name": "Lake of Rage"},
- },
- 10: {
- 0x1: {"name": "Route 32"},
- 0x2: {"name": "Route 35"},
- 0x3: {"name": "Route 36"},
- 0x4: {"name": "Route 37"},
- 0x5: {"name": "Violet City"},
- 0x6: {"name": "Violet Mart"},
- 0x7: {"name": "Violet Gym"},
- 0x8: {"name": "Earl's Pokémon Academy",
- "label": "EarlsPokemonAcademy"},
- 0x9: {"name": "Violet Nickname Speech House"},
- 0xA: {"name": "Violet Pokémon Center 1F",
- "label": "VioletPokeCenter1F"},
- 0xB: {"name": "Violet Onix Trade House"},
- 0xC: {"name": "Route 32 Ruins of Alph Gate"},
- 0xD: {"name": "Route 32 Pokémon Center 1F",
- "label": "Route32PokeCenter1F"},
- 0xE: {"name": "Route 35 Goldenrod gate"},
- 0xF: {"name": "Route 35 National Park gate"},
- 0x10: {"name": "Route 36 Ruins of Alph gate"},
- 0x11: {"name": "Route 36 National Park gate"},
- },
- 11: {
- 0x1: {"name": "Route 34"},
- 0x2: {"name": "Goldenrod City"},
- 0x3: {"name": "Goldenrod Gym"},
- 0x4: {"name": "Goldenrod Bike Shop"},
- 0x5: {"name": "Goldenrod Happiness Rater"},
- 0x6: {"name": "Goldenrod Bill's House"},
- 0x7: {"name": "Goldenrod Magnet Train Station"},
- 0x8: {"name": "Goldenrod Flower Shop"},
- 0x9: {"name": "Goldenrod PP Speech House"},
- 0xA: {"name": "Goldenrod Name Rater's House"},
- 0xB: {"name": "Goldenrod Dept Store 1F"},
- 0xC: {"name": "Goldenrod Dept Store 2F"},
- 0xD: {"name": "Goldenrod Dept Store 3F"},
- 0xE: {"name": "Goldenrod Dept Store 4F"},
- 0xF: {"name": "Goldenrod Dept Store 5F"},
- 0x10: {"name": "Goldenrod Dept Store 6F"},
- 0x11: {"name": "Goldenrod Dept Store Elevator"},
- 0x12: {"name": "Goldenrod Dept Store Roof"},
- 0x13: {"name": "Goldenrod Game Corner"},
- 0x14: {"name": "Goldenrod Pokémon Center 1F",
- "label": "GoldenrodPokeCenter1F"},
- 0x15: {"name": "Goldenrod PokéCom Center 2F Mobile",
- "label": "GoldenrodPokeComCenter2FMobile"},
- 0x16: {"name": "Ilex Forest Azalea Gate"},
- 0x17: {"name": "Route 34 Ilex Forest Gate"},
- 0x18: {"name": "Day Care"},
- },
- 12: {
- 0x1: {"name": "Route 6"},
- 0x2: {"name": "Route 11"},
- 0x3: {"name": "Vermilion City"},
- 0x4: {"name": "Vermilion House Fishing Speech House"},
- 0x5: {"name": "Vermilion Pokémon Center 1F",
- "label": "VermilionPokeCenter1F"},
- 0x6: {"name": "Vermilion Pokémon Center 2F Beta",
- "label": "VermilionPokeCenter2FBeta"},
- 0x7: {"name": "Pokémon Fan Club"},
- 0x8: {"name": "Vermilion Magnet Train Speech House"},
- 0x9: {"name": "Vermilion Mart"},
- 0xA: {"name": "Vermilion House Diglett's Cave Speech House"},
- 0xB: {"name": "Vermilion Gym"},
- 0xC: {"name": "Route 6 Saffron Gate"},
- 0xD: {"name": "Route 6 Underground Entrance"},
- },
- 13: {
- 0x1: {"name": "Route 1"},
- 0x2: {"name": "Pallet Town"},
- 0x3: {"name": "Red's House 1F"},
- 0x4: {"name": "Red's House 2F"},
- 0x5: {"name": "Blue's House"},
- 0x6: {"name": "Oak's Lab"},
- },
- 14: {
- 0x1: {"name": "Route 3"},
- 0x2: {"name": "Pewter City"},
- 0x3: {"name": "Pewter Nidoran Speech House"},
- 0x4: {"name": "Pewter Gym"},
- 0x5: {"name": "Pewter Mart"},
- 0x6: {"name": "Pewter Pokémon Center 1F",
- "label": "PewterPokeCenter1F"},
- 0x7: {"name": "Pewter Pokémon Center 2F Beta",
- "label": "PewterPokeCEnter2FBeta"},
- 0x8: {"name": "Pewter Snooze Speech House"},
- },
- 15: {
- 0x1: {"name": "Olivine Port"},
- 0x2: {"name": "Vermilion Port"},
- 0x3: {"name": "Fast Ship 1F"},
- 0x4: {"name": "Fast Ship Cabins NNW, NNE, NE",
- "label": "FastShipCabins_NNW_NNE_NE"},
- 0x5: {"name": "Fast Ship Cabins SW, SSW, NW",
- "label": "FastShipCabins_SW_SSW_NW"},
- 0x6: {"name": "Fast Ship Cabins SE, SSE, Captain's Cabin",
- "label": "FastShipCabins_SE_SSE_CaptainsCabin"},
- 0x7: {"name": "Fast Ship B1F"},
- 0x8: {"name": "Olivine Port Passage"},
- 0x9: {"name": "Vermilion Port Passage"},
- 0xA: {"name": "Mount Moon Square"},
- 0xB: {"name": "Mount Moon Gift Shop"},
- 0xC: {"name": "Tin Tower Roof"},
- },
- 16: {
- 0x1: {"name": "Route 23"},
- 0x2: {"name": "Indigo Plateau Pokémon Center 1F",
- "label": "IndigoPlateauPokeCenter1F"},
- 0x3: {"name": "Will's Room"},
- 0x4: {"name": "Koga's Room"},
- 0x5: {"name": "Bruno's Room"},
- 0x6: {"name": "Karen's Room"},
- 0x7: {"name": "Lance's Room"},
- 0x8: {"name": "Hall of Fame",
- "label": "HallOfFame"},
- },
- 17: {
- 0x1: {"name": "Route 13"},
- 0x2: {"name": "Route 14"},
- 0x3: {"name": "Route 15"},
- 0x4: {"name": "Route 18"},
- 0x5: {"name": "Fuchsia City"},
- 0x6: {"name": "Fuchsia Mart"},
- 0x7: {"name": "Safari Zone Main Office"},
- 0x8: {"name": "Fuchsia Gym"},
- 0x9: {"name": "Fuchsia Bill Speech House"},
- 0xA: {"name": "Fuchsia Pokémon Center 1F",
- "label": "FuchsiaPokeCenter1F"},
- 0xB: {"name": "Fuchsia Pokémon Center 2F Beta",
- "label": "FuchsiaPokeCenter2FBeta"},
- 0xC: {"name": "Safari Zone Warden's Home"},
- 0xD: {"name": "Route 15 Fuchsia Gate"},
- },
- 18: {
- 0x1: {"name": "Route 8"},
- 0x2: {"name": "Route 12"},
- 0x3: {"name": "Route 10 South"},
- 0x4: {"name": "Lavender Town"},
- 0x5: {"name": "Lavender Pokémon Center 1F",
- "label": "LavenderPokeCenter1F"},
- 0x6: {"name": "Lavender Pokémon Center 2F Beta",
- "label": "LavenderPokeCenter2FBeta"},
- 0x7: {"name": "Mr. Fuji's House"},
- 0x8: {"name": "Lavender Town Speech House"},
- 0x9: {"name": "Lavender Name Rater"},
- 0xA: {"name": "Lavender Mart"},
- 0xB: {"name": "Soul House"},
- 0xC: {"name": "Lav Radio Tower 1F"},
- 0xD: {"name": "Route 8 Saffron Gate"},
- 0xE: {"name": "Route 12 Super Rod House"},
- },
- 19: {
- 0x1: {"name": "Route 28"},
- 0x2: {"name": "Silver Cave Outside"},
- 0x3: {"name": "Silver Cave Pokémon Center 1F",
- "label": "SilverCavePokeCenter1F"},
- 0x4: {"name": "Route 28 Famous Speech House"},
- },
- 20: {
- 0x1: {"name": "Pokémon Center 2F",
- "label": "PokeCenter2F"},
- 0x2: {"name": "Trade Center"},
- 0x3: {"name": "Colosseum"},
- 0x4: {"name": "Time Capsule"},
- 0x5: {"name": "Mobile Trade Room Mobile"},
- 0x6: {"name": "Mobile Battle Room"},
- },
- 21: {
- 0x1: {"name": "Route 7"},
- 0x2: {"name": "Route 16"},
- 0x3: {"name": "Route 17"},
- 0x4: {"name": "Celadon City"},
- 0x5: {"name": "Celadon Dept Store 1F"},
- 0x6: {"name": "Celadon Dept Store 2F"},
- 0x7: {"name": "Celadon Dept Store 3F"},
- 0x8: {"name": "Celadon Dept Store 4F"},
- 0x9: {"name": "Celadon Dept Store 5F"},
- 0xA: {"name": "Celadon Dept Store 6F"},
- 0xB: {"name": "Celadon Dept Store Elevator"},
- 0xC: {"name": "Celadon Mansion 1F"},
- 0xD: {"name": "Celadon Mansion 2F"},
- 0xE: {"name": "Celadon Mansion 3F"},
- 0xF: {"name": "Celadon Mansion Roof"},
- 0x10: {"name": "Celadon Mansion Roof House"},
- 0x11: {"name": "Celadon Pokémon Center 1F",
- "label": "CeladonPokeCenter1F"},
- 0x12: {"name": "Celadon Pokémon Center 2F Beta",
- "label": "CeladonPokeCenter2FBeta"},
- 0x13: {"name": "Celadon Game Corner"},
- 0x14: {"name": "Celadon Game Corner Prize Room"},
- 0x15: {"name": "Celadon Gym"},
- 0x16: {"name": "Celadon Cafe"},
- 0x17: {"name": "Route 16 Fuchsia Speech House"},
- 0x18: {"name": "Route 16 Gate"},
- 0x19: {"name": "Route 7 Saffron Gate"},
- 0x1A: {"name": "Route 17 18 Gate"},
- },
- 22: {
- 0x1: {"name": "Route 40"},
- 0x2: {"name": "Route 41"},
- 0x3: {"name": "Cianwood City"},
- 0x4: {"name": "Mania's House"},
- 0x5: {"name": "Cianwood Gym"},
- 0x6: {"name": "Cianwood Pokémon Center 1F",
- "label": "CianwoodPokeCenter1F"},
- 0x7: {"name": "Cianwood Pharmacy"},
- 0x8: {"name": "Cianwood City Photo Studio"},
- 0x9: {"name": "Cianwood Lugia Speech House"},
- 0xA: {"name": "Poke Seer's House"},
- 0xB: {"name": "Battle Tower 1F"},
- 0xC: {"name": "Battle Tower Battle Room"},
- 0xD: {"name": "Battle Tower Elevator"},
- 0xE: {"name": "Battle Tower Hallway"},
- 0xF: {"name": "Route 40 Battle Tower Gate"},
- 0x10: {"name": "Battle Tower Outside"},
- },
- 23: {
- 0x1: {"name": "Route 2"},
- 0x2: {"name": "Route 22"},
- 0x3: {"name": "Viridian City"},
- 0x4: {"name": "Viridian Gym"},
- 0x5: {"name": "Viridian Nickname Speech House"},
- 0x6: {"name": "Trainer House 1F"},
- 0x7: {"name": "Trainer House B1F"},
- 0x8: {"name": "Viridian Mart"},
- 0x9: {"name": "Viridian Pokémon Center 1F",
- "label": "ViridianPokeCenter1F"},
- 0xA: {"name": "Viridian Pokémon Center 2F Beta",
- "label": "ViridianPokeCenter2FBeta"},
- 0xB: {"name": "Route 2 Nugget Speech House"},
- 0xC: {"name": "Route 2 Gate"},
- 0xD: {"name": "Victory Road Gate"},
- },
- 24: {
- 0x1: {"name": "Route 26"},
- 0x2: {"name": "Route 27"},
- 0x3: {"name": "Route 29"},
- 0x4: {"name": "New Bark Town"},
- 0x5: {"name": "Elm's Lab"},
- 0x6: {"name": "Kris's House 1F"},
- 0x7: {"name": "Kris's House 2F"},
- 0x8: {"name": "Kris's Neighbor's House"},
- 0x9: {"name": "Elm's House"},
- 0xA: {"name": "Route 26 Heal Speech House"},
- 0xB: {"name": "Route 26 Day of Week Siblings House"},
- 0xC: {"name": "Route 27 Sandstorm House"},
- 0xD: {"name": "Route 29 46 Gate"},
- },
- 25: {
- 0x1: {"name": "Route 5"},
- 0x2: {"name": "Saffron City"},
- 0x3: {"name": "Fighting Dojo"},
- 0x4: {"name": "Saffron Gym"},
- 0x5: {"name": "Saffron Mart"},
- 0x6: {"name": "Saffron Pokémon Center 1F",
- "label": "SaffronPokeCenter1F"},
- 0x7: {"name": "Saffron Pokémon Center 2F Beta",
- "label": "SaffronPokeCenter2FBeta"},
- 0x8: {"name": "Mr. Psychic's House"},
- 0x9: {"name": "Saffron Train Station"},
- 0xA: {"name": "Silph Co. 1F"},
- 0xB: {"name": "Copycat's House 1F"},
- 0xC: {"name": "Copycat's House 2F"},
- 0xD: {"name": "Route 5 Underground Entrance"},
- 0xE: {"name": "Route 5 Saffron City Gate"},
- 0xF: {"name": "Route 5 Cleanse Tag Speech House"},
- },
- 26: {
- 0x1: {"name": "Route 30"},
- 0x2: {"name": "Route 31"},
- 0x3: {"name": "Cherrygrove City"},
- 0x4: {"name": "Cherrygrove Mart"},
- 0x5: {"name": "Cherrygrove Pokémon Center 1F",
- "label": "CherrygrovePokeCenter1F"},
- 0x6: {"name": "Cherrygrove Gym Speech House"},
- 0x7: {"name": "Guide Gent's House"},
- 0x8: {"name": "Cherrygrove Evolution Speech House"},
- 0x9: {"name": "Route 30 Berry Speech House"},
- 0xA: {"name": "Mr. Pokémon's House"},
- 0xB: {"name": "Route 31 Violet Gate"},
- },
-}
+from map_names import map_names
+# map names with no labels will be generated
# generate labels for each map name
for map_group_id in map_names.keys():
map_group = map_names[map_group_id]
@@ -6834,7 +6356,7 @@ incbin_lines = []
# storage for processed incbin lines
processed_incbins = {}
-def to_asm(some_object):
+def to_asm(some_object, use_asm_rules=False):
"""shows an object's asm with a label and an ending comment
showing the next byte address"""
if isinstance(some_object, int):
@@ -6850,6 +6372,9 @@ def to_asm(some_object):
asmr = asmr.replace("\n"+spacing+"\n", "\n\n"+spacing)
asmr = asmr.replace("\n\n"+spacing+spacing, "\n\n"+spacing)
asm += spacing + asmr
+ if use_asm_rules:
+ asm = asm.replace("\n" + spacing + "; ", "\n; ")
+ asm = asm.replace("\n" + spacing + ".asm_", "\n.asm_")
# show the address of the next byte below this
asm += "\n; " + hex(last_address)
return asm
@@ -7223,7 +6748,7 @@ class Asm:
asm_list = AsmList(asm)
bank = 0
for line in asm_list:
- if line[0:6] == "INCBIN" or line[1:6] == "INCBIN":
+ if (line[0:6] == "INCBIN" or line[1:6] == "INCBIN") and not any([contaminant+"\"" in line for contaminant in [".2bpp", ".1bpp", ".asm", ".lz"]]):
thing = Incbin(line, bank=bank)
elif line[0:7] == "SECTION":
thing = AsmSection(line)
@@ -7288,11 +6813,13 @@ class Asm:
# check if the object is already inserted
if new_object in self.parts:
- print "object was previously inserted ("+str(new_object)+")"
+ print "object was previously inserted ("+str(new_object)+"; " + hex(new_object.address) + ")"
return
# check by label
- if self.is_label_name_in_file(new_object.label.name):
- print "object was previously inserted ("+str(new_object)+") by label: "+new_object.label.name
+ other_obj = self.is_label_name_in_file(new_object.label.name)
+ if other_obj:
+ other_obj = other_obj.object
+ print "object was previously inserted ("+new_object.label.name+" at "+hex(new_object.address)+") by "+other_obj.label.name+" at "+hex(other_obj.address)
return
# check by address
#if self.does_address_have_label(new_object.address):
diff --git a/extras/disassemble_map_scripts.py b/extras/disassemble_map_scripts.py
new file mode 100644
index 000000000..21df56924
--- /dev/null
+++ b/extras/disassemble_map_scripts.py
@@ -0,0 +1,151 @@
+# -*- encoding: utf-8 -*-
+"""
+Dump out asm for scripting things in bank $25. This script will modify main.asm
+and insert all scripting commands.
+"""
+
+import crystal
+from gbz80disasm import output_bank_opcodes
+
+rom = crystal.load_rom()
+roml = [ord(x) for x in rom]
+
+script_command_table_address = 0x96cb1
+script_command_count = 170
+
+# a list of addresses for each script command
+command_pointers = [crystal.calculate_pointer_from_bytes_at(script_command_table_address + (id * 2), bank=0x25) for id in range(0, 170)]
+
+# a list of hex addresses for each script command in bank $25
+command_pointers_hex = ["$%.2x" % (x % 0x4000 + 0x4000) for x in command_pointers]
+
+commands = {}
+
+# force data into a more usable form
+for command in crystal.command_classes:
+ name = "Script_" + command.macro_name
+ id = command.id
+ params = {}
+
+ for (id2, param_type) in command.param_types.items():
+ param = {
+ "name": param_type["name"],
+ "type": param_type["class"].__name__,
+ }
+ params[id2] = param
+
+ if id <= 0xa9:
+ commands[id] = {
+ "name": name,
+ "params": params,
+ "address": command_pointers[id],
+ }
+
+avoid = [
+ 0x974b0,
+ 0x974be,
+ 0x9754b,
+ 0x97556,
+ 0x97562,
+ 0x9756e,
+ 0x97540,
+
+ 0x96f8e, # verbosegiveitem2
+]
+
+class DisassembledScriptCommand():
+ """
+ Just a temporary object to store information about a script command's asm.
+ This is used by some of the infrastructure in crystal.py to automatically
+ insert asm into main.asm, rather than having someone do it manually.
+ """
+ dependencies = None
+
+ def __init__(self, label=None, id=None, address=None, params=None):
+ self.id = id
+ self.label = crystal.Label(name=label, address=address, object=self)
+ self.address = address
+ self.params = params
+
+ max_byte_count = 0x4000
+
+ # Some of these scripts need to be truncated before insertion, because
+ # output_bank_opcodes doesn't know anything about stopping if some of
+ # the local labels are not resolved yet.
+
+ # Script_if_equal
+ if address == 0x97540:
+ max_byte_count = 86
+
+ # disassemble and laso get the last address
+ (asm, last_address, last_hl_address, last_a_address, used_3d97) = output_bank_opcodes(address, max_byte_count=max_byte_count, stop_at=command_pointers, include_last_address=False)
+
+ # remove indentation
+ asm = asm.replace("\n\t", "\n")
+ if asm[0] == "\t":
+ asm = asm[1:]
+
+ # remove the last two newlines
+ while asm[-1] == "\n":
+ asm = asm[:-1]
+
+ self.asm = asm
+ self.last_address = last_address
+
+ # make sure this gets dumped into main.asm
+ #if crystal.script_parse_table[self.address] == None and crystal.script_parse_table[self.last_address] == None:
+ crystal.script_parse_table[self.address : self.last_address] = self
+ #else:
+ # print ".. hm, something is already at " + hex(self.address) + " for " + self.label.name
+
+ def to_asm(self):
+ #output += self.label + ": ; " + hex(self.address) + "\n"
+ output = "; script command " + hex(self.id) + "\n"
+ if len(self.params) > 0:
+ output += "; parameters:\n"
+ for (id2, param) in self.params.items():
+ output += "; " + param["name"] + " (" + param["type"] + ")\n"
+ output += "\n"
+ output += self.asm
+ return output
+
+ def get_dependencies(*args, **kwargs):
+ return []
+
+# make instances of DisassembledScriptCommand
+for (id, command) in commands.items():
+ name = command["name"]
+ params = command["params"]
+ address = command["address"]
+
+ script_asm = DisassembledScriptCommand(label=name, id=id, address=address, params=params)
+ #print script_asm.to_asm()
+ #print crystal.to_asm(script_asm, use_asm_rules=True)
+
+class ScriptCommandTable():
+ address = script_command_table_address
+ last_address = script_command_table_address + (2 * 170)
+ dependencies = None
+
+ def __init__(self):
+ self.label = crystal.Label(name="ScriptCommandTable", address=self.address, object=self)
+
+ # make sure this gets dumped into main.asm
+ crystal.script_parse_table[self.address : self.last_address] = self
+
+ def get_dependencies(*args, **kwargs):
+ return []
+
+ def to_asm(self):
+ output = ""
+ for (id, command) in commands.items():
+ output += "dw " + command["name"] + "; " + hex(command["address"]) + "\n"
+ if output[-1] == "\n":
+ output = output[:-1]
+ return output
+script_command_table = ScriptCommandTable()
+#print crystal.to_asm(script_command_table, use_asm_rules=True)
+
+# automatic asm insertion
+asm = crystal.Asm()
+asm.insert_and_dump(limit=500)
diff --git a/extras/gbz80disasm.py b/extras/gbz80disasm.py
index d22f152f1..efb4689ab 100644
--- a/extras/gbz80disasm.py
+++ b/extras/gbz80disasm.py
@@ -592,7 +592,7 @@ def asm_label(address):
# why using a random value when you can use the address?
return ".ASM_" + hex(address)[2:]
-def output_bank_opcodes(original_offset, max_byte_count=0x4000, debug = False):
+def output_bank_opcodes(original_offset, max_byte_count=0x4000, include_last_address=True, stop_at=[], debug = False):
#fs = current_address
#b = bank_byte
#in = input_data -- rom
@@ -601,6 +601,10 @@ def output_bank_opcodes(original_offset, max_byte_count=0x4000, debug = False):
#ad = end_address
#a, oa = current_byte_number
+ # stop_at can be used to supply a list of addresses to not disassemble
+ # over. This is useful if you know in advance that there are a lot of
+ # fall-throughs.
+
load_labels()
load_rom()
@@ -622,6 +626,7 @@ def output_bank_opcodes(original_offset, max_byte_count=0x4000, debug = False):
byte_labels = {}
+ first_loop = True
output = ""
keep_reading = True
while offset <= end_address and keep_reading:
@@ -629,6 +634,11 @@ def output_bank_opcodes(original_offset, max_byte_count=0x4000, debug = False):
is_data = False
maybe_byte = current_byte
+ # stop at any address
+ if not first_loop and offset in stop_at:
+ keep_reading = False
+ break
+
#first check if this byte already has a label
#if it does, use the label
#if not, generate a new label
@@ -816,6 +826,8 @@ def output_bank_opcodes(original_offset, max_byte_count=0x4000, debug = False):
#offset += 1
#current_byte_number += 1
+ first_loop = False
+
#clean up unused labels
for label_line in byte_labels.keys():
address = label_line
@@ -824,7 +836,8 @@ def output_bank_opcodes(original_offset, max_byte_count=0x4000, debug = False):
output = output.replace((label_line["name"] + "\n").lower(), "")
#add the offset of the final location
- output += "; " + hex(offset)
+ if include_last_address:
+ output += "; " + hex(offset)
return (output, offset, last_hl_address, last_a_address, used_3d97)
diff --git a/extras/map_names.py b/extras/map_names.py
new file mode 100644
index 000000000..599b377db
--- /dev/null
+++ b/extras/map_names.py
@@ -0,0 +1,486 @@
+# -*- coding: utf-8 -*-
+"""
+"""
+
+# this is modified in crystal.py during run-time
+map_names = {
+ 1: {
+ 0x1: {"name": "Olivine Pokémon Center 1F",
+ "label": "OlivinePokeCenter1F"},
+ 0x2: {"name": "Olivine Gym"},
+ 0x3: {"name": "Olivine Voltorb House"},
+ 0x4: {"name": "Olivine House Beta"},
+ 0x5: {"name": "Olivine Punishment Speech House"},
+ 0x6: {"name": "Olivine Good Rod House"},
+ 0x7: {"name": "Olivine Cafe"},
+ 0x8: {"name": "Olivine Mart"},
+ 0x9: {"name": "Route 38 Ecruteak Gate"},
+ 0xA: {"name": "Route 39 Barn"},
+ 0xB: {"name": "Route 39 Farmhouse"},
+ 0xC: {"name": "Route 38"},
+ 0xD: {"name": "Route 39"},
+ 0xE: {"name": "Olivine City"},
+ },
+ 2: {
+ 0x1: {"name": "Mahogany Red Gyarados Speech House"},
+ 0x2: {"name": "Mahogany Gym"},
+ 0x3: {"name": "Mahogany Pokémon Center 1F",
+ "label": "MahoganyPokeCenter1F"},
+ 0x4: {"name": "Route 42 Ecruteak Gate"},
+ 0x5: {"name": "Route 42"},
+ 0x6: {"name": "Route 44"},
+ 0x7: {"name": "Mahogany Town"},
+ },
+ 3: {
+ 0x1: {"name": "Sprout Tower 1F"},
+ 0x2: {"name": "Sprout Tower 2F"},
+ 0x3: {"name": "Sprout Tower 3F"},
+ 0x4: {"name": "Tin Tower 1F"},
+ 0x5: {"name": "Tin Tower 2F"},
+ 0x6: {"name": "Tin Tower 3F"},
+ 0x7: {"name": "Tin Tower 4F"},
+ 0x8: {"name": "Tin Tower 5F"},
+ 0x9: {"name": "Tin Tower 6F"},
+ 0xA: {"name": "Tin Tower 7F"},
+ 0xB: {"name": "Tin Tower 8F"},
+ 0xC: {"name": "Tin Tower 9F"},
+ 0xD: {"name": "Burned Tower 1F"},
+ 0xE: {"name": "Burned Tower B1F"},
+ 0xF: {"name": "National Park"},
+ 0x10: {"name": "National Park Bug Contest"},
+ 0x11: {"name": "Radio Tower 1F"},
+ 0x12: {"name": "Radio Tower 2F"},
+ 0x13: {"name": "Radio Tower 3F"},
+ 0x14: {"name": "Radio Tower 4F"},
+ 0x15: {"name": "Radio Tower 5F"},
+ 0x16: {"name": "Ruins of Alph Outside"},
+ 0x17: {"name": "Ruins of Alph Ho-oh Chamber"},
+ 0x18: {"name": "Ruins of Alph Kabuto Chamber"},
+ 0x19: {"name": "Ruins of Alph Omanyte Chamber"},
+ 0x1A: {"name": "Ruins of Alph Aerodactyl Chamber"},
+ 0x1B: {"name": "Ruins of Alph Inner Chamber"},
+ 0x1C: {"name": "Ruins of Alph Research Center"},
+ 0x1D: {"name": "Ruins of Alph Ho-oh Item Room"},
+ 0x1E: {"name": "Ruins of Alph Kabuto Item Room"},
+ 0x1F: {"name": "Ruins of Alph Omanyte Item Room"},
+ 0x20: {"name": "Ruins of Alph Aerodactyl Item Room"},
+ 0x21: {"name": "Ruins of Alph Ho-Oh Word Room"},
+ 0x22: {"name": "Ruins of Alph Kabuto Word Room"},
+ 0x23: {"name": "Ruins of Alph Omanyte Word Room"},
+ 0x24: {"name": "Ruins of Alph Aerodactyl Word Room"},
+ 0x25: {"name": "Union Cave 1F"},
+ 0x26: {"name": "Union Cave B1F"},
+ 0x27: {"name": "Union Cave B2F"},
+ 0x28: {"name": "Slowpoke Well B1F"},
+ 0x29: {"name": "Slowpoke Well B2F"},
+ 0x2A: {"name": "Olivine Lighthouse 1F"},
+ 0x2B: {"name": "Olivine Lighthouse 2F"},
+ 0x2C: {"name": "Olivine Lighthouse 3F"},
+ 0x2D: {"name": "Olivine Lighthouse 4F"},
+ 0x2E: {"name": "Olivine Lighthouse 5F"},
+ 0x2F: {"name": "Olivine Lighthouse 6F"},
+ 0x30: {"name": "Mahogany Mart 1F"},
+ 0x31: {"name": "Team Rocket Base B1F"},
+ 0x32: {"name": "Team Rocket Base B2F"},
+ 0x33: {"name": "Team Rocket Base B3F"},
+ 0x34: {"name": "Ilex Forest"},
+ 0x35: {"name": "Warehouse Entrance"},
+ 0x36: {"name": "Underground Path Switch Room Entrances"},
+ 0x37: {"name": "Goldenrod Dept Store B1F"},
+ 0x38: {"name": "Underground Warehouse"},
+ 0x39: {"name": "Mount Mortar 1F Outside"},
+ 0x3A: {"name": "Mount Mortar 1F Inside"},
+ 0x3B: {"name": "Mount Mortar 2F Inside"},
+ 0x3C: {"name": "Mount Mortar B1F"},
+ 0x3D: {"name": "Ice Path 1F"},
+ 0x3E: {"name": "Ice Path B1F"},
+ 0x3F: {"name": "Ice Path B2F Mahogany Side"},
+ 0x40: {"name": "Ice Path B2F Blackthorn Side"},
+ 0x41: {"name": "Ice Path B3F"},
+ 0x42: {"name": "Whirl Island NW"},
+ 0x43: {"name": "Whirl Island NE"},
+ 0x44: {"name": "Whirl Island SW"},
+ 0x45: {"name": "Whirl Island Cave"},
+ 0x46: {"name": "Whirl Island SE"},
+ 0x47: {"name": "Whirl Island B1F"},
+ 0x48: {"name": "Whirl Island B2F"},
+ 0x49: {"name": "Whirl Island Lugia Chamber"},
+ 0x4A: {"name": "Silver Cave Room 1"},
+ 0x4B: {"name": "Silver Cave Room 2"},
+ 0x4C: {"name": "Silver Cave Room 3"},
+ 0x4D: {"name": "Silver Cave Item Rooms"},
+ 0x4E: {"name": "Dark Cave Violet Entrance"},
+ 0x4F: {"name": "Dark Cave Blackthorn Entrance"},
+ 0x50: {"name": "Dragon's Den 1F"},
+ 0x51: {"name": "Dragon's Den B1F"},
+ 0x52: {"name": "Dragon Shrine"},
+ 0x53: {"name": "Tohjo Falls"},
+ 0x54: {"name": "Diglett's Cave"},
+ 0x55: {"name": "Mount Moon"},
+ 0x56: {"name": "Underground"},
+ 0x57: {"name": "Rock Tunnel 1F"},
+ 0x58: {"name": "Rock Tunnel B1F"},
+ 0x59: {"name": "Safari Zone Fuchsia Gate Beta"},
+ 0x5A: {"name": "Safari Zone Beta"},
+ 0x5B: {"name": "Victory Road"},
+ },
+ 4: {
+ 0x1: {"name": "Ecruteak House"}, # passage to Tin Tower
+ 0x2: {"name": "Wise Trio's Room"},
+ 0x3: {"name": "Ecruteak Pokémon Center 1F",
+ "label": "EcruteakPokeCenter1F"},
+ 0x4: {"name": "Ecruteak Lugia Speech House"},
+ 0x5: {"name": "Dance Theatre"},
+ 0x6: {"name": "Ecruteak Mart"},
+ 0x7: {"name": "Ecruteak Gym"},
+ 0x8: {"name": "Ecruteak Itemfinder House"},
+ 0x9: {"name": "Ecruteak City"},
+ },
+ 5: {
+ 0x1: {"name": "Blackthorn Gym 1F"},
+ 0x2: {"name": "Blackthorn Gym 2F"},
+ 0x3: {"name": "Blackthorn Dragon Speech House"},
+ 0x4: {"name": "Blackthorn Dodrio Trade House"},
+ 0x5: {"name": "Blackthorn Mart"},
+ 0x6: {"name": "Blackthorn Pokémon Center 1F",
+ "label": "BlackthornPokeCenter1F"},
+ 0x7: {"name": "Move Deleter's House"},
+ 0x8: {"name": "Route 45"},
+ 0x9: {"name": "Route 46"},
+ 0xA: {"name": "Blackthorn City"},
+ },
+ 6: {
+ 0x1: {"name": "Cinnabar Pokémon Center 1F",
+ "label": "CinnabarPokeCenter1F"},
+ 0x2: {"name": "Cinnabar Pokémon Center 2F Beta",
+ "label": "CinnabarPokeCenter2FBeta"},
+ 0x3: {"name": "Route 19 - Fuchsia Gate"},
+ 0x4: {"name": "Seafoam Gym"},
+ 0x5: {"name": "Route 19"},
+ 0x6: {"name": "Route 20"},
+ 0x7: {"name": "Route 21"},
+ 0x8: {"name": "Cinnabar Island"},
+ },
+ 7: {
+ 0x1: {"name": "Cerulean Gym Badge Speech House"},
+ 0x2: {"name": "Cerulean Police Station"},
+ 0x3: {"name": "Cerulean Trade Speech House"},
+ 0x4: {"name": "Cerulean Pokémon Center 1F",
+ "label": "CeruleanPokeCenter1F"},
+ 0x5: {"name": "Cerulean Pokémon Center 2F Beta",
+ "label": "CeruleanPokeCenter2FBeta"},
+ 0x6: {"name": "Cerulean Gym"},
+ 0x7: {"name": "Cerulean Mart"},
+ 0x8: {"name": "Route 10 Pokémon Center 1F",
+ "label": "Route10PokeCenter1F"},
+ 0x9: {"name": "Route 10 Pokémon Center 2F Beta",
+ "label": "Route10PokeCenter2FBeta"},
+ 0xA: {"name": "Power Plant"},
+ 0xB: {"name": "Bill's House"},
+ 0xC: {"name": "Route 4"},
+ 0xD: {"name": "Route 9"},
+ 0xE: {"name": "Route 10 North"},
+ 0xF: {"name": "Route 24"},
+ 0x10: {"name": "Route 25"},
+ 0x11: {"name": "Cerulean City"},
+ },
+ 8: {
+ 0x1: {"name": "Azalea Pokémon Center 1F",
+ "label": "AzaleaPokeCenter1F"},
+ 0x2: {"name": "Charcoal Kiln"},
+ 0x3: {"name": "Azalea Mart"},
+ 0x4: {"name": "Kurt's House"},
+ 0x5: {"name": "Azalea Gym"},
+ 0x6: {"name": "Route 33"},
+ 0x7: {"name": "Azalea Town"},
+ },
+ 9: {
+ 0x1: {"name": "Lake of Rage Hidden Power House"},
+ 0x2: {"name": "Lake of Rage Magikarp House"},
+ 0x3: {"name": "Route 43 Mahogany Gate"},
+ 0x4: {"name": "Route 43 Gate"},
+ 0x5: {"name": "Route 43"},
+ 0x6: {"name": "Lake of Rage"},
+ },
+ 10: {
+ 0x1: {"name": "Route 32"},
+ 0x2: {"name": "Route 35"},
+ 0x3: {"name": "Route 36"},
+ 0x4: {"name": "Route 37"},
+ 0x5: {"name": "Violet City"},
+ 0x6: {"name": "Violet Mart"},
+ 0x7: {"name": "Violet Gym"},
+ 0x8: {"name": "Earl's Pokémon Academy",
+ "label": "EarlsPokemonAcademy"},
+ 0x9: {"name": "Violet Nickname Speech House"},
+ 0xA: {"name": "Violet Pokémon Center 1F",
+ "label": "VioletPokeCenter1F"},
+ 0xB: {"name": "Violet Onix Trade House"},
+ 0xC: {"name": "Route 32 Ruins of Alph Gate"},
+ 0xD: {"name": "Route 32 Pokémon Center 1F",
+ "label": "Route32PokeCenter1F"},
+ 0xE: {"name": "Route 35 Goldenrod gate"},
+ 0xF: {"name": "Route 35 National Park gate"},
+ 0x10: {"name": "Route 36 Ruins of Alph gate"},
+ 0x11: {"name": "Route 36 National Park gate"},
+ },
+ 11: {
+ 0x1: {"name": "Route 34"},
+ 0x2: {"name": "Goldenrod City"},
+ 0x3: {"name": "Goldenrod Gym"},
+ 0x4: {"name": "Goldenrod Bike Shop"},
+ 0x5: {"name": "Goldenrod Happiness Rater"},
+ 0x6: {"name": "Goldenrod Bill's House"},
+ 0x7: {"name": "Goldenrod Magnet Train Station"},
+ 0x8: {"name": "Goldenrod Flower Shop"},
+ 0x9: {"name": "Goldenrod PP Speech House"},
+ 0xA: {"name": "Goldenrod Name Rater's House"},
+ 0xB: {"name": "Goldenrod Dept Store 1F"},
+ 0xC: {"name": "Goldenrod Dept Store 2F"},
+ 0xD: {"name": "Goldenrod Dept Store 3F"},
+ 0xE: {"name": "Goldenrod Dept Store 4F"},
+ 0xF: {"name": "Goldenrod Dept Store 5F"},
+ 0x10: {"name": "Goldenrod Dept Store 6F"},
+ 0x11: {"name": "Goldenrod Dept Store Elevator"},
+ 0x12: {"name": "Goldenrod Dept Store Roof"},
+ 0x13: {"name": "Goldenrod Game Corner"},
+ 0x14: {"name": "Goldenrod Pokémon Center 1F",
+ "label": "GoldenrodPokeCenter1F"},
+ 0x15: {"name": "Goldenrod PokéCom Center 2F Mobile",
+ "label": "GoldenrodPokeComCenter2FMobile"},
+ 0x16: {"name": "Ilex Forest Azalea Gate"},
+ 0x17: {"name": "Route 34 Ilex Forest Gate"},
+ 0x18: {"name": "Day Care"},
+ },
+ 12: {
+ 0x1: {"name": "Route 6"},
+ 0x2: {"name": "Route 11"},
+ 0x3: {"name": "Vermilion City"},
+ 0x4: {"name": "Vermilion House Fishing Speech House"},
+ 0x5: {"name": "Vermilion Pokémon Center 1F",
+ "label": "VermilionPokeCenter1F"},
+ 0x6: {"name": "Vermilion Pokémon Center 2F Beta",
+ "label": "VermilionPokeCenter2FBeta"},
+ 0x7: {"name": "Pokémon Fan Club"},
+ 0x8: {"name": "Vermilion Magnet Train Speech House"},
+ 0x9: {"name": "Vermilion Mart"},
+ 0xA: {"name": "Vermilion House Diglett's Cave Speech House"},
+ 0xB: {"name": "Vermilion Gym"},
+ 0xC: {"name": "Route 6 Saffron Gate"},
+ 0xD: {"name": "Route 6 Underground Entrance"},
+ },
+ 13: {
+ 0x1: {"name": "Route 1"},
+ 0x2: {"name": "Pallet Town"},
+ 0x3: {"name": "Red's House 1F"},
+ 0x4: {"name": "Red's House 2F"},
+ 0x5: {"name": "Blue's House"},
+ 0x6: {"name": "Oak's Lab"},
+ },
+ 14: {
+ 0x1: {"name": "Route 3"},
+ 0x2: {"name": "Pewter City"},
+ 0x3: {"name": "Pewter Nidoran Speech House"},
+ 0x4: {"name": "Pewter Gym"},
+ 0x5: {"name": "Pewter Mart"},
+ 0x6: {"name": "Pewter Pokémon Center 1F",
+ "label": "PewterPokeCenter1F"},
+ 0x7: {"name": "Pewter Pokémon Center 2F Beta",
+ "label": "PewterPokeCEnter2FBeta"},
+ 0x8: {"name": "Pewter Snooze Speech House"},
+ },
+ 15: {
+ 0x1: {"name": "Olivine Port"},
+ 0x2: {"name": "Vermilion Port"},
+ 0x3: {"name": "Fast Ship 1F"},
+ 0x4: {"name": "Fast Ship Cabins NNW, NNE, NE",
+ "label": "FastShipCabins_NNW_NNE_NE"},
+ 0x5: {"name": "Fast Ship Cabins SW, SSW, NW",
+ "label": "FastShipCabins_SW_SSW_NW"},
+ 0x6: {"name": "Fast Ship Cabins SE, SSE, Captain's Cabin",
+ "label": "FastShipCabins_SE_SSE_CaptainsCabin"},
+ 0x7: {"name": "Fast Ship B1F"},
+ 0x8: {"name": "Olivine Port Passage"},
+ 0x9: {"name": "Vermilion Port Passage"},
+ 0xA: {"name": "Mount Moon Square"},
+ 0xB: {"name": "Mount Moon Gift Shop"},
+ 0xC: {"name": "Tin Tower Roof"},
+ },
+ 16: {
+ 0x1: {"name": "Route 23"},
+ 0x2: {"name": "Indigo Plateau Pokémon Center 1F",
+ "label": "IndigoPlateauPokeCenter1F"},
+ 0x3: {"name": "Will's Room"},
+ 0x4: {"name": "Koga's Room"},
+ 0x5: {"name": "Bruno's Room"},
+ 0x6: {"name": "Karen's Room"},
+ 0x7: {"name": "Lance's Room"},
+ 0x8: {"name": "Hall of Fame",
+ "label": "HallOfFame"},
+ },
+ 17: {
+ 0x1: {"name": "Route 13"},
+ 0x2: {"name": "Route 14"},
+ 0x3: {"name": "Route 15"},
+ 0x4: {"name": "Route 18"},
+ 0x5: {"name": "Fuchsia City"},
+ 0x6: {"name": "Fuchsia Mart"},
+ 0x7: {"name": "Safari Zone Main Office"},
+ 0x8: {"name": "Fuchsia Gym"},
+ 0x9: {"name": "Fuchsia Bill Speech House"},
+ 0xA: {"name": "Fuchsia Pokémon Center 1F",
+ "label": "FuchsiaPokeCenter1F"},
+ 0xB: {"name": "Fuchsia Pokémon Center 2F Beta",
+ "label": "FuchsiaPokeCenter2FBeta"},
+ 0xC: {"name": "Safari Zone Warden's Home"},
+ 0xD: {"name": "Route 15 Fuchsia Gate"},
+ },
+ 18: {
+ 0x1: {"name": "Route 8"},
+ 0x2: {"name": "Route 12"},
+ 0x3: {"name": "Route 10 South"},
+ 0x4: {"name": "Lavender Town"},
+ 0x5: {"name": "Lavender Pokémon Center 1F",
+ "label": "LavenderPokeCenter1F"},
+ 0x6: {"name": "Lavender Pokémon Center 2F Beta",
+ "label": "LavenderPokeCenter2FBeta"},
+ 0x7: {"name": "Mr. Fuji's House"},
+ 0x8: {"name": "Lavender Town Speech House"},
+ 0x9: {"name": "Lavender Name Rater"},
+ 0xA: {"name": "Lavender Mart"},
+ 0xB: {"name": "Soul House"},
+ 0xC: {"name": "Lav Radio Tower 1F"},
+ 0xD: {"name": "Route 8 Saffron Gate"},
+ 0xE: {"name": "Route 12 Super Rod House"},
+ },
+ 19: {
+ 0x1: {"name": "Route 28"},
+ 0x2: {"name": "Silver Cave Outside"},
+ 0x3: {"name": "Silver Cave Pokémon Center 1F",
+ "label": "SilverCavePokeCenter1F"},
+ 0x4: {"name": "Route 28 Famous Speech House"},
+ },
+ 20: {
+ 0x1: {"name": "Pokémon Center 2F",
+ "label": "PokeCenter2F"},
+ 0x2: {"name": "Trade Center"},
+ 0x3: {"name": "Colosseum"},
+ 0x4: {"name": "Time Capsule"},
+ 0x5: {"name": "Mobile Trade Room Mobile"},
+ 0x6: {"name": "Mobile Battle Room"},
+ },
+ 21: {
+ 0x1: {"name": "Route 7"},
+ 0x2: {"name": "Route 16"},
+ 0x3: {"name": "Route 17"},
+ 0x4: {"name": "Celadon City"},
+ 0x5: {"name": "Celadon Dept Store 1F"},
+ 0x6: {"name": "Celadon Dept Store 2F"},
+ 0x7: {"name": "Celadon Dept Store 3F"},
+ 0x8: {"name": "Celadon Dept Store 4F"},
+ 0x9: {"name": "Celadon Dept Store 5F"},
+ 0xA: {"name": "Celadon Dept Store 6F"},
+ 0xB: {"name": "Celadon Dept Store Elevator"},
+ 0xC: {"name": "Celadon Mansion 1F"},
+ 0xD: {"name": "Celadon Mansion 2F"},
+ 0xE: {"name": "Celadon Mansion 3F"},
+ 0xF: {"name": "Celadon Mansion Roof"},
+ 0x10: {"name": "Celadon Mansion Roof House"},
+ 0x11: {"name": "Celadon Pokémon Center 1F",
+ "label": "CeladonPokeCenter1F"},
+ 0x12: {"name": "Celadon Pokémon Center 2F Beta",
+ "label": "CeladonPokeCenter2FBeta"},
+ 0x13: {"name": "Celadon Game Corner"},
+ 0x14: {"name": "Celadon Game Corner Prize Room"},
+ 0x15: {"name": "Celadon Gym"},
+ 0x16: {"name": "Celadon Cafe"},
+ 0x17: {"name": "Route 16 Fuchsia Speech House"},
+ 0x18: {"name": "Route 16 Gate"},
+ 0x19: {"name": "Route 7 Saffron Gate"},
+ 0x1A: {"name": "Route 17 18 Gate"},
+ },
+ 22: {
+ 0x1: {"name": "Route 40"},
+ 0x2: {"name": "Route 41"},
+ 0x3: {"name": "Cianwood City"},
+ 0x4: {"name": "Mania's House"},
+ 0x5: {"name": "Cianwood Gym"},
+ 0x6: {"name": "Cianwood Pokémon Center 1F",
+ "label": "CianwoodPokeCenter1F"},
+ 0x7: {"name": "Cianwood Pharmacy"},
+ 0x8: {"name": "Cianwood City Photo Studio"},
+ 0x9: {"name": "Cianwood Lugia Speech House"},
+ 0xA: {"name": "Poke Seer's House"},
+ 0xB: {"name": "Battle Tower 1F"},
+ 0xC: {"name": "Battle Tower Battle Room"},
+ 0xD: {"name": "Battle Tower Elevator"},
+ 0xE: {"name": "Battle Tower Hallway"},
+ 0xF: {"name": "Route 40 Battle Tower Gate"},
+ 0x10: {"name": "Battle Tower Outside"},
+ },
+ 23: {
+ 0x1: {"name": "Route 2"},
+ 0x2: {"name": "Route 22"},
+ 0x3: {"name": "Viridian City"},
+ 0x4: {"name": "Viridian Gym"},
+ 0x5: {"name": "Viridian Nickname Speech House"},
+ 0x6: {"name": "Trainer House 1F"},
+ 0x7: {"name": "Trainer House B1F"},
+ 0x8: {"name": "Viridian Mart"},
+ 0x9: {"name": "Viridian Pokémon Center 1F",
+ "label": "ViridianPokeCenter1F"},
+ 0xA: {"name": "Viridian Pokémon Center 2F Beta",
+ "label": "ViridianPokeCenter2FBeta"},
+ 0xB: {"name": "Route 2 Nugget Speech House"},
+ 0xC: {"name": "Route 2 Gate"},
+ 0xD: {"name": "Victory Road Gate"},
+ },
+ 24: {
+ 0x1: {"name": "Route 26"},
+ 0x2: {"name": "Route 27"},
+ 0x3: {"name": "Route 29"},
+ 0x4: {"name": "New Bark Town"},
+ 0x5: {"name": "Elm's Lab"},
+ 0x6: {"name": "Kris's House 1F"},
+ 0x7: {"name": "Kris's House 2F"},
+ 0x8: {"name": "Kris's Neighbor's House"},
+ 0x9: {"name": "Elm's House"},
+ 0xA: {"name": "Route 26 Heal Speech House"},
+ 0xB: {"name": "Route 26 Day of Week Siblings House"},
+ 0xC: {"name": "Route 27 Sandstorm House"},
+ 0xD: {"name": "Route 29 46 Gate"},
+ },
+ 25: {
+ 0x1: {"name": "Route 5"},
+ 0x2: {"name": "Saffron City"},
+ 0x3: {"name": "Fighting Dojo"},
+ 0x4: {"name": "Saffron Gym"},
+ 0x5: {"name": "Saffron Mart"},
+ 0x6: {"name": "Saffron Pokémon Center 1F",
+ "label": "SaffronPokeCenter1F"},
+ 0x7: {"name": "Saffron Pokémon Center 2F Beta",
+ "label": "SaffronPokeCenter2FBeta"},
+ 0x8: {"name": "Mr. Psychic's House"},
+ 0x9: {"name": "Saffron Train Station"},
+ 0xA: {"name": "Silph Co. 1F"},
+ 0xB: {"name": "Copycat's House 1F"},
+ 0xC: {"name": "Copycat's House 2F"},
+ 0xD: {"name": "Route 5 Underground Entrance"},
+ 0xE: {"name": "Route 5 Saffron City Gate"},
+ 0xF: {"name": "Route 5 Cleanse Tag Speech House"},
+ },
+ 26: {
+ 0x1: {"name": "Route 30"},
+ 0x2: {"name": "Route 31"},
+ 0x3: {"name": "Cherrygrove City"},
+ 0x4: {"name": "Cherrygrove Mart"},
+ 0x5: {"name": "Cherrygrove Pokémon Center 1F",
+ "label": "CherrygrovePokeCenter1F"},
+ 0x6: {"name": "Cherrygrove Gym Speech House"},
+ 0x7: {"name": "Guide Gent's House"},
+ 0x8: {"name": "Cherrygrove Evolution Speech House"},
+ 0x9: {"name": "Route 30 Berry Speech House"},
+ 0xA: {"name": "Mr. Pokémon's House"},
+ 0xB: {"name": "Route 31 Violet Gate"},
+ },
+}
diff --git a/extras/pksv.py b/extras/pksv.py
index 03ad2d077..f30ab9294 100644
--- a/extras/pksv.py
+++ b/extras/pksv.py
@@ -298,6 +298,7 @@ pksv_crystal_more_enders = [0x03, 0x04, 0x05, 0x0C, 0x51, 0x52,
0x9B,
0xB2, #maybe?
0xCC, #maybe?
+ 0x9A, # describedecoration
]
# these have no pksv names as of pksv 2.1.1
diff --git a/extras/vba.py b/extras/vba.py
new file mode 100644
index 000000000..8ed0d7b5a
--- /dev/null
+++ b/extras/vba.py
@@ -0,0 +1,841 @@
+#!/usr/bin/jython
+# -*- encoding: utf-8 -*-
+"""
+vba-clojure (but really it's jython/python/jvm)
+
+This is jython, not python. Use jython to run this file. Before running this
+file, some of the dependencies need to be constructed. These can be obtained
+from the vba-clojure project.
+ sudo apt-get install g++ libtool openjdk-6-jre openjdk-6-jdk libsdl1.2-dev ant jython
+
+ export JAVA_INCLUDE_PATH=/usr/lib/jvm/java-6-openjdk-amd64/include/
+ export JAVA_INCLUDE_PATH2=/usr/lib/jvm/java-6-openjdk-amd64/include/
+
+ hg clone http://hg.bortreb.com/vba-clojure
+ cd vba-clojure/java/
+ ant all
+ cd ..
+ autoreconf -i
+ ./configure
+ make
+ sudo make install
+
+Make sure vba-clojure bindings are in $CLASSPATH:
+ export CLASSPATH=$CLASSPATH:java/dist/gb-bindings.jar
+
+Make sure vba-clojure is available within "java.library.path":
+ sudo ln -s \
+ $HOME/local/vba-clojure/vba-clojure/src/clojure/.libs/libvba.so.0.0.0 \
+ /usr/lib/jni/libvba.so
+
+Also make sure VisualBoyAdvance.cfg is somewhere in the $PATH for VBA to find.
+A default configuration is provided in vba-clojure under src/.
+
+Usage (in jython, not python):
+ import vba
+
+ # activate the laser beam
+ vba.load_rom("/path/to/baserom.gbc")
+
+ # make the emulator eat some instructions
+ vba.nstep(300)
+
+ # save the state because we're paranoid
+ copyrights = vba.get_state()
+ # or ...
+ vba.save_state("copyrights")
+ # >>> vba.load_state("copyrights") == copyrights
+ # True
+
+ # play for a while, then press F12
+ vba.run()
+
+ # let's save the game again
+ vba.save_state("unknown-delete-me")
+
+ # and let's go back to the other state
+ vba.set_state(copyrights)
+
+ # or why not the other way around?
+ vba.set_state(vba.load_state("unknown-delete-me"))
+
+ vba.get_memory_at(0xDCDA)
+ vba.set_memory_at(0xDCDB, 0xFF)
+ vba.get_memory_range(0xDCDA, 10)
+
+TOOD:
+ [ ] set a specific register
+ [ ] get a specific register
+ [ ] breakpoints
+ [ ] vgm stuff
+ [ ] gbz80disasm integration
+ [ ] pokecrystal.extras integration
+
+"""
+
+import os
+import sys
+import re
+from array import array
+import string
+from copy import copy
+import unittest
+
+# for converting bytes to readable text
+from chars import chars
+
+from map_names import map_names
+
+# for _check_java_library_path
+from java.lang import System
+
+# for passing states to the emulator
+from java.nio import ByteBuffer
+
+# For getRegisters and other times we have to pass a java int array to a
+# function.
+import jarray
+
+# load in the vba-clojure bindings
+import com.aurellem.gb.Gb as Gb
+
+# load the vba-clojure library
+Gb.loadVBA()
+
+from vba_config import *
+
+if not os.path.exists(rom_path):
+ raise Exception("rom_path is not configured properly; edit vba_config.py?")
+
+def _check_java_library_path():
+ """
+ Returns the value of java.library.path. The vba-clojure library must be
+ compiled and linked from this location.
+ """
+ return System.getProperty("java.library.path")
+
+class RomList(list):
+ """
+ Simple wrapper to prevent a giant rom from being shown on screen.
+ """
+ def __init__(self, *args, **kwargs):
+ list.__init__(self, *args, **kwargs)
+
+ def __repr__(self):
+ """
+ Simplifies this object so that the output doesn't overflow stdout.
+ """
+ return "RomList(too long)"
+
+button_masks = {
+ "a": 0x0001,
+ "b": 0x0002,
+ "r": 0x0010,
+ "l": 0x0020,
+ "u": 0x0040,
+ "d": 0x0080,
+ "select": 0x0004,
+ "start": 0x0008,
+ "restart": 0x0800,
+ "listen": -1, # what?
+}
+
+# useful for directly stating what to press
+a, b, r, l, u, d, select, start, restart = "a", "b", "r", "l", "u", "d", "select", "start", "restart"
+
+def button_combiner(buttons):
+ """
+ Combines multiple button presses into an integer. This is used when sending
+ a keypress to the emulator.
+ """
+ result = 0
+
+ # String inputs need to be cleaned up so that "start" doesn't get
+ # recognized as "s" and "t" etc..
+ if isinstance(buttons, str):
+ if "restart" in buttons:
+ buttons.replace("restart", "")
+ result |= button_masks["restart"]
+ if "start" in buttons:
+ buttons.replace("start", "")
+ result |= button_masks["start"]
+ if "select" in buttons:
+ buttons.replace("select", "")
+ result |= button_masks["select"]
+
+ for each in buttons:
+ result |= button_masks[each]
+
+ print "button: " + str(result)
+ return result
+
+def load_rom(path=None):
+ """
+ Starts the emulator with a certain ROM. Defaults to rom_path if no
+ parameters are given.
+ """
+ if path == None:
+ path = rom_path
+ try:
+ root = load_state("root")
+ except:
+ # "root.sav" is required because if you create it in the future, you
+ # will have to shutdown the emulator and possibly lose your state. Some
+ # functions require there to be at least one root state available to do
+ # computations between two states.
+ sys.stderr.write("ERROR: unable to read \"root.sav\", please run"
+ " generate_root() or get_root() to make an initial save.\n")
+ Gb.startEmulator(path)
+
+def shutdown():
+ """
+ Stops the emulator. Closes the window. The "opposite" of this is the
+ load_rom function.
+ """
+ Gb.shutdown()
+
+def step():
+ """
+ Advances the emulator forward by one step.
+ """
+ Gb.step()
+
+def nstep(steplimit):
+ """
+ Step the game forward by a certain number of instructions.
+ """
+ for counter in range(0, steplimit):
+ Gb.step()
+
+def step_until_capture():
+ """
+ Loop step() until SDLK_F12 is detected.
+ """
+ Gb.stepUntilCapture()
+
+# just some aliases for step_until_capture
+run = go = step_until_capture
+
+def translate_chars(charz):
+ result = ""
+ for each in charz:
+ result += chars[each]
+ return result
+
+def _create_byte_buffer(data):
+ """
+ Converts data into a ByteBuffer. This is useful for interfacing with the Gb
+ class.
+ """
+ buf = ByteBuffer.allocateDirect(len(data))
+ if isinstance(data[0], int):
+ for byte in data:
+ buf.put(byte)
+ else:
+ for byte in data:
+ buf.put(ord(byte))
+ return buf
+
+def set_state(state, do_step=False):
+ """
+ Injects the given state into the emulator. Use do_step if you want to call
+ step(), which also allows SDL to render the latest frame. Note that the
+ default is to not step, and that the screen (if it is enabled) will appear
+ as if it still has the last state loaded. This is normal.
+ """
+ Gb.loadState(_create_byte_buffer(state))
+ if do_step:
+ step()
+
+def get_state():
+ """
+ Retrieves the current state of the emulator.
+ """
+ buf = Gb.saveState()
+ state = [buf.get(x) for x in range(0, buf.capacity())]
+ arr = array("b")
+ arr.extend(state)
+ return arr.tostring() # instead of state
+
+def save_state(name, state=None, override=False):
+ """
+ Saves the given state to save_state_path. The file format must be ".sav"
+ (and this will be appended to your string if necessary).
+ """
+ if state == None:
+ state = get_state()
+ if len(name) < 4 or name[-4:] != ".sav":
+ name += ".sav"
+ save_path = os.path.join(save_state_path, name)
+ if not override and os.path.exists(save_path):
+ raise Exception("oops, save state path already exists: " + str(save_path))
+ else:
+ # convert the state into a reasonable output
+ data = array('b')
+ data.extend(state)
+ output = data.tostring()
+
+ file_handler = open(save_path, "wb")
+ file_handler.write(output)
+ file_handler.close()
+
+def load_state(name):
+ """
+ Reads a state from file based on name. Looks in save_state_path for a file
+ with this name (".sav" is optional).
+ """
+ save_path = os.path.join(save_state_path, name)
+ if not os.path.exists(save_path):
+ if len(name) < 4 or name[-4:] != ".sav":
+ name += ".sav"
+ save_path = os.path.join(save_state_path, name)
+ file_handler = open(save_path, "rb")
+ state = file_handler.read()
+ file_handler.close()
+ return state
+
+def generate_root():
+ """
+ Restarts the emulator and saves the initial state to "root.sav".
+ """
+ shutdown()
+ load_rom()
+ root = get_state()
+ save_state("root", state=root, override=True)
+ return root
+
+def get_root():
+ """
+ Loads the root state, or restarts the emulator and creates a new root
+ state.
+ """
+ try:
+ root = load_state("root")
+ except:
+ root = generate_root()
+
+def get_registers():
+ """
+ Returns a list of current register values.
+ """
+ register_array = jarray.zeros(Gb.NUM_REGISTERS, "i")
+ Gb.getRegisters(register_array)
+ return list(register_array)
+
+def set_registers(registers):
+ """
+ Applies the set of registers to the CPU.
+ """
+ Gb.writeRegisters(registers)
+write_registers = set_registers
+
+def get_rom():
+ """
+ Returns the ROM in bytes.
+ """
+ rom_array = jarray.zeros(Gb.ROM_SIZE, "i")
+ Gb.getROM(rom_array)
+ return RomList(rom_array)
+
+def get_ram():
+ """
+ Returns the RAM in bytes.
+ """
+ ram_array = jarray.zeros(Gb.RAM_SIZE, "i")
+ Gb.getRAM(ram_array)
+ return RomList(ram_array)
+
+def say_hello():
+ """
+ Test that the VBA/GB bindings are working.
+ """
+ Gb.sayHello()
+
+def get_memory():
+ """
+ Returns memory in bytes.
+ """
+ memory_size = 0x10000
+ memory = jarray.zeros(memory_size, "i")
+ Gb.getMemory(memory)
+ return RomList(memory)
+
+def set_memory(memory):
+ """
+ Sets memory in the emulator. Use get_memory() to retrieve the current
+ state.
+ """
+ Gb.writeMemory(memory)
+
+def get_pixels():
+ """
+ Returns a list of pixels on the screen display. Broken, probably. Use
+ screenshot() instead.
+ """
+ sys.stderr.write("ERROR: seems to be broken on VBA's end? Good luck. Use"
+ " screenshot() instead.\n")
+ size = Gb.DISPLAY_WIDTH * Gb.DISPLAY_HEIGHT
+ pixels = jarray.zeros(size, "i")
+ Gb.getPixels(pixels)
+ return RomList(pixels)
+
+def screenshot(filename, literal=False):
+ """
+ Saves a PNG screenshot to the file at filename. Use literal if you want to
+ store it in the current directory. Default is to save it to screenshots/
+ under the project.
+ """
+ screenshots_path = os.path.join(project_path, "screenshots/")
+ filename = os.path.join(screenshots_path, filename)
+ if len(filename) < 4 or filename[-4:] != ".png":
+ filename += ".png"
+ Gb.nwritePNG(filename)
+ print "Screenshot saved to: " + str(filename)
+save_png = screenshot
+
+def read_memory(address):
+ """
+ Read an integer at an address.
+ """
+ return Gb.readMemory(address)
+get_memory_at = read_memory
+
+def get_memory_range(start_address, byte_count):
+ """
+ Returns a list of bytes.
+
+ start_address - address to start reading at
+ byte_count - how many bytes (0 returns just 1 byte)
+ """
+ bytez = []
+ for counter in range(0, byte_count):
+ byte = get_memory_at(start_address + counter)
+ bytez.append(byte)
+ return bytez
+
+def set_memory_at(address, value):
+ """
+ Sets a byte at a certain address in memory. This directly sets the memory
+ instead of copying the memory from the emulator.
+ """
+ Gb.setMemoryAt(address, value)
+
+def press(buttons, steplimit=1):
+ """
+ Press a button. Use steplimit to say for how many steps you want to press
+ the button (try leaving it at the default, 1).
+ """
+ if hasattr(buttons, "__len__"):
+ number = button_combiner(buttons)
+ elif isinstance(buttons, int):
+ number = buttons
+ else:
+ number = buttons
+ for step_counter in range(0, steplimit):
+ Gb.step(number)
+
+class Registers:
+ order = [
+ "pc",
+ "sp",
+ "af",
+ "bc",
+ "de",
+ "hl",
+ "iff",
+ "div",
+ "tima",
+ "tma",
+ "tac",
+ "if",
+ "lcdc",
+ "stat",
+ "scy",
+ "scx",
+ "ly",
+ "lyc",
+ "dma",
+ "wy",
+ "wx",
+ "vbk",
+ "hdma1",
+ "hdma2",
+ "hdma3",
+ "hdma4",
+ "hdma5",
+ "svbk",
+ "ie",
+ ]
+
+ def __setitem__(self, key, value):
+ current_registers = get_registers()
+ current_registers[Registers.order.index(key)] = value
+ set_registers(current_registers)
+
+ def __getitem__(self, key):
+ current_registers = get_registers()
+ return current_registers[Registers.order.index(key)]
+
+ def __list__(self):
+ return get_registers()
+
+ def _get_register(id):
+ def constructed_func(self, id=copy(id)):
+ return get_registers()[id]
+ return constructed_func
+
+ def _set_register(id):
+ def constructed_func(self, value, id=copy(id)):
+ current_registers = get_registers()
+ current_registers[id] = value
+ set_registers(current_registers)
+ return constructed_func
+
+ pc = property(fget=_get_register(0), fset=_set_register(0))
+ sp = property(fget=_get_register(1), fset=_set_register(1))
+ af = property(fget=_get_register(2), fset=_set_register(2))
+ bc = property(fget=_get_register(3), fset=_set_register(3))
+ de = property(fget=_get_register(4), fset=_set_register(4))
+ hl = property(fget=_get_register(5), fset=_set_register(5))
+ iff = property(fget=_get_register(6), fset=_set_register(6))
+ div = property(fget=_get_register(7), fset=_set_register(7))
+ tima = property(fget=_get_register(8), fset=_set_register(8))
+ tma = property(fget=_get_register(9), fset=_set_register(9))
+ tac = property(fget=_get_register(10), fset=_set_register(10))
+ _if = property(fget=_get_register(11), fset=_set_register(11))
+ lcdc = property(fget=_get_register(12), fset=_set_register(12))
+ stat = property(fget=_get_register(13), fset=_set_register(13))
+ scy = property(fget=_get_register(14), fset=_set_register(14))
+ scx = property(fget=_get_register(15), fset=_set_register(15))
+ ly = property(fget=_get_register(16), fset=_set_register(16))
+ lyc = property(fget=_get_register(17), fset=_set_register(17))
+ dma = property(fget=_get_register(18), fset=_set_register(18))
+ wy = property(fget=_get_register(19), fset=_set_register(19))
+ wx = property(fget=_get_register(20), fset=_set_register(20))
+ vbk = property(fget=_get_register(21), fset=_set_register(21))
+ hdma1 = property(fget=_get_register(22), fset=_set_register(22))
+ hdma2 = property(fget=_get_register(23), fset=_set_register(23))
+ hdma3 = property(fget=_get_register(24), fset=_set_register(24))
+ hdma4 = property(fget=_get_register(25), fset=_set_register(25))
+ hdma5 = property(fget=_get_register(26), fset=_set_register(26))
+ svbk = property(fget=_get_register(27), fset=_set_register(27))
+ ie = property(fget=_get_register(28), fset=_set_register(28))
+
+ def __repr__(self):
+ spacing = "\t"
+ output = "Registers:\n"
+ for (id, each) in enumerate(self.order):
+ output += spacing + each + " = " + hex(get_registers()[id])
+ #hex(self[each])
+ output += "\n"
+ return output
+
+registers = Registers()
+
+def call(bank, address):
+ """
+ Jumps into a function at a certain address.
+
+ Go into the start menu, pause the game and try call(1, 0x1078) to see a
+ string printed to the screen.
+ """
+ push = [
+ registers.pc,
+ registers.hl,
+ registers.de,
+ registers.bc,
+ registers.af,
+ 0x3bb7,
+ ]
+
+ for value in push:
+ registers.sp -= 2
+ set_memory_at(registers.sp + 1, value >> 8)
+ set_memory_at(registers.sp, value & 0xFF)
+ if get_memory_range(registers.sp, 2) != [value & 0xFF, value >> 8]:
+ print "desired memory values: " + str([value & 0xFF, value >> 8] )
+ print "actual memory values: " + str(get_memory_range(registers.sp , 2))
+ print "wrong value at " + hex(registers.sp) + " expected " + hex(value) + " but got " + hex(get_memory_at(registers.sp))
+
+ if bank != 0:
+ registers["af"] = (bank << 8) | (registers["af"] & 0xFF)
+ registers["hl"] = address
+ registers["pc"] = 0x2d63 # FarJump
+ else:
+ registers["pc"] = address
+
+class crystal:
+ """
+ Just a simple namespace to store a bunch of functions for Pokémon Crystal.
+ """
+
+ @staticmethod
+ def walk_through_walls_slow():
+ memory = get_memory()
+ memory[0xC2FA] = 0
+ memory[0xC2FB] = 0
+ memory[0xC2FC] = 0
+ memory[0xC2FD] = 0
+ set_memory(memory)
+
+ @staticmethod
+ def walk_through_walls():
+ """
+ Lets the player walk all over the map. These values are probably reset
+ by some of the map/collision functions when you move on to a new
+ location, so this needs to be executed each step/tick if continuous
+ walk-through-walls is desired.
+ """
+ set_memory_at(0xC2FA, 0)
+ set_memory_at(0xC2FB, 0)
+ set_memory_at(0xC2FC, 0)
+ set_memory_at(0xC2FD, 0)
+
+ #@staticmethod
+ #def set_enemy_level(level):
+ # set_memory_at(0xd213, level)
+
+ @staticmethod
+ def nstep(steplimit=500):
+ """
+ Steps the CPU forward and calls some functions in between each step,
+ like to manipulate memory. This is pretty slow.
+ """
+ for step_counter in range(0, steplimit):
+ crystal.walk_through_walls()
+ #call(0x1, 0x1078)
+ step()
+
+ @staticmethod
+ def disable_triggers():
+ set_memory_at(0x23c4, 0xAF)
+ set_memory_at(0x23d0, 0xAF);
+
+ @staticmethod
+ def disable_callbacks():
+ set_memory_at(0x23f2, 0xAF)
+ set_memory_at(0x23fe, 0xAF)
+
+ @staticmethod
+ def get_map_group_id():
+ """
+ Returns the current map group.
+ """
+ return get_memory_at(0xdcb5)
+
+ @staticmethod
+ def get_map_id():
+ """
+ Returns the map number of the current map.
+ """
+ return get_memory_at(0xdcb6)
+
+ @staticmethod
+ def get_map_name():
+ """
+ Figures out the current map name.
+ """
+ map_group_id = crystal.get_map_group_id()
+ map_id = crystal.get_map_id()
+ return map_names[map_group_id][map_id]["name"]
+
+ @staticmethod
+ def get_xy():
+ """
+ (x, y) coordinates of player on map.
+ Relative to top-left corner of map.
+ """
+ x = get_memory_at(0xdcb8)
+ y = get_memory_at(0xdcb7)
+ return (x, y)
+
+ @staticmethod
+ def menu_select(id=1):
+ """
+ Sets the cursor to the given pokemon in the player's party. This is
+ under Start -> PKMN. This is useful for selecting a certain pokemon
+ with fly or another skill.
+
+ This probably works on other menus.
+ """
+ set_memory_at(0xcfa9, id)
+
+ @staticmethod
+ def is_in_battle():
+ """
+ Checks whether or not we're in a battle.
+ """
+ return (get_memory_at(0xd22d) != 0) or crystal.is_in_link_battle()
+
+ @staticmethod
+ def is_in_link_battle():
+ return get_memory_at(0xc2dc) != 0
+
+ @staticmethod
+ def unlock_flypoints():
+ """
+ Unlocks different destinations for flying.
+
+ Note: this might start at 0xDCA4 (minus one on all addresses), but not
+ sure.
+ """
+ set_memory_at(0xDCA5, 0xFF)
+ set_memory_at(0xDCA6, 0xFF)
+ set_memory_at(0xDCA7, 0xFF)
+ set_memory_at(0xDCA8, 0xFF)
+
+ @staticmethod
+ def get_gender():
+ """
+ Returns 'male' or 'female'.
+ """
+ gender = get_memory_at(0xD472)
+ if gender == 0:
+ return "male"
+ elif gender == 1:
+ return "female"
+ else:
+ return gender
+
+ @staticmethod
+ def get_player_name():
+ """
+ Returns the 7 characters making up the player's name.
+ """
+ bytez = get_memory_range(0xD47D, 7)
+ name = translate_chars(bytez)
+ return name
+
+ @staticmethod
+ def warp(map_group_id, map_id, x, y):
+ set_memory_at(0xdcb5, map_group_id)
+ set_memory_at(0xdcb6, map_id)
+ set_memory_at(0xdcb7, y)
+ set_memory_at(0xdcb8, x)
+ set_memory_at(0xd001, 0xFF)
+ set_memory_at(0xff9f, 0xF1)
+ set_memory_at(0xd432, 1)
+ set_memory_at(0xd434, 0 & 251)
+
+ @staticmethod
+ def warp_pokecenter():
+ crystal.warp(1, 1, 3, 3)
+ crystal.nstep(200)
+
+ @staticmethod
+ def masterballs():
+ # masterball
+ set_memory_at(0xd8d8, 1)
+ set_memory_at(0xd8d9, 99)
+
+ # ultraball
+ set_memory_at(0xd8da, 2)
+ set_memory_at(0xd8db, 99)
+
+ # pokeballs
+ set_memory_at(0xd8dc, 5)
+ set_memory_at(0xd8dd, 99)
+
+ @staticmethod
+ def get_text():
+ """
+ Returns alphanumeric text on the screen. Other characters will not be
+ shown.
+ """
+ output = ""
+ tiles = get_memory_range(0xc4a0, 1000)
+ for each in tiles:
+ if each in chars.keys():
+ thing = chars[each]
+ acceptable = False
+
+ if len(thing) == 2:
+ portion = thing[1:]
+ else:
+ portion = thing
+
+ if portion in string.printable:
+ acceptable = True
+
+ if acceptable:
+ output += thing
+
+ # remove extra whitespace
+ output = re.sub(" +", " ", output)
+ output = output.strip()
+
+ return output
+
+ @staticmethod
+ def set_partymon2():
+ """
+ This causes corruption, so it's not working yet.
+ """
+ memory = get_memory()
+ memory[0xdcd7] = 2
+ memory[0xdcd9] = 0x7
+
+ memory[0xdd0f] = 0x7
+ memory[0xdd10] = 0x1
+
+ # moves
+ memory[0xdd11] = 0x1
+ memory[0xdd12] = 0x2
+ memory[0xdd13] = 0x3
+ memory[0xdd14] = 0x4
+
+ # id
+ memory[0xdd15] = 0x1
+ memory[0xdd16] = 0x2
+
+ # experience
+ memory[0xdd17] = 0x2
+ memory[0xdd18] = 0x3
+ memory[0xdd19] = 0x4
+
+ # hp
+ memory[0xdd1a] = 0x5
+ memory[0xdd1b] = 0x6
+
+ # current hp
+ memory[0xdd31] = 0x10
+ memory[0xdd32] = 0x25
+
+ # max hp
+ memory[0xdd33] = 0x10
+ memory[0xdd34] = 0x40
+
+ set_memory(memory)
+
+class TestEmulator(unittest.TestCase):
+ try:
+ state = load_state("cheating-12")
+ except:
+ if "__name__" == "__main__":
+ raise Exception("failed to setup unit tests because no save state found")
+
+ def setUp(self):
+ load_rom()
+ set_state(self.state)
+
+ def tearDown(self):
+ shutdown()
+
+ def test_PlaceString(self):
+ call(0, 0x1078)
+
+ # where to draw the text
+ registers["hl"] = 0xc4a0
+
+ # what text to read from
+ registers["de"] = 0x1276
+
+ nstep(10)
+
+ text = crystal.get_text()
+
+ self.assertTrue("TRAINER" in text)
+
+if __name__ == "__main__":
+ unittest.main()
+
diff --git a/extras/vba_config.py b/extras/vba_config.py
new file mode 100644
index 000000000..8377c8818
--- /dev/null
+++ b/extras/vba_config.py
@@ -0,0 +1,15 @@
+#!/usr/bin/jython
+# -*- encoding: utf-8 -*-
+import os
+
+# by default we assume the user has things in their $HOME
+home = os.path.expanduser("~") # or System.getProperty("user.home")
+
+# and that the pokecrystal project folder is in there somewhere
+project_path = os.path.join(home, os.path.join("code", "pokecrystal"))
+
+# save states are in ~/code/pokecrystal/save-states/
+save_state_path = os.path.join(project_path, "save-states")
+
+# where is your rom?
+rom_path = os.path.join(project_path, "baserom.gbc")
diff --git a/gbhw.asm b/gbhw.asm
new file mode 100644
index 000000000..de87d304a
--- /dev/null
+++ b/gbhw.asm
@@ -0,0 +1,65 @@
+; Graciously aped from http://nocash.emubase.de/pandocs.htm .
+
+rJOYP EQU $ff00 ; Joypad (R/W)
+rSB EQU $ff01 ; Serial transfer data (R/W)
+rSC EQU $ff02 ; Serial Transfer Control (R/W)
+rDIV EQU $ff04 ; Divider Register (R/W)
+rTIMA EQU $ff05 ; Timer counter (R/W)
+rTMA EQU $ff06 ; Timer Modulo (R/W)
+rTAC EQU $ff07 ; Timer Control (R/W)
+rIF EQU $ff0f ; Interrupt Flag (R/W)
+rNR10 EQU $ff10 ; Channel 1 Sweep register (R/W)
+rNR11 EQU $ff11 ; Channel 1 Sound length/Wave pattern duty (R/W)
+rNR12 EQU $ff12 ; Channel 1 Volume Envelope (R/W)
+rNR13 EQU $ff13 ; Channel 1 Frequency lo (Write Only)
+rNR14 EQU $ff14 ; Channel 1 Frequency hi (R/W)
+rNR21 EQU $ff16 ; Channel 2 Sound Length/Wave Pattern Duty (R/W)
+rNR22 EQU $ff17 ; Channel 2 Volume Envelope (R/W)
+rNR23 EQU $ff18 ; Channel 2 Frequency lo data (W)
+rNR24 EQU $ff19 ; Channel 2 Frequency hi data (R/W)
+rNR30 EQU $ff1a ; Channel 3 Sound on/off (R/W)
+rNR31 EQU $ff1b ; Channel 3 Sound Length
+rNR32 EQU $ff1c ; Channel 3 Select output level (R/W)
+rNR33 EQU $ff1d ; Channel 3 Frequency's lower data (W)
+rNR34 EQU $ff1e ; Channel 3 Frequency's higher data (R/W)
+rNR41 EQU $ff20 ; Channel 4 Sound Length (R/W)
+rNR42 EQU $ff21 ; Channel 4 Volume Envelope (R/W)
+rNR43 EQU $ff22 ; Channel 4 Polynomial Counter (R/W)
+rNR44 EQU $ff23 ; Channel 4 Counter/consecutive; Inital (R/W)
+rNR50 EQU $ff24 ; Channel control / ON-OFF / Volume (R/W)
+rNR51 EQU $ff25 ; Selection of Sound output terminal (R/W)
+rNR52 EQU $ff26 ; Sound on/off
+rLCDC EQU $ff40 ; LCD Control (R/W)
+rSTAT EQU $ff41 ; LCDC Status (R/W)
+rSCY EQU $ff42 ; Scroll Y (R/W)
+rSCX EQU $ff43 ; Scroll X (R/W)
+rLY EQU $ff44 ; LCDC Y-Coordinate (R)
+rLYC EQU $ff45 ; LY Compare (R/W)
+rDMA EQU $ff46 ; DMA Transfer and Start Address (W)
+rBGP EQU $ff47 ; BG Palette Data (R/W) - Non CGB Mode Only
+rOBP0 EQU $ff48 ; Object Palette 0 Data (R/W) - Non CGB Mode Only
+rOBP1 EQU $ff49 ; Object Palette 1 Data (R/W) - Non CGB Mode Only
+rWY EQU $ff4a ; Window Y Position (R/W)
+rWX EQU $ff4b ; Window X Position minus 7 (R/W)
+rKEY1 EQU $ff4d ; CGB Mode Only - Prepare Speed Switch
+rVBK EQU $ff4f ; CGB Mode Only - VRAM Bank
+rHDMA1 EQU $ff51 ; CGB Mode Only - New DMA Source, High
+rHDMA2 EQU $ff52 ; CGB Mode Only - New DMA Source, Low
+rHDMA3 EQU $ff53 ; CGB Mode Only - New DMA Destination, High
+rHDMA4 EQU $ff54 ; CGB Mode Only - New DMA Destination, Low
+rHDMA5 EQU $ff55 ; CGB Mode Only - New DMA Length/Mode/Start
+rRP EQU $ff56 ; CGB Mode Only - Infrared Communications Port
+rBGPI EQU $ff68 ; CGB Mode Only - Background Palette Index
+rBGPD EQU $ff69 ; CGB Mode Only - Background Palette Data
+rOBPI EQU $ff6a ; CGB Mode Only - Sprite Palette Index
+rOBPD EQU $ff6b ; CGB Mode Only - Sprite Palette Data
+rUNKNOWN1 EQU $ff6c ; (FEh) Bit 0 (Read/Write) - CGB Mode Only
+rSVBK EQU $ff70 ; CGB Mode Only - WRAM Bank
+rUNKNOWN2 EQU $ff72 ; (00h) - Bit 0-7 (Read/Write)
+rUNKNOWN3 EQU $ff73 ; (00h) - Bit 0-7 (Read/Write)
+rUNKNOWN4 EQU $ff74 ; (00h) - Bit 0-7 (Read/Write) - CGB Mode Only
+rUNKNOWN5 EQU $ff75 ; (8Fh) - Bit 4-6 (Read/Write)
+rUNKNOWN6 EQU $ff76 ; (00h) - Always 00h (Read Only)
+rUNKNOWN7 EQU $ff77 ; (00h) - Always 00h (Read Only)
+rIE EQU $ffff ; Interrupt Enable (R/W)
+
diff --git a/gfx/debug/color_test.2bpp b/gfx/debug/color_test.2bpp
new file mode 100644
index 000000000..113aa1256
--- /dev/null
+++ b/gfx/debug/color_test.2bpp
Binary files differ
diff --git a/gfx/evo/bubble.2bpp b/gfx/evo/bubble.2bpp
new file mode 100644
index 000000000..741ee9026
--- /dev/null
+++ b/gfx/evo/bubble.2bpp
Binary files differ
diff --git a/gfx/evo/bubble_large.2bpp b/gfx/evo/bubble_large.2bpp
new file mode 100644
index 000000000..a69044414
--- /dev/null
+++ b/gfx/evo/bubble_large.2bpp
Binary files differ
diff --git a/gfx/font.1bpp b/gfx/misc/font.1bpp
index ff8d2d4fe..ff8d2d4fe 100644
--- a/gfx/font.1bpp
+++ b/gfx/misc/font.1bpp
Binary files differ
diff --git a/gfx/font_battle_extra.2bpp b/gfx/misc/font_battle_extra.2bpp
index 77c2f3576..77c2f3576 100644
--- a/gfx/font_battle_extra.2bpp
+++ b/gfx/misc/font_battle_extra.2bpp
Binary files differ
diff --git a/gfx/font_extra.2bpp b/gfx/misc/font_extra.2bpp
index 50d66916f..50d66916f 100644
--- a/gfx/font_extra.2bpp
+++ b/gfx/misc/font_extra.2bpp
Binary files differ
diff --git a/gfx/font_inversed.1bpp b/gfx/misc/font_inversed.1bpp
index 39a7e73d6..39a7e73d6 100644
--- a/gfx/font_inversed.1bpp
+++ b/gfx/misc/font_inversed.1bpp
diff --git a/gfx/misc/pack_f.2bpp b/gfx/misc/pack_f.2bpp
new file mode 100644
index 000000000..60d6b7f91
--- /dev/null
+++ b/gfx/misc/pack_f.2bpp
Binary files differ
diff --git a/gfx/misc/unown_font.2bpp b/gfx/misc/unown_font.2bpp
new file mode 100644
index 000000000..4ec0bbea6
--- /dev/null
+++ b/gfx/misc/unown_font.2bpp
Binary files differ
diff --git a/gfx/ow/misc.2bpp b/gfx/ow/misc.2bpp
new file mode 100644
index 000000000..8f9b3b96f
--- /dev/null
+++ b/gfx/ow/misc.2bpp
Binary files differ
diff --git a/gfx/special/celebi/1.2bpp b/gfx/special/celebi/1.2bpp
new file mode 100644
index 000000000..6379fc92f
--- /dev/null
+++ b/gfx/special/celebi/1.2bpp
@@ -0,0 +1 @@
+00.>  d$6&_g?83<}__{jn @ ظ00 \ No newline at end of file
diff --git a/gfx/special/celebi/2.2bpp b/gfx/special/celebi/2.2bpp
new file mode 100644
index 000000000..f7c3294d3
--- /dev/null
+++ b/gfx/special/celebi/2.2bpp
Binary files differ
diff --git a/gfx/special/celebi/3.2bpp b/gfx/special/celebi/3.2bpp
new file mode 100644
index 000000000..00cac65a7
--- /dev/null
+++ b/gfx/special/celebi/3.2bpp
Binary files differ
diff --git a/gfx/special/celebi/4.2bpp b/gfx/special/celebi/4.2bpp
new file mode 100644
index 000000000..00cac65a7
--- /dev/null
+++ b/gfx/special/celebi/4.2bpp
Binary files differ
diff --git a/gfx/special/celebi/leaf.2bpp b/gfx/special/celebi/leaf.2bpp
new file mode 100644
index 000000000..1c8a3f9a8
--- /dev/null
+++ b/gfx/special/celebi/leaf.2bpp
Binary files differ
diff --git a/joypad.asm b/joypad.asm
new file mode 100644
index 000000000..099bfbef6
--- /dev/null
+++ b/joypad.asm
@@ -0,0 +1,275 @@
+JoypadInt: ; 92e
+; Replaced by Joypad, called from VBlank instead of the useless
+; joypad interrupt.
+
+; This is a placeholder in case the interrupt is somehow enabled.
+ reti
+; 92f
+
+ClearJoypadPublic: ; 92f
+ xor a
+; Pressed this frame (delta)
+ ld [$ffa7], a
+; Currently pressed
+ ld [$ffa8], a
+ ret
+; 935
+
+Joypad: ; 935
+; Read the joypad register and translate it to something more
+; workable for use in-game. There are 8 buttons, so we can use
+; one byte to contain all player input.
+
+; Updates:
+
+; $ffa2: released this frame (delta)
+; $ffa3: pressed this frame (delta)
+; $ffa4: currently pressed
+; $ffa5: pressed so far
+
+; Any of these three bits can be used to disable input.
+ ld a, [$cfbe]
+ and %11010000
+ ret nz
+
+; If we're saving, input is disabled.
+ ld a, [$c2cd]
+ and a
+ ret nz
+
+; We can only get four inputs at a time.
+; We take d-pad first for no particular reason.
+ ld a, D_PAD
+ ld [rJOYP], a
+; Read twice to give the request time to take.
+ ld a, [rJOYP]
+ ld a, [rJOYP]
+
+; The Joypad register output is in the lo nybble (inversed).
+; We make the hi nybble of our new container d-pad input.
+ cpl
+ and $f
+ swap a
+
+; We'll keep this in b for now.
+ ld b, a
+
+; Buttons make 8 total inputs (A, B, Select, Start).
+; We can fit this into one byte.
+ ld a, BUTTONS
+ ld [rJOYP], a
+; Wait for input to stabilize.
+ ld a, [rJOYP]
+ ld a, [rJOYP]
+ ld a, [rJOYP]
+ ld a, [rJOYP]
+ ld a, [rJOYP]
+ ld a, [rJOYP]
+; Buttons take the lo nybble.
+ cpl
+ and $f
+ or b
+ ld b, a
+
+; Reset the joypad register since we're done with it.
+ ld a, $30
+ ld [rJOYP], a
+
+; To get the delta we xor the last frame's input with the new one.
+ ld a, [$ffa4] ; last frame
+ ld e, a
+ xor b
+ ld d, a
+; Released this frame:
+ and e
+ ld [$ffa2], a
+; Pressed this frame:
+ ld a, d
+ and b
+ ld [$ffa3], a
+
+; Add any new presses to the list of collective presses:
+ ld c, a
+ ld a, [$ffa5]
+ or c
+ ld [$ffa5], a
+
+; Currently pressed:
+ ld a, b
+ ld [$ffa4], a
+
+; Now that we have the input, we can do stuff with it.
+
+; For example, soft reset:
+ and BUTTON_A | BUTTON_B | SELECT | START
+ cp BUTTON_A | BUTTON_B | SELECT | START
+ jp z, $0150 ; reset
+
+ ret
+; 984
+
+
+GetJoypadPublic: ; 984
+; Update mirror joypad input from $ffa4 (real input)
+
+; $ffa6: released this frame (delta)
+; $ffa7: pressed this frame (delta)
+; $ffa8: currently pressed
+
+; bit 0 A
+; 1 B
+; 2 SELECT
+; 3 START
+; 4 RIGHT
+; 5 LEFT
+; 6 UP
+; 7 DOWN
+
+ push af
+ push hl
+ push de
+ push bc
+
+; The player input can be automated using an input stream.
+; See more below.
+ ld a, [InputType]
+ cp a, AUTO_INPUT
+ jr z, .auto
+
+; To get deltas, take this and last frame's input.
+ ld a, [$ffa4] ; real input
+ ld b, a
+ ld a, [$ffa8] ; last frame mirror
+ ld e, a
+
+; Released this frame:
+ xor b
+ ld d, a
+ and e
+ ld [$ffa6], a
+
+; Pressed this frame:
+ ld a, d
+ and b
+ ld [$ffa7], a
+
+; It looks like the collective presses got commented out here.
+ ld c, a
+
+; Currently pressed:
+ ld a, b
+ ld [$ffa8], a ; frame input
+
+.quit
+ pop bc
+ pop de
+ pop hl
+ pop af
+ ret
+
+.auto
+; Use a predetermined input stream (used in the catching tutorial).
+
+; Stream format: [input][duration]
+; A value of $ff will immediately end the stream.
+
+; Read from the input stream.
+ ld a, [$ff9d]
+ push af
+ ld a, [AutoInputBank]
+ rst Bankswitch
+
+ ld hl, AutoInputAddress
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+
+; We only update when the input duration has expired.
+ ld a, [AutoInputLength]
+ and a
+ jr z, .updateauto
+
+; Until then, don't change anything.
+ dec a
+ ld [AutoInputLength], a
+ pop af
+ rst Bankswitch
+ jr .quit
+
+
+.updateauto
+; An input of $ff will end the stream.
+ ld a, [hli]
+ cp a, $ff
+ jr z, .stopauto
+ ld b, a
+
+; A duration of $ff will end the stream indefinitely.
+ ld a, [hli]
+ ld [AutoInputLength], a
+ cp a, $ff
+ jr nz, .next
+
+; The current input is overwritten.
+ dec hl
+ dec hl
+ ld b, NO_INPUT
+ jr .finishauto
+
+.next
+; On to the next input...
+ ld a, l
+ ld [AutoInputAddress], a
+ ld a, h
+ ld [AutoInputAddress+1], a
+ jr .finishauto
+
+.stopauto
+ call StopAutoInput
+ ld b, NO_INPUT
+
+.finishauto
+ pop af
+ rst Bankswitch
+ ld a, b
+ ld [$ffa7], a ; pressed
+ ld [$ffa8], a ; input
+ jr .quit
+; 9ee
+
+
+StartAutoInput: ; 9ee
+; Start reading automated input stream at a:hl.
+
+ ld [AutoInputBank], a
+ ld a, l
+ ld [AutoInputAddress], a
+ ld a, h
+ ld [AutoInputAddress+1], a
+; Start reading the stream immediately.
+ xor a
+ ld [AutoInputLength], a
+; Reset input mirrors.
+ xor a
+ ld [$ffa7], a ; pressed this frame
+ ld [$ffa6], a ; released this frame
+ ld [$ffa8], a ; currently pressed
+
+ ld a, AUTO_INPUT
+ ld [InputType], a
+ ret
+; a0a
+
+
+StopAutoInput: ; a0a
+; Clear variables related to automated input.
+ xor a
+ ld [AutoInputBank], a
+ ld [AutoInputAddress], a
+ ld [AutoInputAddress+1], a
+ ld [AutoInputLength], a
+; Back to normal input.
+ ld [InputType], a
+ ret
+; a1b
+
diff --git a/main.asm b/main.asm
index 6674f4c76..0b99b9c22 100644
--- a/main.asm
+++ b/main.asm
@@ -4,7 +4,7 @@ SECTION "rst0",HOME[$0]
jp Start
SECTION "rst8",HOME[$8] ; FarCall
- jp $2d63
+ jp FarJpHl
SECTION "rst10",HOME[$10] ; Bankswitch
ld [$ff9d], a
@@ -47,7 +47,7 @@ SECTION "serial",HOME[$58] ; serial interrupt
jp $06ef
SECTION "joypad",HOME[$60] ; joypad interrupt
- jp $092e
+ jp JoypadInt
SECTION "romheader",HOME[$100]
Start:
@@ -85,7 +85,6 @@ DelayFrames: ; 0x468
ret
; 0x46f
-
RTC: ; 46f
; update time and time-sensitive palettes
@@ -150,47 +149,47 @@ DisableLCD: ; 568
; Most of this is just going through the motions
; don't need to do anything if lcd is already off
- ld a, [$ff40] ; LCDC
+ ld a, [rLCDC]
bit 7, a ; lcd enable
ret z
; reset ints
xor a
- ld [$ff0f], a ; IF
+ ld [rIF], a
; save enabled ints
- ld a, [$ffff] ; IE
+ ld a, [rIE]
ld b, a
; disable vblank
res 0, a ; vblank
- ld [$ffff], a ; IE
+ ld [rIE], a
.wait
; wait until vblank
- ld a, [$ff44] ; LY
+ ld a, [rLY]
cp 145 ; >144 (ensure beginning of vblank)
jr nz, .wait
; turn lcd off
- ld a, [$ff40] ; LCDC
+ ld a, [rLCDC]
and %01111111 ; lcd enable off
- ld [$ff40], a ; LCDC
+ ld [rLCDC], a
; reset ints
xor a
- ld [$ff0f], a ; IF
+ ld [rIF], a
; restore enabled ints
ld a, b
- ld [$ffff], a ; IE
+ ld [rIE], a
ret
; 58a
EnableLCD: ; 58a
- ld a, [$ff40] ; LCDC
+ ld a, [rLCDC]
set 7, a ; lcd enable
- ld [$ff40], a ; LCDC
+ ld [rLCDC], a
ret
; 591
@@ -425,252 +424,11 @@ SetClock: ; 691
ret
; 6c4
-INCBIN "baserom.gbc",$6c4,$935 - $6c4
+INCBIN "baserom.gbc",$6c4,$92e - $6c4
-Joypad: ; 935
-; update joypad state
-; $ffa2: released
-; $ffa3: pressed
-; $ffa4: input
-; $ffa5: total pressed
-;
- ld a, [$cfbe]
- and $d0
- ret nz
-
-; pause game update?
- ld a, [$c2cd]
- and a
- ret nz
-
-; d-pad
- ld a, $20
- ld [$ff00], a
- ld a, [$ff00]
- ld a, [$ff00]
-; hi nybble
- cpl
- and $f
- swap a
- ld b, a
-
-; buttons
- ld a, $10
- ld [$ff00], a
-; wait to stabilize
- ld a, [$ff00]
- ld a, [$ff00]
- ld a, [$ff00]
- ld a, [$ff00]
- ld a, [$ff00]
- ld a, [$ff00]
-; lo nybble
- cpl
- and $f
- or b
- ld b, a
-
-; reset joypad
- ld a, $30
- ld [$ff00], a
-
-; get change in input
- ld a, [$ffa4] ; last frame's input
- ld e, a
- xor b ; current frame input
- ld d, a
-; released
- and e
- ld [$ffa2], a
-; pressed
- ld a, d
- and b
- ld [$ffa3], a
-
-; total pressed
- ld c, a
- ld a, [$ffa5]
- or c
- ld [$ffa5], a
-
-; original input
- ld a, b
- ld [$ffa4], a
-
-; A+B+SELECT+START
- and $f
- cp $f
- jp z, $0150 ; reset
-
- ret
-; 984
-
-
-GetJoypadPublic: ; 984
-; update mirror joypad input from $ffa4 (real input)
-
-; $ffa6: released
-; $ffa7: pressed
-; $ffa8: input
-
-; bit 0 A
-; 1 B
-; 2 SELECT
-; 3 START
-; 4 RIGHT
-; 5 LEFT
-; 6 UP
-; 7 DOWN
-
- push af
- push hl
- push de
- push bc
-
-; automated input?
- ld a, [InputType]
- cp a, $ff ; INPUT_AUTO
- jr z, .auto
-
-; get input
- ld a, [$ffa4] ; real input
- ld b, a
- ld a, [$ffa8] ; last frame mirror
- ld e, a
-
-; released
- xor b
- ld d, a
- and e
- ld [$ffa6], a
-
-; pressed
- ld a, d
- and b
- ld [$ffa7], a
-
-; leftover from pasted code
- ld c, a
-
-;
- ld a, b
- ld [$ffa8], a ; frame input
-.quit
- pop bc
- pop de
- pop hl
- pop af
- ret
+INCLUDE "joypad.asm"
-.auto
-; use predetermined input feed (used in catch tutorial)
-; struct: [input][duration]
-
-; save bank
- ld a, [$ff9d]
- push af
-;
- ld a, [AutoInputBank]
- rst Bankswitch
-;
- ld hl, AutoInputAddress ; AutoInputAddress-9
- ld a, [hli]
- ld h, [hl]
- ld l, a
-
-; update when frame count hits 0
- ld a, [AutoInputLength]
- and a
- jr z, .updateauto
-
-; until then, do nothing
- dec a
- ld [AutoInputLength], a
-; restore bank
- pop af
- rst Bankswitch
-; we're done
- jr .quit
-
-.updateauto
-; get input
- ld a, [hli]
-; stop?
- cp a, $ff
- jr z, .stopinput
- ld b, a
-
-; duration
- ld a, [hli]
- ld [AutoInputLength], a
-; duration $ff = end at input
- cp a, $ff
- jr nz, .next
-
-; no input
- dec hl
- dec hl
- ld b, $00 ; no input
- jr .finishauto
-
-.next
-; output recorded
- ld a, l
- ld [AutoInputAddress], a
- ld a, h
- ld [AutoInputAddress+1], a
- jr .finishauto
-
-.stopinput
- call StopAutoInput
- ld b, $00 ; no input
-
-.finishauto
-; restore bank
- pop af
- rst Bankswitch
-; update mirrors
- ld a, b
- ld [$ffa7], a ; pressed
- ld [$ffa8], a ; input
- jr .quit
-; 9ee
-
-StartAutoInput: ; 9ee
-; start auto input stream at a:hl
-; bank
- ld [AutoInputBank], a
-; address
- ld a, l
- ld [AutoInputAddress], a
- ld a, h
- ld [AutoInputAddress+1], a
-; don't wait to update
- xor a
- ld [AutoInputLength], a
-; clear input mirrors
- xor a
- ld [$ffa7], a ; pressed
- ld [$ffa6], a ; released
- ld [$ffa8], a ; input
-; start reading input stream instead of player input
- ld a, $ff ; INPUT_AUTO
- ld [InputType], a
- ret
-; a0a
-
-StopAutoInput: ; a0a
-; clear autoinput ram
- xor a
- ld [AutoInputBank], a
- ld [AutoInputAddress], a
- ld [AutoInputAddress+1], a
- ld [AutoInputLength], a
-; normal input
- ld [InputType], a
- ret
-; a1b
INCBIN "baserom.gbc",$a1b,$b40 - $a1b
@@ -1063,18 +821,18 @@ UpdateCGBPals: ; c33
ForceUpdateCGBPals: ; c37
; save wram bank
- ld a, [$ff70] ; wram bank
+ ld a, [rSVBK]
push af
; bankswitch
ld a, 5 ; BANK(BGPals)
- ld [$ff70], a ; wram bank
+ ld [rSVBK], a
; get bg pal buffer
ld hl, BGPals ; 5:d080
; update bg pals
ld a, %10000000 ; auto increment, index 0
- ld [$ff68], a ; BGPI
- ld c, $69 ; $ff69
+ ld [rBGPI], a
+ ld c, rBGPD - rJOYP
ld b, 4 ; NUM_PALS / 2
.bgp
@@ -1119,8 +877,8 @@ ForceUpdateCGBPals: ; c37
; update obj pals
ld a, %10000000 ; auto increment, index 0
- ld [$ff6a], a
- ld c, $6b ; $ff6b - $ff00
+ ld [rOBPI], a
+ ld c, rOBPD - rJOYP
ld b, 4 ; NUM_PALS / 2
.obp
@@ -1163,7 +921,7 @@ ForceUpdateCGBPals: ; c37
; restore wram bank
pop af
- ld [$ff70], a ; wram bank
+ ld [rSVBK], a
; clear pal update queue
xor a
ld [$ffe5], a
@@ -1177,7 +935,7 @@ DmgToCgbBGPals: ; c9f
; exists to forego reinserting cgb-converted image data
; input: a -> bgp
- ld [$ff47], a ; bgp
+ ld [rBGP], a
push af
; check cgb
@@ -1199,7 +957,7 @@ DmgToCgbBGPals: ; c9f
ld hl, BGPals ; to
ld de, Unkn1Pals ; from
; order
- ld a, [$ff47] ; bgp
+ ld a, [rBGP]
ld b, a
; # pals
ld c, 8 ; all pals
@@ -1225,9 +983,9 @@ DmgToCgbObjPals: ; ccb
; input: d -> obp1
; e -> obp2
ld a, e
- ld [$ff48], a ; obp0
+ ld [rOBP0], a
ld a, d
- ld [$ff49], a ; obp1
+ ld [rOBP1], a
; check cgb
ld a, [$ffe6]
@@ -1250,7 +1008,7 @@ DmgToCgbObjPals: ; ccb
; from
ld de, Unkn2Pals
; order
- ld a, [$ff48] ; obp0
+ ld a, [rOBP0]
ld b, a
; # pals
ld c, 8 ; all pals
@@ -1378,7 +1136,7 @@ ClearTileMap: ; fc8
call ByteFill
; We aren't done if the LCD is on
- ld a, [$ff40] ; LCDC
+ ld a, [rLCDC]
bit 7, a
ret z
jp WaitBGMap
@@ -1668,7 +1426,7 @@ DMATransfer: ; 15d8
and a
ret z
; start transfer
- ld [$ff55], a ; hdma5
+ ld [rHDMA5], a
; indicate that transfer has occurred
xor a
ld [$ffe8], a
@@ -1689,7 +1447,7 @@ UpdateBGMapBuffer: ; 15e3
and a
ret z
; save wram bank
- ld a, [$ff4f] ; vram bank
+ ld a, [rVBK]
push af
; save sp
ld [$ffd9], sp
@@ -1712,7 +1470,7 @@ UpdateBGMapBuffer: ; 15e3
pop bc
; update palettes
ld a, $1
- ld [$ff4f], a ; vram bank
+ ld [rVBK], a
; tile 1
ld a, [hli]
ld [bc], a
@@ -1723,7 +1481,7 @@ UpdateBGMapBuffer: ; 15e3
dec c
; update tiles
ld a, $0
- ld [$ff4f], a ; vram bank
+ ld [rVBK], a
; tile 1
ld a, [de]
inc de
@@ -1740,7 +1498,7 @@ UpdateBGMapBuffer: ; 15e3
pop bc
; update palettes
ld a, $1
- ld [$ff4f], a ; vram bank
+ ld [rVBK], a
; tile 1
ld a, [hli]
ld [bc], a
@@ -1751,7 +1509,7 @@ UpdateBGMapBuffer: ; 15e3
dec c
; update tiles
ld a, $0
- ld [$ff4f], a ; vram bank
+ ld [rVBK], a
; tile 1
ld a, [de]
inc de
@@ -1781,7 +1539,7 @@ UpdateBGMapBuffer: ; 15e3
; restore vram bank
pop af
- ld [$ff4f], a ; vram bank
+ ld [rVBK], a
; we don't need to update bg map until new tiles are loaded
xor a
@@ -1859,13 +1617,13 @@ UpdateBGMap: ; 164c
.attr
; switch vram banks
ld a, 1
- ld [$ff4f], a ; vram bank
+ ld [rVBK], a
; bg map 1
ld hl, AttrMap
call .getthird
; restore vram bank
ld a, 0
- ld [$ff4f], a ; vram bank
+ ld [rVBK], a
ret
.tiles
@@ -2012,7 +1770,7 @@ SafeLoadTiles2: ; 170a
and a
ret z
; abort if too far into vblank
- ld a, [$ff44] ; LY
+ ld a, [rLY]
; ly = 144-145?
cp 144
ret c
@@ -2114,7 +1872,7 @@ SafeLoadTiles: ; 1769
and a
ret z
; abort if too far into vblank
- ld a, [$ff44] ; LY
+ ld a, [rLY]
; ly = 144-145?
cp 144
ret c
@@ -2230,7 +1988,7 @@ SafeTileAnimation: ; 17d3
ret z
; abort if too far into vblank
- ld a, [$ff44] ; LY
+ ld a, [rLY]
; ret unless ly = 144-150
cp 144
ret c
@@ -2244,24 +2002,24 @@ SafeTileAnimation: ; 17d3
ld a, BANK(DoTileAnimation)
rst Bankswitch ; bankswitch
- ld a, [$ff70] ; wram bank
+ ld a, [rSVBK]
push af ; save wram bank
ld a, $1 ; wram bank 1
- ld [$ff70], a ; wram bank
+ ld [rSVBK], a
- ld a, [$ff4f] ; vram bank
+ ld a, [rVBK]
push af ; save vram bank
ld a, $0 ; vram bank 0
- ld [$ff4f], a ; vram bank
+ ld [rVBK], a
; take care of tile animation queue
call DoTileAnimation
; restore affected banks
pop af
- ld [$ff4f], a ; vram bank
+ ld [rVBK], a
pop af
- ld [$ff70], a ; wram bank
+ ld [rSVBK], a
pop af
rst Bankswitch ; bankswitch
ret
@@ -2319,15 +2077,15 @@ AskSerial: ; 2063
; handshake
ld a, $88
- ld [$ff01], a
+ ld [rSB], a
; switch to internal clock
ld a, %00000001
- ld [$ff02], a
+ ld [rSC], a
; start transfer
ld a, %10000001
- ld [$ff02], a
+ ld [rSC], a
ret
; 208a
@@ -2339,17 +2097,17 @@ GameTimer: ; 209e
nop
; save wram bank
- ld a, [$ff70] ; wram bank
+ ld a, [rSVBK]
push af
ld a, $1
- ld [$ff70], a ; wram bank
+ ld [rSVBK], a
call UpdateGameTimer
; restore wram bank
pop af
- ld [$ff70], a ; wram bank
+ ld [rSVBK], a
ret
; 20ad
@@ -2486,16 +2244,50 @@ PushScriptPointer: ; 261f
ret
; 2631
-INCBIN "baserom.gbc",$2631,$26ef - $2631
+INCBIN "baserom.gbc",$2631,$26d4 - $2631
+
+GetScriptByte: ; 0x26d4
+; Return byte at ScriptBank:ScriptPos in a.
+
+ push hl
+ push bc
+
+ ld a, [$ff9d]
+ push af
+
+ ld a, [ScriptBank]
+ rst Bankswitch
+
+ ld hl, ScriptPos
+ ld c, [hl]
+ inc hl
+ ld b, [hl]
+
+ ld a, [bc]
+
+ inc bc
+ ld [hl], b
+ dec hl
+ ld [hl], c
+
+ ld b, a
+ pop af
+ rst Bankswitch
+ ld a, b
+
+ pop bc
+ pop hl
+ ret
+; 0x26ef
ObjectEvent: ; 0x26ef
jumptextfaceplayer ObjectEventText
; 0x26f2
-
ObjectEventText:
TX_FAR _ObjectEventText
db "@"
+; 0x26f7
INCBIN "baserom.gbc",$26f7,$2bed-$26f7
@@ -2530,6 +2322,7 @@ GetMapHeaderPointer: ; 0x2bed
ld a, OlivineGym_MapHeader - OlivinePokeCenter1F_MapHeader
call AddNTimes
ret
+; 0x2c04
GetMapHeaderMember: ; 0x2c04
; Extract data from the current map's header.
@@ -2596,7 +2389,43 @@ GetWorldMapLocation: ; 0x2caf
ret
; 0x2cbd
-INCBIN "baserom.gbc",$2cbd,$2d83-$2cbd
+INCBIN "baserom.gbc",$2cbd,$2d63-$2cbd
+
+FarJpHl: ; 2d63
+; Jump to a:hl.
+; Preserves all registers besides a.
+
+; Switch to the new bank.
+ ld [$ff8b], a
+ ld a, [$ff9d]
+ push af
+ ld a, [$ff8b]
+ rst Bankswitch
+
+ call .hl
+
+; We want to retain the contents of f.
+; To do this, we can pop to bc instead of af.
+
+ ld a, b
+ ld [$cfb9], a
+ ld a, c
+ ld [$cfba], a
+
+; Restore the working bank.
+ pop bc
+ ld a, b
+ rst Bankswitch
+
+ ld a, [$cfb9]
+ ld b, a
+ ld a, [$cfba]
+ ld c, a
+ ret
+.hl
+ jp [hl]
+; 2d83
+
Predef: ; 2d83
; call a function from given id a
@@ -2764,13 +2593,13 @@ RNG: ; 2f8c
push bc
; Added value
- ld a, [$ff04] ; divider
+ ld a, [rDIV]
ld b, a
ld a, [$ffe1]
adc b
ld [$ffe1], a
; Subtracted value
- ld a, [$ff04] ; divider
+ ld a, [rDIV]
ld b, a
ld a, [$ffe2]
sbc b
@@ -3216,9 +3045,9 @@ ClearPalettes: ; 3317
; In DMG mode, we can just change palettes to 0 (white)
xor a
- ld [$ff47], a ; BGP
- ld [$ff48], a ; OBP0
- ld [$ff49], a ; OBP1
+ ld [rBGP], a
+ ld [rOBP0], a
+ ld [rOBP1], a
ret
.cgb
@@ -3633,7 +3462,71 @@ StartMusic: ; 3b97
ret
; 3bbc
-INCBIN "baserom.gbc",$3bbc,$3c23 - $3bbc
+INCBIN "baserom.gbc",$3bbc,$3be3 - $3bbc
+
+PlayCryHeader: ; 3be3
+; Play a cry given parameters in header de
+
+ push hl
+ push de
+ push bc
+ push af
+
+; Save current bank
+ ld a, [$ff9d]
+ push af
+
+; Cry headers are stuck in one bank.
+ ld a, BANK(CryHeaders)
+ ld [$ff9d], a
+ ld [$2000], a
+
+; Each header is 6 bytes long:
+ ld hl, CryHeaders
+ add hl, de
+ add hl, de
+ add hl, de
+ add hl, de
+ add hl, de
+ add hl, de
+
+; Header struct:
+
+; id
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ inc hl
+; pitch
+ ld a, [hli]
+ ld [CryPitch], a
+; echo
+ ld a, [hli]
+ ld [CryEcho], a
+; length
+ ld a, [hli]
+ ld [CryLength], a
+ ld a, [hl]
+ ld [CryLength+1], a
+
+; That's it for the header
+ ld a, BANK(PlayCry)
+ ld [$ff9d], a
+ ld [$2000], a
+ call PlayCry
+
+; Restore bank
+ pop af
+ ld [$ff9d], a
+ ld [$2000], a
+
+ pop af
+ pop bc
+ pop de
+ pop hl
+ ret
+; 3c23
+
StartSFX: ; 3c23
; sfx id order is by priority (highest to lowest)
@@ -3782,7 +3675,66 @@ IntroFadePalettes: ; 0x617c
db %11100100
; 6182
-INCBIN "baserom.gbc",$6182,$669f - $6182
+INCBIN "baserom.gbc",$6182,$6274 - $6182
+
+FarStartTitleScreen: ; 6274
+ callba StartTitleScreen
+ ret
+; 627b
+
+INCBIN "baserom.gbc",$627b,$62bc - $627b
+
+TitleScreenEntrance: ; 62bc
+
+; Animate the logo:
+; Move each line by 4 pixels until our count hits 0.
+ ld a, [$ffcf]
+ and a
+ jr z, .done
+ sub 4
+ ld [$ffcf], a
+
+; Lay out a base (all lines scrolling together).
+ ld e, a
+ ld hl, $d100
+ ld bc, 8 * 10 ; logo height
+ call ByteFill
+
+; Alternate signage for each line's position vector.
+; This is responsible for the interlaced effect.
+ ld a, e
+ xor $ff
+ inc a
+
+ ld b, 8 * 10 / 2 ; logo height / 2
+ ld hl, $d101
+.loop
+ ld [hli], a
+ inc hl
+ dec b
+ jr nz, .loop
+
+ callba AnimateTitleCrystal
+ ret
+
+
+.done
+; Next scene
+ ld hl, $cf63
+ inc [hl]
+ xor a
+ ld [$ffc6], a
+
+; Play the title screen music.
+ ld de, MUSIC_TITLE
+ call StartMusic
+
+ ld a, $88
+ ld [$ffd2], a
+ ret
+; 62f6
+
+INCBIN "baserom.gbc",$62f6,$669f - $62f6
CheckNickErrors: ; 669f
; error-check monster nick before use
@@ -3890,7 +3842,7 @@ DrawGraphic: ; 6eef
ret
; 6f07
-INCBIN "baserom.gbc",$6f07,$8000 - $6f07
+INCBIN "baserom.gbc",$6f07,$747b - $6f07
SECTION "bank2",DATA,BANK[$2]
@@ -4102,7 +4054,7 @@ INCBIN "baserom.gbc",$b0ae,$b0d2 - $b0ae
TrainerPalettes:
INCLUDE "gfx/trainers/palette_pointers.asm"
-INCBIN "baserom.gbc",$b1de,$bc3a - $b1de
+INCBIN "baserom.gbc",$b1de,$b825 - $b1de
SECTION "bank3",DATA,BANK[$3]
@@ -4666,7 +4618,7 @@ AskSurfText: ; ca36
db "@" ; Want to SURF?
; ca3b
-INCBIN "baserom.gbc",$ca3b,$10000 - $ca3b
+INCBIN "baserom.gbc",$ca3b,$fa0b - $ca3b
SECTION "bank4",DATA,BANK[$4]
@@ -4887,7 +4839,39 @@ OpenPartyStats: ; 12e00
ret
; 0x12e1b
-INCBIN "baserom.gbc",$12e1b,$14000 - $12e1b
+INCBIN "baserom.gbc",$12e1b,$13b87 - $12e1b
+
+GetSquareRoot: ; 13b87
+; Return the square root of de in b.
+
+; Rather than calculating the result, we take the index of the
+; first value in a table of squares that isn't lower than de.
+
+ ld hl, Squares
+ ld b, 0
+.loop
+; Make sure we don't go past the end of the table.
+ inc b
+ ld a, b
+ cp $ff
+ ret z
+
+; Iterate over the table until b**2 >= de.
+ ld a, [hli]
+ sub e
+ ld a, [hli]
+ sbc d
+
+ jr c, .loop
+ ret
+
+Squares: ; 13b98
+root set 1
+ rept $ff
+ dw root*root
+root set root+1
+ endr
+; 13d96
SECTION "bank5",DATA,BANK[$5]
@@ -4989,7 +4973,7 @@ Tileset20GFX: ; 1b43e
INCBIN "gfx/tilesets/20.lz"
; 1b8f1
-INCBIN "baserom.gbc", $1b8f1, $1c000 - $1b8f1
+INCBIN "baserom.gbc", $1b8f1, $1bdfe - $1b8f1
SECTION "bank7",DATA,BANK[$7]
@@ -5032,8 +5016,6 @@ Music_Credits: INCLUDE "audio/music/credits.asm"
Music_Clair: INCLUDE "audio/music/clair.asm"
Music_MobileAdapter: INCLUDE "audio/music/mobileadapter.asm"
-INCBIN "baserom.gbc",$1ff6c, $20000 - $1ff6c
-
SECTION "bank8",DATA,BANK[$8]
@@ -5172,7 +5154,7 @@ TrainerClassDVs ; 270d6
db $98, $88 ; mysticalman
; 2715c
-INCBIN "baserom.gbc",$2715c,$28000 - $2715c
+INCBIN "baserom.gbc",$2715c,$27a2d - $2715c
SECTION "bankA",DATA,BANK[$A]
@@ -5415,7 +5397,7 @@ INCBIN "baserom.gbc",$2C41a,$2ee8f - $2C41a
pop hl
ret
-INCBIN "baserom.gbc",$2ef18,$30000 - $2ef18
+INCBIN "baserom.gbc",$2ef18,$2ef9f - $2ef18
SECTION "bankC",DATA,BANK[$C]
@@ -5448,7 +5430,7 @@ Tileset30GFX: ; 326b0
INCBIN "gfx/tilesets/30.lz"
; 329ed
-INCBIN "baserom.gbc",$329ed,$34000 - $329ed
+INCBIN "baserom.gbc",$329ed,$333f0 - $329ed
SECTION "bankD",DATA,BANK[$D]
@@ -5459,7 +5441,7 @@ TypeMatchup: ; 34bb1
INCLUDE "battle/type_matchup.asm"
; 34cfd
-INCBIN "baserom.gbc",$34cfd,$38000 - $34cfd
+INCBIN "baserom.gbc",$34cfd,$37ee2 - $34cfd
SECTION "bankE",DATA,BANK[$E]
@@ -5761,7 +5743,7 @@ LoadEnemyMon: ; 3e8eb
callab CalcMagikarpLength
; We're clear if the length is < 1536
- ld a, [MagikarpLengthHi]
+ ld a, [MagikarpLength]
cp a, $06 ; $600 = 1536
jr nz, .CheckMagikarpArea
@@ -5770,7 +5752,7 @@ LoadEnemyMon: ; 3e8eb
cp a, $0c ; / $100
jr c, .CheckMagikarpArea
; Try again if > 1614
- ld a, [MagikarpLengthLo]
+ ld a, [MagikarpLength + 1]
cp a, $50
jr nc, .GenerateDVs
@@ -5779,7 +5761,7 @@ LoadEnemyMon: ; 3e8eb
cp a, $32 ; / $100
jr c, .CheckMagikarpArea
; Try again if > 1598
- ld a, [MagikarpLengthLo]
+ ld a, [MagikarpLength + 1]
cp a, $40
jr nc, .GenerateDVs
@@ -5804,7 +5786,7 @@ LoadEnemyMon: ; 3e8eb
cp a, $64 ; / $100
jr c, .Happiness
; Floor at length 1024
- ld a, [MagikarpLengthHi]
+ ld a, [MagikarpLength]
cp a, $04 ; $400 = 1024
jr c, .GenerateDVs ; try again
@@ -6081,42 +6063,47 @@ CheckSleepingTreeMon: ; 3eb38
CheckUnownLetter: ; 3eb75
; Return carry if the Unown letter hasn't been unlocked yet
- ld a, [$def3] ; UnownLetter
+
+ ld a, [UnlockedUnowns]
ld c, a
- ld de, $0000
+ ld de, 0
+
.loop
-; Has this set been unlocked?
+
+; Don't check this set unless it's been unlocked
srl c
jr nc, .next
-; Check out the set
+
+; Is our letter in the set?
ld hl, .LetterSets
add hl, de
ld a, [hli]
ld h, [hl]
ld l, a
-; Is our letter in the set?
+
push de
- ld a, [$d234]
- ld de, $0001
+ ld a, [UnownLetter]
+ ld de, 1
push bc
call IsInArray
pop bc
pop de
- jr c, .Match
+
+ jr c, .match
+
.next
-; Next set
+; Make sure we haven't gone past the end of the table
inc e
inc e
ld a, e
-; Gone past the end of the table?
- cp a, 4*2 ; 4 sets with 2-byte pointers
+ cp a, .Set1 - .LetterSets
jr c, .loop
-; Didn't find the letter (not unlocked)
+; Hasn't been unlocked, or the letter is invalid
scf
ret
-.Match
+.match
; Valid letter
and a
ret
@@ -6128,26 +6115,21 @@ CheckUnownLetter: ; 3eb75
dw .Set4
.Set1
- ; A B C D E F G H I J K
- db $01, $02, $03, $04, $05, $06, $07, $08, $09, $0a, $0b
- db $ff ; end
-
+ ; A B C D E F G H I J K
+ db 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, $ff
.Set2
- ; L M N O P Q R
- db $0c, $0d, $0e, $0f, $10, $11, $12
- db $ff ; end
-
+ ; L M N O P Q R
+ db 12, 13, 14, 15, 16, 17, 18, $ff
.Set3
- ; S T U V W
- db $13, $14, $15, $16, $17
- db $ff ; end
-
+ ; S T U V W
+ db 19, 20, 21, 22, 23, $ff
.Set4
- ; X Y Z
- db $18, $19, $1a
- db $ff ; end
+ ; X Y Z
+ db 24, 25, 26, $ff
+
; 3ebc7
+
INCBIN "baserom.gbc", $3ebc7, $3edd8 - $3ebc7
BattleRNG: ; 3edd8
@@ -6341,7 +6323,7 @@ BattleStartMessage:
ret
; 0x3fd26
-INCBIN "baserom.gbc",$3fd26,$40000 - $3fd26
+INCBIN "baserom.gbc",$3fd26,$3fe86 - $3fd26
SECTION "bank10",DATA,BANK[$10]
@@ -6374,12 +6356,26 @@ INCBIN "baserom.gbc",$44000,$44378 - $44000
PokedexDataPointerTable: ; 0x44378
INCLUDE "stats/pokedex/entry_pointers.asm"
-INCBIN "baserom.gbc",$4456e,$3a92
+INCBIN "baserom.gbc",$4456e,$44997 - $4456e
SECTION "bank12",DATA,BANK[$12]
-INCBIN "baserom.gbc",$48000,$49d24 - $48000
+INCBIN "baserom.gbc",$48000,$48e9b - $48000
+
+PackFGFX:
+INCBIN "gfx/misc/pack_f.2bpp"
+
+INCBIN "baserom.gbc",$4925b,$49962 - $4925b
+
+SpecialCelebiGFX:
+INCBIN "gfx/special/celebi/leaf.2bpp"
+INCBIN "gfx/special/celebi/1.2bpp"
+INCBIN "gfx/special/celebi/2.2bpp"
+INCBIN "gfx/special/celebi/3.2bpp"
+INCBIN "gfx/special/celebi/4.2bpp"
+
+INCBIN "baserom.gbc",$49aa2,$49d24 - $49aa2
ContinueText: ; 0x49d24
db "CONTINUE@"
@@ -6736,7 +6732,7 @@ UpdateOTPointer: ; 0x4a83a
ret
; 0x4a843
-INCBIN "baserom.gbc",$4a843,$4C000 - $4a843
+INCBIN "baserom.gbc",$4a843,$4ae78 - $4a843
SECTION "bank13",DATA,BANK[$13]
@@ -6985,7 +6981,13 @@ EggALotMoreTimeString: ; 0x4e46e
; 0x4e497
-INCBIN "baserom.gbc",$4e497,$50000 - $4e497
+INCBIN "baserom.gbc",$4e497,$4e831 - $4e497
+
+EvolutionGFX:
+INCBIN "gfx/evo/bubble_large.2bpp"
+INCBIN "gfx/evo/bubble.2bpp"
+
+INCBIN "baserom.gbc",$4e881,$4f31c - $4e881
SECTION "bank14",DATA,BANK[$14]
@@ -7167,8 +7169,128 @@ Dragon:
Dark:
db "DARK@"
-INCBIN "baserom.gbc",$50A28, $51424 - $50A28
+INCBIN "baserom.gbc", $50a28, $50bdd - $50a28
+
+
+GetGender: ; 50bdd
+; Return the gender of a given monster in a.
+
+; 1: male
+; 0: female
+; c: genderless
+
+; This is determined by comparing the Attack and Speed DVs
+; with the species' gender ratio.
+
+
+; Figure out what type of monster struct we're looking at.
+
+; 0: PartyMon
+ ld hl, PartyMon1DVs
+ ld bc, PartyMon2 - PartyMon1
+ ld a, [MonType]
+ and a
+ jr z, .PartyMon
+
+; 1: OTPartyMon
+ ld hl, OTPartyMon1DVs
+ dec a
+ jr z, .PartyMon
+
+; 2: BoxMon
+ ld hl, $ad26 + $15 ; BoxMon1DVs
+ ld bc, $20 ; BoxMon2 - BoxMon1
+ dec a
+ jr z, .BoxMon
+
+; 3: Unknown
+ ld hl, $d123 ; DVBuffer
+ dec a
+ jr z, .DVs
+
+; else: WildMon
+ ld hl, EnemyMonDVs
+ jr .DVs
+
+
+; Get our place in the party/box.
+
+.PartyMon
+.BoxMon
+ ld a, [CurPartyMon]
+ call AddNTimes
+
+
+.DVs
+
+; BoxMon data is read directly from SRAM.
+ ld a, [MonType]
+ cp 2
+ ld a, 1
+ call z, GetSRAMBank
+
+; Attack DV
+ ld a, [hli]
+ and $f0
+ ld b, a
+; Speed DV
+ ld a, [hl]
+ and $f0
+ swap a
+
+; Put our DVs together.
+ or b
+ ld b, a
+
+; Close SRAM if we were dealing with a BoxMon.
+ ld a, [MonType] ; MonType
+ cp 2 ; BOXMON
+ call z, CloseSRAM
+
+
+; We need the gender ratio to do anything with this.
+ push bc
+ ld a, [CurPartySpecies]
+ dec a
+ ld hl, BaseStats + 13 ; BASE_GENDER
+ ld bc, BaseStats1 - BaseStats
+ call AddNTimes
+ pop bc
+
+ ld a, BANK(BaseStats)
+ call GetFarByte
+
+
+; The higher the ratio, the more likely the monster is to be female.
+
+ cp $ff
+ jr z, .Genderless
+
+ and a
+ jr z, .Male
+
+ cp $fe
+ jr z, .Female
+
+; Values below the ratio are male, and vice versa.
+ cp b
+ jr c, .Male
+
+.Female
+ xor a
+ ret
+
+.Male
+ ld a, 1
+ and a
+ ret
+
+.Genderless
+ scf
+ ret
+; 50c50
+INCBIN "baserom.gbc", $50c50, $51424 - $50c50
BaseStats:
INCLUDE "stats/base_stats.asm"
@@ -7176,7 +7298,7 @@ INCLUDE "stats/base_stats.asm"
PokemonNames:
INCLUDE "stats/pokemon_names.asm"
-INCBIN "baserom.gbc",$53D84,$54000 - $53D84
+INCBIN "baserom.gbc",$53D84,$53e2e - $53D84
SECTION "bank15",DATA,BANK[$15]
@@ -8596,7 +8718,12 @@ BattleText_0x8188e: ; 0x8188e
db "left today!", $57
; 0x818ac
-INCBIN "baserom.gbc",$818ac,$84000-$818ac
+INCBIN "baserom.gbc",$818ac,$81fe3-$818ac
+
+DebugColorTestGFX:
+INCBIN "gfx/debug/color_test.2bpp"
+
+INCBIN "baserom.gbc",$82153,$823c8-$82153
SECTION "bank21",DATA,BANK[$21]
@@ -8836,8 +8963,50 @@ FX39GFX: ; 8638e
INCBIN "gfx/fx/039.lz"
; 8640b
-INCBIN "baserom.gbc", $8640b, $88000 - $8640b
+INCBIN "baserom.gbc", $8640b, $8640e - $8640b
+
+HallOfFame3: ; 0x8640e
+ call $648e
+ ld a, [$d84c]
+ push af
+ ld a, $1
+ ld [$c2cd], a
+ call $2ed3
+ ld a, $1
+ ld [$d4b5], a
+
+ ; Enable the Pokégear map to cycle through all of Kanto
+ ld hl, $d84c
+ set 6, [hl]
+
+ ld a, $5
+ ld hl, $4da0
+ rst $8
+ ld hl, $d95e
+ ld a, [hl]
+ cp $c8
+ jr nc, .asm_86436 ; 0x86433 $1
+ inc [hl]
+.asm_86436
+ ld a, $5
+ ld hl, $4b85
+ rst $8
+ call $653f
+ ld a, $5
+ ld hl, $4b5f
+ rst $8
+ xor a
+ ld [$c2cd], a
+ call $64c3
+ pop af
+ ld b, a
+ ld a, $42
+ ld hl, $5847
+ rst $8
+ ret
+; 0x86455
+INCBIN "baserom.gbc", $86455, $88000 - $86455
SECTION "bank22",DATA,BANK[$22]
@@ -9027,7 +9196,7 @@ GetNthPartyMon: ; 0x8b1ce
scf
ret
-INCBIN "baserom.gbc",$8b1e1,$8c000-$8b1e1
+INCBIN "baserom.gbc",$8b1e1,$8ba24-$8b1e1
SECTION "bank23",DATA,BANK[$23]
@@ -9068,11 +9237,11 @@ TimeOfDayPals: ; 8c011
ld hl, $d038 ; Unkn1Pals + 7 pals
; save wram bank
- ld a, [$ff70] ; wram bank
+ ld a, [rSVBK]
ld b, a
; wram bank 5
ld a, 5
- ld [$ff70], a ; wram bank
+ ld [rSVBK], a
; push palette
ld c, 4 ; NUM_PAL_COLORS
@@ -9087,7 +9256,7 @@ TimeOfDayPals: ; 8c011
; restore wram bank
ld a, b
- ld [$ff70], a ; wram bank
+ ld [rSVBK], a
; update sgb pals
@@ -9099,11 +9268,11 @@ TimeOfDayPals: ; 8c011
ld hl, $d03f ; last byte in Unkn1Pals
; save wram bank
- ld a, [$ff70] ; wram bank
+ ld a, [rSVBK]
ld d, a
; wram bank 5
ld a, 5
- ld [$ff70], a ; wram bank
+ ld [rSVBK], a
; pop palette
ld e, 4 ; NUM_PAL_COLORS
@@ -9118,7 +9287,7 @@ TimeOfDayPals: ; 8c011
; restore wram bank
ld a, d
- ld [$ff70], a ; wram bank
+ ld [rSVBK], a
; update palettes
call UpdateTimePals
@@ -10364,8 +10533,11 @@ INCLUDE "maps/map_headers.asm"
INCLUDE "maps/second_map_headers.asm"
-INCBIN "baserom.gbc",$966b0,$1950
+INCBIN "baserom.gbc",$966b0,$96cb1 - $966b0
+INCLUDE "scripting.asm"
+
+INCBIN "baserom.gbc",$97c20,$35e
SECTION "bank26",DATA,BANK[$26]
@@ -10423,12 +10595,12 @@ INCLUDE "maps/BattleTowerOutside.asm"
SECTION "bank28",DATA,BANK[$28]
-INCBIN "baserom.gbc",$A0000,$4000
+INCBIN "baserom.gbc",$a0000,$a1eca - $a0000
SECTION "bank29",DATA,BANK[$29]
-INCBIN "baserom.gbc",$A4000,$4000
+INCBIN "baserom.gbc",$a4000,$a64ad - $a4000
SECTION "bank2A",DATA,BANK[$2A]
@@ -10693,8 +10865,6 @@ Route22_BlockData: ; 0xabef7
INCBIN "maps/Route22.blk"
; 0xabfab
-INCBIN "baserom.gbc",$abfab,$55
-
SECTION "bank2B",DATA,BANK[$2B]
@@ -11563,7 +11733,7 @@ Tileset16GFX: ; b74e8
INCBIN "gfx/tilesets/16.lz"
; b799a
-INCBIN "baserom.gbc", $b799a, $b8000 - $b799a
+INCBIN "baserom.gbc", $b799a, $b7ea8 - $b799a
SECTION "bank2E",DATA,BANK[$2E]
@@ -11808,7 +11978,7 @@ WildRockMonTable: ; b83de
db $ff ; end
; b83e5
-INCBIN "baserom.gbc",$B83E5,$bc000 - $b83e5
+INCBIN "baserom.gbc",$b83e5,$b9e8b - $b83e5
SECTION "bank2F",DATA,BANK[$2F]
@@ -12242,17 +12412,17 @@ INCBIN "baserom.gbc",$bd0d0,$be699-$bd0d0
SECTION "bank30",DATA,BANK[$30]
-INCBIN "baserom.gbc",$C0000,$4000
+INCBIN "baserom.gbc",$c0000,$c3fc0 - $c0000
SECTION "bank31",DATA,BANK[$31]
-INCBIN "baserom.gbc",$C4000,$4000
+INCBIN "baserom.gbc",$c4000,$c7f80 - $c4000
SECTION "bank32",DATA,BANK[$32]
-INCBIN "baserom.gbc",$C8000,$4000
+INCBIN "baserom.gbc",$c8000,$cbe2b - $c8000
SECTION "bank33",DATA,BANK[$33]
@@ -12263,7 +12433,6 @@ INCBIN "baserom.gbc",$cc000, $cfd9e - $cc000
Music_PostCredits: INCLUDE "audio/music/postcredits.asm"
-INCBIN "baserom.gbc",$cff04, $d0000 - $cff04
; Pic animations I
@@ -12324,7 +12493,7 @@ INCLUDE "gfx/pics/kanto_frames.asm"
SECTION "bank36",DATA,BANK[$36]
-FontInversed: INCBIN "gfx/font_inversed.1bpp"
+FontInversed: INCBIN "gfx/misc/font_inversed.1bpp"
; Johto frame definitions
INCLUDE "gfx/pics/johto_frames.asm"
@@ -12364,12 +12533,12 @@ Tileset11GFX: ; de570
INCBIN "gfx/tilesets/11.lz"
; de98a
-INCBIN "baserom.gbc", $de98a, $e0000 - $de98a
+INCBIN "baserom.gbc", $de98a, $dfd14 - $de98a
SECTION "bank38",DATA,BANK[$38]
-INCBIN "baserom.gbc",$E0000,$4000
+INCBIN "baserom.gbc",$e0000,$e37f9 - $e0000
SECTION "bank39",DATA,BANK[$39]
@@ -12677,13 +12846,13 @@ Music_BugCatchingContest: INCLUDE "audio/music/bugcatchingcontest.asm"
SECTION "bank3E",DATA,BANK[$3E]
FontExtra:
-INCBIN "gfx/font_extra.2bpp",$0,$200
+INCBIN "gfx/misc/font_extra.2bpp",$0,$200
Font:
-INCBIN "gfx/font.1bpp",$0,$400
+INCBIN "gfx/misc/font.1bpp",$0,$400
FontBattleExtra:
-INCBIN "gfx/font_battle_extra.2bpp",$0,$200
+INCBIN "gfx/misc/font_battle_extra.2bpp",$0,$200
INCBIN "baserom.gbc", $f8800, $f8ba0 - $f8800
@@ -12693,192 +12862,9 @@ INCBIN "gfx/misc/town_map.lz"
INCBIN "baserom.gbc", $f8ea3, $fbbfc - $f8ea3
-CalcMagikarpLength: ; fbbfc
-; Stores Magikarp's length at $d1ea-$d1eb in big endian
-;
-; input:
-; de: EnemyMonDVs
-; bc: PlayerID
-; output:
-; $d1ea-$d1eb: length
-;
-; does a whole bunch of arbitrary nonsense
-; cycles through a table of arbitrary values
-; http://web.archive.org/web/20110628181718/http://upokecenter.com/games/gs/guides/magikarp.php
-
-; b = rrcrrc(atkdefdv) xor rrc(pidhi)
- ld h, b
- ld l, c
- ld a, [hli]
- ld b, a
- ld c, [hl] ; ld bc, [PlayerID]
- rrc b
- rrc c
- ld a, [de]
- inc de
- rrca
- rrca
- xor b
- ld b, a
-
-; c = rrcrrc(spdspcdv) xor rrc(pidlo)
- ld a, [de]
- rrca
- rrca
- xor c
- ld c, a
-
-; if bc < $000a:
- ld a, b
- and a
- jr nz, .loadtable
- ld a, c
- cp a, $0a
- jr nc, .loadtable
-
-; de = hl = bc + $be
- ld hl, $00be
- add hl, bc
- ld d, h
- ld e, l
- jr .endtable
-
-.loadtable
- ld hl, .MagikarpLengthTable
- ld a, $02
- ld [$d265], a
-
-.readtable
- ld a, [hli]
- ld e, a
- ld a, [hli]
- ld d, a
- call .BLessThanD
- jr nc, .advancetable
-
-; c = bc / [hl]
- call .BCMinusDE
- ld a, b
- ld [$ffb3], a
- ld a, c
- ld [$ffb4], a
- ld a, [hl]
- ld [$ffb7], a
- ld b, $02
- call Divide
- ld a, [$ffb6]
- ld c, a
-
-; de = c + $64 * (2 + number of rows down the table)
- xor a
- ld [$ffb4], a
- ld [$ffb5], a
- ld a, $64
- ld [$ffb6], a
- ld a, [$d265]
- ld [$ffb7], a
- call Multiply
- ld b, $00
- ld a, [$ffb6]
- add c
- ld e, a
- ld a, [$ffb5]
- adc b
- ld d, a
- jr .endtable
-
-.advancetable
- inc hl ; align to next triplet
- ld a, [$d265]
- inc a
- ld [$d265], a
- cp a, $10
- jr c, .readtable
-
- call .BCMinusDE
- ld hl, $0640
- add hl, bc
- ld d, h
- ld e, l
-
-.endtable
- ld h, d
- ld l, e
- add hl, hl
- add hl, hl
- add hl, de
- add hl, hl ; hl = de * 10
-
- ld de, $ff02
- ld a, $ff
-.loop
- inc a
- add hl, de ; - 254
- jr c, .loop
-
- ld d, $00
-
-; mod $0c
-.modloop
- cp a, $0c
- jr c, .done
- sub a, $0c
- inc d
- jr .modloop
-
-.done
- ld e, a
- ld hl, $d1ea
- ld [hl], d
- inc hl
- ld [hl], e
- ret
-; fbc9a
-
-.BLessThanD ; fbc9a
-; return carry if b < d
- ld a, b
- cp d
- ret c
- ret nc
-; fbc9e
-
-.CLessThanE ; fbc9e
-; unused
- ld a, c
- cp e
- ret
-; fbca1
-
-.BCMinusDE ; fbca1
-; bc -= de
- ld a, c
- sub e
- ld c, a
- ld a, b
- sbc d
- ld b, a
- ret
-; fbca8
-
-.MagikarpLengthTable ; fbca8
-; ????, divisor
- dwb $006e, $01
- dwb $0136, $02
- dwb $02c6, $04
- dwb $0a96, $14
- dwb $1e1e, $32
- dwb $452e, $64
- dwb $7fc6, $96
- dwb $ba5e, $96
- dwb $e16e, $64
- dwb $f4f6, $32
- dwb $fcc6, $14
- dwb $feba, $05
- dwb $ff82, $02
-; fbccf
+INCLUDE "battle/magikarp_length.asm"
-INCBIN "baserom.gbc",$FBCCF,$fc000-$fbccf
+INCBIN "baserom.gbc",$fbccf,$fbe91 - $fbccf
SECTION "bank3F",DATA,BANK[$3F]
@@ -12930,12 +12916,16 @@ INCBIN "baserom.gbc",$fcf38,$fd1d2-$fcf38
SECTION "bank40",DATA,BANK[$40]
-INCBIN "baserom.gbc",$100000,$4000
+INCBIN "baserom.gbc",$100000,$10389d - $100000
SECTION "bank41",DATA,BANK[$41]
-INCBIN "baserom.gbc",$104000,$105258 - $104000
+INCBIN "baserom.gbc",$104000,$104350 - $104000
+
+INCBIN "gfx/ow/misc.2bpp"
+
+INCBIN "baserom.gbc",$1045b0,$105258 - $1045b0
MysteryGiftGFX:
INCBIN "gfx/misc/mystery_gift.2bpp"
@@ -12945,14 +12935,24 @@ INCBIN "baserom.gbc",$105688,$105930 - $105688
; japanese mystery gift gfx
INCBIN "gfx/misc/mystery_gift_jp.2bpp"
-INCBIN "baserom.gbc",$105db0,$1060bb - $105db0
+INCBIN "baserom.gbc",$105db0,$105ef6 - $105db0
+
+HallOfFame2: ; 0x105ef6
+ ret
+
+INCBIN "baserom.gbc",$105ef7,$106078 - $105ef7
+
+HallOfFame1: ; 0x106078
+ ret
+
+INCBIN "baserom.gbc",$106079,$1060bb - $106079
Function1060bb: ; 1060bb
; commented out
ret
; 1060bc
-INCBIN "baserom.gbc",$1060bc,$108000 - $1060bc
+INCBIN "baserom.gbc",$1060bc,$106dbc - $1060bc
SECTION "bank42",DATA,BANK[$42]
@@ -12963,128 +12963,17 @@ IntroLogoGFX: ; 109407
INCBIN "gfx/intro/logo.lz"
; 10983f
-INCBIN "baserom.gbc", $10983f, $10aee1 - $10983f
-
-Credits:
- db " SATOSHI TAJIRI@" ; "たじり さとし@"
- db " JUNICHI MASUDA@" ; "ますだ じゅんいち@"
- db " TETSUYA WATANABE@" ; "わたなべ てつや@"
- db " SHIGEKI MORIMOTO@" ; "もりもと しげき@"
- db " SOUSUKE TAMADA@" ; "たまだ そうすけ@"
- db " TAKENORI OOTA@" ; "おおた たけのり@"
- db " KEN SUGIMORI@" ; "すぎもり けん@"
- db " MOTOFUMI FUJIWARA@" ; "ふじわら もとふみ@"
- db " ATSUKO NISHIDA@" ; "にしだ あつこ@"
- db " MUNEO SAITO@" ; "さいとう むねお@"
- db " SATOSHI OOTA@" ; "おおた さとし@"
- db " RENA YOSHIKAWA@" ; "よしかわ れな@"
- db " JUN OKUTANI@" ; "おくたに じゅん@"
- db " HIRONOBU YOSHIDA@" ; "よしだ ひろのぶ@"
- db " ASUKA IWASHITA@" ; "いわした あすか@"
- db " GO ICHINOSE@" ; "いちのせ ごう@"
- db " MORIKAZU AOKI@" ; "あおき もりかず@"
- db " KOHJI NISHINO@" ; "にしの こうじ@"
- db " KENJI MATSUSHIMA@" ; "まつしま けんじ@"
- db "TOSHINOBU MATSUMIYA@" ; "まつみや としのぶ@"
- db " SATORU IWATA@" ; "いわた さとる@"
- db " NOBUHIRO SEYA@" ; "せや のぶひろ@"
- db " KAZUHITO SEKINE@" ; "せきね かずひと@"
- db " TETSUJI OOTA@" ; "おおた てつじ@"
- db "NCL SUPER MARIO CLUB@" ; "スーパーマりォクラブ@"
- db " SARUGAKUCHO@" ; "さるがくちょう@"
- db " AKITO MORI@" ; "もり あきと@"
- db " TAKAHIRO HARADA@" ; "はらだ たかひろ@"
- db " TOHRU HASHIMOTO@" ; "はしもと とおる@"
- db " NOBORU MATSUMOTO@" ; "まつもと のぼる@"
- db " TAKEHIRO IZUSHI@" ; "いずし たけひろ@"
- db " TAKASHI KAWAGUCHI@" ; "かわぐち たかし@"
- db " TSUNEKAZU ISHIHARA@" ; "いしはら つねかず@"
- db " HIROSHI YAMAUCHI@" ; "やまうち ひろし@"
- db " KENJI SAIKI@" ; "さいき けんじ@"
- db " ATSUSHI TADA@" ; "ただ あつし@"
- db " NAOKO KAWAKAMI@" ; "かわかみ なおこ@"
- db " HIROYUKI ZINNAI@" ; "じんない ひろゆき@"
- db " KUNIMI KAWAMURA@" ; "かわむら くにみ@"
- db " HISASHI SOGABE@" ; "そがべ ひさし@"
- db " KEITA KAGAYA@" ; "かがや けいた@"
- db " YOSHINORI MATSUDA@" ; "まつだ よしのり@"
- db " HITOMI SATO@" ; "さとう ひとみ@"
- db " TORU OSAWA@" ; "おおさわ とおる@"
- db " TAKAO OHARA@" ; "おおはら たかお@"
- db " YUICHIRO ITO@" ; "いとう ゆういちろう@"
- db " TAKAO SHIMIZU@" ; "しみず たかお@"
- db " SPECIAL PRODUCTION", $4e
- db " PLANNING", $4e ; "きかくかいはつぶ@"
- db " & DEVELOPMENT DEPT.@"
- db " KEITA NAKAMURA@" ; "なかむら けいた@"
- db " HIROTAKA UEMURA@" ; "うえむら ひろたか@"
- db " HIROAKI TAMURA@" ; "たむら ひろあき@"
- db " NORIAKI SAKAGUCHI@" ; "さかぐち のりあき@"
- db " MIYUKI SATO@" ; "さとう みゆき@"
- db " GAKUZI NOMOTO@" ; "のもと がくじ@"
- db " AI MASHIMA@" ; "ましま あい@"
- db " MIKIHIRO ISHIKAWA@" ; "いしかわ みきひろ@"
- db " HIDEYUKI HASHIMOTO@" ; "はしもと ひでゆき@"
- db " SATOSHI YAMATO@" ; "やまと さとし@"
- db " SHIGERU MIYAMOTO@" ; "みやもと しげる@"
- db " END@" ; "おしまい@"
- db " ????????@" ; "????????@"
- db " GAIL TILDEN@"
- db " NOB OGASAWARA@"
- db " SETH McMAHILL@"
- db " HIROTO ALEXANDER@"
- db " TERESA LILLYGREN@"
- db " THOMAS HERTZOG@"
- db " ERIK JOHNSON@"
- db " HIRO NAKAMURA@"
- db " TERUKI MURAKAWA@"
- db " KAZUYOSHI OSAWA@"
- db " KIMIKO NAKAMICHI@"
- db " #MON", $4e ; "ポケットモンスター", $4e
- db " CRYSTAL VERSION", $4e ; " クりスタル バージョン", $4e
- db " STAFF@" ; " スタッフ@"
- db " DIRECTOR@" ; "エグゼクティブ ディレクター@"
- db " CO-DIRECTOR@" ; "ディレクター@"
- db " PROGRAMMERS@" ; "プログラム@"
- db " GRAPHICS DIRECTOR@" ; "グラフィック ディレクター@"
- db " MONSTER DESIGN@" ; "# デザイン@"
- db " GRAPHICS DESIGN@" ; "グラフィック デザイン@"
- db " MUSIC@" ; "おんがく@"
- db " SOUND EFFECTS@" ; "サウンド エフ→クト@"
- db " GAME DESIGN@" ; "ゲームデザイン@"
- db " GAME SCENARIO@" ; "シナりォ@"
- db " TOOL PROGRAMMING@" ; "ツール プログラム@"
- db " PARAMETRIC DESIGN@" ; "パラメーター せってい@"
- db " SCRIPT DESIGN@" ; "スクりプト せってい@"
- db " MAP DATA DESIGN@" ; "マップデータ せってい@"
- db " MAP DESIGN@" ; "マップ デザイン@"
- db " PRODUCT TESTING@" ; "デバッグプレイ@"
- db " SPECIAL THANKS@" ; "スぺシャルサンクス@"
- db " PRODUCERS@" ; "プロデューサー@"
- db " EXECUTIVE PRODUCER@" ; "エグゼクティブ プロデューサー@"
- db " #MON ANIMATION@" ; "# アニメーション@"
- db " #DEX TEXT@" ; "ずかん テキスト@"
- db " MOBILE PRJ. LEADER@" ; "モバイルプロジ→クト りーダー@"
- db " MOBILE SYSTEM AD.@" ; "モバイル システムアドバイザー@"
- db "MOBILE STADIUM DIR.@" ; "モバイルスタジアム ディレクター@"
- db " COORDINATION@" ; "コーディネーター@"
- db " US VERSION STAFF@"
- db " US COORDINATION@"
- db " TEXT TRANSLATION@"
- db " PAAD TESTING@"
- ; (C) 1 9 9 5 - 2 0 0 1 N i n t e n d o
- db $60,$61,$62,$63,$64,$65,$66, $67, $68, $69, $6a, $6b, $6c, $4e
- ; (C) 1 9 9 5 - 2 0 0 1 C r e a t u r e s i n c .
- db $60,$61,$62,$63,$64,$65,$66, $6d, $6e, $6f, $70, $71, $72, $7a, $7b, $7c, $4e
- ; (C) 1 9 9 5 - 2 0 0 1 G A M E F R E A K i n c .
- db $60,$61,$62,$63,$64,$65,$66, $73, $74, $75, $76, $77, $78, $79, $7a, $7b, $7c, "@"
+INCBIN "baserom.gbc", $10983f, $1099aa - $10983f
+
+; Credits
+INCLUDE "credits.asm"
SECTION "bank43",DATA,BANK[$43]
INCBIN "baserom.gbc", $10c000, $10ed67 - $10c000
-TitleScreen: ; 10ed67
+StartTitleScreen: ; 10ed67
call WhiteBGMap
call ClearSprites
@@ -13107,7 +12996,7 @@ TitleScreen: ; 10ed67
; VRAM bank 1
ld a, 1
- ld [$ff4f], a
+ ld [rVBK], a
; Decompress running Suicune gfx
@@ -13180,7 +13069,7 @@ TitleScreen: ; 10ed67
; Back to VRAM bank 0
ld a, $0
- ld [$ff4f], a
+ ld [rVBK], a
; Decompress logo
@@ -13276,7 +13165,7 @@ TitleScreen: ; 10ed67
call ByteFill
; Let LCD Stat know we're messing around with SCX
- ld a, $43 ; ff43 ; SCX
+ ld a, rSCX - rJOYP
ld [$ffc6], a
; Restore WRAM bank
@@ -13289,9 +13178,9 @@ TitleScreen: ; 10ed67
call $058a
; Set sprite size to 8x16
- ld a, [$ff40] ; LCDC
+ ld a, [rLCDC]
set 2, a
- ld [$ff40], a ; LCDC
+ ld [rLCDC], a
;
ld a, $70
@@ -13320,7 +13209,32 @@ TitleScreen: ; 10ed67
ret
; 10eea7
-INCBIN "baserom.gbc", $10eea7, $10ef46 - $10eea7
+INCBIN "baserom.gbc", $10eea7, $10ef32 - $10eea7
+
+AnimateTitleCrystal: ; 10ef32
+; Move the title screen crystal downward until it's fully visible
+
+; Stop at y=6
+; y is really from the bottom of the sprite, which is two tiles high
+ ld hl, Sprites
+ ld a, [hl]
+ cp 6 + 16
+ ret z
+
+; Move all 30 parts of the crystal down by 2
+ ld c, 30
+.loop
+ ld a, [hl]
+ add 2
+ ld [hli], a
+ inc hl
+ inc hl
+ inc hl
+ dec c
+ jr nz, .loop
+
+ ret
+; 10ef46
TitleSuicuneGFX: ; 10ef46
INCBIN "gfx/title/suicune.lz"
@@ -13423,14 +13337,22 @@ TitleScreenPalettes:
RGB 00, 00, 00
RGB 00, 00, 00
-
-INCBIN "baserom.gbc", $10ff5e, $110000 - $10ff5e
-
-
SECTION "bank44",DATA,BANK[$44]
-INCBIN "baserom.gbc",$110000,$4000
+INCBIN "baserom.gbc",$110000,$110fad - $110000
+URIPrefix: ; 0x110fad
+ ascii "http://"
+HTTPDownloadURL: ; 0x110fb4
+ ascii "gameboy.datacenter.ne.jp/cgb/download"
+HTTPUploadURL: ; 0x110fd9
+ ascii "gameboy.datacenter.ne.jp/cgb/upload"
+HTTPUtilityURL: ; 0x110ffc
+ ascii "gameboy.datacenter.ne.jp/cgb/utility"
+HTTPRankingURL: ; 0x111020
+ ascii "gameboy.datacenter.ne.jp/cgb/ranking"
+
+INCBIN "baserom.gbc",$111044,$113f84 - $111044
SECTION "bank45",DATA,BANK[$45]
@@ -13785,12 +13707,38 @@ Function117cdd: ; 0x117cdd
SECTION "bank46",DATA,BANK[$46]
-INCBIN "baserom.gbc",$118000,$4000
+INCBIN "baserom.gbc",$118000,$118ba5 - $118000
+
+ExchangeDownloadURL: ; 0x118ba5
+ ascii "http://gameboy.datacenter.ne.jp/cgb/download?name=/01/CGB-BXTJ/exchange/index.txt"
+
+db $0
+
+BattleDownloadURL: ; 0x118bf7
+ ascii "http://gameboy.datacenter.ne.jp/cgb/download?name=/01/CGB-BXTJ/battle/index.txt"
+db $0
+
+NewsDownloadURL: ; 0x118c47
+ ascii "http://gameboy.datacenter.ne.jp/cgb/download?name=/01/CGB-BXTJ/news/index.txt"
+
+db $0
+
+MenuDownloadURL: ; 0x118c95
+ ascii "http://gameboy.datacenter.ne.jp/cgb/download?name=/01/CGB-BXTJ/POKESTA/menu.cgb"
+
+db $0
+
+IndexDownloadURL: ; 0x118ce4
+ ascii "http://gameboy.datacenter.ne.jp/cgb/download?name=/01/CGB-BXTJ/tamago/index.txt"
+
+db $0
+
+INCBIN "baserom.gbc",$118d35,$11bc9e - $118d35
SECTION "bank47",DATA,BANK[$47]
-INCBIN "baserom.gbc",$11C000,$4000
+INCBIN "baserom.gbc",$11c000,$11f686 - $11c000
SECTION "bank48",DATA,BANK[$48]
@@ -14617,17 +14565,17 @@ INCBIN "gfx/pics/201r/back.lz"
SECTION "bank5B",DATA,BANK[$5B]
-INCBIN "baserom.gbc",$16C000,$4000
+INCBIN "baserom.gbc",$16c000,$16d7fe - $16c000
SECTION "bank5C",DATA,BANK[$5C]
-INCBIN "baserom.gbc",$170000,$4000
+INCBIN "baserom.gbc",$170000,$17367f - $170000
SECTION "bank5D",DATA,BANK[$5D]
-INCBIN "baserom.gbc",$174000,$4000
+INCBIN "baserom.gbc",$174000,$177561 - $174000
SECTION "bank5E",DATA,BANK[$5E]
@@ -14655,7 +14603,7 @@ INCBIN "baserom.gbc",$17a68f, $17b629 - $17a68f
SECTION "bank5F",DATA,BANK[$5F]
-INCBIN "baserom.gbc",$17C000,$4000
+INCBIN "baserom.gbc",$17c000,$17ff6c - $17c000
SECTION "bank60",DATA,BANK[$60]
@@ -14953,7 +14901,7 @@ INCLUDE "stats/pokedex/entries_2.asm"
SECTION "bank6F",DATA,BANK[$6F]
-INCBIN "baserom.gbc",$1BC000,$4000
+INCBIN "baserom.gbc",$1bc000,$1be08d - $1bc000
SECTION "bank70",DATA,BANK[$70]
@@ -15093,12 +15041,12 @@ PokegearGFX: ; 1de2e4
INCBIN "gfx/misc/pokegear.lz"
; 1de5c7
-INCBIN "baserom.gbc",$1de5c7,$1e0000 - $1de5c7
+INCBIN "baserom.gbc",$1de5c7,$1df238 - $1de5c7
SECTION "bank78",DATA,BANK[$78]
-INCBIN "baserom.gbc",$1E0000,$4000
+INCBIN "baserom.gbc",$1e0000,$1e1000 - $1e0000
SECTION "bank79",DATA,BANK[$79]
@@ -15109,24 +15057,26 @@ SECTION "bank7A",DATA,BANK[$7A]
SECTION "bank7B",DATA,BANK[$7B]
-INCBIN "baserom.gbc",$1EC000,$4000
+INCBIN "baserom.gbc",$1ec000,$1ecf02 - $1ec000
SECTION "bank7C",DATA,BANK[$7C]
-INCBIN "baserom.gbc",$1F0000,$4000
+INCBIN "baserom.gbc",$1f0000,$1f09d8 - $1f0000
SECTION "bank7D",DATA,BANK[$7D]
-INCBIN "baserom.gbc",$1F4000,$4000
+INCBIN "baserom.gbc",$1f4000,$1f636a - $1f4000
SECTION "bank7E",DATA,BANK[$7E]
-INCBIN "baserom.gbc",$1F8000,$4000
+INCBIN "baserom.gbc",$1f8000,$1fb8a8 - $1f8000
SECTION "bank7F",DATA,BANK[$7F]
-INCBIN "baserom.gbc",$1FC000,$4000
+SECTION "stadium2",DATA[$8000-$220],BANK[$7F]
+INCBIN "baserom.gbc",$1ffde0,$220
+
diff --git a/maps/KrissHouse2F.asm b/maps/KrissHouse2F.asm
index 76b4caccb..f4f8aadfa 100644
--- a/maps/KrissHouse2F.asm
+++ b/maps/KrissHouse2F.asm
@@ -38,15 +38,64 @@ INCBIN "baserom.gbc",$7abc9,$7abcc - $7abc9
UnknownScript_0x7abcc: ; 0x7abcc
describedecoration $1
+; 0x7abce
+
+UnknownScript_0x7abce: ; 0x7abce
describedecoration $2
+; 0x7abd0
+
+UnknownScript_0x7abd0: ; 0x7abd0
describedecoration $3
+; 0x7abd2
+
+UnknownScript_0x7abd2: ; 0x7abd2
describedecoration $4
- unknown0xcc
-; 0x7abd5
+; 0x7abd4
+
+MapKrissHouse2FSignpost4: ; 0x7abd4
+ dw $02cc ; bit1
+ dw MapKrissHouse2FSignpost4Script
+; 0x7abd8
+
+MapKrissHouse2FSignpost4Script: ; 0x7abd8
+ describedecoration $0
+; 0x7abda
+
+MapKrissHouse2FSignpost2Script: ; 0x7abda
+ checkbit1 $001a
+ iftrue UnknownScript_0x7ac07
+ checkbit1 $0325
+ iftrue UnknownScript_0x7ac0a
+ playmusic $001d
+ loadfont
+ 2writetext UnknownText_0x7ac24
+ pause 45
+ 2writetext UnknownText_0x7ac55
+ pause 45
+ 2writetext UnknownText_0x7ac64
+ pause 45
+ musicfadeout $003c, $10
+ 2writetext UnknownText_0x7ac84
+ pause 45
+ loadmovesprites
+ setbit1 $0325
+ end
+; 0x7ac07
+
+UnknownScript_0x7ac07: ; 0x7ac07
+ jumpstd $000b
+; 0x7ac0a
+
+UnknownScript_0x7ac0a: ; 0x7ac0a
+ loadfont
+ 2writetext UnknownText_0x7ac84
+ pause 45
+ loadmovesprites
+ end
+; 0x7ac12
-INCBIN "baserom.gbc",$7abd5,$3d
-MapKrissHouse2FSignpost2Script: ; 0x7ac12
+MapKrissHouse2FSignpost3Script: ; 0x7ac12
jumpstd $0002
; 0x7ac15
@@ -97,15 +146,15 @@ KrissHouse2F_MapEventHeader: ; 0x7ac99
; signposts
db 4
signpost 1, 2, $1, MapKrissHouse2FSignpost0Script
- signpost 1, 3, $0, $6bda
- signpost 1, 5, $0, MapKrissHouse2FSignpost2Script
- signpost 0, 6, $5, $6bd4
+ signpost 1, 3, $0, MapKrissHouse2FSignpost2Script
+ signpost 1, 5, $0, MapKrissHouse2FSignpost3Script
+ signpost 0, 6, $5, MapKrissHouse2FSignpost4 ; 6bd4
; people-events
db 4
- person_event $f0, 6, 8, $1, $0, 255, 255, $0, 0, $6bd2, $0741
+ person_event $f0, 6, 8, $1, $0, 255, 255, $0, 0, UnknownScript_0x7abd2, $0741
person_event $f1, 8, 8, $1, $0, 255, 255, $0, 0, UnknownScript_0x7abcc, $0742
- person_event $f2, 8, 9, $1, $0, 255, 255, $0, 0, $6bce, $0743
- person_event $f3, 5, 4, $21, $0, 255, 255, $0, 0, $6bd0, $0744
+ person_event $f2, 8, 9, $1, $0, 255, 255, $0, 0, UnknownScript_0x7abce, $0743
+ person_event $f3, 5, 4, $21, $0, 255, 255, $0, 0, UnknownScript_0x7abd0, $0744
; 0x7acec
diff --git a/maps/KurtsHouse.asm b/maps/KurtsHouse.asm
index f3325b0d0..0536d9630 100644
--- a/maps/KurtsHouse.asm
+++ b/maps/KurtsHouse.asm
@@ -208,9 +208,8 @@ UnknownScript_0x18e2b4: ; 0x18e2b4
iftrue UnknownScript_0x18e3c5
2writetext UnknownText_0x18e7fb
keeptextopen
- verbosegiveitem2 LEVEL_BALL
- addvar $8
- unknown0xb2 $62
+ verbosegiveitem2 LEVEL_BALL, $16
+ iffalse UnknownScript_0x18e2b2
UnknownScript_0x18e2c4: ; 0x18e2c4
clearbit1 $0258
2jump UnknownScript_0x18e2ab
@@ -221,9 +220,8 @@ UnknownScript_0x18e2ca: ; 0x18e2ca
iftrue UnknownScript_0x18e3c5
2writetext UnknownText_0x18e7fb
keeptextopen
- verbosegiveitem2 LURE_BALL
- addvar $8
- unknown0xb2 $62
+ verbosegiveitem2 LURE_BALL, $16
+ iffalse UnknownScript_0x18e2b2
UnknownScript_0x18e2da: ; 0x18e2da
clearbit1 $0259
2jump UnknownScript_0x18e2ab
@@ -234,9 +232,8 @@ UnknownScript_0x18e2e0: ; 0x18e2e0
iftrue UnknownScript_0x18e3c5
2writetext UnknownText_0x18e7fb
keeptextopen
- verbosegiveitem2 MOON_BALL
- addvar $8
- unknown0xb2 $62
+ verbosegiveitem2 MOON_BALL, $16
+ iffalse UnknownScript_0x18e2b2
UnknownScript_0x18e2f0: ; 0x18e2f0
clearbit1 $025a
2jump UnknownScript_0x18e2ab
@@ -247,9 +244,8 @@ UnknownScript_0x18e2f6: ; 0x18e2f6
iftrue UnknownScript_0x18e3c5
2writetext UnknownText_0x18e7fb
keeptextopen
- verbosegiveitem2 FRIEND_BALL
- addvar $8
- unknown0xb2 $62
+ verbosegiveitem2 FRIEND_BALL, $16
+ iffalse UnknownScript_0x18e2b2
UnknownScript_0x18e306: ; 0x18e306
clearbit1 $025b
2jump UnknownScript_0x18e2ab
@@ -260,9 +256,8 @@ UnknownScript_0x18e30c: ; 0x18e30c
iftrue UnknownScript_0x18e3c5
2writetext UnknownText_0x18e7fb
keeptextopen
- verbosegiveitem2 FAST_BALL
- addvar $8
- unknown0xb2 $62
+ verbosegiveitem2 FAST_BALL, $16
+ iffalse UnknownScript_0x18e2b2
UnknownScript_0x18e31c: ; 0x18e31c
clearbit1 $025c
2jump UnknownScript_0x18e2ab
@@ -273,9 +268,8 @@ UnknownScript_0x18e322: ; 0x18e322
iftrue UnknownScript_0x18e3c5
2writetext UnknownText_0x18e7fb
keeptextopen
- verbosegiveitem2 HEAVY_BALL
- addvar $8
- unknown0xb2 $62
+ verbosegiveitem2 HEAVY_BALL, $16
+ iffalse UnknownScript_0x18e2b2
UnknownScript_0x18e332: ; 0x18e332
clearbit1 $025d
2jump UnknownScript_0x18e2ab
@@ -286,9 +280,8 @@ UnknownScript_0x18e338: ; 0x18e338
iftrue UnknownScript_0x18e3c5
2writetext UnknownText_0x18e7fb
keeptextopen
- verbosegiveitem2 LOVE_BALL
- addvar $8
- unknown0xb2 $62
+ verbosegiveitem2 LOVE_BALL, $16
+ iffalse UnknownScript_0x18e2b2
UnknownScript_0x18e348: ; 0x18e348
clearbit1 $025e
2jump UnknownScript_0x18e2ab
diff --git a/pokecrystal.asm b/pokecrystal.asm
index 163ce91c4..fe71bfa29 100644
--- a/pokecrystal.asm
+++ b/pokecrystal.asm
@@ -1,3 +1,4 @@
INCLUDE "wram.asm"
INCLUDE "constants.asm"
+INCLUDE "gbhw.asm"
INCLUDE "main.tx"
diff --git a/preprocessor.py b/preprocessor.py
index 3ef9e1e88..cb09fb898 100644
--- a/preprocessor.py
+++ b/preprocessor.py
@@ -599,6 +599,11 @@ def read_line(l):
if "INCLUDE \"" in l:
include_file(asm)
+ # ascii string macro preserves the bytes as ascii (skip the translator)
+ elif len(asm) > 6 and "\tascii " in [asm[:7], "\t" + asm[:6]]:
+ asm = asm.replace("ascii", "db", 1)
+ sys.stdout.write(asm)
+
# convert text to bytes when a quote appears (not in a comment)
elif "\"" in asm:
quote_translator(asm)
diff --git a/requirement.txt b/requirements.txt
index af0addcb2..af0addcb2 100644
--- a/requirement.txt
+++ b/requirements.txt
diff --git a/scripting.asm b/scripting.asm
new file mode 100644
index 000000000..b029b7865
--- /dev/null
+++ b/scripting.asm
@@ -0,0 +1,3127 @@
+ScriptCommandTable: ; 0x96cb1
+ dw Script_2call
+ dw Script_3call
+ dw Script_2ptcall
+ dw Script_2jump
+ dw Script_3jump
+ dw Script_2ptjump
+ dw Script_if_equal
+ dw Script_if_not_equal
+ dw Script_iffalse
+ dw Script_iftrue
+ dw Script_if_less_than
+ dw Script_if_greater_than
+ dw Script_jumpstd
+ dw Script_callstd
+ dw Script_3callasm
+ dw Script_special
+ dw Script_2ptcallasm
+ dw Script_checkmaptriggers
+ dw Script_domaptrigger
+ dw Script_checktriggers
+ dw Script_dotrigger
+ dw Script_writebyte
+ dw Script_addvar
+ dw Script_random
+ dw Script_checkver
+ dw Script_copybytetovar
+ dw Script_copyvartobyte
+ dw Script_loadvar
+ dw Script_checkcode
+ dw Script_writevarcode
+ dw Script_writecode
+ dw Script_giveitem
+ dw Script_takeitem
+ dw Script_checkitem
+ dw Script_givemoney
+ dw Script_takemoney
+ dw Script_checkmoney
+ dw Script_givecoins
+ dw Script_takecoins
+ dw Script_checkcoins
+ dw Script_addcellnum
+ dw Script_delcellnum
+ dw Script_checkcellnum
+ dw Script_checktime
+ dw Script_checkpoke
+ dw Script_givepoke
+ dw Script_giveegg
+ dw Script_givepokeitem
+ dw Script_checkpokeitem
+ dw Script_checkbit1
+ dw Script_clearbit1
+ dw Script_setbit1
+ dw Script_checkbit2
+ dw Script_clearbit2
+ dw Script_setbit2
+ dw Script_wildoff
+ dw Script_wildon
+ dw Script_xycompare
+ dw Script_warpmod
+ dw Script_blackoutmod
+ dw Script_warp
+ dw Script_readmoney
+ dw Script_readcoins
+ dw Script_RAM2MEM
+ dw Script_pokenamemem
+ dw Script_itemtotext
+ dw Script_mapnametotext
+ dw Script_trainertotext
+ dw Script_stringtotext
+ dw Script_itemnotify
+ dw Script_pocketisfull
+ dw Script_loadfont
+ dw Script_refreshscreen
+ dw Script_loadmovesprites
+ dw Script_loadbytec1ce
+ dw Script_3writetext
+ dw Script_2writetext
+ dw Script_repeattext
+ dw Script_yesorno
+ dw Script_loadmenudata
+ dw Script_writebackup
+ dw Script_jumptextfaceplayer
+ dw Script_3jumptext
+ dw Script_jumptext
+ dw Script_closetext
+ dw Script_keeptextopen
+ dw Script_pokepic
+ dw Script_pokepicyesorno
+ dw Script_interpretmenu
+ dw Script_interpretmenu2
+ dw Script_loadpikachudata
+ dw Script_battlecheck
+ dw Script_loadtrainerdata
+ dw Script_loadpokedata
+ dw Script_loadtrainer
+ dw Script_startbattle
+ dw Script_returnafterbattle
+ dw Script_catchtutorial
+ dw Script_trainertext
+ dw Script_trainerstatus
+ dw Script_winlosstext
+ dw Script_scripttalkafter
+ dw Script_talkaftercancel
+ dw Script_talkaftercheck
+ dw Script_setlasttalked
+ dw Script_applymovement
+ dw Script_applymovement2
+ dw Script_faceplayer
+ dw Script_faceperson
+ dw Script_variablesprite
+ dw Script_disappear
+ dw Script_appear
+ dw Script_follow
+ dw Script_stopfollow
+ dw Script_moveperson
+ dw Script_writepersonxy
+ dw Script_loademote
+ dw Script_showemote
+ dw Script_spriteface
+ dw Script_follownotexact
+ dw Script_earthquake
+ dw Script_changemap
+ dw Script_changeblock
+ dw Script_reloadmap
+ dw Script_reloadmappart
+ dw Script_writecmdqueue
+ dw Script_delcmdqueue
+ dw Script_playmusic
+ dw Script_playrammusic
+ dw Script_musicfadeout
+ dw Script_playmapmusic
+ dw Script_reloadmapmusic
+ dw Script_cry
+ dw Script_playsound
+ dw Script_waitbutton
+ dw Script_warpsound
+ dw Script_specialsound
+ dw Script_passtoengine
+ dw Script_newloadmap
+ dw Script_pause
+ dw Script_deactivatefacing
+ dw Script_priorityjump
+ dw Script_warpcheck
+ dw Script_ptpriorityjump
+ dw Script_return
+ dw Script_end
+ dw Script_reloadandreturn
+ dw Script_resetfuncs
+ dw Script_pokemart
+ dw Script_elevator
+ dw Script_trade
+ dw Script_askforphonenumber
+ dw Script_phonecall
+ dw Script_hangup
+ dw Script_describedecoration
+ dw Script_fruittree
+ dw Script_specialphonecall
+ dw Script_checkphonecall
+ dw Script_verbosegiveitem
+ dw Script_verbosegiveitem2
+ dw Script_loadwilddata
+ dw Script_halloffame
+ dw Script_credits
+ dw Script_warpfacing
+ dw Script_storetext
+ dw Script_displaylocation
+ dw Script_unknown0xa6
+ dw Script_unknown0xa7
+ dw Script_unknown0xa8
+ dw Script_unknown0xa9
+; 0x96e05
+
+Unknown_0x96e05: ; 0x96e05
+ ld hl, $d434
+ set 2, [hl]
+ ret
+; 0x96e0b
+
+Unknown_0x96e0b: ; 0x96e0b
+ ld hl, $d434
+ bit 2, [hl]
+ ret
+; 0x96e11
+
+Unknown_0x96e11: ; 0x96e11
+ ld hl, $d434
+ res 2, [hl]
+ ret
+; 0x96e17
+
+Script_3callasm: ; 0x96e17
+; script command 0xe
+; parameters:
+; asm (AsmPointerParam)
+
+ call GetScriptByte
+ ld b, a
+ call GetScriptByte
+ ld l, a
+ call GetScriptByte
+ ld h, a
+ ld a, b
+ rst $8
+ ret
+; 0x96e26
+
+Script_special: ; 0x96e26
+; script command 0xf
+; parameters:
+; predefined_script (MultiByteParam)
+
+ call GetScriptByte
+ ld e, a
+ call GetScriptByte
+ ld d, a
+ ld a, $3
+ ld hl, $401b
+ rst $8
+ ret
+; 0x96e35
+
+Script_2ptcallasm: ; 0x96e35
+; script command 0x10
+; parameters:
+; asm (PointerToAsmPointerParam)
+
+ call GetScriptByte
+ ld l, a
+ call GetScriptByte
+ ld h, a
+ ld b, [hl]
+ inc hl
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, b
+ rst $8
+ ret
+; 0x96e45
+
+Script_jumptextfaceplayer: ; 0x96e45
+; script command 0x51
+; parameters:
+; text_pointer (RawTextPointerLabelParam)
+
+ ld a, [ScriptBank]
+ ld [$d44e], a
+ call GetScriptByte
+ ld [$d44f], a
+ call GetScriptByte
+ ld [$d450], a
+ ld b, $25
+ ld hl, $6e79
+ jp $759d
+; 0x96e5f
+
+Script_jumptext: ; 0x96e5f
+; script command 0x53
+; parameters:
+; text_pointer (RawTextPointerLabelParam)
+
+ ld a, [ScriptBank]
+ ld [$d44e], a
+ call GetScriptByte
+ ld [$d44f], a
+ call GetScriptByte
+ ld [$d450], a
+ ld b, $25
+ ld hl, $6e7a
+ jp $759d
+; 0x96e79
+
+INCBIN "baserom.gbc",$96e79,$96e81 - $96e79
+
+Script_3jumptext: ; 0x96e81
+; script command 0x52
+; parameters:
+; text_pointer (PointerLabelBeforeBank)
+
+ call GetScriptByte
+ ld [$d44e], a
+ call GetScriptByte
+ ld [$d44f], a
+ call GetScriptByte
+ ld [$d450], a
+ ld b, $25
+ ld hl, $6e7a
+ jp $759d
+; 0x96e9b
+
+Script_2writetext: ; 0x96e9b
+; script command 0x4c
+; parameters:
+; text_pointer (RawTextPointerLabelParam)
+
+ call GetScriptByte
+ ld l, a
+ call GetScriptByte
+ ld h, a
+ ld a, [ScriptBank]
+ ld b, a
+ call $269a
+ ret
+; 0x96eab
+
+Script_3writetext: ; 0x96eab
+; script command 0x4b
+; parameters:
+; text_pointer (PointerLabelBeforeBank)
+
+ call GetScriptByte
+ ld b, a
+ call GetScriptByte
+ ld l, a
+ call GetScriptByte
+ ld h, a
+ call $269a
+ ret
+; 0x96ebb
+
+Script_repeattext: ; 0x96ebb
+; script command 0x4d
+; parameters:
+; byte (SingleByteParam)
+; byte (SingleByteParam)
+
+ call GetScriptByte
+ ld l, a
+ call GetScriptByte
+ ld h, a
+ cp $ff
+ jr nz, .asm_96ed8 ; 0x96ec5 $11
+ ld a, l
+ cp $ff
+ jr nz, .asm_96ed8 ; 0x96eca $c
+ ld hl, $d44e
+ ld a, [hli]
+ ld b, a
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call $269a
+ ret
+.asm_96ed8
+ ret
+; 0x96ed9
+
+Script_closetext: ; 0x96ed9
+; script command 0x54
+
+ jp $0a46
+; 0x96edc
+
+Script_keeptextopen: ; 0x96edc
+; script command 0x55
+
+ ld a, [$ffd8]
+ push af
+ ld a, $1
+ ld [$ffd8], a
+ call $31f6
+ call $0aaf
+ pop af
+ ld [$ffd8], a
+ ret
+; 0x96eed
+
+Script_yesorno: ; 0x96eed
+; script command 0x4e
+
+ call $1dcf
+ ld a, $0
+ jr c, .asm_96ef6 ; 0x96ef2 $2
+ ld a, $1
+.asm_96ef6
+ ld [$c2dd], a
+ ret
+; 0x96efa
+
+Script_loadmenudata: ; 0x96efa
+; script command 0x4f
+; parameters:
+; data (MenuDataPointerParam)
+
+ call GetScriptByte
+ ld l, a
+ call GetScriptByte
+ ld h, a
+ ld de, $1d35
+ ld a, [ScriptBank]
+ call $26b7
+ call $1ad2
+ ret
+; 0x96f0f
+
+Script_writebackup: ; 0x96f0f
+; script command 0x50
+
+ call $1c17
+ call $1ad2
+ ret
+; 0x96f16
+
+Script_pokepic: ; 0x96f16
+; script command 0x56
+; parameters:
+; pokemon (PokemonParam)
+
+ call GetScriptByte
+ and a
+ jr nz, .asm_96f1f ; 0x96f1a $3
+ ld a, [$c2dd]
+.asm_96f1f
+ ld [$d108], a
+ ld a, $9
+ ld hl, $44e3
+ rst $8
+ ret
+; 0x96f29
+
+Script_pokepicyesorno: ; 0x96f29
+; script command 0x57
+
+ ld a, $9
+ ld hl, $4528
+ rst $8
+ ret
+; 0x96f30
+
+Script_interpretmenu2: ; 0x96f30
+; script command 0x59
+
+ ld a, [ScriptBank]
+ ld hl, $1d81
+ rst $8
+ ld a, [$cfa9]
+ jr nc, .asm_96f3d ; 0x96f3a $1
+ xor a
+.asm_96f3d
+ ld [$c2dd], a
+ ret
+; 0x96f41
+
+Script_interpretmenu: ; 0x96f41
+; script command 0x58
+
+ ld a, [ScriptBank]
+ ld hl, $202a
+ rst $8
+ ld a, [$cf88]
+ jr nc, .asm_96f4e ; 0x96f4b $1
+ xor a
+.asm_96f4e
+ ld [$c2dd], a
+ ret
+; 0x96f52
+
+Script_storetext: ; 0x96f52
+; script command 0xa4
+; parameters:
+; pointer (PointerLabelBeforeBank)
+; memory (SingleByteParam)
+
+ call $106c
+ call GetScriptByte
+ ld c, a
+ ld a, $47
+ ld hl, $4000
+ rst $8
+ ret
+; 0x96f60
+
+Script_verbosegiveitem: ; 0x96f60
+; script command 0x9e
+; parameters:
+; item (ItemLabelByte)
+; quantity (DecimalParam)
+
+ call $77ca
+ call $7051
+ ld de, $d073
+ ld a, $1
+ call $76c8
+ ld b, $25
+ ld de, $6f77
+ jp $74cb
+; 0x96f76
+
+INCBIN "baserom.gbc",$96f76,$96f8e - $96f76
+
+Script_verbosegiveitem2: ; 0x96f8e
+; script command 0x9f
+; parameters:
+; item (ItemLabelByte)
+; var (SingleByteParam)
+
+ call GetScriptByte
+ cp $ff
+ jr nz, .asm_96f98 ; 0x96f93 $3
+ ld a, [$c2dd]
+.asm_96f98
+ ld [$d106], a
+ call GetScriptByte
+ call $769e
+ ld a, [de]
+ ld [$d10c], a
+ ld hl, $d892
+ call $2f66
+ ld a, $1
+ jr c, .asm_96fb0 ; 0x96fad $1
+ xor a
+.asm_96fb0
+ ld [$c2dd], a
+ call $7051
+ ld de, $d073
+ ld a, $1
+ call $76c8
+ ld b, $25
+ ld de, $6f77
+ jp $74cb
+; 0x96fc6
+
+Script_itemnotify: ; 0x96fc6
+; script command 0x45
+
+ call $6ffe
+ call $7051
+ ld b, $25
+ ld hl, $705b
+ call $269a
+ ret
+; 0x96fd5
+
+Script_pocketisfull: ; 0x96fd5
+; script command 0x46
+
+ call $6ffe
+ call $7051
+ ld b, $25
+ ld hl, $7060
+ call $269a
+ ret
+; 0x96fe4
+
+Script_specialsound: ; 0x96fe4
+; script command 0x88
+
+ ld a, $3
+ ld hl, $543d
+ rst $8
+ ld a, [$d142]
+ cp $4
+ ld de, $009b
+ jr z, .asm_96ff7 ; 0x96ff2 $3
+ ld de, $0001
+.asm_96ff7
+ call StartSFX
+ call $3c55
+ ret
+; 0x96ffe
+
+INCBIN "baserom.gbc",$96ffe,$97065 - $96ffe
+
+Script_pokemart: ; 0x97065
+; script command 0x94
+; parameters:
+; dialog_id (SingleByteParam)
+; mart_id (MultiByteParam)
+
+ call GetScriptByte
+ ld c, a
+ call GetScriptByte
+ ld e, a
+ call GetScriptByte
+ ld d, a
+ ld a, [ScriptBank]
+ ld b, a
+ ld a, $5
+ ld hl, $5a45
+ rst $8
+ ret
+; 0x9707c
+
+Script_elevator: ; 0x9707c
+; script command 0x95
+; parameters:
+; floor_list_pointer (PointerLabelParam)
+
+ xor a
+ ld [$c2dd], a
+ call GetScriptByte
+ ld e, a
+ call GetScriptByte
+ ld d, a
+ ld a, [ScriptBank]
+ ld b, a
+ ld a, $4
+ ld hl, $742d
+ rst $8
+ ret c
+ ld a, $1
+ ld [$c2dd], a
+ ret
+; 0x97099
+
+Script_trade: ; 0x97099
+; script command 0x96
+; parameters:
+; trade_id (SingleByteParam)
+
+ call GetScriptByte
+ ld e, a
+ ld a, $3f
+ ld hl, $4ba8
+ rst $8
+ ret
+; 0x970a4
+
+Script_phonecall: ; 0x970a4
+; script command 0x98
+; parameters:
+; caller_name (RawTextPointerLabelParam)
+
+ call GetScriptByte
+ ld e, a
+ call GetScriptByte
+ ld d, a
+ ld a, [ScriptBank]
+ ld b, a
+ ld a, $24
+ ld hl, $429a
+ rst $8
+ ret
+; 0x970b7
+
+Script_hangup: ; 0x970b7
+; script command 0x99
+
+ ld a, $24
+ ld hl, $42eb
+ rst $8
+ ret
+; 0x970be
+
+Script_askforphonenumber: ; 0x970be
+; script command 0x97
+; parameters:
+; number (SingleByteParam)
+
+ call $1dcf
+ jr c, .asm_970d6 ; 0x970c1 $13
+ call GetScriptByte
+ ld c, a
+ ld a, $24
+ ld hl, $4000
+ rst $8
+ jr c, .asm_970d2 ; 0x970cd $3
+ xor a
+ jr .asm_970db ; 0x970d0 $9
+.asm_970d2
+ ld a, $1
+ jr .asm_970db ; 0x970d4 $5
+.asm_970d6
+ call GetScriptByte
+ ld a, $2
+.asm_970db
+ ld [$c2dd], a
+ ret
+; 0x970df
+
+Script_describedecoration: ; 0x970df
+; script command 0x9a
+; parameters:
+; byte (SingleByteParam)
+
+ call GetScriptByte
+ ld b, a
+ ld a, $9
+ ld hl, $6f59
+ rst $8
+ ld h, d
+ ld l, e
+ jp $759d
+; 0x970ee
+
+Script_fruittree: ; 0x970ee
+; script command 0x9b
+; parameters:
+; tree_id (SingleByteParam)
+
+ call GetScriptByte
+ ld [$d03e], a
+ ld b, $11
+ ld hl, $4000
+ jp $759d
+; 0x970fc
+
+Script_loadwilddata: ; 0x970fc
+; script command 0xa0
+; parameters:
+; map_group (MapGroupParam)
+; map_id (MapIdParam)
+
+ call GetScriptByte
+ ld c, a
+ call GetScriptByte
+ ld d, a
+ call GetScriptByte
+ ld e, a
+ ld a, $3
+ ld hl, $4403
+ rst $8
+ ret
+; 0x9710f
+
+Script_trainertext: ; 0x9710f
+; script command 0x62
+; parameters:
+; which_text (SingleByteParam)
+
+ call GetScriptByte
+ ld c, a
+ ld b, $0
+ ld hl, $d045
+ add hl, bc
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [$d03e]
+ ld b, a
+ call $269a
+ ret
+; 0x97125
+
+Script_scripttalkafter: ; 0x97125
+; script command 0x65
+
+ ld hl, $d04b
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [$d03e]
+ ld b, a
+ jp $759d
+; 0x97132
+
+Script_trainerstatus: ; 0x97132
+; script command 0x63
+; parameters:
+; action (SingleByteParam)
+
+ xor a
+ ld [$c2dd], a
+ ld hl, $d041
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ call GetScriptByte
+ ld b, a
+ call BitTable1Func
+ ld a, c
+ and a
+ ret z
+ ld a, $1
+ ld [$c2dd], a
+ ret
+; 0x9714c
+
+Script_winlosstext: ; 0x9714c
+; script command 0x64
+; parameters:
+; win_text_pointer (TextPointerLabelParam)
+; loss_text_pointer (TextPointerLabelParam)
+
+ ld hl, $d047
+ call GetScriptByte
+ ld [hli], a
+ call GetScriptByte
+ ld [hli], a
+ ld hl, $d049
+ call GetScriptByte
+ ld [hli], a
+ call GetScriptByte
+ ld [hli], a
+ ret
+; 0x97163
+
+Script_talkaftercancel: ; 0x97163
+; script command 0x66
+
+ ld a, [$d04d]
+ and a
+ ret z
+ jp $7b74
+; 0x9716b
+
+Script_talkaftercheck: ; 0x9716b
+; script command 0x67
+
+ ld a, $1
+ ld [$c2dd], a
+ ld a, [$d04d]
+ and a
+ ret nz
+ xor a
+ ld [$c2dd], a
+ ret
+; 0x9717a
+
+Script_playrammusic: ; 0x9717a
+; script command 0x80
+
+ ld a, [$d22f]
+ ld e, a
+ ld a, $3a
+ ld hl, $500a
+ rst $8
+ ret
+; 0x97185
+
+Script_playmapmusic: ; 0x97185
+; script command 0x82
+
+ call $3cdf
+ ret
+; 0x97189
+
+Script_playmusic: ; 0x97189
+; script command 0x7f
+; parameters:
+; music_pointer (MultiByteParam)
+
+ ld de, $0000
+ call StartMusic
+ xor a
+ ld [$c2a7], a
+ call MaxVolume
+ call GetScriptByte
+ ld e, a
+ call GetScriptByte
+ ld d, a
+ call StartMusic
+ ret
+; 0x971a2
+
+Script_musicfadeout: ; 0x971a2
+; script command 0x81
+; parameters:
+; music (MultiByteParam)
+; fadetime (SingleByteParam)
+
+ call GetScriptByte
+ ld [$c2a9], a
+ call GetScriptByte
+ ld [$c2aa], a
+ call GetScriptByte
+ and $7f
+ ld [$c2a7], a
+ ret
+; 0x971b7
+
+Script_playsound: ; 0x971b7
+; script command 0x85
+; parameters:
+; sound_pointer (MultiByteParam)
+
+ call GetScriptByte
+ ld e, a
+ call GetScriptByte
+ ld d, a
+ call StartSFX
+ ret
+; 0x971c3
+
+Script_waitbutton: ; 0x971c3
+; script command 0x86
+
+ call $3c55
+ ret
+; 0x971c7
+
+Script_warpsound: ; 0x971c7
+; script command 0x87
+
+ ld a, $5
+ ld hl, $4a07
+ rst $8
+ call StartSFX
+ ret
+; 0x971d1
+
+Script_cry: ; 0x971d1
+; script command 0x84
+; parameters:
+; cry_id (MultiByteParam)
+
+ call GetScriptByte
+ push af
+ call GetScriptByte
+ pop af
+ and a
+ jr nz, .asm_971df ; 0x971da $3
+ ld a, [$c2dd]
+.asm_971df
+ call $37ce
+ ret
+; 0x971e3
+
+Unknown_0x971e3: ; 0x971e3
+ and a
+ ret z
+ cp $fe
+ ret z
+ dec a
+ ret
+; 0x971ea
+
+Script_setlasttalked: ; 0x971ea
+; script command 0x68
+; parameters:
+; person (SingleByteParam)
+
+ call GetScriptByte
+ call Unknown_0x971e3
+ ld [$ffe0], a
+ ret
+; 0x971f3
+
+Script_applymovement: ; 0x971f3
+; script command 0x69
+; parameters:
+; person (SingleByteParam)
+; data (MovementPointerLabelParam)
+
+ call GetScriptByte
+ call Unknown_0x971e3
+ ld c, a
+ push bc
+ ld a, c
+ ld a, $1
+ ld hl, $585c
+ rst $8
+ pop bc
+ push bc
+ call $7221
+ pop bc
+ call GetScriptByte
+ ld l, a
+ call GetScriptByte
+ ld h, a
+ ld a, [ScriptBank]
+ ld b, a
+ call $26c7
+ ret c
+ ld a, $2
+ ld [$d437], a
+ call Unknown_0x96e11
+ ret
+; 0x97221
+
+Unknown_0x97221: ; 0x97221
+ ld a, $1
+ ld hl, $5897
+ rst $8
+ ret
+; 0x97228
+
+Script_applymovement2: ; 0x97228
+; script command 0x6a
+; parameters:
+; data (MovementPointerLabelParam)
+
+ ld a, [$ffe0]
+ ld c, a
+ jp $71fa
+; 0x9722e
+
+Script_faceplayer: ; 0x9722e
+; script command 0x6b
+
+ ld a, [$ffe0]
+ and a
+ ret z
+ ld d, $0
+ ld a, [$ffe0]
+ ld e, a
+ ld a, $2
+ ld hl, $4417
+ rst $8
+ ld a, d
+ add a
+ add a
+ ld e, a
+ ld a, [$ffe0]
+ ld d, a
+ call $728b
+ ret
+; 0x97248
+
+Script_faceperson: ; 0x97248
+; script command 0x6c
+; parameters:
+; person1 (SingleByteParam)
+; person2 (SingleByteParam)
+
+ call GetScriptByte
+ call Unknown_0x971e3
+ cp $fe
+ jr c, .asm_97254 ; 0x97250 $2
+ ld a, [$ffe0]
+.asm_97254
+ ld e, a
+ call GetScriptByte
+ call Unknown_0x971e3
+ cp $fe
+ jr nz, .asm_97261 ; 0x9725d $2
+ ld a, [$ffe0]
+.asm_97261
+ ld d, a
+ push de
+ ld a, $2
+ ld hl, $4417
+ rst $8
+ pop bc
+ ret c
+ ld a, d
+ add a
+ add a
+ ld e, a
+ ld d, c
+ call $728b
+ ret
+; 0x97274
+
+Script_spriteface: ; 0x97274
+; script command 0x76
+; parameters:
+; person (SingleByteParam)
+; facing (SingleByteParam)
+
+ call GetScriptByte
+ call Unknown_0x971e3
+ cp $fe
+ jr nz, .asm_97280 ; 0x9727c $2
+ ld a, [$ffe0]
+.asm_97280
+ ld d, a
+ call GetScriptByte
+ add a
+ add a
+ ld e, a
+ call $728b
+ ret
+; 0x9728b
+
+Unknown_0x9728b: ; 0x9728b
+ ld a, d
+ push de
+ call $18de
+ jr c, .asm_972b9 ; 0x97290 $27
+ ld hl, $0000
+ add hl, bc
+ ld a, [hl]
+ push bc
+ call $1836
+ pop bc
+ jr c, .asm_972b9 ; 0x9729c $1b
+ ld hl, $0004
+ add hl, bc
+ bit 2, [hl]
+ jr nz, .asm_972b9 ; 0x972a4 $13
+ pop de
+ ld a, e
+ call $1af8
+ ld hl, $d0ed
+ bit 6, [hl]
+ jr nz, .asm_972b5 ; 0x972b0 $3
+ call $72bc
+.asm_972b5
+ call $1ad2
+ ret
+.asm_972b9
+ pop de
+ scf
+ ret
+; 0x972bc
+
+Unknown_0x972bc: ; 0x972bc
+ call $217a
+ ld hl, $c4a0
+ ld bc, $0168
+.asm_972c5
+ res 7, [hl]
+ inc hl
+ dec bc
+ ld a, b
+ or c
+ jr nz, .asm_972c5 ; 0x972cb $f8
+ ret
+; 0x972ce
+
+Script_variablesprite: ; 0x972ce
+; script command 0x6d
+; parameters:
+; byte (SingleByteParam)
+; sprite (SingleByteParam)
+
+ call GetScriptByte
+ ld e, a
+ ld d, $0
+ ld hl, $d82e
+ add hl, de
+ call GetScriptByte
+ ld [hl], a
+ ret
+; 0x972dd
+
+Script_appear: ; 0x972dd
+; script command 0x6f
+; parameters:
+; person (SingleByteParam)
+
+ call GetScriptByte
+ call Unknown_0x971e3
+ call $1956
+ ld a, [$ffaf]
+ ld b, $0
+ call $730b
+ ret
+; 0x972ee
+
+Script_disappear: ; 0x972ee
+; script command 0x6e
+; parameters:
+; person (SingleByteParam)
+
+ call GetScriptByte
+ call Unknown_0x971e3
+ cp $fe
+ jr nz, .asm_972fa ; 0x972f6 $2
+ ld a, [$ffe0]
+.asm_972fa
+ call $199f
+ ld a, [$ffaf]
+ ld b, $1
+ call $730b
+ ld a, $1
+ ld hl, $5920
+ rst $8
+ ret
+; 0x9730b
+
+Unknown_0x9730b: ; 0x9730b
+ push bc
+ call $18d2
+ ld hl, $000c
+ add hl, bc
+ pop bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ld a, $ff
+ cp e
+ jr nz, .asm_97321 ; 0x9731a $5
+ cp d
+ jr nz, .asm_97321 ; 0x9731d $2
+ xor a
+ ret
+.asm_97321
+ call BitTable1Func
+ ret
+; 0x97325
+
+Script_follow: ; 0x97325
+; script command 0x70
+; parameters:
+; person2 (SingleByteParam)
+; person1 (SingleByteParam)
+
+ call GetScriptByte
+ call Unknown_0x971e3
+ ld b, a
+ call GetScriptByte
+ call Unknown_0x971e3
+ ld c, a
+ ld a, $1
+ ld hl, $5803
+ rst $8
+ ret
+; 0x9733a
+
+Script_stopfollow: ; 0x9733a
+; script command 0x71
+
+ ld a, $1
+ ld hl, $581f
+ rst $8
+ ret
+; 0x97341
+
+Script_moveperson: ; 0x97341
+; script command 0x72
+; parameters:
+; person (SingleByteParam)
+; x (SingleByteParam)
+; y (SingleByteParam)
+
+ call GetScriptByte
+ call Unknown_0x971e3
+ ld b, a
+ call GetScriptByte
+ add $4
+ ld d, a
+ call GetScriptByte
+ add $4
+ ld e, a
+ ld a, $2
+ ld hl, $407e
+ rst $8
+ ret
+; 0x9735b
+
+Script_writepersonxy: ; 0x9735b
+; script command 0x73
+; parameters:
+; person (SingleByteParam)
+
+ call GetScriptByte
+ call Unknown_0x971e3
+ cp $fe
+ jr nz, .asm_97367 ; 0x97363 $2
+ ld a, [$ffe0]
+.asm_97367
+ ld b, a
+ ld a, $2
+ ld hl, $40a1
+ rst $8
+ ret
+; 0x9736f
+
+Script_follownotexact: ; 0x9736f
+; script command 0x77
+; parameters:
+; person2 (SingleByteParam)
+; person1 (SingleByteParam)
+
+ call GetScriptByte
+ call Unknown_0x971e3
+ ld b, a
+ call GetScriptByte
+ call Unknown_0x971e3
+ ld c, a
+ ld a, $2
+ ld hl, $439e
+ rst $8
+ ret
+; 0x97384
+
+Script_loademote: ; 0x97384
+; script command 0x74
+; parameters:
+; bubble (SingleByteParam)
+
+ call GetScriptByte
+ cp $ff
+ jr nz, .asm_9738e ; 0x97389 $3
+ ld a, [$c2dd]
+.asm_9738e
+ ld c, a
+ ld a, $5
+ ld hl, $442f
+ rst $8
+ ret
+; 0x97396
+
+Script_showemote: ; 0x97396
+; script command 0x75
+; parameters:
+; bubble (SingleByteParam)
+; person (SingleByteParam)
+; time (DecimalParam)
+
+ call GetScriptByte
+ ld [$c2dd], a
+ call GetScriptByte
+ call Unknown_0x971e3
+ cp $fe
+ jr z, .asm_973a8 ; 0x973a4 $2
+ ld [$ffe0], a
+.asm_973a8
+ call GetScriptByte
+ ld [$d44d], a
+ ld b, $25
+ ld de, $73b6
+ jp $74cb
+; 0x973b6
+
+INCBIN "baserom.gbc",$973b6,$973c7 - $973b6
+
+Script_earthquake: ; 0x973c7
+; script command 0x78
+; parameters:
+; param (DecimalParam)
+
+ ld hl, $73eb
+ ld de, $d002
+ ld bc, $0005
+ call CopyBytes
+ call GetScriptByte
+ ld [$d003], a
+ and $3f
+ ld [$d005], a
+ ld b, $25
+ ld de, $73e6
+ jp $74cb
+; 0x973e6
+
+INCBIN "baserom.gbc",$973e6,$973f0 - $973e6
+
+Script_loadpikachudata: ; 0x973f0
+; script command 0x5a
+
+ ld a, $19
+ ld [$d22e], a
+ ld a, $5
+ ld [$d143], a
+ ret
+; 0x973fb
+
+Script_battlecheck: ; 0x973fb
+; script command 0x5b
+
+ xor a
+ ld [$d459], a
+ ret
+; 0x97400
+
+Script_loadtrainerdata: ; 0x97400
+; script command 0x5c
+
+ ld a, $81
+ ld [$d459], a
+ ld a, [$d043]
+ ld [$d22f], a
+ ld a, [$d044]
+ ld [$d231], a
+ ret
+; 0x97412
+
+Script_loadpokedata: ; 0x97412
+; script command 0x5d
+; parameters:
+; pokemon (PokemonParam)
+; level (DecimalParam)
+
+ ld a, $80
+ ld [$d459], a
+ call GetScriptByte
+ ld [$d22e], a
+ call GetScriptByte
+ ld [$d143], a
+ ret
+; 0x97424
+
+Script_loadtrainer: ; 0x97424
+; script command 0x5e
+; parameters:
+; trainer_group (TrainerGroupParam)
+; trainer_id (TrainerIdParam)
+
+ ld a, $81
+ ld [$d459], a
+ call GetScriptByte
+ ld [$d22f], a
+ call GetScriptByte
+ ld [$d231], a
+ ret
+; 0x97436
+
+Script_startbattle: ; 0x97436
+; script command 0x5f
+
+ call $2879
+ ld a, $16
+ call $2d83
+ ld a, [$d0ee]
+ and $3f
+ ld [$c2dd], a
+ ret
+; 0x97447
+
+Script_catchtutorial: ; 0x97447
+; script command 0x61
+; parameters:
+; byte (SingleByteParam)
+
+ call GetScriptByte
+ ld [$d230], a
+ call $2879
+ ld a, $13
+ ld hl, $6554
+ rst $8
+ jp $7491
+; 0x97459
+
+Script_returnafterbattle: ; 0x97459
+; script command 0x60
+
+ ld hl, $d459
+ ld d, [hl]
+ ld [hl], $0
+ ld a, [$d0ee]
+ and $3f
+ cp $1
+ jr nz, .asm_97470 ; 0x97466 $8
+ ld b, $4
+ ld hl, $64c1
+ jp $759d
+.asm_97470
+ bit 0, d
+ jr z, .asm_9747c ; 0x97472 $8
+ ld a, $3f
+ ld hl, $4fec
+ rst $8
+ jr .asm_9748e ; 0x9747a $12
+.asm_9747c
+ ld a, [$d0ee]
+ bit 7, a
+ jr z, .asm_9748e ; 0x97481 $b
+ ld b, $24
+ ld de, $4255
+ ld a, $25
+ ld hl, $7c4f
+ rst $8
+.asm_9748e
+ jp $7491
+; 0x97491
+
+Script_reloadmap: ; 0x97491
+; script command 0x7b
+
+ xor a
+ ld [$d459], a
+ ld a, $f3
+ ld [$ff9f], a
+ ld a, $1
+ call $261b
+ call Unknown_0x96e11
+ ret
+; 0x974a2
+
+Script_2call: ; 0x974a2
+; script command 0x0
+; parameters:
+; pointer (ScriptPointerLabelParam)
+
+ ld a, [ScriptBank]
+ ld b, a
+ call GetScriptByte
+ ld e, a
+ call GetScriptByte
+ ld d, a
+ jr ScriptCall
+; 0x974b0
+
+Script_3call: ; 0x974b0
+; script command 0x1
+; parameters:
+; pointer (ScriptPointerLabelBeforeBank)
+
+ call GetScriptByte
+ ld b, a
+ call GetScriptByte
+ ld e, a
+ call GetScriptByte
+ ld d, a
+ jr ScriptCall
+; 0x974be
+
+Script_2ptcall: ; 0x974be
+; script command 0x2
+; parameters:
+; pointer (PointerLabelToScriptPointer)
+
+ call GetScriptByte
+ ld l, a
+ call GetScriptByte
+ ld h, a
+ ld b, [hl]
+ inc hl
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ; fallthrough
+
+ScriptCall: ; 0x974cb
+ push de
+ ld hl, $d43c
+ ld e, [hl]
+ inc [hl]
+ ld d, $0
+ ld hl, $d43d
+ add hl, de
+ add hl, de
+ add hl, de
+ pop de
+ ld a, [ScriptBank]
+ ld [hli], a
+ ld a, [ScriptPos]
+ ld [hli], a
+ ld a, [$d43b]
+ ld [hl], a
+ ld a, b
+ ld [ScriptBank], a
+ ld a, e
+ ld [ScriptPos], a
+ ld a, d
+ ld [$d43b], a
+ ret
+; 0x974f3
+
+Unknown_0x974f3: ; 0x974f3
+ ld a, [ScriptBank]
+ or $80
+ ld [ScriptBank], a
+ jp $74cb
+; 0x974fe
+
+Script_2jump: ; 0x974fe
+; script command 0x3
+; parameters:
+; pointer (ScriptPointerLabelParam)
+
+ call GetScriptByte
+ ld l, a
+ call GetScriptByte
+ ld h, a
+ ld a, [ScriptBank]
+ ld b, a
+ jp $759d
+; 0x9750d
+
+Script_3jump: ; 0x9750d
+; script command 0x4
+; parameters:
+; pointer (ScriptPointerLabelBeforeBank)
+
+ call GetScriptByte
+ ld b, a
+ call GetScriptByte
+ ld l, a
+ call GetScriptByte
+ ld h, a
+ jp $759d
+; 0x9751c
+
+Script_2ptjump: ; 0x9751c
+; script command 0x5
+; parameters:
+; pointer (PointerLabelToScriptPointer)
+
+ call GetScriptByte
+ ld l, a
+ call GetScriptByte
+ ld h, a
+ ld b, [hl]
+ inc hl
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp $759d
+; 0x9752c
+
+Script_iffalse: ; 0x9752c
+; script command 0x8
+; parameters:
+; pointer (ScriptPointerLabelParam)
+
+ ld a, [$c2dd]
+ and a
+ jp nz, $7596
+ jp Script_2jump
+; 0x97536
+
+Script_iftrue: ; 0x97536
+; script command 0x9
+; parameters:
+; pointer (ScriptPointerLabelParam)
+
+ ld a, [$c2dd]
+ and a
+ jp nz, Script_2jump
+ jp $7596
+; 0x97540
+
+Script_if_equal: ; 0x97540
+; script command 0x6
+; parameters:
+; byte (SingleByteParam)
+; pointer (ScriptPointerLabelParam)
+
+ call GetScriptByte
+ ld hl, $c2dd
+ cp [hl]
+ jr z, Script_2jump ; 0x97547 $b5
+ jr Unknown_97596 ; 0x97549 $4b
+; 0x9754b
+
+Script_if_not_equal: ; 0x9754b
+; script command 0x7
+; parameters:
+; byte (SingleByteParam)
+; pointer (ScriptPointerLabelParam)
+
+ call GetScriptByte
+ ld hl, $c2dd
+ cp [hl]
+ jr nz, Script_2jump ; 0x97552 $aa
+ jr Unknown_97596 ; 0x97554 $40
+; 0x97556
+
+Script_if_less_than: ; 0x97556
+; script command 0xa
+; parameters:
+; byte (SingleByteParam)
+; pointer (ScriptPointerLabelParam)
+
+ ld a, [$c2dd]
+ ld b, a
+ call GetScriptByte
+ cp b
+ jr c, Script_2jump ; 0x9755e $9e
+ jr Unknown_97596 ; 0x97560 $34
+; 0x97562
+
+Script_if_greater_than: ; 0x97562
+; script command 0xb
+; parameters:
+; byte (SingleByteParam)
+; pointer (ScriptPointerLabelParam)
+
+ call GetScriptByte
+ ld b, a
+ ld a, [$c2dd]
+ cp b
+ jr c, Script_2jump ; 0x9756a $92
+ jr Unknown_97596 ; 0x9756c $28
+; 0x9756e
+
+Script_jumpstd: ; 0x9756e
+; script command 0xc
+; parameters:
+; predefined_script (MultiByteParam)
+
+ call $757b
+ jr Unknown_9759d ; 0x97571 $2a
+; 0x97573
+
+Script_callstd: ; 0x97573
+; script command 0xd
+; parameters:
+; predefined_script (MultiByteParam)
+
+ call $757b
+ ld d, h
+ ld e, l
+ jp $74cb
+; 0x9757b
+
+Unknown_0x9757b: ; 0x9757b
+ call GetScriptByte
+ ld e, a
+ call GetScriptByte
+ ld d, a
+ ld hl, $4000
+ add hl, de
+ add hl, de
+ add hl, de
+ ld a, $2f
+ call GetFarByte
+ ld b, a
+ inc hl
+ ld a, $2f
+ call GetFarHalfword
+ ret
+; 0x97596
+
+Unknown_97596: ; 0x97596
+ call GetScriptByte
+ call GetScriptByte
+ ret
+; 0x9759d
+
+Unknown_9759d: ; 0x9759d
+ ld a, b
+ ld [ScriptBank], a
+ ld a, l
+ ld [ScriptPos], a
+ ld a, h
+ ld [$d43b], a
+ ret
+; 0x975aa
+
+Script_priorityjump: ; 0x975aa
+; script command 0x8d
+; parameters:
+; pointer (ScriptPointerLabelParam)
+
+ ld a, [ScriptBank]
+ ld [$d44e], a
+ call GetScriptByte
+ ld [$d44f], a
+ call GetScriptByte
+ ld [$d450], a
+ ld hl, $d434
+ set 3, [hl]
+ ret
+; 0x975c2
+
+Script_checktriggers: ; 0x975c2
+; script command 0x13
+
+ call $211b
+ jr z, .asm_975cb ; 0x975c5 $4
+ ld [$c2dd], a
+ ret
+.asm_975cb
+ ld a, $ff
+ ld [$c2dd], a
+ ret
+; 0x975d1
+
+Script_checkmaptriggers: ; 0x975d1
+; script command 0x11
+; parameters:
+; map_group (SingleByteParam)
+; map_id (SingleByteParam)
+
+ call GetScriptByte
+ ld b, a
+ call GetScriptByte
+ ld c, a
+ call $2147
+ ld a, d
+ or e
+ jr z, .asm_975e5 ; 0x975de $5
+ ld a, [de]
+ ld [$c2dd], a
+ ret
+.asm_975e5
+ ld a, $ff
+ ld [$c2dd], a
+ ret
+; 0x975eb
+
+Script_dotrigger: ; 0x975eb
+; script command 0x14
+; parameters:
+; trigger_id (SingleByteParam)
+
+ ld a, [$dcb5]
+ ld b, a
+ ld a, [$dcb6]
+ ld c, a
+ jr Unknown_975fd ; 0x975f3 $8
+; 0x975f5
+
+Script_domaptrigger: ; 0x975f5
+; script command 0x12
+; parameters:
+; map_group (MapGroupParam)
+; map_id (MapIdParam)
+; trigger_id (SingleByteParam)
+
+ call GetScriptByte
+ ld b, a
+ call GetScriptByte
+ ld c, a
+ ; fallthrough
+
+Unknown_975fd: ; 0x975fd
+ call $2147
+ ld a, d
+ or e
+ jr z, .asm_97608 ; 0x97602 $4
+ call GetScriptByte
+ ld [de], a
+.asm_97608
+ ret
+; 0x97609
+
+Script_copybytetovar: ; 0x97609
+; script command 0x19
+; parameters:
+; address (RAMAddressParam)
+
+ call GetScriptByte
+ ld l, a
+ call GetScriptByte
+ ld h, a
+ ld a, [hl]
+ ld [$c2dd], a
+ ret
+; 0x97616
+
+Script_copyvartobyte: ; 0x97616
+; script command 0x1a
+; parameters:
+; address (RAMAddressParam)
+
+ call GetScriptByte
+ ld l, a
+ call GetScriptByte
+ ld h, a
+ ld a, [$c2dd]
+ ld [hl], a
+ ret
+; 0x97623
+
+Script_loadvar: ; 0x97623
+; script command 0x1b
+; parameters:
+; address (RAMAddressParam)
+; value (SingleByteParam)
+
+ call GetScriptByte
+ ld l, a
+ call GetScriptByte
+ ld h, a
+ call GetScriptByte
+ ld [hl], a
+ ret
+; 0x97630
+
+Script_writebyte: ; 0x97630
+; script command 0x15
+; parameters:
+; value (SingleByteParam)
+
+ call GetScriptByte
+ ld [$c2dd], a
+ ret
+; 0x97637
+
+Script_addvar: ; 0x97637
+; script command 0x16
+; parameters:
+; value (SingleByteParam)
+
+ call GetScriptByte
+ ld hl, $c2dd
+ add [hl]
+ ld [hl], a
+ ret
+; 0x97640
+
+Script_random: ; 0x97640
+; script command 0x17
+; parameters:
+; input (SingleByteParam)
+
+ call GetScriptByte
+ ld [$c2dd], a
+ and a
+ ret z
+ ld c, a
+ call $7673
+ and a
+ jr z, .asm_9765f ; 0x9764d $10
+ ld b, a
+ xor a
+ sub b
+ ld b, a
+.asm_97653
+ push bc
+ call $2f8c
+ pop bc
+ ld a, [$ffe1]
+ cp b
+ jr nc, .asm_97653 ; 0x9765b $f6
+ jr .asm_97666 ; 0x9765d $7
+.asm_9765f
+ push bc
+ call $2f8c
+ pop bc
+ ld a, [$ffe1]
+.asm_97666
+ push af
+ ld a, [$c2dd]
+ ld c, a
+ pop af
+ call $3110
+ ld [$c2dd], a
+ ret
+; 0x97673
+
+Unknown_0x97673: ; 0x97673
+ xor a
+ ld b, a
+ sub c
+.asm_97676
+ inc b
+ sub c
+ jr nc, .asm_97676 ; 0x97678 $fc
+ dec b
+ add c
+ ret
+; 0x9767d
+
+Script_checkcode: ; 0x9767d
+; script command 0x1c
+; parameters:
+; variable_id (SingleByteParam)
+
+ call GetScriptByte
+ call $769e
+ ld a, [de]
+ ld [$c2dd], a
+ ret
+; 0x97688
+
+Script_writevarcode: ; 0x97688
+; script command 0x1d
+; parameters:
+; variable_id (SingleByteParam)
+
+ call GetScriptByte
+ call $769e
+ ld a, [$c2dd]
+ ld [de], a
+ ret
+; 0x97693
+
+Script_writecode: ; 0x97693
+; script command 0x1e
+; parameters:
+; variable_id (SingleByteParam)
+; value (SingleByteParam)
+
+ call GetScriptByte
+ call $769e
+ call GetScriptByte
+ ld [de], a
+ ret
+; 0x9769e
+
+Unknown_0x9769e: ; 0x9769e
+ ld c, a
+ ld a, $20
+ ld hl, $4648
+ rst $8
+ ret
+; 0x976a6
+
+Script_checkver: ; 0x976a6
+; script command 0x18
+
+ ld a, [$76ad]
+ ld [$c2dd], a
+ ret
+; 0x976ad
+
+INCBIN "baserom.gbc",$976ad,$976ae - $976ad
+
+Script_pokenamemem: ; 0x976ae
+; script command 0x40
+; parameters:
+; pokemon (PokemonParam)
+; memory (SingleByteParam)
+
+ call GetScriptByte
+ and a
+ jr nz, .asm_976b7 ; 0x976b2 $3
+ ld a, [$c2dd]
+.asm_976b7
+ ld [$d265], a
+ call $343b
+ ld de, $d073
+
+Unknown_976c0: ; 0x976c0
+ call GetScriptByte
+ cp $3
+ jr c, .asm_976c8 ; 0x976c5 $1
+ xor a
+.asm_976c8
+ ld hl, $d099
+ ld bc, $0013
+ call AddNTimes
+ call CopyName2
+ ret
+; 0x976d5
+
+Script_itemtotext: ; 0x976d5
+; script command 0x41
+; parameters:
+; item (ItemLabelByte)
+; memory (SingleByteParam)
+
+ call GetScriptByte
+ and a
+ jr nz, .asm_976de ; 0x976d9 $3
+ ld a, [$c2dd]
+.asm_976de
+ ld [$d265], a
+ call GetItemName
+ ld de, $d073
+ jr Unknown_976c0 ; 0x976e7 $d7
+; 0x976e9
+
+Script_mapnametotext: ; 0x976e9
+; script command 0x42
+; parameters:
+; memory (SingleByteParam)
+
+ ld a, [$dcb5]
+ ld b, a
+ ld a, [$dcb6]
+ ld c, a
+ call GetWorldMapLocation
+
+Unknown_976f4: ; 0x976f4
+ ld e, a
+ ld a, $72
+ ld hl, $68a5
+ rst $8
+ ld de, $d073
+ jp $76c0
+; 0x97701
+
+Script_displaylocation: ; 0x97701
+; script command 0xa5
+; parameters:
+; id (SingleByteParam)
+
+ call GetScriptByte
+ jr Unknown_976f4 ; 0x97704 $ee
+; 0x97706
+
+Script_trainertotext: ; 0x97706
+; script command 0x43
+; parameters:
+; trainer_id (TrainerGroupParam)
+; trainer_group (TrainerIdParam)
+; memory (SingleByteParam)
+
+ call GetScriptByte
+ ld c, a
+ call GetScriptByte
+ ld b, a
+ ld a, $e
+ ld hl, $594c
+ rst $8
+ jr Unknown_976c0 ; 0x97714 $aa
+; 0x97716
+
+Script_unknown0xa7: ; 0x97716
+; script command 0xa7
+
+ call GetScriptByte
+ ld [$cf61], a
+
+Unknown_9771c: ; 0x9771c
+ call GetScriptByte
+ ld [$cf60], a
+ call GetName
+ ld de, $d073
+ jp $76c0
+; 0x9772b
+
+Script_unknown0xa6: ; 0x9772b
+; script command 0xa6
+
+ ld a, $7
+ ld [$cf61], a
+ jr Unknown_9771c ; 0x97730 $ea
+; 0x97732
+
+Script_readmoney: ; 0x97732
+; script command 0x3d
+; parameters:
+; account (SingleByteParam)
+; memory (SingleByteParam)
+
+ call $7771
+ call $7861
+ ld hl, $d073
+ ld bc, $4306
+ call $3198
+ ld de, $d073
+ jp $76c0
+; 0x97747
+
+Script_readcoins: ; 0x97747
+; script command 0x3e
+; parameters:
+; memory (SingleByteParam)
+
+ call $7771
+ ld hl, $d073
+ ld de, $d855
+ ld bc, $4206
+ call $3198
+ ld de, $d073
+ jp $76c0
+; 0x9775c
+
+Script_RAM2MEM: ; 0x9775c
+; script command 0x3f
+; parameters:
+; memory (SingleByteParam)
+
+ call $7771
+ ld de, $c2dd
+ ld hl, $d073
+ ld bc, $4103
+ call $3198
+ ld de, $d073
+ jp $76c0
+; 0x97771
+
+Unknown_0x97771: ; 0x97771
+ ld hl, $d073
+ ld bc, $000b
+ ld a, $50
+ call ByteFill
+ ret
+; 0x9777d
+
+Script_stringtotext: ; 0x9777d
+; script command 0x44
+; parameters:
+; text_pointer (EncodedTextLabelParam)
+; memory (SingleByteParam)
+
+ call GetScriptByte
+ ld e, a
+ call GetScriptByte
+ ld d, a
+ ld a, [ScriptBank]
+ ld hl, $30d6
+ rst $8
+ ld de, $d086
+ jp $76c0
+; 0x97792
+
+Script_givepokeitem: ; 0x97792
+; script command 0x2f
+; parameters:
+; pointer (PointerParamToItemAndLetter)
+
+ call GetScriptByte
+ ld l, a
+ call GetScriptByte
+ ld h, a
+ ld a, [ScriptBank]
+ call GetFarByte
+ ld b, a
+ push bc
+ inc hl
+ ld bc, $0020
+ ld de, $d002
+ ld a, [ScriptBank]
+ call FarCopyBytes
+ pop bc
+ ld a, $11
+ ld hl, $46cc
+ rst $8
+ ret
+; 0x977b7
+
+Script_checkpokeitem: ; 0x977b7
+; script command 0x30
+; parameters:
+; pointer (PointerParamToItemAndLetter)
+
+ call GetScriptByte
+ ld e, a
+ call GetScriptByte
+ ld d, a
+ ld a, [ScriptBank]
+ ld b, a
+ ld a, $11
+ ld hl, $4654
+ rst $8
+ ret
+; 0x977ca
+
+Script_giveitem: ; 0x977ca
+; script command 0x1f
+; parameters:
+; item (ItemLabelByte)
+; quantity (SingleByteParam)
+
+ call GetScriptByte
+ cp $ff
+ jr nz, .asm_977d4 ; 0x977cf $3
+ ld a, [$c2dd]
+.asm_977d4
+ ld [$d106], a
+ call GetScriptByte
+ ld [$d10c], a
+ ld hl, $d892
+ call $2f66
+ jr nc, .asm_977eb ; 0x977e3 $6
+ ld a, $1
+ ld [$c2dd], a
+ ret
+.asm_977eb
+ xor a
+ ld [$c2dd], a
+ ret
+; 0x977f0
+
+Script_takeitem: ; 0x977f0
+; script command 0x20
+; parameters:
+; item (ItemLabelByte)
+; quantity (DecimalParam)
+
+ xor a
+ ld [$c2dd], a
+ call GetScriptByte
+ ld [$d106], a
+ call GetScriptByte
+ ld [$d10c], a
+ ld a, $ff
+ ld [$d107], a
+ ld hl, $d892
+ call $2f53
+ ret nc
+ ld a, $1
+ ld [$c2dd], a
+ ret
+; 0x97812
+
+Script_checkitem: ; 0x97812
+; script command 0x21
+; parameters:
+; item (ItemLabelByte)
+
+ xor a
+ ld [$c2dd], a
+ call GetScriptByte
+ ld [$d106], a
+ ld hl, $d892
+ call $2f79
+ ret nc
+ ld a, $1
+ ld [$c2dd], a
+ ret
+; 0x97829
+
+Script_givemoney: ; 0x97829
+; script command 0x22
+; parameters:
+; account (SingleByteParam)
+; money (MoneyByteParam)
+
+ call $7861
+ call $786d
+ ld a, $5
+ ld hl, $5fd7
+ rst $8
+ ret
+; 0x97836
+
+Script_takemoney: ; 0x97836
+; script command 0x23
+; parameters:
+; account (SingleByteParam)
+; money (MoneyByteParam)
+
+ call $7861
+ call $786d
+ ld a, $5
+ ld hl, $5ffa
+ rst $8
+ ret
+; 0x97843
+
+Script_checkmoney: ; 0x97843
+; script command 0x24
+; parameters:
+; account (SingleByteParam)
+; money (MoneyByteParam)
+
+ call $7861
+ call $786d
+ ld a, $5
+ ld hl, $600b
+ rst $8
+; 0x9784f
+
+Unknown_9784f: ; 0x9784f
+ jr c, .asm_9785b ; 0x9784f $a
+ jr z, .asm_97857 ; 0x97851 $4
+ ld a, $0
+ jr .asm_9785d ; 0x97855 $6
+.asm_97857
+ ld a, $1
+ jr .asm_9785d ; 0x97859 $2
+.asm_9785b
+ ld a, $2
+.asm_9785d
+ ld [$c2dd], a
+ ret
+; 0x97861
+
+Unknown_0x97861: ; 0x97861
+ call GetScriptByte
+ and a
+ ld de, $d84e
+ ret z
+ ld de, $d851
+ ret
+; 0x9786d
+
+Unknown_0x9786d: ; 0x9786d
+ ld bc, $ffc3
+ push bc
+ call GetScriptByte
+ ld [bc], a
+ inc bc
+ call GetScriptByte
+ ld [bc], a
+ inc bc
+ call GetScriptByte
+ ld [bc], a
+ pop bc
+ ret
+; 0x97881
+
+Script_givecoins: ; 0x97881
+; script command 0x25
+; parameters:
+; coins (CoinByteParam)
+
+ call $78a0
+ ld a, $5
+ ld hl, $606f
+ rst $8
+ ret
+; 0x9788b
+
+Script_takecoins: ; 0x9788b
+; script command 0x26
+; parameters:
+; coins (CoinByteParam)
+
+ call $78a0
+ ld a, $5
+ ld hl, $608f
+ rst $8
+ ret
+; 0x97895
+
+Script_checkcoins: ; 0x97895
+; script command 0x27
+; parameters:
+; coins (CoinByteParam)
+
+ call $78a0
+ ld a, $5
+ ld hl, $60a1
+ rst $8
+ jr Unknown_9784f ; 0x9789e $af
+ call GetScriptByte
+ ld [$ffc4], a
+ call GetScriptByte
+ ld [$ffc3], a
+ ld bc, $ffc3
+ ret
+; 0x978ae
+
+Script_checktime: ; 0x978ae
+; script command 0x2b
+; parameters:
+; time (SingleByteParam)
+
+ xor a
+ ld [$c2dd], a
+ ld a, $3
+ ld hl, $4000
+ rst $8
+ call GetScriptByte
+ and c
+ ret z
+ ld a, $1
+ ld [$c2dd], a
+ ret
+; 0x978c3
+
+Script_checkpoke: ; 0x978c3
+; script command 0x2c
+; parameters:
+; pkmn (PokemonParam)
+
+ xor a
+ ld [$c2dd], a
+ call GetScriptByte
+ ld hl, $dcd8
+ ld de, $0001
+ call IsInArray
+ ret nc
+ ld a, $1
+ ld [$c2dd], a
+ ret
+; 0x978da
+
+Script_addcellnum: ; 0x978da
+; script command 0x28
+; parameters:
+; person (SingleByteParam)
+
+ xor a
+ ld [$c2dd], a
+ call GetScriptByte
+ ld c, a
+ ld a, $24
+ ld hl, $4000
+ rst $8
+ ret nc
+ ld a, $1
+ ld [$c2dd], a
+ ret
+; 0x978ef
+
+Script_delcellnum: ; 0x978ef
+; script command 0x29
+; parameters:
+; person (SingleByteParam)
+
+ xor a
+ ld [$c2dd], a
+ call GetScriptByte
+ ld c, a
+ ld a, $24
+ ld hl, $400f
+ rst $8
+ ret nc
+ ld a, $1
+ ld [$c2dd], a
+ ret
+; 0x97904
+
+Script_checkcellnum: ; 0x97904
+; script command 0x2a
+; parameters:
+; person (SingleByteParam)
+
+ xor a
+ ld [$c2dd], a
+ call GetScriptByte
+ ld c, a
+ ld a, $24
+ ld hl, $4019
+ rst $8
+ ret nc
+ ld a, $1
+ ld [$c2dd], a
+ ret
+; 0x97919
+
+Script_specialphonecall: ; 0x97919
+; script command 0x9c
+; parameters:
+; call_id (MultiByteParam)
+
+ call GetScriptByte
+ ld [$dc31], a
+ call GetScriptByte
+ ld [$dc32], a
+ ret
+; 0x97926
+
+Script_checkphonecall: ; 0x97926
+; script command 0x9d
+
+ ld a, [$dc31]
+ and a
+ jr z, .asm_9792e ; 0x9792a $2
+ ld a, $1
+.asm_9792e
+ ld [$c2dd], a
+ ret
+; 0x97932
+
+Script_givepoke: ; 0x97932
+; script command 0x2d
+; parameters:
+; pokemon (PokemonParam)
+; level (DecimalParam)
+; item (ItemLabelByte)
+; trainer (DecimalParam)
+; trainer_name_pointer (MultiByteParam)
+; pkmn_nickname (MultiByteParam)
+
+ call GetScriptByte
+ ld [$d108], a
+ call GetScriptByte
+ ld [$d143], a
+ call GetScriptByte
+ ld [$d106], a
+ call GetScriptByte
+ and a
+ ld b, a
+ jr z, .asm_9795d ; 0x97949 $12
+ ld hl, ScriptPos
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ call GetScriptByte
+ call GetScriptByte
+ call GetScriptByte
+ call GetScriptByte
+.asm_9795d
+ ld a, $3
+ ld hl, $6277
+ rst $8
+ ld a, b
+ ld [$c2dd], a
+ ret
+; 0x97968
+
+Script_giveegg: ; 0x97968
+; script command 0x2e
+; parameters:
+; pkmn (PokemonParam)
+; level (DecimalParam)
+
+ xor a
+ ld [$c2dd], a
+ ld [$cf5f], a
+ call GetScriptByte
+ ld [$d108], a
+ call GetScriptByte
+ ld [$d143], a
+ ld a, $3
+ ld hl, $5f8c
+ rst $8
+ ret nc
+ ld a, $2
+ ld [$c2dd], a
+ ret
+; 0x97988
+
+Script_setbit1: ; 0x97988
+; script command 0x33
+; parameters:
+; bit_number (MultiByteParam)
+
+ call GetScriptByte
+ ld e, a
+ call GetScriptByte
+ ld d, a
+ ld b, $1
+ call BitTable1Func
+ ret
+; 0x97996
+
+Script_clearbit1: ; 0x97996
+; script command 0x32
+; parameters:
+; bit_number (MultiByteParam)
+
+ call GetScriptByte
+ ld e, a
+ call GetScriptByte
+ ld d, a
+ ld b, $0
+ call BitTable1Func
+ ret
+; 0x979a4
+
+Script_checkbit1: ; 0x979a4
+; script command 0x31
+; parameters:
+; bit_number (MultiByteParam)
+
+ call GetScriptByte
+ ld e, a
+ call GetScriptByte
+ ld d, a
+ ld b, $2
+ call BitTable1Func
+ ld a, c
+ and a
+ jr z, .asm_979b7 ; 0x979b3 $2
+ ld a, $1
+.asm_979b7
+ ld [$c2dd], a
+ ret
+; 0x979bb
+
+Script_setbit2: ; 0x979bb
+; script command 0x36
+; parameters:
+; bit_number (MultiByteParam)
+
+ call GetScriptByte
+ ld e, a
+ call GetScriptByte
+ ld d, a
+ ld b, $1
+ call $79ee
+ ret
+; 0x979c9
+
+Script_clearbit2: ; 0x979c9
+; script command 0x35
+; parameters:
+; bit_number (MultiByteParam)
+
+ call GetScriptByte
+ ld e, a
+ call GetScriptByte
+ ld d, a
+ ld b, $0
+ call $79ee
+ ret
+; 0x979d7
+
+Script_checkbit2: ; 0x979d7
+; script command 0x34
+; parameters:
+; bit_number (MultiByteParam)
+
+ call GetScriptByte
+ ld e, a
+ call GetScriptByte
+ ld d, a
+ ld b, $2
+ call $79ee
+ ld a, c
+ and a
+ jr z, .asm_979ea ; 0x979e6 $2
+ ld a, $1
+.asm_979ea
+ ld [$c2dd], a
+ ret
+; 0x979ee
+
+Unknown_0x979ee: ; 0x979ee
+ ld a, $20
+ ld hl, $4430
+ rst $8
+ ret
+; 0x979f5
+
+Script_wildon: ; 0x979f5
+; script command 0x38
+
+ ld hl, $d84c
+ set 5, [hl]
+ ret
+; 0x979fb
+
+Script_wildoff: ; 0x979fb
+; script command 0x37
+
+ ld hl, $d84c
+ res 5, [hl]
+ ret
+; 0x97a01
+
+Script_xycompare: ; 0x97a01
+; script command 0x39
+; parameters:
+; pointer (MultiByteParam)
+
+ call GetScriptByte
+ ld [$d453], a
+ call GetScriptByte
+ ld [$d454], a
+ ret
+; 0x97a0e
+
+Script_warpfacing: ; 0x97a0e
+; script command 0xa3
+; parameters:
+; facing (SingleByteParam)
+; map_group (MapGroupParam)
+; map_id (MapIdParam)
+; x (SingleByteParam)
+; y (SingleByteParam)
+
+ call GetScriptByte
+ and $3
+ ld c, a
+ ld a, [$d45b]
+ set 5, a
+ or c
+ ld [$d45b], a
+; 0x97a1d
+
+Script_warp: ; 0x97a1d
+; script command 0x3c
+; parameters:
+; map_group (MapGroupParam)
+; map_id (MapIdParam)
+; x (SingleByteParam)
+; y (SingleByteParam)
+
+ call GetScriptByte
+ and a
+ jr z, .asm_97a4a ; 0x97a21 $27
+ ld [$dcb5], a
+ call GetScriptByte
+ ld [$dcb6], a
+ call GetScriptByte
+ ld [$dcb8], a
+ call GetScriptByte
+ ld [$dcb7], a
+ ld a, $ff
+ ld [$d001], a
+ ld a, $f1
+ ld [$ff9f], a
+ ld a, $1
+ call $261b
+ call Unknown_0x96e11
+ ret
+.asm_97a4a
+ call GetScriptByte
+ call GetScriptByte
+ call GetScriptByte
+ ld a, $ff
+ ld [$d001], a
+ ld a, $fb
+ ld [$ff9f], a
+ ld a, $1
+ call $261b
+ call Unknown_0x96e11
+ ret
+; 0x97a65
+
+Script_warpmod: ; 0x97a65
+; script command 0x3a
+; parameters:
+; warp_id (SingleByteParam)
+; map_group (MapGroupParam)
+; map_id (MapIdParam)
+
+ call GetScriptByte
+ ld [$dcac], a
+ call GetScriptByte
+ ld [$dcad], a
+ call GetScriptByte
+ ld [$dcae], a
+ ret
+; 0x97a78
+
+Script_blackoutmod: ; 0x97a78
+; script command 0x3b
+; parameters:
+; map_group (MapGroupParam)
+; map_id (MapIdParam)
+
+ call GetScriptByte
+ ld [$dcb2], a
+ call GetScriptByte
+ ld [$dcb3], a
+ ret
+; 0x97a85
+
+Script_reloadmapmusic: ; 0x97a85
+; script command 0x83
+
+ ld a, $1
+ ld [$c2c1], a
+ ret
+; 0x97a8b
+
+Script_writecmdqueue: ; 0x97a8b
+; script command 0x7d
+; parameters:
+; queue_pointer (MultiByteParam)
+
+ call GetScriptByte
+ ld e, a
+ call GetScriptByte
+ ld d, a
+ ld a, [ScriptBank]
+ ld b, a
+ ld a, $25
+ ld hl, $7e31
+ rst $8
+ ret
+; 0x97a9e
+
+Script_delcmdqueue: ; 0x97a9e
+; script command 0x7e
+; parameters:
+; byte (SingleByteParam)
+
+ xor a
+ ld [$c2dd], a
+ call GetScriptByte
+ ld b, a
+ ld a, $25
+ ld hl, $7e5c
+ rst $8
+ ret c
+ ld a, $1
+ ld [$c2dd], a
+ ret
+; 0x97ab3
+
+Script_changemap: ; 0x97ab3
+; script command 0x79
+; parameters:
+; map_data_pointer (MapDataPointerParam)
+
+ call GetScriptByte
+ ld [$d1a0], a
+ call GetScriptByte
+ ld [$d1a1], a
+ call GetScriptByte
+ ld [$d1a2], a
+ call $24e4
+ call $2879
+ ret
+; 0x97acc
+
+Script_changeblock: ; 0x97acc
+; script command 0x7a
+; parameters:
+; x (SingleByteParam)
+; y (SingleByteParam)
+; block (SingleByteParam)
+
+ call GetScriptByte
+ add $4
+ ld d, a
+ call GetScriptByte
+ add $4
+ ld e, a
+ call $2a66
+ call GetScriptByte
+ ld [hl], a
+ call $2879
+ ret
+; 0x97ae3
+
+Script_reloadmappart: ; 0x97ae3
+; script command 0x7c
+
+ xor a
+ ld [$ffd4], a
+ call $2173
+ call $2914
+ ld a, $41
+ ld hl, $4061
+ rst $8
+ call $1ad2
+ ret
+; 0x97af6
+
+Script_warpcheck: ; 0x97af6
+; script command 0x8e
+
+ call $224a
+ ret nc
+ ld a, $25
+ ld hl, $66d0
+ rst $8
+ ret
+; 0x97b01
+
+Unknown_0x97b01: ; 0x97b01
+ ld a, $25
+ ld hl, $66d0
+ rst $8
+ ret
+; 0x97b08
+
+Script_newloadmap: ; 0x97b08
+; script command 0x8a
+; parameters:
+; which_method (SingleByteParam)
+
+ call GetScriptByte
+ ld [$ff9f], a
+ ld a, $1
+ call $261b
+ call Unknown_0x96e11
+ ret
+; 0x97b16
+
+Script_reloadandreturn: ; 0x97b16
+; script command 0x92
+
+ call $7b08
+ jp $7b74
+; 0x97b1c
+
+Script_loadfont: ; 0x97b1c
+; script command 0x47
+
+ call $2e08
+ ret
+; 0x97b20
+
+Script_refreshscreen: ; 0x97b20
+; script command 0x48
+; parameters:
+; dummy (SingleByteParam)
+
+ call $2dba
+ call GetScriptByte
+ ret
+; 0x97b27
+
+Script_loadbytec1ce: ; 0x97b27
+; script command 0x4a
+; parameters:
+; byte (SingleByteParam)
+
+ call GetScriptByte
+ ld [$c2cf], a
+ ret
+; 0x97b2e
+
+INCBIN "baserom.gbc",$97b2e,$97b2f - $97b2e
+
+Script_loadmovesprites: ; 0x97b2f
+; script command 0x49
+
+ call $2e20
+ call $2dcf
+ ret
+; 0x97b36
+
+Script_passtoengine: ; 0x97b36
+; script command 0x89
+; parameters:
+; data_pointer (PointerLabelBeforeBank)
+
+ call GetScriptByte
+ push af
+ call GetScriptByte
+ ld l, a
+ call GetScriptByte
+ ld h, a
+ pop af
+ call StartAutoInput
+ ret
+; 0x97b47
+
+Script_pause: ; 0x97b47
+; script command 0x8b
+; parameters:
+; length (DecimalParam)
+
+ call GetScriptByte
+ and a
+ jr z, .asm_97b50 ; 0x97b4b $3
+ ld [$d44d], a
+.asm_97b50
+ ld c, $2
+ call DelayFrames
+ ld hl, $d44d
+ dec [hl]
+ jr nz, .asm_97b50 ; 0x97b59 $f5
+ ret
+; 0x97b5c
+
+Script_deactivatefacing: ; 0x97b5c
+; script command 0x8c
+; parameters:
+; time (SingleByteParam)
+
+ call GetScriptByte
+ and a
+ jr z, .asm_97b65 ; 0x97b60 $3
+ ld [$d44d], a
+.asm_97b65
+ ld a, $3
+ ld [$d437], a
+ call Unknown_0x96e11
+ ret
+; 0x97b6e
+
+Script_ptpriorityjump: ; 0x97b6e
+; script command 0x8f
+; parameters:
+; pointer (ScriptPointerLabelParam)
+
+ call Unknown_0x96e11
+ jp Script_2jump
+; 0x97b74
+
+Script_end: ; 0x97b74
+; script command 0x91
+
+ call $7b9a
+ jr c, .asm_97b7a ; 0x97b77 $1
+ ret
+.asm_97b7a
+ xor a
+ ld [$d438], a
+ ld a, $0
+ ld [$d437], a
+ ld hl, $d434
+ res 0, [hl]
+ call Unknown_0x96e11
+ ret
+; 0x97b8c
+
+Script_return: ; 0x97b8c
+; script command 0x90
+
+ call $7b9a
+ jr c, .asm_97b91 ; 0x97b8f $0
+.asm_97b91
+ ld hl, $d434
+ res 0, [hl]
+ call Unknown_0x96e11
+ ret
+; 0x97b9a
+
+Unknown_0x97b9a: ; 0x97b9a
+ ld hl, $d43c
+ ld a, [hl]
+ and a
+ jr z, .asm_97bbe ; 0x97b9f $1d
+ dec [hl]
+ ld e, [hl]
+ ld d, $0
+ ld hl, $d43d
+ add hl, de
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld b, a
+ and $7f
+ ld [ScriptBank], a
+ ld a, [hli]
+ ld e, a
+ ld [ScriptPos], a
+ ld a, [hl]
+ ld d, a
+ ld [$d43b], a
+ and a
+ ret
+.asm_97bbe
+ scf
+ ret
+; 0x97bc0
+
+Script_resetfuncs: ; 0x97bc0
+; script command 0x93
+
+ xor a
+ ld [$d43c], a
+ ld [$d438], a
+ ld a, $0
+ ld [$d437], a
+ ld hl, $d434
+ res 0, [hl]
+ call Unknown_0x96e11
+ ret
+; 0x97bd5
+
+Script_halloffame: ; 0x97bd5
+; script command 0xa1
+
+ ld hl, $cfbc
+ res 0, [hl]
+ ld a, BANK(HallOfFame1)
+ ld hl, HallOfFame1
+ rst $8
+ ld a, BANK(HallOfFame2)
+ ld hl, HallOfFame2
+ rst $8
+ ld a, BANK(HallOfFame3)
+ ld hl, HallOfFame3
+ rst $8
+ ld hl, $cfbc
+ set 0, [hl]
+ jr DisplayCredits
+; 0x97bf3
+
+Script_credits: ; 0x97bf3
+; script command 0xa2
+
+ ld a, $21
+ ld hl, $6455
+ rst $8
+ ; fallthrough
+DisplayCredits:
+ call $7bc0
+ ld a, $3
+ call $261b
+ call Unknown_0x96e11
+ ret
+; 0x97c05
+
+Script_unknown0xa8: ; 0x97c05
+; script command 0xa8
+; parameters:
+; unknown (SingleByteParam)
+
+ push bc
+ call GetScriptByte
+.asm_97c09
+ push af
+ ld c, $6
+ call DelayFrames
+ pop af
+ dec a
+ jr nz, .asm_97c09 ; 0x97c11 $f6
+ pop bc
+ ret
+; 0x97c15
+
+Script_unknown0xa9: ; 0x97c15
+; script command 0xa9
+
+ ld a, $13
+ ld hl, $4ffe
+ rst $8
+ ld a, c
+ ld [$c2dd], a
+ ret
+; 0x97c20
diff --git a/vblank.asm b/vblank.asm
index 78d7151f0..8201c1e5c 100644
--- a/vblank.asm
+++ b/vblank.asm
@@ -69,13 +69,13 @@ VBlank0: ; 2b1
inc [hl]
; advance rng
- ld a, [$ff04] ; divider
+ ld a, [rDIV]
ld b, a
ld a, [$ffe1]
adc b
ld [$ffe1], a
- ld a, [$ff04] ; divider
+ ld a, [rDIV]
ld b, a
ld a, [$ffe2]
sbc b
@@ -87,16 +87,16 @@ VBlank0: ; 2b1
; scroll x
ld a, [$ffcf]
- ld [$ff43], a ; scx
+ ld [rSCX], a
; scroll y
ld a, [$ffd0]
- ld [$ff42], a ; scy
+ ld [rSCY], a
; window y
ld a, [$ffd2]
- ld [$ff4a], a ; wy
+ ld [rWY], a
; window x + 7
ld a, [$ffd1]
- ld [$ff4b], a ; wx
+ ld [rWX], a
; some time management is in order
; only have time for one of these during vblank
@@ -131,7 +131,7 @@ VBlank0: ; 2b1
call $ff80
; 403f:
; ld a, $c4
-; ld [$ff46], a ; oam dma
+; ld [rDMA], a
; ld a, $28
; .loop
; dec a
@@ -216,11 +216,11 @@ VBlank1: ; 337
; scroll x
ld a, [$ffcf]
- ld [$ff43], a ; scx
+ ld [rSCX], a
; scroll y
ld a, [$ffd0]
- ld [$ff42], a ; scy
+ ld [rSCY], a
; time-sensitive fns
call UpdatePals
@@ -233,7 +233,7 @@ VBlank1: ; 337
call $ff80
; 403f:
; ld a, $c4
-; ld [$ff46], a ; oam dma
+; ld [rDMA], a
; ld a, $28
; .loop
; dec a
@@ -246,20 +246,20 @@ VBlank1: ; 337
ld [VBlankOccurred], a
; get requested ints
- ld a, [$ff0f] ; IF
+ ld a, [rIF]
ld b, a
; discard requested ints
xor a
- ld [$ff0f], a ; IF
+ ld [rIF], a
; enable lcd stat
ld a, %10 ; lcd stat
- ld [$ffff], a ; IE
+ ld [rIE], a
; rerequest serial int if applicable (still disabled)
; request lcd stat
ld a, b
and %1000 ; serial
or %10 ; lcd stat
- ld [$ff0f], a ; IF
+ ld [rIF], a
ei
; update sound
@@ -272,17 +272,17 @@ VBlank1: ; 337
di
; get requested ints
- ld a, [$ff0f] ; IF
+ ld a, [rIF]
ld b, a
; discard requested ints
xor a
- ld [$ff0f], a ; IF
+ ld [rIF], a
; enable ints besides joypad
ld a, %1111 ; serial timer lcdstat vblank
- ld [$ffff], a ; IE
+ ld [rIE], a
; rerequest ints
ld a, b
- ld [$ff0f], a ; IF
+ ld [rIF], a
ret
; 37f
@@ -297,13 +297,13 @@ UpdatePals: ; 37f
; update gb pals
ld a, [$cfc7]
- ld [$ff47], a ; BGP
+ ld [rBGP], a
ld a, [$cfc8]
- ld [$ff48], a ; OBP0
+ ld [rOBP0], a
ld a, [$cfc9]
- ld [$ff49], a ; 0BP1
+ ld [rOBP1], a
and a
ret
@@ -324,10 +324,10 @@ VBlank3: ; 396
; scroll x
ld a, [$ffcf]
- ld [$ff43], a ; scx
+ ld [rSCX], a
; scroll y
ld a, [$ffd0]
- ld [$ff42], a ; scy
+ ld [rSCY], a
; any pals to update?
ld a, [$ffe5]
@@ -342,7 +342,7 @@ VBlank3: ; 396
call $ff80
; 403f:
; ld a, $c4 ; Sprites / $100
-; ld [$ff46], a ; oam dma
+; ld [rDMA], a
; ld a, $28
; .loop
; dec a
@@ -355,15 +355,15 @@ VBlank3: ; 396
ld [VBlankOccurred], a
; save int flag
- ld a, [$ff0f] ; IF
+ ld a, [rIF]
push af
; reset ints
xor a
- ld [$ff0f], a ; IF
+ ld [rIF], a
; force lcdstat int during sound update
ld a, %10 ; lcd stat
- ld [$ffff], a ; IE
- ld [$ff0f], a ; IF
+ ld [rIE], a
+ ld [rIF], a
ei
; update sound
@@ -376,7 +376,7 @@ VBlank3: ; 396
di
; request lcdstat
- ld a, [$ff0f] ; IF
+ ld a, [rIF]
ld b, a
; and any other ints
pop af
@@ -384,13 +384,13 @@ VBlank3: ; 396
ld b, a
; reset ints
xor a
- ld [$ff0f], a ; IF
+ ld [rIF], a
; enable ints besides joypad
ld a, %1111 ; serial timer lcdstat vblank
- ld [$ffff], a ; IE
+ ld [rIE], a
; request ints
ld a, b
- ld [$ff0f], a ; IF
+ ld [rIF], a
ret
; 3df
@@ -414,7 +414,7 @@ VBlank4: ; 3df
call $ff80
; 403f:
; ld a, $c4
-; ld [$ff46], a ; oam dma
+; ld [rDMA], a
; ld a, $28
; .loop
; dec a
@@ -456,7 +456,7 @@ VBlank5: ; 400
; scroll x
ld a, [$ffcf]
- ld [$ff43], a ; scx
+ ld [rSCX], a
; if we can update pals, skip this part
call UpdatePalsIfCGB
@@ -475,12 +475,12 @@ VBlank5: ; 400
; discard requested ints
xor a
- ld [$ff0f], a ; IF
+ ld [rIF], a
; enable lcd stat
ld a, %10 ; lcd stat
- ld [$ffff], a ; IE
+ ld [rIE], a
; request lcd stat
- ld [$ff0f], a ; IF
+ ld [rIF], a
ei
; update sound
@@ -494,10 +494,10 @@ VBlank5: ; 400
; discard requested ints
xor a
- ld [$ff0f], a ; IF
+ ld [rIF], a
; enable ints besides joypad
ld a, %1111 ; serial timer lcdstat vblank
- ld [$ffff], a ; IE
+ ld [rIE], a
ret
; 436
diff --git a/wram.asm b/wram.asm
index 31b292a3e..a693e28c7 100644
--- a/wram.asm
+++ b/wram.asm
@@ -168,7 +168,13 @@ Channel1VibratoRate: ; c121
ds 1
; c126
ds 1
- ds 7
+; c127
+ ds 1
+Channel1CryPitch: ; c128
+ ds 1
+Channel1CryEcho: ; c129
+ ds 1
+ ds 4
Channel1NoteLength: ; c12e
; # frames per 16th note
ds 1
@@ -278,9 +284,14 @@ MusicFadeIDLo: ; c2a9
ds 1
MusicFadeIDHi: ; c2aa
ds 1
- ds 9
+ ds 5
+CryPitch: ; c2b0
+ ds 1
+CryEcho: ; c2b1
+ ds 1
+CryLength: ; c2b2
+ ds 2
LastVolume: ; c2b4
-; preserves volume of a song playing so cries can have their own volume
ds 1
ds 1
SFXPriority: ; c2b6
@@ -643,8 +654,12 @@ OverworldMapEnd
ds 12
SECTION "gfx2",BSS[$cd20]
-BGMapBuffer: ; cd20
- ds 40
+BGMapBuffer:
+CreditsPos: ; cd20
+ ds 2
+CreditsTimer: ; cd22
+ ds 1
+ ds 37
BGMapPalBuffer: ; cd48
ds 40
@@ -837,11 +852,9 @@ TileSetPalettes: ; d1e6
ds 2
Buffer1:
-MagikarpLength:
-MagikarpLengthHi: ; d1ea
+MagikarpLength: ; d1ea
ds 1
-Buffer2:
-MagikarpLengthLo: ; d1eb
+Buffer2: ; d1eb
ds 1
SECTION "prng2",BSS[$d1fa]
@@ -1102,6 +1115,12 @@ OTPartyMon5Nickname: ; d416
OTPartyMon6Nickname: ; d421
ds 11
+SECTION "Scripting",BSS[$d439]
+
+ScriptBank: ; d439
+ ds 1
+ScriptPos: ; d43a
+ ds 2
SECTION "Player",BSS[$d472]
PlayerGender: ; d472