mirror of
https://github.com/pret/pokered.git
synced 2025-02-17 04:17:54 +00:00
Build the Virtual Console patches with make red_vc
and make blue_vc
(#351)
This commit is contained in:
parent
07df4a5f88
commit
fe8d3c51a4
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -15,3 +15,6 @@
|
||||
*.wav binary
|
||||
*.blk binary
|
||||
*.pic binary
|
||||
|
||||
# Declare files that will always have CRLF line endings on checkout.
|
||||
*.patch.template text eol=crlf linguist-language=INI
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,6 +9,7 @@
|
||||
# compiled roms
|
||||
*.gbc
|
||||
*.gb
|
||||
*.patch
|
||||
|
||||
# rgbds extras
|
||||
*.map
|
||||
|
68
Makefile
68
Makefile
@ -1,19 +1,27 @@
|
||||
roms := pokered.gbc pokeblue.gbc pokeblue_debug.gbc
|
||||
roms := \
|
||||
pokered.gbc \
|
||||
pokeblue.gbc \
|
||||
pokeblue_debug.gbc
|
||||
patches := \
|
||||
pokered.patch \
|
||||
pokeblue.patch
|
||||
|
||||
rom_obj := \
|
||||
audio.o \
|
||||
home.o \
|
||||
main.o \
|
||||
maps.o \
|
||||
text.o \
|
||||
wram.o \
|
||||
gfx/pics.o \
|
||||
gfx/sprites.o \
|
||||
gfx/tilesets.o
|
||||
audio.o \
|
||||
home.o \
|
||||
main.o \
|
||||
maps.o \
|
||||
text.o \
|
||||
wram.o \
|
||||
gfx/pics.o \
|
||||
gfx/sprites.o \
|
||||
gfx/tilesets.o
|
||||
|
||||
pokered_obj := $(rom_obj:.o=_red.o)
|
||||
pokeblue_obj := $(rom_obj:.o=_blue.o)
|
||||
pokeblue_debug_obj := $(rom_obj:.o=_blue_debug.o)
|
||||
pokered_vc_obj := $(rom_obj:.o=_red_vc.o)
|
||||
pokeblue_vc_obj := $(rom_obj:.o=_blue_vc.o)
|
||||
|
||||
|
||||
### Build tools
|
||||
@ -43,15 +51,34 @@ all: $(roms)
|
||||
red: pokered.gbc
|
||||
blue: pokeblue.gbc
|
||||
blue_debug: pokeblue_debug.gbc
|
||||
red_vc: pokered.patch
|
||||
blue_vc: pokeblue.patch
|
||||
|
||||
clean: tidy
|
||||
find gfx \( -iname '*.1bpp' -o -iname '*.2bpp' -o -iname '*.pic' \) -delete
|
||||
find gfx \
|
||||
\( -iname '*.1bpp' \
|
||||
-o -iname '*.2bpp' \
|
||||
-o -iname '*.pic' \) \
|
||||
-delete
|
||||
|
||||
tidy:
|
||||
$(RM) $(roms) $(pokered_obj) $(pokeblue_obj) $(pokeblue_debug_obj) $(roms:.gbc=.map) $(roms:.gbc=.sym) rgbdscheck.o
|
||||
$(RM) $(roms) \
|
||||
$(roms:.gbc=.sym) \
|
||||
$(roms:.gbc=.map) \
|
||||
$(patches) \
|
||||
$(patches:.patch=_vc.gbc) \
|
||||
$(patches:.patch=_vc.sym) \
|
||||
$(patches:.patch=_vc.map) \
|
||||
$(patches:%.patch=vc/%.constants.sym) \
|
||||
$(pokered_obj) \
|
||||
$(pokeblue_obj) \
|
||||
$(pokered_vc_obj) \
|
||||
$(pokeblue_vc_obj) \
|
||||
$(pokeblue_debug_obj) \
|
||||
rgbdscheck.o
|
||||
$(MAKE) clean -C tools/
|
||||
|
||||
compare: $(roms)
|
||||
compare: $(roms) $(patches)
|
||||
@$(SHA1) -c roms.sha1
|
||||
|
||||
tools:
|
||||
@ -67,6 +94,11 @@ endif
|
||||
$(pokered_obj): RGBASMFLAGS += -D _RED
|
||||
$(pokeblue_obj): RGBASMFLAGS += -D _BLUE
|
||||
$(pokeblue_debug_obj): RGBASMFLAGS += -D _BLUE -D _DEBUG
|
||||
$(pokered_vc_obj): RGBASMFLAGS += -D _RED -D _RED_VC
|
||||
$(pokeblue_vc_obj): RGBASMFLAGS += -D _BLUE -D _BLUE_VC
|
||||
|
||||
%.patch: vc/%.constants.sym %_vc.gbc %.gbc vc/%.patch.template
|
||||
tools/make_patch $*_vc.sym $^ $@
|
||||
|
||||
rgbdscheck.o: rgbdscheck.asm
|
||||
$(RGBASM) -o $@ $<
|
||||
@ -89,6 +121,12 @@ $(info $(shell $(MAKE) -C tools))
|
||||
$(foreach obj, $(pokered_obj), $(eval $(call DEP,$(obj),$(obj:_red.o=.asm))))
|
||||
$(foreach obj, $(pokeblue_obj), $(eval $(call DEP,$(obj),$(obj:_blue.o=.asm))))
|
||||
$(foreach obj, $(pokeblue_debug_obj), $(eval $(call DEP,$(obj),$(obj:_blue_debug.o=.asm))))
|
||||
$(foreach obj, $(pokered_vc_obj), $(eval $(call DEP,$(obj),$(obj:_red_vc.o=.asm))))
|
||||
$(foreach obj, $(pokeblue_vc_obj), $(eval $(call DEP,$(obj),$(obj:_blue_vc.o=.asm))))
|
||||
|
||||
# Dependencies for VC files that need to run scan_includes
|
||||
%.constants.sym: %.constants.asm $(shell tools/scan_includes %.constants.asm) | rgbdscheck.o
|
||||
$(RGBASM) $< > $@
|
||||
|
||||
endif
|
||||
|
||||
@ -98,11 +136,15 @@ endif
|
||||
|
||||
pokered_pad = 0x00
|
||||
pokeblue_pad = 0x00
|
||||
pokered_vc_pad = 0x00
|
||||
pokeblue_vc_pad = 0x00
|
||||
pokeblue_debug_pad = 0xff
|
||||
|
||||
pokered_opt = -jsv -n 0 -k 01 -l 0x33 -m 0x13 -r 03 -t "POKEMON RED"
|
||||
pokeblue_opt = -jsv -n 0 -k 01 -l 0x33 -m 0x13 -r 03 -t "POKEMON BLUE"
|
||||
pokeblue_debug_opt = -jsv -n 0 -k 01 -l 0x33 -m 0x13 -r 03 -t "POKEMON BLUE"
|
||||
pokered_vc_opt = -jsv -n 0 -k 01 -l 0x33 -m 0x13 -r 03 -t "POKEMON RED"
|
||||
pokeblue_vc_opt = -jsv -n 0 -k 01 -l 0x33 -m 0x13 -r 03 -t "POKEMON BLUE"
|
||||
|
||||
%.gbc: $$(%_obj) layout.link
|
||||
$(RGBLINK) -p $($*_pad) -d -m $*.map -n $*.sym -l layout.link -o $@ $(filter %.o,$^)
|
||||
|
@ -7,6 +7,8 @@ It builds the following ROMs:
|
||||
- Pokemon Red (UE) [S][!].gb `sha1: ea9bcae617fdf159b045185467ae58b2e4a48b9a`
|
||||
- Pokemon Blue (UE) [S][!].gb `sha1: d7037c83e1ae5b39bde3c30787637ba1d4c48ce2`
|
||||
- BLUEMONS.GB (debug build) `sha1: 5b1456177671b79b263c614ea0e7cc9ac542e9c4`
|
||||
- dmgapae0.e69.patch `sha1: 0fb5f743696adfe1dbb2e062111f08f9bc5a293a`
|
||||
- dmgapee0.e68.patch `sha1: ed4be94dc29c64271942c87f2157bca9ca1019c7`
|
||||
|
||||
To set up the repository, see [**INSTALL.md**](INSTALL.md).
|
||||
|
||||
|
@ -211,9 +211,19 @@ _CableClubNPCPleaseWaitText::
|
||||
text_end
|
||||
|
||||
_CableClubNPCLinkClosedBecauseOfInactivityText::
|
||||
vc_patch Change_MSG
|
||||
IF DEF(_RED_VC) || DEF(_BLUE_VC)
|
||||
text "Please come again!"
|
||||
done
|
||||
text_start
|
||||
text "sed because of"
|
||||
cont "inactivity."
|
||||
ELSE
|
||||
text "The link has been"
|
||||
line "closed because of"
|
||||
cont "inactivity."
|
||||
ENDC
|
||||
vc_patch_end
|
||||
|
||||
para "Please contact"
|
||||
line "your friend and"
|
||||
|
@ -176,8 +176,12 @@ PlayAnimation:
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
.animationLoop
|
||||
vc_hook FPA_Thunderbolt_End
|
||||
ld a, [hli]
|
||||
vc_hook_red FPA_007_End
|
||||
vc_hook_blue FPA_009_End
|
||||
cp -1
|
||||
vc_hook_blue FPA_008_End
|
||||
jr z, .AnimationOver
|
||||
cp FIRST_SE_ID ; is this subanimation or a special effect?
|
||||
jr c, .playSubanimation
|
||||
@ -246,37 +250,55 @@ PlayAnimation:
|
||||
ld a, [wAnimPalette]
|
||||
ldh [rOBP0], a
|
||||
call LoadAnimationTileset
|
||||
vc_hook FPA_001_Begin
|
||||
call LoadSubanimation
|
||||
call PlaySubanimation
|
||||
vc_hook FPA_001_End
|
||||
pop af
|
||||
vc_hook_red FPA_008_End
|
||||
ldh [rOBP0], a
|
||||
.nextAnimationCommand
|
||||
vc_hook FPA_005_End
|
||||
pop hl
|
||||
vc_hook FPA_002_End
|
||||
jr .animationLoop
|
||||
.AnimationOver
|
||||
ret
|
||||
|
||||
LoadSubanimation:
|
||||
vc_hook FPA_002_Begin
|
||||
ld a, [wSubAnimAddrPtr + 1]
|
||||
vc_hook FPA_003_Begin
|
||||
ld h, a
|
||||
vc_hook_red FPA_131_Begin
|
||||
ld a, [wSubAnimAddrPtr]
|
||||
vc_hook_red FPA_56_Begin
|
||||
ld l, a
|
||||
ld a, [hli]
|
||||
ld e, a
|
||||
vc_hook FPA_76_Begin
|
||||
ld a, [hl]
|
||||
vc_hook FPA_Thunderbolt_Begin
|
||||
ld d, a ; de = address of subanimation
|
||||
ld a, [de]
|
||||
vc_hook_blue FPA_012_Begin
|
||||
ld b, a
|
||||
vc_hook FPA_Spore_Begin
|
||||
and %00011111
|
||||
vc_hook FPA_Bubblebeam_Begin
|
||||
ld [wSubAnimCounter], a ; number of frame blocks
|
||||
vc_hook_red FPA_010_Begin
|
||||
vc_hook_blue FPA_009_Begin
|
||||
ld a, b
|
||||
and %11100000
|
||||
cp SUBANIMTYPE_ENEMY << 5
|
||||
vc_hook_blue FPA_004_Begin
|
||||
jr nz, .isNotType5
|
||||
.isType5
|
||||
call GetSubanimationTransform2
|
||||
jr .saveTransformation
|
||||
.isNotType5
|
||||
vc_hook FPA_Hyper_Beam_Begin
|
||||
call GetSubanimationTransform1
|
||||
.saveTransformation
|
||||
; place the upper 3 bits of a into bits 0-2 of a before storing
|
||||
@ -307,6 +329,7 @@ LoadSubanimation:
|
||||
; sets the transform to SUBANIMTYPE_NORMAL if it's the player's turn
|
||||
; sets the transform to the subanimation type if it's the enemy's turn
|
||||
GetSubanimationTransform1:
|
||||
vc_hook FPA_Reflect_Begin
|
||||
ld b, a
|
||||
ldh a, [hWhoseTurn]
|
||||
and a
|
||||
@ -399,11 +422,15 @@ MoveAnimation:
|
||||
jr nz, .animationsDisabled
|
||||
call ShareMoveAnimations
|
||||
call PlayAnimation
|
||||
vc_hook_red FPA_004_End
|
||||
vc_hook_blue FPA_011_End
|
||||
jr .next4
|
||||
.animationsDisabled
|
||||
ld c, 30
|
||||
call DelayFrames
|
||||
.next4
|
||||
vc_hook_red FPA_010_End
|
||||
vc_hook_blue FPA_012_End
|
||||
call PlayApplyingAttackAnimation ; shake the screen or flash the pic in and out (to show damage)
|
||||
.animationFinished
|
||||
call WaitForSoundToFinish
|
||||
@ -541,6 +568,7 @@ SetAnimationPalette:
|
||||
.notSGB
|
||||
ld a, $e4
|
||||
ld [wAnimPalette], a
|
||||
vc_hook FPA_Dream_Eater_Begin
|
||||
ldh [rOBP0], a
|
||||
ld a, $6c
|
||||
ldh [rOBP1], a
|
||||
@ -956,6 +984,7 @@ AnimationFlashScreenLong:
|
||||
ld [wFlashScreenLongCounter], a
|
||||
pop hl
|
||||
jr nz, .loop
|
||||
vc_hook_red FPA_phy_End
|
||||
ret
|
||||
|
||||
; BG palettes
|
||||
|
@ -3023,6 +3023,7 @@ LinkBattleExchangeData:
|
||||
ld a, b
|
||||
.doExchange
|
||||
ld [wSerialExchangeNybbleSendData], a
|
||||
vc_hook send_byt2
|
||||
callfar PrintWaitingText
|
||||
.syncLoop1
|
||||
call Serial_ExchangeNybble
|
||||
@ -3030,18 +3031,33 @@ LinkBattleExchangeData:
|
||||
ld a, [wSerialExchangeNybbleReceiveData]
|
||||
inc a
|
||||
jr z, .syncLoop1
|
||||
vc_hook send_byt2_ret
|
||||
vc_patch FIGHT
|
||||
IF DEF(_RED_VC) || DEF(_BLUE_VC)
|
||||
ld b, 26
|
||||
ELSE
|
||||
ld b, 10
|
||||
ENDC
|
||||
vc_patch_end
|
||||
.syncLoop2
|
||||
call DelayFrame
|
||||
call Serial_ExchangeNybble
|
||||
dec b
|
||||
jr nz, .syncLoop2
|
||||
vc_hook send_dummy
|
||||
vc_patch FIGHT2
|
||||
IF DEF(_RED_VC) || DEF(_BLUE_VC)
|
||||
ld b, 26
|
||||
ELSE
|
||||
ld b, 10
|
||||
ENDC
|
||||
vc_patch_end
|
||||
.syncLoop3
|
||||
call DelayFrame
|
||||
call Serial_SendZeroByte
|
||||
dec b
|
||||
jr nz, .syncLoop3
|
||||
vc_hook send_dummy_end
|
||||
ret
|
||||
|
||||
ExecutePlayerMove:
|
||||
@ -6661,7 +6677,14 @@ BattleRandom:
|
||||
ld a, [hl]
|
||||
pop bc
|
||||
pop hl
|
||||
vc_hook fight_ret_c
|
||||
vc_patch fight_ret
|
||||
IF DEF(_RED_VC) || DEF(_BLUE_VC)
|
||||
ret
|
||||
ELSE
|
||||
ret c
|
||||
ENDC
|
||||
vc_patch_end
|
||||
|
||||
; if we picked the last seed, we need to recalculate the nine seeds
|
||||
push hl
|
||||
@ -6726,7 +6749,9 @@ HandleExplodingAnimation:
|
||||
|
||||
PlayMoveAnimation:
|
||||
ld [wAnimationID], a
|
||||
vc_hook_red FPA_conf_Begin
|
||||
call Delay3
|
||||
vc_hook_red FPA_phy_Begin
|
||||
predef_jump MoveAnimation
|
||||
|
||||
InitBattle::
|
||||
|
@ -484,6 +484,7 @@ CheckSGB:
|
||||
ldh a, [rJOYP]
|
||||
ldh a, [rJOYP]
|
||||
call Wait7000
|
||||
vc_hook Network_RESET
|
||||
call Wait7000
|
||||
ld a, $30
|
||||
ldh [rJOYP], a
|
||||
|
@ -124,18 +124,21 @@ CableClub_DoBattleOrTradeAgain:
|
||||
ld hl, wSerialRandomNumberListBlock
|
||||
ld de, wSerialOtherGameboyRandomNumberListBlock
|
||||
ld bc, $11
|
||||
vc_hook Network17
|
||||
call Serial_ExchangeBytes
|
||||
ld a, SERIAL_NO_DATA_BYTE
|
||||
ld [de], a
|
||||
ld hl, wSerialPlayerDataBlock
|
||||
ld de, wSerialEnemyDataBlock
|
||||
ld bc, $1a8
|
||||
vc_hook Network424
|
||||
call Serial_ExchangeBytes
|
||||
ld a, SERIAL_NO_DATA_BYTE
|
||||
ld [de], a
|
||||
ld hl, wSerialPartyMonsPatchList
|
||||
ld de, wSerialEnemyMonsPatchList
|
||||
ld bc, $c8
|
||||
vc_hook Network200
|
||||
call Serial_ExchangeBytes
|
||||
ld a, (1 << SERIAL) | (1 << TIMER) | (1 << VBLANK)
|
||||
ldh [rIE], a
|
||||
@ -859,6 +862,7 @@ TradeCenter_Trade:
|
||||
ld de, TradeCompleted
|
||||
call PlaceString
|
||||
predef SaveSAVtoSRAM2
|
||||
vc_hook save_game_end
|
||||
ld c, 50
|
||||
call DelayFrames
|
||||
xor a
|
||||
|
@ -27,6 +27,7 @@ CableClubNPC::
|
||||
xor a
|
||||
ldh [hSerialReceiveData], a
|
||||
ld a, START_TRANSFER_EXTERNAL_CLOCK
|
||||
vc_hook linkCable_fake_begin
|
||||
ldh [rSC], a
|
||||
ld a, [wLinkTimeoutCounter]
|
||||
dec a
|
||||
@ -54,6 +55,7 @@ CableClubNPC::
|
||||
ld a, [wCurrentMenuItem]
|
||||
and a
|
||||
jr nz, .choseNo
|
||||
vc_hook linkCable_block_input
|
||||
callfar SaveSAVtoSRAM
|
||||
call WaitForSoundToFinish
|
||||
ld a, SFX_SAVE
|
||||
@ -66,8 +68,10 @@ CableClubNPC::
|
||||
xor a
|
||||
ld [hl], a
|
||||
ldh [hSerialReceivedNewData], a
|
||||
vc_hook linkCable_fake_end
|
||||
ld [wSerialExchangeNybbleSendData], a
|
||||
call Serial_SyncAndExchangeNybble
|
||||
vc_hook Network_RECHECK
|
||||
ld hl, wUnknownSerialCounter
|
||||
ld a, [hli]
|
||||
inc a
|
||||
|
@ -284,9 +284,11 @@ LinkMenu:
|
||||
.choseCancel
|
||||
xor a
|
||||
ld [wMenuJoypadPollCount], a
|
||||
vc_hook Network_STOP
|
||||
call Delay3
|
||||
call CloseLinkConnection
|
||||
ld hl, LinkCanceledText
|
||||
vc_hook Network_END
|
||||
call PrintText
|
||||
ld hl, wd72e
|
||||
res 6, [hl]
|
||||
|
@ -37,20 +37,23 @@ LoadSAV0:
|
||||
ld a, $1
|
||||
ld [MBC1SRamBankingMode], a
|
||||
ld [MBC1SRamBank], a
|
||||
ld hl, sPlayerName ; hero name located in SRAM
|
||||
ld bc, sMainDataCheckSum - sPlayerName ; but here checks the full SAV
|
||||
; This vc_hook does not have to be in any particular location.
|
||||
; It is defined here because it refers to the same labels as the two lines below.
|
||||
vc_hook SaveLimit
|
||||
ld hl, sGameData
|
||||
ld bc, sGameDataEnd - sGameData
|
||||
call SAVCheckSum
|
||||
ld c, a
|
||||
ld a, [sMainDataCheckSum] ; SAV's checksum
|
||||
ld a, [sMainDataCheckSum]
|
||||
cp c
|
||||
jp z, .checkSumsMatched
|
||||
|
||||
; If the computed checksum didn't match the saved on, try again.
|
||||
ld hl, sPlayerName
|
||||
ld bc, sMainDataCheckSum - sPlayerName
|
||||
ld hl, sGameData
|
||||
ld bc, sGameDataEnd - sGameData
|
||||
call SAVCheckSum
|
||||
ld c, a
|
||||
ld a, [sMainDataCheckSum] ; SAV's checksum
|
||||
ld a, [sMainDataCheckSum]
|
||||
cp c
|
||||
jp nz, SAVBadCheckSum
|
||||
|
||||
@ -84,11 +87,11 @@ LoadSAV1:
|
||||
ld a, $1
|
||||
ld [MBC1SRamBankingMode], a
|
||||
ld [MBC1SRamBank], a
|
||||
ld hl, sPlayerName ; hero name located in SRAM
|
||||
ld bc, sMainDataCheckSum - sPlayerName ; but here checks the full SAV
|
||||
ld hl, sGameData
|
||||
ld bc, sGameDataEnd - sGameData
|
||||
call SAVCheckSum
|
||||
ld c, a
|
||||
ld a, [sMainDataCheckSum] ; SAV's checksum
|
||||
ld a, [sMainDataCheckSum]
|
||||
cp c
|
||||
jr nz, SAVBadCheckSum
|
||||
ld hl, sCurBoxData
|
||||
@ -104,11 +107,11 @@ LoadSAV2:
|
||||
ld a, $1
|
||||
ld [MBC1SRamBankingMode], a
|
||||
ld [MBC1SRamBank], a
|
||||
ld hl, sPlayerName ; hero name located in SRAM
|
||||
ld bc, sMainDataCheckSum - sPlayerName ; but here checks the full SAV
|
||||
ld hl, sGameData
|
||||
ld bc, sGameDataEnd - sGameData
|
||||
call SAVCheckSum
|
||||
ld c, a
|
||||
ld a, [sMainDataCheckSum] ; SAV's checksum
|
||||
ld a, [sMainDataCheckSum]
|
||||
cp c
|
||||
jp nz, SAVBadCheckSum
|
||||
ld hl, sPartyData
|
||||
@ -219,8 +222,8 @@ SaveSAVtoSRAM0:
|
||||
call CopyData
|
||||
ldh a, [hTileAnimations]
|
||||
ld [sTileAnimations], a
|
||||
ld hl, sPlayerName
|
||||
ld bc, sMainDataCheckSum - sPlayerName
|
||||
ld hl, sGameData
|
||||
ld bc, sGameDataEnd - sGameData
|
||||
call SAVCheckSum
|
||||
ld [sMainDataCheckSum], a
|
||||
xor a
|
||||
@ -239,8 +242,8 @@ SaveSAVtoSRAM1:
|
||||
ld de, sCurBoxData
|
||||
ld bc, wBoxDataEnd - wBoxDataStart
|
||||
call CopyData
|
||||
ld hl, sPlayerName
|
||||
ld bc, sMainDataCheckSum - sPlayerName
|
||||
ld hl, sGameData
|
||||
ld bc, sGameDataEnd - sGameData
|
||||
call SAVCheckSum
|
||||
ld [sMainDataCheckSum], a
|
||||
xor a
|
||||
@ -262,8 +265,8 @@ SaveSAVtoSRAM2:
|
||||
ld de, sMainData
|
||||
ld bc, wPokedexSeenEnd - wPokedexOwned
|
||||
call CopyData
|
||||
ld hl, sPlayerName
|
||||
ld bc, sMainDataCheckSum - sPlayerName
|
||||
ld hl, sGameData
|
||||
ld bc, sGameDataEnd - sGameData
|
||||
call SAVCheckSum
|
||||
ld [sMainDataCheckSum], a
|
||||
xor a
|
||||
@ -612,8 +615,8 @@ SAVCheckRandomID:
|
||||
ld a, [sPlayerName]
|
||||
and a
|
||||
jr z, .next
|
||||
ld hl, sPlayerName
|
||||
ld bc, sMainDataCheckSum - sPlayerName
|
||||
ld hl, sGameData
|
||||
ld bc, sGameDataEnd - sGameData
|
||||
call SAVCheckSum
|
||||
ld c, a
|
||||
ld a, [sMainDataCheckSum]
|
||||
|
@ -230,6 +230,7 @@ Serial_PrintWaitingTextAndSyncAndExchangeNybble::
|
||||
jp LoadScreenTilesFromBuffer1
|
||||
|
||||
Serial_SyncAndExchangeNybble::
|
||||
vc_hook send_send_buf2
|
||||
ld a, $ff
|
||||
ld [wSerialExchangeNybbleReceiveData], a
|
||||
.loop1
|
||||
@ -253,13 +254,25 @@ Serial_SyncAndExchangeNybble::
|
||||
ld a, [wSerialExchangeNybbleReceiveData]
|
||||
inc a
|
||||
jr z, .loop1
|
||||
vc_patch Network10
|
||||
IF DEF(_RED_VC) || DEF(_BLUE_VC)
|
||||
ld b, 26
|
||||
ELSE
|
||||
ld b, 10
|
||||
ENDC
|
||||
vc_patch_end
|
||||
.loop2
|
||||
call DelayFrame
|
||||
call Serial_ExchangeNybble
|
||||
dec b
|
||||
jr nz, .loop2
|
||||
vc_patch Network11
|
||||
IF DEF(_RED_VC) || DEF(_BLUE_VC)
|
||||
ld b, 26
|
||||
ELSE
|
||||
ld b, 10
|
||||
ENDC
|
||||
vc_patch_end
|
||||
.loop3
|
||||
call DelayFrame
|
||||
call Serial_SendZeroByte
|
||||
@ -267,6 +280,7 @@ Serial_SyncAndExchangeNybble::
|
||||
jr nz, .loop3
|
||||
ld a, [wSerialExchangeNybbleReceiveData]
|
||||
ld [wSerialSyncAndExchangeNybbleReceiveData], a
|
||||
vc_hook send_send_buf2_ret
|
||||
ret
|
||||
|
||||
Serial_ExchangeNybble::
|
||||
|
@ -6,6 +6,7 @@ INCLUDE "macros/data.asm"
|
||||
INCLUDE "macros/code.asm"
|
||||
INCLUDE "macros/gfx.asm"
|
||||
INCLUDE "macros/coords.asm"
|
||||
INCLUDE "macros/vc.asm"
|
||||
|
||||
INCLUDE "macros/scripts/audio.asm"
|
||||
INCLUDE "macros/scripts/maps.asm"
|
||||
|
39
macros/vc.asm
Normal file
39
macros/vc.asm
Normal file
@ -0,0 +1,39 @@
|
||||
vc_hook: MACRO
|
||||
IF DEF(_RED_VC) || DEF(_BLUE_VC)
|
||||
.VC_\1::
|
||||
ENDC
|
||||
ENDM
|
||||
|
||||
vc_hook_red: MACRO
|
||||
IF DEF(_RED_VC)
|
||||
.VC_\1::
|
||||
ENDC
|
||||
ENDM
|
||||
|
||||
vc_hook_blue: MACRO
|
||||
IF DEF(_BLUE_VC)
|
||||
.VC_\1::
|
||||
ENDC
|
||||
ENDM
|
||||
|
||||
vc_patch: MACRO
|
||||
IF DEF(_RED_VC) || DEF(_BLUE_VC)
|
||||
ASSERT !DEF(CURRENT_VC_PATCH), "Already started a vc_patch"
|
||||
CURRENT_VC_PATCH EQUS "\1"
|
||||
.VC_{CURRENT_VC_PATCH}::
|
||||
ENDC
|
||||
ENDM
|
||||
|
||||
vc_patch_end: MACRO
|
||||
IF DEF(_RED_VC) || DEF(_BLUE_VC)
|
||||
ASSERT DEF(CURRENT_VC_PATCH), "No vc_patch started"
|
||||
.VC_{CURRENT_VC_PATCH}_End::
|
||||
PURGE CURRENT_VC_PATCH
|
||||
ENDC
|
||||
ENDM
|
||||
|
||||
vc_assert: MACRO
|
||||
IF DEF(_RED_VC) || DEF(_BLUE_VC)
|
||||
ASSERT \#
|
||||
ENDC
|
||||
ENDM
|
@ -1,3 +1,5 @@
|
||||
ea9bcae617fdf159b045185467ae58b2e4a48b9a *pokered.gbc
|
||||
d7037c83e1ae5b39bde3c30787637ba1d4c48ce2 *pokeblue.gbc
|
||||
5b1456177671b79b263c614ea0e7cc9ac542e9c4 *pokeblue_debug.gbc
|
||||
0fb5f743696adfe1dbb2e062111f08f9bc5a293a *pokered.patch
|
||||
ed4be94dc29c64271942c87f2157bca9ca1019c7 *pokeblue.patch
|
||||
|
2
sram.asm
2
sram.asm
@ -13,12 +13,14 @@ SECTION "Save Data", SRAM
|
||||
|
||||
ds $598
|
||||
|
||||
sGameData::
|
||||
sPlayerName:: ds NAME_LENGTH
|
||||
sMainData:: ds wMainDataEnd - wMainDataStart
|
||||
sSpriteData:: ds wSpriteDataEnd - wSpriteDataStart
|
||||
sPartyData:: ds wPartyDataEnd - wPartyDataStart
|
||||
sCurBoxData:: ds wBoxDataEnd - wBoxDataStart
|
||||
sTileAnimations:: db
|
||||
sGameDataEnd::
|
||||
sMainDataCheckSum:: db
|
||||
|
||||
|
||||
|
3
tools/.gitignore
vendored
3
tools/.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
scan_includes
|
||||
gfx
|
||||
make_patch
|
||||
pkmncompress
|
||||
scan_includes
|
||||
|
@ -5,6 +5,7 @@ CFLAGS := -O3 -flto -std=c11 -Wall -Wextra -pedantic
|
||||
|
||||
tools := \
|
||||
gfx \
|
||||
make_patch \
|
||||
pkmncompress \
|
||||
scan_includes
|
||||
|
||||
|
469
tools/make_patch.c
Normal file
469
tools/make_patch.c
Normal file
@ -0,0 +1,469 @@
|
||||
#define PROGRAM_NAME "make_patch"
|
||||
#define USAGE_OPTS "labels.sym constants.sym patched.gbc original.gbc vc.patch.template vc.patch"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
struct Buffer {
|
||||
size_t item_size;
|
||||
size_t size;
|
||||
size_t capacity;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct Symbol {
|
||||
struct Symbol *next;
|
||||
unsigned int address;
|
||||
unsigned int offset;
|
||||
char name[]; // C99 FAM
|
||||
};
|
||||
|
||||
struct Patch {
|
||||
unsigned int offset;
|
||||
unsigned int size;
|
||||
};
|
||||
|
||||
struct Buffer *buffer_create(size_t item_size) {
|
||||
struct Buffer *buffer = xmalloc(sizeof(*buffer));
|
||||
buffer->item_size = item_size;
|
||||
buffer->size = 0;
|
||||
buffer->capacity = 0x10;
|
||||
buffer->data = xmalloc(buffer->capacity * item_size);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void buffer_append(struct Buffer *buffer, const void *item) {
|
||||
if (buffer->size >= buffer->capacity) {
|
||||
buffer->capacity = (buffer->capacity + 1) * 2;
|
||||
buffer->data = xrealloc(buffer->data, buffer->capacity * buffer->item_size);
|
||||
}
|
||||
memcpy((char *)buffer->data + (buffer->size++ * buffer->item_size), item, buffer->item_size);
|
||||
}
|
||||
|
||||
void buffer_free(struct Buffer *buffer) {
|
||||
free(buffer->data);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
void symbol_append(struct Symbol **symbols, const char *name, int bank, int address) {
|
||||
size_t name_len = strlen(name) + 1;
|
||||
struct Symbol *symbol = xmalloc(sizeof(*symbol) + name_len);
|
||||
symbol->address = address;
|
||||
symbol->offset = address < 0x8000
|
||||
? (bank > 0 ? address + (bank - 1) * 0x4000 : address) // ROM addresses are relative to their bank
|
||||
: address - 0x8000; // RAM addresses are relative to the start of all RAM
|
||||
memcpy(symbol->name, name, name_len);
|
||||
symbol->next = *symbols;
|
||||
*symbols = symbol;
|
||||
}
|
||||
|
||||
void symbol_free(struct Symbol *symbols) {
|
||||
for (struct Symbol *next; symbols; symbols = next) {
|
||||
next = symbols->next;
|
||||
free(symbols);
|
||||
}
|
||||
}
|
||||
|
||||
const struct Symbol *symbol_find(const struct Symbol *symbols, const char *name) {
|
||||
size_t name_len = strlen(name);
|
||||
for (const struct Symbol *symbol = symbols; symbol; symbol = symbol->next) {
|
||||
size_t sym_name_len = strlen(symbol->name);
|
||||
if (name_len > sym_name_len) {
|
||||
continue;
|
||||
}
|
||||
const char *sym_name = symbol->name;
|
||||
if (name[0] == '.') {
|
||||
// If `name` is a local label, compare it to the local part of `symbol->name`
|
||||
sym_name += sym_name_len - name_len;
|
||||
}
|
||||
if (!strcmp(sym_name, name)) {
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
error_exit("Error: Unknown symbol: \"%s\"\n", name);
|
||||
}
|
||||
|
||||
const struct Symbol *symbol_find_cat(const struct Symbol *symbols, const char *prefix, const char *suffix) {
|
||||
char *sym_name = xmalloc(strlen(prefix) + strlen(suffix) + 1);
|
||||
sprintf(sym_name, "%s%s", prefix, suffix);
|
||||
const struct Symbol *symbol = symbol_find(symbols, sym_name);
|
||||
free(sym_name);
|
||||
return symbol;
|
||||
}
|
||||
|
||||
int parse_number(const char *input, int base) {
|
||||
char *endptr;
|
||||
int n = (int)strtol(input, &endptr, base);
|
||||
if (endptr == input || *endptr || n < 0) {
|
||||
error_exit("Error: Cannot parse number: \"%s\"\n", input);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
void parse_symbol_value(char *input, int *restrict bank, int *restrict address) {
|
||||
char *colon = strchr(input, ':');
|
||||
if (!colon) {
|
||||
error_exit("Error: Cannot parse bank+address: \"%s\"\n", input);
|
||||
}
|
||||
*colon++ = '\0';
|
||||
*bank = parse_number(input, 16);
|
||||
*address = parse_number(colon, 16);
|
||||
}
|
||||
|
||||
void parse_symbols(const char *filename, struct Symbol **symbols) {
|
||||
FILE *file = xfopen(filename, 'r');
|
||||
struct Buffer *buffer = buffer_create(1);
|
||||
|
||||
enum { SYM_PRE, SYM_VALUE, SYM_SPACE, SYM_NAME } state = SYM_PRE;
|
||||
int bank = 0;
|
||||
int address = 0;
|
||||
|
||||
for (;;) {
|
||||
int c = getc(file);
|
||||
if (c == EOF || c == '\n' || c == '\r' || c == ';' || (state == SYM_NAME && (c == ' ' || c == '\t'))) {
|
||||
if (state == SYM_NAME) {
|
||||
// The symbol name has ended; append the buffered symbol
|
||||
buffer_append(buffer, &(char []){'\0'});
|
||||
symbol_append(symbols, buffer->data, bank, address);
|
||||
}
|
||||
// Skip to the next line, ignoring anything after the symbol value and name
|
||||
state = SYM_PRE;
|
||||
while (c != EOF && c != '\n' && c != '\r') {
|
||||
c = getc(file);
|
||||
}
|
||||
if (c == EOF) {
|
||||
break;
|
||||
}
|
||||
} else if (c != ' ' && c != '\t') {
|
||||
if (state == SYM_PRE || state == SYM_SPACE) {
|
||||
// The symbol value or name has started; buffer its contents
|
||||
if (++state == SYM_NAME) {
|
||||
// The symbol name has started; parse the buffered value
|
||||
buffer_append(buffer, &(char []){'\0'});
|
||||
parse_symbol_value(buffer->data, &bank, &address);
|
||||
}
|
||||
buffer->size = 0;
|
||||
}
|
||||
buffer_append(buffer, &c);
|
||||
} else if (state == SYM_VALUE) {
|
||||
// The symbol value has ended; wait to see if a name comes after it
|
||||
state = SYM_SPACE;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
buffer_free(buffer);
|
||||
}
|
||||
|
||||
int strfind(const char *s, const char *list[], int count) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (!strcmp(s, list[i])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define vstrfind(s, ...) strfind(s, (const char *[]){__VA_ARGS__}, sizeof (const char *[]){__VA_ARGS__} / sizeof(const char *))
|
||||
|
||||
int parse_arg_value(const char *arg, bool absolute, const struct Symbol *symbols, const char *patch_name) {
|
||||
// Comparison operators for "ConditionValueB" evaluate to their particular values
|
||||
int op = vstrfind(arg, "==", ">", "<", ">=", "<=", "!=", "||");
|
||||
if (op >= 0) {
|
||||
return op == 6 ? 0x11 : op; // "||" is 0x11
|
||||
}
|
||||
|
||||
// Literal numbers evaluate to themselves
|
||||
if (isdigit((unsigned)arg[0]) || arg[0] == '+') {
|
||||
return parse_number(arg, 0);
|
||||
}
|
||||
|
||||
// Symbols evaluate to their offset or address, plus an optional offset mod
|
||||
int offset_mod = 0;
|
||||
char *plus = strchr(arg, '+');
|
||||
if (plus) {
|
||||
offset_mod = parse_number(plus, 0);
|
||||
*plus = '\0';
|
||||
}
|
||||
const char *sym_name = !strcmp(arg, "@") ? patch_name : arg; // "@" is the current patch label
|
||||
const struct Symbol *symbol = symbol_find(symbols, sym_name);
|
||||
return (absolute ? symbol->offset : symbol->address) + offset_mod;
|
||||
}
|
||||
|
||||
void interpret_command(char *command, const struct Symbol *current_hook, const struct Symbol *symbols, struct Buffer *patches, FILE *restrict new_rom, FILE *restrict orig_rom, FILE *restrict output) {
|
||||
// Strip all leading spaces and all but one trailing space
|
||||
int x = 0;
|
||||
for (int i = 0; command[i]; i++) {
|
||||
if (!isspace((unsigned)command[i]) || (i > 0 && !isspace((unsigned)command[i - 1]))) {
|
||||
command[x++] = command[i];
|
||||
}
|
||||
}
|
||||
command[x - (x > 0 && isspace((unsigned)command[x - 1]))] = '\0';
|
||||
|
||||
// Count the arguments
|
||||
int argc = 0;
|
||||
for (const char *c = command; *c; c++) {
|
||||
if (isspace((unsigned)*c)) {
|
||||
argc++;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the arguments
|
||||
char *argv[argc]; // VLA
|
||||
char *arg = command;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
while (*arg && !isspace((unsigned)*arg)) {
|
||||
arg++;
|
||||
}
|
||||
if (!*arg) {
|
||||
break;
|
||||
}
|
||||
*arg++ = '\0';
|
||||
argv[i] = arg;
|
||||
}
|
||||
|
||||
// Use the arguments
|
||||
if (vstrfind(command, "patch", "PATCH", "patch_", "PATCH_", "patch/", "PATCH/") >= 0) {
|
||||
if (argc > 2) {
|
||||
error_exit("Error: Invalid arguments for command: \"%s\"\n", command);
|
||||
}
|
||||
if (!current_hook) {
|
||||
error_exit("Error: No current patch for command: \"%s\"\n", command);
|
||||
}
|
||||
int current_offset = current_hook->offset + (argc > 0 ? parse_number(argv[0], 0) : 0);
|
||||
if (fseek(orig_rom, current_offset, SEEK_SET)) {
|
||||
error_exit("Error: Cannot seek to \"vc_patch %s\" in the original ROM\n", current_hook->name);
|
||||
}
|
||||
if (fseek(new_rom, current_offset, SEEK_SET)) {
|
||||
error_exit("Error: Cannot seek to \"vc_patch %s\" in the new ROM\n", current_hook->name);
|
||||
}
|
||||
int length;
|
||||
if (argc == 2) {
|
||||
length = parse_number(argv[1], 0);
|
||||
} else {
|
||||
const struct Symbol *current_hook_end = symbol_find_cat(symbols, current_hook->name, "_End");
|
||||
length = current_hook_end->offset - current_offset;
|
||||
}
|
||||
buffer_append(patches, &(struct Patch){current_offset, length});
|
||||
bool modified = false;
|
||||
if (length == 1) {
|
||||
int c = getc(new_rom);
|
||||
modified = c != getc(orig_rom);
|
||||
fprintf(output, isupper((unsigned)command[0]) ? "0x%02X" : "0x%02x", c);
|
||||
} else {
|
||||
if (command[strlen(command) - 1] != '/') {
|
||||
fprintf(output, command[strlen(command) - 1] == '_' ? "a%d: " : "a%d:", length);
|
||||
}
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (i) {
|
||||
putc(' ', output);
|
||||
}
|
||||
int c = getc(new_rom);
|
||||
modified |= c != getc(orig_rom);
|
||||
fprintf(output, isupper((unsigned)command[0]) ? "%02X" : "%02x", c);
|
||||
}
|
||||
}
|
||||
if (!modified) {
|
||||
fprintf(stderr, PROGRAM_NAME ": Warning: \"vc_patch %s\" doesn't alter the ROM\n", current_hook->name);
|
||||
}
|
||||
|
||||
} else if (vstrfind(command, "dws", "DWS", "dws_", "DWS_", "dws/", "DWS/") >= 0) {
|
||||
if (argc < 1) {
|
||||
error_exit("Error: Invalid arguments for command: \"%s\"\n", command);
|
||||
}
|
||||
if (command[strlen(command) - 1] != '/') {
|
||||
fprintf(output, command[strlen(command) - 1] == '_' ? "a%d: " : "a%d:", argc * 2);
|
||||
}
|
||||
for (int i = 0; i < argc; i++) {
|
||||
int value = parse_arg_value(argv[i], false, symbols, current_hook->name);
|
||||
if (value > 0xffff) {
|
||||
error_exit("Error: Invalid value for \"%s\" argument: 0x%x\n", command, value);
|
||||
}
|
||||
if (i) {
|
||||
putc(' ', output);
|
||||
}
|
||||
fprintf(output, isupper((unsigned)command[0]) ? "%02X %02X": "%02x %02x", value & 0xff, value >> 8);
|
||||
}
|
||||
|
||||
} else if (vstrfind(command, "db", "DB", "db_", "DB_", "db/", "DB/") >= 0) {
|
||||
if (argc != 1) {
|
||||
error_exit("Error: Invalid arguments for command: \"%s\"\n", command);
|
||||
}
|
||||
int value = parse_arg_value(argv[0], false, symbols, current_hook->name);
|
||||
if (value > 0xff) {
|
||||
error_exit("Error: Invalid value for \"%s\" argument: 0x%x\n", command, value);
|
||||
}
|
||||
if (command[strlen(command) - 1] != '/') {
|
||||
fputs(command[strlen(command) - 1] == '_' ? "a1: " : "a1:", output);
|
||||
}
|
||||
fprintf(output, isupper((unsigned)command[0]) ? "%02X" : "%02x", value);
|
||||
|
||||
} else if (vstrfind(command, "hex", "HEX", "HEx", "Hex", "heX", "hEX", "hex~", "HEX~", "HEx~", "Hex~", "heX~", "hEX~") >= 0) {
|
||||
if (argc != 1 && argc != 2) {
|
||||
error_exit("Error: Invalid arguments for command: \"%s\"\n", command);
|
||||
}
|
||||
int value = parse_arg_value(argv[0], command[strlen(command) - 1] != '~', symbols, current_hook->name);
|
||||
int padding = argc > 1 ? parse_number(argv[1], 0) : 2;
|
||||
if (vstrfind(command, "HEx", "HEx~") >= 0) {
|
||||
fprintf(output, "0x%0*X%02x", padding - 2, value >> 8, value & 0xff);
|
||||
} else if (vstrfind(command, "Hex", "Hex~") >= 0) {
|
||||
fprintf(output, "0x%0*X%03x", padding - 3, value >> 12, value & 0xfff);
|
||||
} else if (vstrfind(command, "heX", "heX~") >= 0) {
|
||||
fprintf(output, "0x%0*x%02X", padding - 2, value >> 8, value & 0xff);
|
||||
} else if (vstrfind(command, "hEX", "hEX~") >= 0) {
|
||||
fprintf(output, "0x%0*x%03X", padding - 3, value >> 12, value & 0xfff);
|
||||
} else {
|
||||
fprintf(output, isupper((unsigned)command[0]) ? "0x%0*X" : "0x%0*x", padding, value);
|
||||
}
|
||||
|
||||
} else {
|
||||
error_exit("Error: Unknown command: \"%s\"\n", command);
|
||||
}
|
||||
}
|
||||
|
||||
void skip_to_next_line(FILE *restrict input, FILE *restrict output) {
|
||||
for (int c = getc(input); c != EOF; c = getc(input)) {
|
||||
putc(c, output);
|
||||
if (c == '\n' || c == '\r') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Buffer *process_template(const char *template_filename, const char *patch_filename, FILE *restrict new_rom, FILE *restrict orig_rom, const struct Symbol *symbols) {
|
||||
FILE *input = xfopen(template_filename, 'r');
|
||||
FILE *output = xfopen(patch_filename, 'w');
|
||||
|
||||
struct Buffer *patches = buffer_create(sizeof(struct Patch));
|
||||
struct Buffer *buffer = buffer_create(1);
|
||||
|
||||
// The ROM checksum will always differ
|
||||
buffer_append(patches, &(struct Patch){0x14e, 2});
|
||||
// The Stadium data (see stadium.c) will always differ
|
||||
unsigned int rom_size = (unsigned int)xfsize("", orig_rom);
|
||||
unsigned int stadium_size = 24 + 6 + 2 + (rom_size / 0x2000) * 2;
|
||||
buffer_append(patches, &(struct Patch){rom_size - stadium_size, stadium_size});
|
||||
|
||||
// Fill in the template
|
||||
const struct Symbol *current_hook = NULL;
|
||||
for (int c = getc(input); c != EOF; c = getc(input)) {
|
||||
switch (c) {
|
||||
case ';':
|
||||
// ";" comments until the end of the line
|
||||
putc(c, output);
|
||||
skip_to_next_line(input, output);
|
||||
break;
|
||||
|
||||
case '{':
|
||||
// "{...}" is a template command; buffer its contents
|
||||
buffer->size = 0;
|
||||
for (c = getc(input); c != EOF && c != '}'; c = getc(input)) {
|
||||
buffer_append(buffer, &c);
|
||||
}
|
||||
buffer_append(buffer, &(char []){'\0'});
|
||||
// Interpret the command in the context of the current patch
|
||||
interpret_command(buffer->data, current_hook, symbols, patches, new_rom, orig_rom, output);
|
||||
break;
|
||||
|
||||
case '[':
|
||||
// "[...]" is a patch label; buffer its contents
|
||||
putc(c, output);
|
||||
bool alternate = false;
|
||||
buffer->size = 0;
|
||||
for (c = getc(input); c != EOF; c = getc(input)) {
|
||||
if (!alternate && c == '@') {
|
||||
// "@" designates an alternate name for the ".VC_" label
|
||||
alternate = true;
|
||||
buffer->size = 0;
|
||||
} else if (c == ']') {
|
||||
putc(c, output);
|
||||
break;
|
||||
} else {
|
||||
if (!alternate) {
|
||||
putc(c, output);
|
||||
if (!isalnum(c) && c != '_') {
|
||||
// Convert non-identifier characters to underscores
|
||||
c = '_';
|
||||
}
|
||||
}
|
||||
buffer_append(buffer, &c);
|
||||
}
|
||||
}
|
||||
buffer_append(buffer, &(char []){'\0'});
|
||||
// The current patch should have a corresponding ".VC_" label
|
||||
current_hook = symbol_find_cat(symbols, ".VC_", buffer->data);
|
||||
skip_to_next_line(input, output);
|
||||
break;
|
||||
|
||||
default:
|
||||
putc(c, output);
|
||||
}
|
||||
}
|
||||
|
||||
rewind(orig_rom);
|
||||
rewind(new_rom);
|
||||
|
||||
fclose(input);
|
||||
fclose(output);
|
||||
buffer_free(buffer);
|
||||
return patches;
|
||||
}
|
||||
|
||||
int compare_patch(const void *patch1, const void *patch2) {
|
||||
unsigned int offset1 = ((const struct Patch *)patch1)->offset;
|
||||
unsigned int offset2 = ((const struct Patch *)patch2)->offset;
|
||||
return offset1 > offset2 ? 1 : offset1 < offset2 ? -1 : 0;
|
||||
}
|
||||
|
||||
bool verify_completeness(FILE *restrict orig_rom, FILE *restrict new_rom, struct Buffer *patches) {
|
||||
qsort(patches->data, patches->size, patches->item_size, compare_patch);
|
||||
for (unsigned int offset = 0, index = 0; ; offset++) {
|
||||
int orig_byte = getc(orig_rom);
|
||||
int new_byte = getc(new_rom);
|
||||
if (orig_byte == EOF || new_byte == EOF) {
|
||||
return orig_byte == new_byte;
|
||||
}
|
||||
struct Patch *patch = &((struct Patch *)patches->data)[index];
|
||||
if (index < patches->size && patch->offset == offset) {
|
||||
if (fseek(orig_rom, patch->size, SEEK_CUR)) {
|
||||
return false;
|
||||
}
|
||||
if (fseek(new_rom, patch->size, SEEK_CUR)) {
|
||||
return false;
|
||||
}
|
||||
offset += patch->size;
|
||||
index++;
|
||||
} else if (orig_byte != new_byte) {
|
||||
fprintf(stderr, PROGRAM_NAME ": Warning: Unpatched difference at offset: 0x%x\n", offset);
|
||||
fprintf(stderr, " Original ROM value: 0x%02x\n", orig_byte);
|
||||
fprintf(stderr, " Patched ROM value: 0x%02x\n", new_byte);
|
||||
fprintf(stderr, " Current patch offset: 0x%06x\n", patch->offset);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc != 7) {
|
||||
usage_exit(1);
|
||||
}
|
||||
|
||||
struct Symbol *symbols = NULL;
|
||||
parse_symbols(argv[1], &symbols);
|
||||
parse_symbols(argv[2], &symbols);
|
||||
|
||||
FILE *new_rom = xfopen(argv[3], 'r');
|
||||
FILE *orig_rom = xfopen(argv[4], 'r');
|
||||
struct Buffer *patches = process_template(argv[5], argv[6], new_rom, orig_rom, symbols);
|
||||
|
||||
if (!verify_completeness(orig_rom, new_rom, patches)) {
|
||||
fprintf(stderr, PROGRAM_NAME ": Warning: Not all ROM differences are defined by \"%s\"\n", argv[6]);
|
||||
}
|
||||
|
||||
symbol_free(symbols);
|
||||
fclose(new_rom);
|
||||
fclose(orig_rom);
|
||||
buffer_free(patches);
|
||||
return 0;
|
||||
}
|
71
vc/pokeblue.constants.asm
Normal file
71
vc/pokeblue.constants.asm
Normal file
@ -0,0 +1,71 @@
|
||||
INCLUDE "constants.asm"
|
||||
|
||||
; These are all the asm constants needed to make the blue_vc patch.
|
||||
|
||||
vc_const: MACRO
|
||||
x = \1
|
||||
PRINTLN "00:{04x:x} \1" ; same format as rgblink's .sym file
|
||||
ENDM
|
||||
|
||||
; [FPA 001 Begin]
|
||||
vc_const "M"
|
||||
vc_const "E"
|
||||
vc_const "G"
|
||||
vc_const "A"
|
||||
vc_const "P"
|
||||
vc_const "S"
|
||||
vc_const "L"
|
||||
vc_const "F"
|
||||
vc_const "X"
|
||||
vc_const MEGA_PUNCH
|
||||
|
||||
; [FPA 001 End]
|
||||
vc_const EXPLOSION
|
||||
|
||||
; [FPA 002 Begin]
|
||||
vc_const "U"
|
||||
vc_const "I"
|
||||
vc_const GUILLOTINE
|
||||
|
||||
; [FPA 002 End]
|
||||
vc_const "K"
|
||||
vc_const MEGA_KICK
|
||||
|
||||
; [FPA 004 Begin]
|
||||
vc_const "B"
|
||||
vc_const "Z"
|
||||
vc_const BLIZZARD
|
||||
|
||||
; [FPA 005 Begin]
|
||||
vc_const BUBBLEBEAM
|
||||
|
||||
; [FPA 005 End]
|
||||
vc_const HYPER_BEAM
|
||||
|
||||
; [FPA 006 Begin]
|
||||
vc_const "H"
|
||||
vc_const "Y"
|
||||
|
||||
; [FPA 007 Begin]
|
||||
vc_const "T"
|
||||
vc_const "N"
|
||||
vc_const THUNDERBOLT
|
||||
|
||||
; [FPA 008 Begin]
|
||||
vc_const "R"
|
||||
vc_const REFLECT
|
||||
|
||||
; [FPA 009 Begin]
|
||||
vc_const SELFDESTRUCT
|
||||
|
||||
; [FPA 010 Begin]
|
||||
vc_const "D"
|
||||
vc_const DREAM_EATER
|
||||
|
||||
; [FPA 011 Begin]
|
||||
vc_const "O"
|
||||
vc_const SPORE
|
||||
|
||||
; [FPA 012 Begin]
|
||||
vc_const "C"
|
||||
vc_const ROCK_SLIDE
|
436
vc/pokeblue.patch.template
Normal file
436
vc/pokeblue.patch.template
Normal file
@ -0,0 +1,436 @@
|
||||
;Format Sample
|
||||
;[xxxx] ;User-defined Name (Max:31 chars)
|
||||
;Mode = 1 ;1:Fixcode; 2:Fixvalue; 3:Mask; 4:Palette; 5:Double Frame Buffer
|
||||
;Type = 0 ;0:Begin 1:End
|
||||
;Index = 0 ;Index
|
||||
;Address = x1F8000 ;ROM Address
|
||||
;MemAddress = x2000 ;RAM Address
|
||||
;Fixcode = 0 ;Mode1: Fixed Rom Code; Mode2: Fixed Value
|
||||
;DelayFrame = 0 ;Delay Frame
|
||||
;FadeFrame = 0 ;Fade Frame 0:Off
|
||||
;DarkEnable0 = 0 ;0:Off, 1:On (for Normal Mode)
|
||||
;ReduceEnable0 = 0 ;0:Off, 1:On (for Normal Mode)
|
||||
;MotionBEnable0 = 0 ;0:Off, 1:Black Fade, 2:, 3:Frame Blend (for Normal Mode)
|
||||
;Dark0 = 10 ;0~10 (for Normal Mode)
|
||||
;ReduceColorR0 = 0 ;0~31 (for Normal Mode)
|
||||
;ReduceColorG0 = 0 ;0~31 (for Normal Mode)
|
||||
;ReduceColorB0 = 0 ;0~31 (for Normal Mode)
|
||||
;MotionBlur0 = 31 ;0~31 (for Normal Mode)
|
||||
;DarkEnable1 = 0 ;0:Off, 1:On (for Green Mode)
|
||||
;ReduceEnable1 = 0 ;0:Off, 1:On (for Green Mode)
|
||||
;MotionBEnable1 = 0 ;0:Off, 1:Black Fade, 2:, 3:Frame Blend (for Green Mode)
|
||||
;Dark1 = 10 ;0~10 (for Green Mode)
|
||||
;ReduceColorR1 = 0 ;0~31 (for Green Mode)
|
||||
;ReduceColorG1 = 0 ;0~31 (for Green Mode)
|
||||
;ReduceColorB1 = 0 ;0~31 (for Green Mode)
|
||||
;MotionBlur1 = 31 ;0~31 (for Green Mode)
|
||||
;PaletteX = c31,31,31 ;X:0~15, cR,G,B (0~31)
|
||||
[SaveLimit]
|
||||
Mode = 12
|
||||
Type = 1
|
||||
Index = {hex sGameData}
|
||||
Address = {hex sGameDataEnd}
|
||||
|
||||
[send_send_buf2]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 29
|
||||
|
||||
[send_send_buf2_ret]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 30
|
||||
|
||||
[send_byt2]
|
||||
Mode = 2
|
||||
Address = {HEX @+5}
|
||||
Type = 31
|
||||
|
||||
[send_byt2_ret]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 32
|
||||
|
||||
[send_dummy]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 33
|
||||
|
||||
[send_dummy_end]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 34
|
||||
|
||||
[FIGHT]
|
||||
Mode = 1
|
||||
Address = {HEX @+1}
|
||||
Fixcode = {PATCH +1}
|
||||
|
||||
[FIGHT2]
|
||||
Mode = 1
|
||||
Address = {HEX @+1}
|
||||
Fixcode = {PATCH +1}
|
||||
|
||||
[Network10]
|
||||
Mode = 1
|
||||
Address = {HEX @+1}
|
||||
Fixcode = {PATCH +1}
|
||||
|
||||
[Network11]
|
||||
Mode = 1
|
||||
Address = {HEX @+1}
|
||||
Fixcode = {PATCH +1}
|
||||
|
||||
[Network17]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 5
|
||||
|
||||
[Network424]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 4
|
||||
|
||||
[Network200]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 4
|
||||
|
||||
[Network_RECHECK]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 7
|
||||
|
||||
[Network_STOP]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 8
|
||||
|
||||
[Network_END]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 9
|
||||
|
||||
[Network_RESET]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 10
|
||||
|
||||
[linkCable fake begin]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 16
|
||||
|
||||
[linkCable fake end]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 17
|
||||
|
||||
[linkCable block input]
|
||||
Mode = 2
|
||||
Address = {HEX @+5}
|
||||
Type = 18
|
||||
|
||||
;[save game start]
|
||||
;Mode = 2
|
||||
;Address = 0x59E6
|
||||
;Type = 19
|
||||
|
||||
[save game end]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 20
|
||||
|
||||
[Change_MSG]
|
||||
Mode = 1
|
||||
Address = {HEX @+1}
|
||||
Fixcode = {PATCH_ +1 20}
|
||||
|
||||
[fight_ret]
|
||||
Mode = 1
|
||||
Address = {HEX @}
|
||||
Fixcode = {PATCH}
|
||||
|
||||
[fight_ret_c]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 98
|
||||
|
||||
;rsm003758
|
||||
;No151
|
||||
[FPA 001 Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {HEX @}
|
||||
MotionBEnable0 = 3
|
||||
MotionBlur0 = 27
|
||||
ConditionType = 11
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wStringBuffer+5 wAnimationID 00 wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID 00 wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == == || == == == == == || == == == == == }
|
||||
ConditionValueC = {dws_ "M" "E" "G" "A" "P" MEGA_PUNCH 00 "S" "E" "L" "F" MEGA_PUNCH 00 "E" "X" "P" "L" MEGA_PUNCH }
|
||||
|
||||
[FPA 001 End]
|
||||
Mode = 3
|
||||
Type = 1
|
||||
Address = {HEX @}
|
||||
ConditionType = 11
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wStringBuffer+5 wAnimationID 00 wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID 00 wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == == || == == == == == || == == == == == }
|
||||
ConditionValueC = {dws_ "M" "E" "G" "A" "P" MEGA_PUNCH 00 "E" "X" "P" "L" EXPLOSION 00 "E" "X" "P" "L" MEGA_PUNCH }
|
||||
|
||||
|
||||
|
||||
;rsm141151
|
||||
;No117
|
||||
[FPA 002 Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {HEX @}
|
||||
MotionBEnable0 = 3
|
||||
MotionBlur0 = 9
|
||||
MotionBEnable1 = 3
|
||||
MotionBlur1 = 8
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "G" "U" "I" "L" GUILLOTINE }
|
||||
|
||||
[FPA 002 End]
|
||||
Mode = 3
|
||||
Type = 1
|
||||
Address = {HEX @}
|
||||
ConditionType = 11
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID 00 wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wStringBuffer+5 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == || == == == == == == }
|
||||
ConditionValueC = {dws_ "G" "U" "I" "L" GUILLOTINE 00 "M" "E" "G" "A" "K" MEGA_KICK }
|
||||
|
||||
|
||||
|
||||
;rsm143918
|
||||
;No150
|
||||
[FPA 003 Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {HEX @}
|
||||
MotionBEnable0 = 3
|
||||
MotionBlur0 = 25
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wStringBuffer+5 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == == }
|
||||
ConditionValueC = {dws_ "M" "E" "G" "A" "K" MEGA_KICK }
|
||||
|
||||
|
||||
|
||||
;rsm152422
|
||||
;No131
|
||||
[FPA 004 Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {HEX @}
|
||||
MotionBEnable0 = 3
|
||||
MotionBlur0 = 25
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "B" "L" "I" "Z" BLIZZARD }
|
||||
|
||||
|
||||
;rsm160334
|
||||
;No123
|
||||
[FPA 005 Begin@FPA_Bubblebeam_Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {hex @}
|
||||
MotionBEnable0 = 3
|
||||
MotionBlur0 = 27
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "B" "U" "B" "B" BUBBLEBEAM }
|
||||
|
||||
[FPA 005 End]
|
||||
Mode = 3
|
||||
Type = 1
|
||||
Address = {HEX @}
|
||||
ConditionType = 11
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID 00 wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID 00 wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == || == == == == == || == == == == == }
|
||||
ConditionValueC = {dws_ "B" "U" "B" "B" BUBBLEBEAM 00 "H" "Y" "P" "E" HYPER_BEAM 00 "B" "L" "I" "Z" BLIZZARD }
|
||||
|
||||
|
||||
;rsm163356
|
||||
;No116
|
||||
[FPA 006 Begin@FPA_Hyper_Beam_Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {HEX @}
|
||||
MotionBEnable0 = 1
|
||||
MotionBlur0 = 5
|
||||
MotionBEnable1 = 1
|
||||
MotionBlur1 = 5
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "H" "Y" "P" "E" HYPER_BEAM }
|
||||
|
||||
|
||||
|
||||
;rsm174631
|
||||
;No57
|
||||
[FPA 007 Begin@FPA_Thunderbolt_Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {HEX @}
|
||||
MotionBEnable0 = 3
|
||||
MotionBlur0 = 30
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "T" "H" "U" "N" THUNDERBOLT }
|
||||
|
||||
|
||||
[FPA 007 End@FPA_Thunderbolt_End]
|
||||
Mode = 3
|
||||
Type = 1
|
||||
Address = {HEX @}
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "T" "H" "U" "N" THUNDERBOLT }
|
||||
|
||||
|
||||
;rsm134518
|
||||
;No159
|
||||
[FPA 008 Begin@FPA_Reflect_Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {hex @}
|
||||
MotionBEnable0 = 1
|
||||
MotionBlur0 = 5
|
||||
MotionBEnable1 = 1
|
||||
MotionBlur1 = 5
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "R" "E" "F" "L" REFLECT }
|
||||
|
||||
[FPA 008 End]
|
||||
Mode = 3
|
||||
Type = 1
|
||||
Address = {HEX @}
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "R" "E" "F" "L" REFLECT }
|
||||
|
||||
|
||||
|
||||
|
||||
;rsm140510
|
||||
;No56
|
||||
[FPA 009 Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {HEX @}
|
||||
MotionBEnable0 = 3
|
||||
MotionBlur0 = 27
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "S" "E" "L" "F" SELFDESTRUCT}
|
||||
|
||||
[FPA 009 End]
|
||||
Mode = 3
|
||||
Type = 1
|
||||
Address = {HEX @}
|
||||
ConditionType = 11
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID 00 wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == || == == == == == }
|
||||
ConditionValueC = {dws_ "S" "E" "L" "F" MEGA_PUNCH 00 "S" "E" "L" "F" SELFDESTRUCT}
|
||||
|
||||
;rsm150211
|
||||
;No156
|
||||
[FPA 010 Begin@FPA_Dream_Eater_Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {hex @}
|
||||
MotionBEnable0 = 3
|
||||
MotionBlur0 = 10
|
||||
MotionBEnable1 = 3
|
||||
MotionBlur1 = 7
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "D" "R" "E" "A" DREAM_EATER }
|
||||
|
||||
;[FPA 010 End]
|
||||
;Mode = 3
|
||||
;Type = 1
|
||||
;Address = 0x78176
|
||||
;ConditionType = 0
|
||||
;ConditionValueA = a10: 4b cf 4c cf 4d cf 4e cf 7c d0
|
||||
;ConditionValueB = a10: 00 00 00 00 00 00 00 00 00 00
|
||||
;ConditionValueC = a10: 83 00 91 00 84 00 80 00 8a 00
|
||||
|
||||
;rsm163334
|
||||
;No36
|
||||
[FPA 011 Begin@FPA_Spore_Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {HEX @}
|
||||
MotionBEnable0 = 3
|
||||
MotionBlur0 = 8
|
||||
MotionBEnable1 = 3
|
||||
MotionBlur1 = 8
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "S" "P" "O" "R" SPORE }
|
||||
|
||||
[FPA 011 End]
|
||||
Mode = 3
|
||||
Type = 1
|
||||
Address = {hex @}
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "S" "P" "O" "R" SPORE }
|
||||
|
||||
;rsm012224
|
||||
;No12
|
||||
[FPA 012 Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {HEX @}
|
||||
MotionBEnable0 = 3
|
||||
MotionBlur0 = 27
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "R" "O" "C" "K" ROCK_SLIDE }
|
||||
|
||||
[FPA 012 End]
|
||||
Mode = 3
|
||||
Type = 1
|
||||
Address = {hex @}
|
||||
ConditionType = 11
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID 00 wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == || == == == == == }
|
||||
ConditionValueC = {dws_ "R" "O" "C" "K" ROCK_SLIDE 00 "D" "R" "E" "A" DREAM_EATER }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;explosion
|
||||
;No76
|
||||
[FPA 76 Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = 0x78186
|
||||
MotionBEnable0 = 3
|
||||
MotionBlur0 = 28
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "E" "X" "P" "L" EXPLOSION }
|
74
vc/pokered.constants.asm
Normal file
74
vc/pokered.constants.asm
Normal file
@ -0,0 +1,74 @@
|
||||
INCLUDE "constants.asm"
|
||||
|
||||
; These are all the asm constants needed to make the red_vc patch.
|
||||
|
||||
vc_const: MACRO
|
||||
x = \1
|
||||
PRINTLN "00:{04x:x} \1" ; same format as rgblink's .sym file
|
||||
ENDM
|
||||
|
||||
; [FPA 001 Begin]
|
||||
vc_const "M"
|
||||
vc_const "E"
|
||||
vc_const "G"
|
||||
vc_const "A"
|
||||
vc_const "P"
|
||||
vc_const "S"
|
||||
vc_const "L"
|
||||
vc_const "F"
|
||||
vc_const "D"
|
||||
vc_const "X"
|
||||
vc_const MEGA_PUNCH
|
||||
|
||||
; [FPA 002 Begin]
|
||||
vc_const "U"
|
||||
vc_const "I"
|
||||
vc_const GUILLOTINE
|
||||
|
||||
; [FPA 003 Begin]
|
||||
vc_const "K"
|
||||
vc_const MEGA_KICK
|
||||
|
||||
; [FPA 004 Begin]
|
||||
vc_const "B"
|
||||
vc_const BUBBLEBEAM
|
||||
|
||||
; [FPA 005 Begin]
|
||||
vc_const "H"
|
||||
vc_const "Y"
|
||||
vc_const HYPER_BEAM
|
||||
|
||||
; [FPA 006 Begin]
|
||||
vc_const "T"
|
||||
vc_const "N"
|
||||
vc_const THUNDERBOLT
|
||||
|
||||
; [FPA 007 Begin]
|
||||
vc_const "R"
|
||||
vc_const "F"
|
||||
vc_const REFLECT
|
||||
|
||||
; [FPA 008 Begin]
|
||||
vc_const DREAM_EATER
|
||||
|
||||
; [FPA 008 End]
|
||||
vc_const "Z"
|
||||
vc_const BLIZZARD
|
||||
|
||||
; [FPA 009 Begin]
|
||||
vc_const "O"
|
||||
vc_const SPORE
|
||||
|
||||
; [FPA 010 Begin]
|
||||
vc_const "C"
|
||||
vc_const ROCK_SLIDE
|
||||
|
||||
; [FPA 010 End]
|
||||
vc_const SELFDESTRUCT
|
||||
vc_const EXPLOSION
|
||||
|
||||
; [FPA conf Begin]
|
||||
vc_const CONFUSION
|
||||
|
||||
; [FPA phy Begin]
|
||||
vc_const PSYCHIC_M
|
482
vc/pokered.patch.template
Normal file
482
vc/pokered.patch.template
Normal file
@ -0,0 +1,482 @@
|
||||
;Format Sample
|
||||
;[xxxx] ;User-defined Name (Max:31 chars)
|
||||
;Mode = 1 ;1:Fixcode; 2:Fixvalue; 3:Mask; 4:Palette; 5:Double Frame Buffer
|
||||
;Type = 0 ;0:Begin 1:End
|
||||
;Index = 0 ;Index
|
||||
;Address = x1F8000 ;ROM Address
|
||||
;MemAddress = x2000 ;RAM Address
|
||||
;Fixcode = 0 ;Mode1: Fixed Rom Code; Mode2: Fixed Value
|
||||
;DelayFrame = 0 ;Delay Frame
|
||||
;FadeFrame = 0 ;Fade Frame 0:Off
|
||||
;DarkEnable0 = 0 ;0:Off, 1:On (for Normal Mode)
|
||||
;ReduceEnable0 = 0 ;0:Off, 1:On (for Normal Mode)
|
||||
;MotionBEnable0 = 0 ;0:Off, 1:Black Fade, 2:, 3:Frame Blend (for Normal Mode)
|
||||
;Dark0 = 10 ;0~10 (for Normal Mode)
|
||||
;ReduceColorR0 = 0 ;0~31 (for Normal Mode)
|
||||
;ReduceColorG0 = 0 ;0~31 (for Normal Mode)
|
||||
;ReduceColorB0 = 0 ;0~31 (for Normal Mode)
|
||||
;MotionBlur0 = 31 ;0~31 (for Normal Mode)
|
||||
;DarkEnable1 = 0 ;0:Off, 1:On (for Green Mode)
|
||||
;ReduceEnable1 = 0 ;0:Off, 1:On (for Green Mode)
|
||||
;MotionBEnable1 = 0 ;0:Off, 1:Black Fade, 2:, 3:Frame Blend (for Green Mode)
|
||||
;Dark1 = 10 ;0~10 (for Green Mode)
|
||||
;ReduceColorR1 = 0 ;0~31 (for Green Mode)
|
||||
;ReduceColorG1 = 0 ;0~31 (for Green Mode)
|
||||
;ReduceColorB1 = 0 ;0~31 (for Green Mode)
|
||||
;MotionBlur1 = 31 ;0~31 (for Green Mode)
|
||||
;PaletteX = c31,31,31 ;X:0~15, cR,G,B (0~31)
|
||||
[SaveLimit]
|
||||
Mode = 12
|
||||
Type = 1
|
||||
Index = {hex sGameData}
|
||||
Address = {hex sGameDataEnd}
|
||||
|
||||
;[Fix pokemon]
|
||||
;Mode = 2
|
||||
;Address = 0x1551
|
||||
;Type = 3
|
||||
|
||||
[send_send_buf2]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 29
|
||||
|
||||
[send_send_buf2_ret]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 30
|
||||
|
||||
[send_byt2]
|
||||
Mode = 2
|
||||
Address = {HEX @+5}
|
||||
Type = 31
|
||||
|
||||
[send_byt2_ret]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 32
|
||||
|
||||
[send_dummy]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 33
|
||||
|
||||
[send_dummy_end]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 34
|
||||
|
||||
[FIGHT]
|
||||
Mode = 1
|
||||
Address = {HEX @+1}
|
||||
Fixcode = {PATCH +1}
|
||||
|
||||
[FIGHT2]
|
||||
Mode = 1
|
||||
Address = {HEX @+1}
|
||||
Fixcode = {PATCH +1}
|
||||
|
||||
[Network10]
|
||||
Mode = 1
|
||||
Address = {HEX @+1}
|
||||
Fixcode = {PATCH +1}
|
||||
|
||||
[Network11]
|
||||
Mode = 1
|
||||
Address = {HEX @+1}
|
||||
Fixcode = {PATCH +1}
|
||||
|
||||
[Network17]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 5
|
||||
|
||||
[Network424]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 4
|
||||
|
||||
[Network200]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 4
|
||||
|
||||
[Network_RECHECK]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 7
|
||||
|
||||
[Network_STOP]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 8
|
||||
|
||||
[Network_END]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 9
|
||||
|
||||
[Network_RESET]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 10
|
||||
|
||||
[linkCable fake begin]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 16
|
||||
|
||||
[linkCable fake end]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 17
|
||||
|
||||
[linkCable block input]
|
||||
Mode = 2
|
||||
Address = {HEX @+5}
|
||||
Type = 18
|
||||
|
||||
;[save game start]
|
||||
;Mode = 2
|
||||
;Address = 0x59E6
|
||||
;Type = 19
|
||||
|
||||
[save game end]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 20
|
||||
|
||||
;93 A7 A4 7F AB A8 AD AA 7F A7
|
||||
;at 93
|
||||
[Change_MSG]
|
||||
Mode = 1
|
||||
Address = {HEX @+1}
|
||||
Fixcode = {PATCH_ +1 20}
|
||||
|
||||
[fight_ret]
|
||||
Mode = 1
|
||||
Address = {HEX @}
|
||||
Fixcode = {PATCH}
|
||||
|
||||
[fight_ret_c]
|
||||
Mode = 2
|
||||
Address = {HEX @}
|
||||
Type = 98
|
||||
|
||||
; The effect_no decide which animation will be played.
|
||||
; So we use it as a condition value. The address of effect_no is 0xd07c
|
||||
; a7 c0 3e 05 ea
|
||||
; and a A7
|
||||
; ret nz C0
|
||||
;
|
||||
; ld a,5 3E 05
|
||||
; ld (anime_buf),a EA
|
||||
;
|
||||
;
|
||||
;effect_select_rdy:
|
||||
; ld (effect_no),a
|
||||
;
|
||||
; call put_wait
|
||||
;
|
||||
; ld a,B_EFFECT_SELECT
|
||||
|
||||
|
||||
;rsm033659
|
||||
;no151 mega punch
|
||||
[FPA 001 Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {HEX @}
|
||||
MotionBEnable0 = 3
|
||||
MotionBlur0 = 21
|
||||
MotionBEnable1 = 3
|
||||
MotionBlur1 = 21
|
||||
ConditionType = 11
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wStringBuffer+5 wAnimationID 00 wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wStringBuffer+4 wAnimationID 00 wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == == || == == == == == == || == == == == == }
|
||||
ConditionValueC = {dws_ "M" "E" "G" "A" "P" MEGA_PUNCH 00 "S" "E" "L" "F" "D" MEGA_PUNCH 00 "E" "X" "P" "L" MEGA_PUNCH }
|
||||
|
||||
|
||||
[FPA 001 End]
|
||||
Mode = 3
|
||||
Type = 1
|
||||
Address = {HEX @}
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wStringBuffer+5 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == == }
|
||||
ConditionValueC = {dws_ "M" "E" "G" "A" "P" MEGA_PUNCH }
|
||||
|
||||
|
||||
;rsm032916
|
||||
;no117 guillotine
|
||||
[FPA 002 Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {HEX @}
|
||||
MotionBEnable0 = 3
|
||||
MotionBlur0 = 9
|
||||
MotionBEnable1 = 3
|
||||
MotionBlur1 = 8
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "G" "U" "I" "L" GUILLOTINE }
|
||||
|
||||
[FPA 002 End]
|
||||
Mode = 3
|
||||
Type = 1
|
||||
Address = {HEX @}
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "G" "U" "I" "L" GUILLOTINE }
|
||||
|
||||
|
||||
;rsm041307
|
||||
;no150 mega kick
|
||||
[FPA 003 Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {HEX @}
|
||||
MotionBEnable0 = 3
|
||||
MotionBlur0 = 25
|
||||
MotionBEnable1 = 3
|
||||
MotionBlur1 = 21
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wStringBuffer+5 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == == }
|
||||
ConditionValueC = {dws_ "M" "E" "G" "A" "K" MEGA_KICK }
|
||||
|
||||
|
||||
;rsm001929
|
||||
;no123 bubble beam
|
||||
[FPA 004 Begin@FPA_Bubblebeam_Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {hex @}
|
||||
MotionBEnable0 = 3
|
||||
MotionBlur0 = 30
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "B" "U" "B" "B" BUBBLEBEAM }
|
||||
|
||||
[FPA 004 End]
|
||||
Mode = 3
|
||||
Type = 1
|
||||
Address = {hex @}
|
||||
ConditionType = 11
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID 00 wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wStringBuffer+5 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == || == == == == == == }
|
||||
ConditionValueC = {dws_ "B" "U" "B" "B" BUBBLEBEAM 00 "M" "E" "G" "A" "K" MEGA_KICK }
|
||||
|
||||
|
||||
;rsm103658
|
||||
;no116 hyper beam
|
||||
[FPA 005 Begin@FPA_Hyper_Beam_Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {HEX @}
|
||||
MotionBEnable0 = 1
|
||||
MotionBlur0 = 5
|
||||
MotionBEnable1 = 1
|
||||
MotionBlur1 = 5
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "H" "Y" "P" "E" HYPER_BEAM }
|
||||
|
||||
[FPA 005 End]
|
||||
Mode = 3
|
||||
Type = 1
|
||||
Address = {HEX @}
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "H" "Y" "P" "E" HYPER_BEAM }
|
||||
|
||||
|
||||
;rsm133358
|
||||
;no57 thunderbolt
|
||||
[FPA 006 Begin@FPA_Thunderbolt_Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {HEX @}
|
||||
MotionBEnable0 = 3
|
||||
MotionBlur0 = 30
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "T" "H" "U" "N" THUNDERBOLT }
|
||||
|
||||
|
||||
[FPA 006 End@FPA_Thunderbolt_End]
|
||||
Mode = 3
|
||||
Type = 1
|
||||
Address = {HEX @}
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "T" "H" "U" "N" THUNDERBOLT }
|
||||
|
||||
;rsm152340
|
||||
;no159 reflect
|
||||
[FPA 007 Begin@FPA_Reflect_Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {hex @}
|
||||
MotionBEnable0 = 1
|
||||
MotionBlur0 = 6
|
||||
MotionBEnable1 = 1
|
||||
MotionBlur1 = 5
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "R" "E" "F" "L" REFLECT }
|
||||
|
||||
[FPA 007 End]
|
||||
Mode = 3
|
||||
Type = 1
|
||||
Address = {HEX @}
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "R" "E" "F" "L" REFLECT }
|
||||
|
||||
;rsm171812
|
||||
;no156 dream eater
|
||||
[FPA 008 Begin@FPA_Dream_Eater_Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {hex @}
|
||||
MotionBEnable0 = 3
|
||||
MotionBlur0 = 10
|
||||
MotionBEnable1 = 3
|
||||
MotionBlur1 = 7
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "D" "R" "E" "A" DREAM_EATER }
|
||||
|
||||
[FPA 008 End]
|
||||
Mode = 3
|
||||
Type = 1
|
||||
Address = {HEX @}
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wStringBuffer+4} {dws/ wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == } {dws/ == }
|
||||
ConditionValueC = {dws_ "B" "L" "I" "Z" "Z" } {dws/ BLIZZARD }
|
||||
|
||||
;rsm174650
|
||||
;no36 spore
|
||||
[FPA 009 Begin@FPA_Spore_Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {HEX @}
|
||||
MotionBEnable0 = 3
|
||||
MotionBlur0 = 8
|
||||
MotionBEnable1 = 3
|
||||
MotionBlur1 = 8
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "S" "P" "O" "R" SPORE }
|
||||
|
||||
|
||||
;rsm152115
|
||||
;no12 rock slide
|
||||
[FPA 010 Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {HEX @}
|
||||
MotionBEnable0 = 3
|
||||
MotionBlur0 = 27
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "R" "O" "C" "K" ROCK_SLIDE }
|
||||
|
||||
[FPA 010 End]
|
||||
Mode = 3
|
||||
Type = 1
|
||||
Address = {HEX @}
|
||||
ConditionType = 11
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID 00 wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID 00 wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID 00 wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wStringBuffer+4 wAnimationID 00 wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wStringBuffer+4 wAnimationID 00 wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wStringBuffer+5 wAnimationID 00 wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID 00 wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == || == == == == == || == == == == == || == == == == == == || == == == == == == || == == == == == == || == == == == == || == == == == == }
|
||||
ConditionValueC = {dws_ "D" "R" "E" "A" DREAM_EATER 00 "R" "O" "C" "K" ROCK_SLIDE 00 "S" "P" "O" "R" SPORE 00 "S" "E" "L" "F" "D" MEGA_PUNCH 00 "S" "E" "L" "F" "D" SELFDESTRUCT 00 "C" "O" "N" "F" "S" CONFUSION 00 "E" "X" "P" "L" EXPLOSION 00 "E" "X" "P" "L" MEGA_PUNCH }
|
||||
|
||||
|
||||
;explosion
|
||||
;No76 explosion
|
||||
[FPA 76 Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {HEX @}
|
||||
MotionBEnable0 = 3
|
||||
MotionBlur0 = 28
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == }
|
||||
ConditionValueC = {dws_ "E" "X" "P" "L" EXPLOSION }
|
||||
|
||||
|
||||
;No56 self-destruct
|
||||
[FPA 56 Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {HEX @}
|
||||
MotionBEnable0 = 3
|
||||
MotionBlur0 = 23
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wStringBuffer+4 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == == }
|
||||
ConditionValueC = {dws_ "S" "E" "L" "F" "D" SELFDESTRUCT}
|
||||
|
||||
|
||||
;No131 blizzard
|
||||
[FPA 131 Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {HEX @}
|
||||
MotionBEnable0 = 3
|
||||
MotionBlur0 = 26
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wStringBuffer+4 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == == }
|
||||
ConditionValueC = {dws_ "B" "L" "I" "Z" "Z" BLIZZARD }
|
||||
|
||||
|
||||
;confusion
|
||||
[FPA conf Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {hex @}
|
||||
MotionBEnable1 = 3
|
||||
MotionBlur1 = 21
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wStringBuffer+5 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == == }
|
||||
ConditionValueC = {dws_ "C" "O" "N" "F" "S" CONFUSION }
|
||||
|
||||
;phychic
|
||||
[FPA phy Begin]
|
||||
Mode = 3
|
||||
Type = 0
|
||||
Address = {hex @}
|
||||
MotionBEnable1 = 3
|
||||
MotionBlur1 = 21
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wStringBuffer+5 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == == }
|
||||
ConditionValueC = {dws_ "P" "S" "Y" "C" "I" PSYCHIC_M }
|
||||
|
||||
[FPA phy End]
|
||||
Mode = 3
|
||||
Type = 1
|
||||
Address = {hex @}
|
||||
ConditionType = 0
|
||||
ConditionValueA = {dws_ wStringBuffer wStringBuffer+1 wStringBuffer+2 wStringBuffer+3 wStringBuffer+5 wAnimationID}
|
||||
ConditionValueB = {dws_ == == == == == == }
|
||||
ConditionValueC = {dws_ "P" "S" "Y" "C" "I" PSYCHIC_M }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user