mirror of
https://gitlab.com/xCrystal/pokecrystal-board.git
synced 2024-11-16 11:27:33 -08:00
Sync with pokecrystal up to 8873506b1
This commit is contained in:
parent
193882bc77
commit
d6001be90c
44
README.md
44
README.md
@ -20,33 +20,35 @@ To set up the repository, see [INSTALL.md](INSTALL.md).
|
|||||||
- [**Documentation**][docs]
|
- [**Documentation**][docs]
|
||||||
- [**Wiki**][wiki] (includes [tutorials][tutorials])
|
- [**Wiki**][wiki] (includes [tutorials][tutorials])
|
||||||
- [**Symbols**][symbols]
|
- [**Symbols**][symbols]
|
||||||
- **Discord:** [pret][discord]
|
|
||||||
- **IRC:** [libera#pret][irc]
|
|
||||||
|
|
||||||
Other disassembly projects:
|
Other disassembly and/or decompilation projects:
|
||||||
|
* [**Pokémon Red and Blue**](https://github.com/pret/pokered)
|
||||||
|
* [**Pokémon Gold and Silver (Space World '97 demo)**](https://github.com/pret/pokegold-spaceworld)
|
||||||
|
* [**Pokémon Yellow**](https://github.com/pret/pokeyellow)
|
||||||
|
* [**Pokémon Trading Card Game**](https://github.com/pret/poketcg)
|
||||||
|
* [**Pokémon Pinball**](https://github.com/pret/pokepinball)
|
||||||
|
* [**Pokémon Stadium**](https://github.com/pret/pokestadium)
|
||||||
|
* [**Pokémon Gold and Silver**](https://github.com/pret/pokegold)
|
||||||
|
* [**Pokémon Ruby and Sapphire**](https://github.com/pret/pokeruby)
|
||||||
|
* [**Pokémon Pinball: Ruby & Sapphire**](https://github.com/pret/pokepinballrs)
|
||||||
|
* [**Pokémon FireRed and LeafGreen**](https://github.com/pret/pokefirered)
|
||||||
|
* [**Pokémon Emerald**](https://github.com/pret/pokeemerald)
|
||||||
|
* [**Pokémon Mystery Dungeon: Red Rescue Team**](https://github.com/pret/pmd-red)
|
||||||
|
* [**Pokémon Diamond and Pearl**](https://github.com/pret/pokediamond)
|
||||||
|
* [**Pokémon Platinum**](https://github.com/pret/pokeplatinum)
|
||||||
|
* [**Pokémon HeartGold and SoulSilver**](https://github.com/pret/pokeheartgold)
|
||||||
|
* [**Pokémon Mystery Dungeon: Explorers of Sky**](https://github.com/pret/pmd-sky)
|
||||||
|
|
||||||
- [**Pokémon Red/Blue**][pokered]
|
## Contacts
|
||||||
- [**Pokémon Yellow**][pokeyellow]
|
|
||||||
- [**Pokémon Gold/Silver**][pokegold]
|
You can find us on:
|
||||||
- [**Pokémon Pinball**][pokepinball]
|
|
||||||
- [**Pokémon TCG**][poketcg]
|
* [Discord (PRET, #pokecrystal)](https://discord.gg/d5dubZ3)
|
||||||
- [**Pokémon Ruby**][pokeruby]
|
* [IRC](https://web.libera.chat/?#pret)
|
||||||
- [**Pokémon FireRed**][pokefirered]
|
|
||||||
- [**Pokémon Emerald**][pokeemerald]
|
|
||||||
|
|
||||||
[pokered]: https://github.com/pret/pokered
|
|
||||||
[pokeyellow]: https://github.com/pret/pokeyellow
|
|
||||||
[pokegold]: https://github.com/pret/pokegold
|
|
||||||
[pokepinball]: https://github.com/pret/pokepinball
|
|
||||||
[poketcg]: https://github.com/pret/poketcg
|
|
||||||
[pokeruby]: https://github.com/pret/pokeruby
|
|
||||||
[pokefirered]: https://github.com/pret/pokefirered
|
|
||||||
[pokeemerald]: https://github.com/pret/pokeemerald
|
|
||||||
[docs]: https://pret.github.io/pokecrystal/
|
[docs]: https://pret.github.io/pokecrystal/
|
||||||
[wiki]: https://github.com/pret/pokecrystal/wiki
|
[wiki]: https://github.com/pret/pokecrystal/wiki
|
||||||
[tutorials]: https://github.com/pret/pokecrystal/wiki/Tutorials
|
[tutorials]: https://github.com/pret/pokecrystal/wiki/Tutorials
|
||||||
[symbols]: https://github.com/pret/pokecrystal/tree/symbols
|
[symbols]: https://github.com/pret/pokecrystal/tree/symbols
|
||||||
[discord]: https://discord.gg/d5dubZ3
|
|
||||||
[irc]: https://web.libera.chat/?#pret
|
|
||||||
[ci]: https://github.com/pret/pokecrystal/actions
|
[ci]: https://github.com/pret/pokecrystal/actions
|
||||||
[ci-badge]: https://github.com/pret/pokecrystal/actions/workflows/main.yml/badge.svg
|
[ci-badge]: https://github.com/pret/pokecrystal/actions/workflows/main.yml/badge.svg
|
||||||
|
@ -713,6 +713,9 @@ DEF NUM_BATTLEANIMFRAMESETS EQU const_value
|
|||||||
const BATTLEANIMOAMSET_D7
|
const BATTLEANIMOAMSET_D7
|
||||||
DEF NUM_BATTLEANIMOAMSETS EQU const_value
|
DEF NUM_BATTLEANIMOAMSETS EQU const_value
|
||||||
|
|
||||||
|
assert NUM_BATTLEANIMOAMSETS <= FIRST_OAM_CMD, \
|
||||||
|
"BATTLEANIMOAMSET_* constants overlap oam*_command constants"
|
||||||
|
|
||||||
; BattleBGEffects indexes (see engine/battle_anims/bg_effects.asm)
|
; BattleBGEffects indexes (see engine/battle_anims/bg_effects.asm)
|
||||||
const_def 1
|
const_def 1
|
||||||
const ANIM_BG_FLASH_INVERTED
|
const ANIM_BG_FLASH_INVERTED
|
||||||
|
@ -90,7 +90,7 @@ DEF SPDSPCDV_SHINY EQU $AA
|
|||||||
const BATTLETYPE_FISH
|
const BATTLETYPE_FISH
|
||||||
const BATTLETYPE_ROAMING
|
const BATTLETYPE_ROAMING
|
||||||
const BATTLETYPE_CONTEST
|
const BATTLETYPE_CONTEST
|
||||||
const BATTLETYPE_SHINY
|
const BATTLETYPE_FORCESHINY
|
||||||
const BATTLETYPE_TREE
|
const BATTLETYPE_TREE
|
||||||
const BATTLETYPE_TRAP
|
const BATTLETYPE_TRAP
|
||||||
const BATTLETYPE_FORCEITEM
|
const BATTLETYPE_FORCEITEM
|
||||||
|
@ -97,6 +97,7 @@ DEF RELATIVE_ATTRIBUTES EQU 1 << RELATIVE_ATTRIBUTES_F
|
|||||||
DEF ABSOLUTE_TILE_ID EQU 1 << ABSOLUTE_TILE_ID_F
|
DEF ABSOLUTE_TILE_ID EQU 1 << ABSOLUTE_TILE_ID_F
|
||||||
|
|
||||||
; map_object struct members (see macros/ram.asm)
|
; map_object struct members (see macros/ram.asm)
|
||||||
|
; struct initialized by object_event macro (see macros/scripts/maps.asm)
|
||||||
rsreset
|
rsreset
|
||||||
DEF MAPOBJECT_OBJECT_STRUCT_ID rb ; 0
|
DEF MAPOBJECT_OBJECT_STRUCT_ID rb ; 0
|
||||||
DEF MAPOBJECT_SPRITE rb ; 1
|
DEF MAPOBJECT_SPRITE rb ; 1
|
||||||
|
@ -109,7 +109,8 @@ DEF CALLBACK_SIZE EQU 3 ; callback
|
|||||||
DEF WARP_EVENT_SIZE EQU 5 ; warp_event
|
DEF WARP_EVENT_SIZE EQU 5 ; warp_event
|
||||||
DEF COORD_EVENT_SIZE EQU 8 ; coord_event
|
DEF COORD_EVENT_SIZE EQU 8 ; coord_event
|
||||||
DEF BG_EVENT_SIZE EQU 5 ; bg_event
|
DEF BG_EVENT_SIZE EQU 5 ; bg_event
|
||||||
DEF OBJECT_EVENT_SIZE EQU 13 ; object_event
|
; An object_event is a map_object without its initial MAPOBJECT_OBJECT_STRUCT_ID or final padding
|
||||||
|
DEF OBJECT_EVENT_SIZE EQU MAPOBJECT_LENGTH - 3 ; 13
|
||||||
|
|
||||||
; A coord_event for scene -1 will always activate,
|
; A coord_event for scene -1 will always activate,
|
||||||
; regardless of the map's scene variable value.
|
; regardless of the map's scene variable value.
|
||||||
|
@ -370,3 +370,6 @@ DEF NUM_SPRITE_ANIM_FRAMESETS EQU const_value
|
|||||||
const SPRITE_ANIM_OAMSET_LEVEL_SELECTION_MENU_FEMALE_RIGHT_1 ; 9a
|
const SPRITE_ANIM_OAMSET_LEVEL_SELECTION_MENU_FEMALE_RIGHT_1 ; 9a
|
||||||
const SPRITE_ANIM_OAMSET_LEVEL_SELECTION_MENU_FEMALE_RIGHT_2 ; 9b
|
const SPRITE_ANIM_OAMSET_LEVEL_SELECTION_MENU_FEMALE_RIGHT_2 ; 9b
|
||||||
DEF NUM_SPRITE_ANIM_OAMSETS EQU const_value
|
DEF NUM_SPRITE_ANIM_OAMSETS EQU const_value
|
||||||
|
|
||||||
|
assert NUM_SPRITE_ANIM_OAMSETS <= FIRST_OAM_CMD, \
|
||||||
|
"SPRITE_ANIM_OAMSET_* constants overlap oam*_command constants"
|
||||||
|
@ -31,52 +31,52 @@ MACRO connection
|
|||||||
|
|
||||||
; Calculate tile offsets for source (current) and target maps
|
; Calculate tile offsets for source (current) and target maps
|
||||||
DEF _src = 0
|
DEF _src = 0
|
||||||
DEF _tgt = (\4) + 3
|
DEF _tgt = (\4) + MAP_CONNECTION_PADDING_WIDTH
|
||||||
if _tgt < 0
|
if _tgt < 0
|
||||||
DEF _src = -_tgt
|
DEF _src = -_tgt
|
||||||
DEF _tgt = 0
|
DEF _tgt = 0
|
||||||
endc
|
endc
|
||||||
|
|
||||||
if !STRCMP("\1", "north")
|
if !STRCMP("\1", "north")
|
||||||
DEF _blk = \3_WIDTH * (\3_HEIGHT - 3) + _src
|
DEF _blk = \3_WIDTH * (\3_HEIGHT - MAP_CONNECTION_PADDING_WIDTH) + _src
|
||||||
DEF _map = _tgt
|
DEF _map = _tgt
|
||||||
DEF _win = (\3_WIDTH + 6) * \3_HEIGHT + 1
|
DEF _win = (\3_WIDTH + MAP_CONNECTION_PADDING_WIDTH * 2) * \3_HEIGHT + 1
|
||||||
DEF _y = \3_HEIGHT * 2 - 1
|
DEF _y = \3_HEIGHT * 2 - 1
|
||||||
DEF _x = (\4) * -2
|
DEF _x = (\4) * -2
|
||||||
DEF _len = CURRENT_MAP_WIDTH + 3 - (\4)
|
DEF _len = CURRENT_MAP_WIDTH + MAP_CONNECTION_PADDING_WIDTH - (\4)
|
||||||
if _len > \3_WIDTH
|
if _len > \3_WIDTH
|
||||||
DEF _len = \3_WIDTH
|
DEF _len = \3_WIDTH
|
||||||
endc
|
endc
|
||||||
|
|
||||||
elif !STRCMP("\1", "south")
|
elif !STRCMP("\1", "south")
|
||||||
DEF _blk = _src
|
DEF _blk = _src
|
||||||
DEF _map = (CURRENT_MAP_WIDTH + 6) * (CURRENT_MAP_HEIGHT + 3) + _tgt
|
DEF _map = (CURRENT_MAP_WIDTH + MAP_CONNECTION_PADDING_WIDTH * 2) * (CURRENT_MAP_HEIGHT + MAP_CONNECTION_PADDING_WIDTH) + _tgt
|
||||||
DEF _win = \3_WIDTH + 7
|
DEF _win = \3_WIDTH + MAP_CONNECTION_PADDING_WIDTH * 2 + 1
|
||||||
DEF _y = 0
|
DEF _y = 0
|
||||||
DEF _x = (\4) * -2
|
DEF _x = (\4) * -2
|
||||||
DEF _len = CURRENT_MAP_WIDTH + 3 - (\4)
|
DEF _len = CURRENT_MAP_WIDTH + MAP_CONNECTION_PADDING_WIDTH - (\4)
|
||||||
if _len > \3_WIDTH
|
if _len > \3_WIDTH
|
||||||
DEF _len = \3_WIDTH
|
DEF _len = \3_WIDTH
|
||||||
endc
|
endc
|
||||||
|
|
||||||
elif !STRCMP("\1", "west")
|
elif !STRCMP("\1", "west")
|
||||||
DEF _blk = (\3_WIDTH * _src) + \3_WIDTH - 3
|
DEF _blk = (\3_WIDTH * _src) + \3_WIDTH - MAP_CONNECTION_PADDING_WIDTH
|
||||||
DEF _map = (CURRENT_MAP_WIDTH + 6) * _tgt
|
DEF _map = (CURRENT_MAP_WIDTH + MAP_CONNECTION_PADDING_WIDTH * 2) * _tgt
|
||||||
DEF _win = (\3_WIDTH + 6) * 2 - 6
|
DEF _win = (\3_WIDTH + MAP_CONNECTION_PADDING_WIDTH * 2) * 2 - MAP_CONNECTION_PADDING_WIDTH * 2
|
||||||
DEF _y = (\4) * -2
|
DEF _y = (\4) * -2
|
||||||
DEF _x = \3_WIDTH * 2 - 1
|
DEF _x = \3_WIDTH * 2 - 1
|
||||||
DEF _len = CURRENT_MAP_HEIGHT + 3 - (\4)
|
DEF _len = CURRENT_MAP_HEIGHT + MAP_CONNECTION_PADDING_WIDTH - (\4)
|
||||||
if _len > \3_HEIGHT
|
if _len > \3_HEIGHT
|
||||||
DEF _len = \3_HEIGHT
|
DEF _len = \3_HEIGHT
|
||||||
endc
|
endc
|
||||||
|
|
||||||
elif !STRCMP("\1", "east")
|
elif !STRCMP("\1", "east")
|
||||||
DEF _blk = (\3_WIDTH * _src)
|
DEF _blk = (\3_WIDTH * _src)
|
||||||
DEF _map = (CURRENT_MAP_WIDTH + 6) * _tgt + CURRENT_MAP_WIDTH + 3
|
DEF _map = (CURRENT_MAP_WIDTH + MAP_CONNECTION_PADDING_WIDTH * 2) * _tgt + CURRENT_MAP_WIDTH + MAP_CONNECTION_PADDING_WIDTH
|
||||||
DEF _win = \3_WIDTH + 7
|
DEF _win = \3_WIDTH + MAP_CONNECTION_PADDING_WIDTH * 2 + 1
|
||||||
DEF _y = (\4) * -2
|
DEF _y = (\4) * -2
|
||||||
DEF _x = 0
|
DEF _x = 0
|
||||||
DEF _len = CURRENT_MAP_HEIGHT + 3 - (\4)
|
DEF _len = CURRENT_MAP_HEIGHT + MAP_CONNECTION_PADDING_WIDTH - (\4)
|
||||||
if _len > \3_HEIGHT
|
if _len > \3_HEIGHT
|
||||||
DEF _len = \3_HEIGHT
|
DEF _len = \3_HEIGHT
|
||||||
endc
|
endc
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
TypeNames:
|
TypeNames:
|
||||||
; entries correspond to types (see constants/type_constants.asm)
|
; entries correspond to types (see constants/type_constants.asm)
|
||||||
table_width 2, TypeNames
|
table_width 2, TypeNames
|
||||||
|
|
||||||
dw Normal
|
dw Normal
|
||||||
dw Fighting
|
dw Fighting
|
||||||
dw Flying
|
dw Flying
|
||||||
@ -12,17 +13,13 @@ TypeNames:
|
|||||||
dw Ghost
|
dw Ghost
|
||||||
dw Steel
|
dw Steel
|
||||||
assert_table_length UNUSED_TYPES
|
assert_table_length UNUSED_TYPES
|
||||||
|
|
||||||
|
rept UNUSED_TYPES_END - UNUSED_TYPES - 1 ; discount CURSE_TYPE
|
||||||
dw Normal
|
dw Normal
|
||||||
dw Normal
|
endr
|
||||||
dw Normal
|
|
||||||
dw Normal
|
|
||||||
dw Normal
|
|
||||||
dw Normal
|
|
||||||
dw Normal
|
|
||||||
dw Normal
|
|
||||||
dw Normal
|
|
||||||
dw CurseType
|
dw CurseType
|
||||||
assert_table_length UNUSED_TYPES_END
|
assert_table_length UNUSED_TYPES_END
|
||||||
|
|
||||||
dw Fire
|
dw Fire
|
||||||
dw Water
|
dw Water
|
||||||
dw Grass
|
dw Grass
|
||||||
|
@ -59,6 +59,7 @@ Fixes in the [multi-player battle engine](#multi-player-battle-engine) category
|
|||||||
- [AI makes a false assumption about `CheckTypeMatchup`](#ai-makes-a-false-assumption-about-checktypematchup)
|
- [AI makes a false assumption about `CheckTypeMatchup`](#ai-makes-a-false-assumption-about-checktypematchup)
|
||||||
- [AI use of Full Heal or Full Restore does not cure Nightmare status](#ai-use-of-full-heal-or-full-restore-does-not-cure-nightmare-status)
|
- [AI use of Full Heal or Full Restore does not cure Nightmare status](#ai-use-of-full-heal-or-full-restore-does-not-cure-nightmare-status)
|
||||||
- [AI use of Full Heal does not cure confusion status](#ai-use-of-full-heal-does-not-cure-confusion-status)
|
- [AI use of Full Heal does not cure confusion status](#ai-use-of-full-heal-does-not-cure-confusion-status)
|
||||||
|
- [AI might use its base reward value as an item](#ai-might-use-its-base-reward-value-as-an-item)
|
||||||
- [Wild Pokémon can always Teleport regardless of level difference](#wild-pok%C3%A9mon-can-always-teleport-regardless-of-level-difference)
|
- [Wild Pokémon can always Teleport regardless of level difference](#wild-pok%C3%A9mon-can-always-teleport-regardless-of-level-difference)
|
||||||
- [`RIVAL2` has lower DVs than `RIVAL1`](#rival2-has-lower-dvs-than-rival1)
|
- [`RIVAL2` has lower DVs than `RIVAL1`](#rival2-has-lower-dvs-than-rival1)
|
||||||
- [`HELD_CATCH_CHANCE` has no effect](#held_catch_chance-has-no-effect)
|
- [`HELD_CATCH_CHANCE` has no effect](#held_catch_chance-has-no-effect)
|
||||||
@ -1455,6 +1456,33 @@ Pryce's dialog ("That BADGE will raise the SPECIAL stats of POKéMON.") implies
|
|||||||
ret
|
ret
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### AI might use its base reward value as an item
|
||||||
|
|
||||||
|
In the `AI_TryItem` routine, an item pointer is set to `wEnemyTrainerItem1` and then increments to `wEnemyTrainerItem2` to see if either of the AI's items are in the `AI_Items` list. However, if the AI has used its first item (or its first one is `ITEM_NONE`) and hasn't used its second item, the item pointer can increment from `wEnemyTrainerItem2` to `wEnemyTrainerBaseReward`. If the value at this address then matches an item in the `AI_Items` list, the AI could mistakenly use it.
|
||||||
|
|
||||||
|
**Fix:** Edit `AI_TryItem` in [engine/battle/ai/items.asm](https://github.com/pret/pokecrystal/blob/master/engine/battle/ai/items.asm):
|
||||||
|
|
||||||
|
```diff
|
||||||
|
AI_TryItem:
|
||||||
|
...
|
||||||
|
ld a, [wTrainerClass]
|
||||||
|
dec a
|
||||||
|
ld hl, TrainerClassAttributes + TRNATTR_AI_ITEM_SWITCH
|
||||||
|
ld bc, NUM_TRAINER_ATTRIBUTES
|
||||||
|
call AddNTimes
|
||||||
|
ld b, h
|
||||||
|
ld c, l
|
||||||
|
ld hl, AI_Items
|
||||||
|
-; BUG: AI might use its base reward value as an item (see docs/bugs_and_glitches.md)
|
||||||
|
- ld de, wEnemyTrainerItem1
|
||||||
|
.loop
|
||||||
|
+ ld de, wEnemyTrainerItem1
|
||||||
|
ld a, [hl]
|
||||||
|
and a
|
||||||
|
inc a
|
||||||
|
ret z
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### Wild Pokémon can always Teleport regardless of level difference
|
### Wild Pokémon can always Teleport regardless of level difference
|
||||||
|
|
||||||
|
@ -175,6 +175,7 @@ AI_TryItem:
|
|||||||
ld b, h
|
ld b, h
|
||||||
ld c, l
|
ld c, l
|
||||||
ld hl, AI_Items
|
ld hl, AI_Items
|
||||||
|
; BUG: AI might use its base reward value as an item (see docs/bugs_and_glitches.md)
|
||||||
ld de, wEnemyTrainerItem1
|
ld de, wEnemyTrainerItem1
|
||||||
.loop
|
.loop
|
||||||
ld a, [hl]
|
ld a, [hl]
|
||||||
|
@ -3522,7 +3522,7 @@ TryToRunAwayFromBattle:
|
|||||||
jp z, .cant_escape
|
jp z, .cant_escape
|
||||||
cp BATTLETYPE_CELEBI
|
cp BATTLETYPE_CELEBI
|
||||||
jp z, .cant_escape
|
jp z, .cant_escape
|
||||||
cp BATTLETYPE_SHINY
|
cp BATTLETYPE_FORCESHINY
|
||||||
jp z, .cant_escape
|
jp z, .cant_escape
|
||||||
cp BATTLETYPE_SUICUNE
|
cp BATTLETYPE_SUICUNE
|
||||||
jp z, .cant_escape
|
jp z, .cant_escape
|
||||||
@ -5954,7 +5954,7 @@ LoadEnemyMon:
|
|||||||
|
|
||||||
; Forced shiny battle type
|
; Forced shiny battle type
|
||||||
; Used by Red Gyarados at Lake of Rage
|
; Used by Red Gyarados at Lake of Rage
|
||||||
cp BATTLETYPE_SHINY
|
cp BATTLETYPE_FORCESHINY
|
||||||
jr nz, .GenerateDVs
|
jr nz, .GenerateDVs
|
||||||
|
|
||||||
ld b, ATKDEFDV_SHINY ; $ea
|
ld b, ATKDEFDV_SHINY ; $ea
|
||||||
|
@ -4161,14 +4161,14 @@ RaiseStat:
|
|||||||
add hl, bc
|
add hl, bc
|
||||||
ld b, [hl]
|
ld b, [hl]
|
||||||
inc b
|
inc b
|
||||||
ld a, $d
|
ld a, MAX_STAT_LEVEL
|
||||||
cp b
|
cp b
|
||||||
jp c, .cant_raise_stat
|
jp c, .cant_raise_stat
|
||||||
ld a, [wLoweredStat]
|
ld a, [wLoweredStat]
|
||||||
and $f0
|
and $f0
|
||||||
jr z, .got_num_stages
|
jr z, .got_num_stages
|
||||||
inc b
|
inc b
|
||||||
ld a, $d
|
ld a, MAX_STAT_LEVEL
|
||||||
cp b
|
cp b
|
||||||
jr nc, .got_num_stages
|
jr nc, .got_num_stages
|
||||||
ld b, a
|
ld b, a
|
||||||
@ -4176,7 +4176,7 @@ RaiseStat:
|
|||||||
ld [hl], b
|
ld [hl], b
|
||||||
push hl
|
push hl
|
||||||
ld a, c
|
ld a, c
|
||||||
cp $5
|
cp ACCURACY
|
||||||
jr nc, .done_calcing_stats
|
jr nc, .done_calcing_stats
|
||||||
ld hl, wBattleMonStats + 1
|
ld hl, wBattleMonStats + 1
|
||||||
ld de, wPlayerStats
|
ld de, wPlayerStats
|
||||||
@ -4684,7 +4684,7 @@ LowerStat:
|
|||||||
.got_num_stages
|
.got_num_stages
|
||||||
ld [hl], b
|
ld [hl], b
|
||||||
ld a, c
|
ld a, c
|
||||||
cp 5
|
cp ACCURACY
|
||||||
jr nc, .accuracy_evasion
|
jr nc, .accuracy_evasion
|
||||||
|
|
||||||
push hl
|
push hl
|
||||||
@ -4955,7 +4955,7 @@ SetBattleDraw:
|
|||||||
|
|
||||||
BattleCommand_ForceSwitch:
|
BattleCommand_ForceSwitch:
|
||||||
ld a, [wBattleType]
|
ld a, [wBattleType]
|
||||||
cp BATTLETYPE_SHINY
|
cp BATTLETYPE_FORCESHINY
|
||||||
jp z, .fail
|
jp z, .fail
|
||||||
cp BATTLETYPE_TRAP
|
cp BATTLETYPE_TRAP
|
||||||
jp z, .fail
|
jp z, .fail
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
BattleCommand_Teleport:
|
BattleCommand_Teleport:
|
||||||
ld a, [wBattleType]
|
ld a, [wBattleType]
|
||||||
cp BATTLETYPE_SHINY
|
cp BATTLETYPE_FORCESHINY
|
||||||
jr z, .failed
|
jr z, .failed
|
||||||
cp BATTLETYPE_TRAP
|
cp BATTLETYPE_TRAP
|
||||||
jr z, .failed
|
jr z, .failed
|
||||||
|
@ -20,11 +20,11 @@ ShowPlayerMonsRemaining:
|
|||||||
ld de, wPartyCount
|
ld de, wPartyCount
|
||||||
call StageBallTilesData
|
call StageBallTilesData
|
||||||
; ldpixel wPlaceBallsX, 12, 12
|
; ldpixel wPlaceBallsX, 12, 12
|
||||||
ld a, 12 * 8
|
ld a, 12 * TILE_WIDTH
|
||||||
ld hl, wPlaceBallsX
|
ld hl, wPlaceBallsX
|
||||||
ld [hli], a
|
ld [hli], a
|
||||||
ld [hl], a
|
ld [hl], a
|
||||||
ld a, 8
|
ld a, TILE_WIDTH
|
||||||
ld [wPlaceBallsDirection], a
|
ld [wPlaceBallsDirection], a
|
||||||
ld hl, wShadowOAMSprite00
|
ld hl, wShadowOAMSprite00
|
||||||
jp LoadTrainerHudOAM
|
jp LoadTrainerHudOAM
|
||||||
@ -36,10 +36,10 @@ ShowOTTrainerMonsRemaining:
|
|||||||
call StageBallTilesData
|
call StageBallTilesData
|
||||||
; ldpixel wPlaceBallsX, 9, 4
|
; ldpixel wPlaceBallsX, 9, 4
|
||||||
ld hl, wPlaceBallsX
|
ld hl, wPlaceBallsX
|
||||||
ld a, 9 * 8
|
ld a, 9 * TILE_WIDTH
|
||||||
ld [hli], a
|
ld [hli], a
|
||||||
ld [hl], 4 * 8
|
ld [hl], 4 * TILE_WIDTH
|
||||||
ld a, -8
|
ld a, -TILE_WIDTH
|
||||||
ld [wPlaceBallsDirection], a
|
ld [wPlaceBallsDirection], a
|
||||||
ld hl, wShadowOAMSprite00 + PARTY_LENGTH * SPRITEOAMSTRUCT_LENGTH
|
ld hl, wShadowOAMSprite00 + PARTY_LENGTH * SPRITEOAMSTRUCT_LENGTH
|
||||||
jp LoadTrainerHudOAM
|
jp LoadTrainerHudOAM
|
||||||
@ -182,10 +182,10 @@ LinkBattle_TrainerHuds:
|
|||||||
ld de, wPartyCount
|
ld de, wPartyCount
|
||||||
call StageBallTilesData
|
call StageBallTilesData
|
||||||
ld hl, wPlaceBallsX
|
ld hl, wPlaceBallsX
|
||||||
ld a, 10 * 8
|
ld a, 10 * TILE_WIDTH
|
||||||
ld [hli], a
|
ld [hli], a
|
||||||
ld [hl], 8 * 8
|
ld [hl], 8 * TILE_WIDTH
|
||||||
ld a, 8
|
ld a, TILE_WIDTH
|
||||||
ld [wPlaceBallsDirection], a
|
ld [wPlaceBallsDirection], a
|
||||||
ld hl, wShadowOAMSprite00
|
ld hl, wShadowOAMSprite00
|
||||||
call LoadTrainerHudOAM
|
call LoadTrainerHudOAM
|
||||||
@ -194,9 +194,9 @@ LinkBattle_TrainerHuds:
|
|||||||
ld de, wOTPartyCount
|
ld de, wOTPartyCount
|
||||||
call StageBallTilesData
|
call StageBallTilesData
|
||||||
ld hl, wPlaceBallsX
|
ld hl, wPlaceBallsX
|
||||||
ld a, 10 * 8
|
ld a, 10 * TILE_WIDTH
|
||||||
ld [hli], a
|
ld [hli], a
|
||||||
ld [hl], 13 * 8
|
ld [hl], 13 * TILE_WIDTH
|
||||||
ld hl, wShadowOAMSprite00 + PARTY_LENGTH * SPRITEOAMSTRUCT_LENGTH
|
ld hl, wShadowOAMSprite00 + PARTY_LENGTH * SPRITEOAMSTRUCT_LENGTH
|
||||||
jp LoadTrainerHudOAM
|
jp LoadTrainerHudOAM
|
||||||
|
|
||||||
|
@ -243,7 +243,7 @@ InitBattleAnimBuffer:
|
|||||||
add hl, bc
|
add hl, bc
|
||||||
ld a, [hli]
|
ld a, [hli]
|
||||||
ld d, a
|
ld d, a
|
||||||
ld a, (-10 * 8) + 4
|
ld a, (-10 * TILE_WIDTH) + 4
|
||||||
sub d
|
sub d
|
||||||
ld [wBattleAnimTempXCoord], a
|
ld [wBattleAnimTempXCoord], a
|
||||||
ld a, [hli]
|
ld a, [hli]
|
||||||
@ -251,7 +251,7 @@ InitBattleAnimBuffer:
|
|||||||
ld a, [wBattleAnimTempFixY]
|
ld a, [wBattleAnimTempFixY]
|
||||||
cp $ff
|
cp $ff
|
||||||
jr nz, .check_kinesis_softboiled_milkdrink
|
jr nz, .check_kinesis_softboiled_milkdrink
|
||||||
ld a, 5 * 8
|
ld a, 5 * TILE_WIDTH
|
||||||
add d
|
add d
|
||||||
jr .done
|
jr .done
|
||||||
|
|
||||||
@ -270,7 +270,7 @@ InitBattleAnimBuffer:
|
|||||||
jr nz, .no_sub
|
jr nz, .no_sub
|
||||||
.do_sub
|
.do_sub
|
||||||
pop af
|
pop af
|
||||||
sub 1 * 8
|
sub 1 * TILE_WIDTH
|
||||||
jr .done
|
jr .done
|
||||||
|
|
||||||
.no_sub
|
.no_sub
|
||||||
|
@ -347,7 +347,7 @@ FlyToAnim:
|
|||||||
ld [hl], SPRITE_ANIM_SEQ_FLY_TO
|
ld [hl], SPRITE_ANIM_SEQ_FLY_TO
|
||||||
ld hl, SPRITEANIMSTRUCT_VAR4
|
ld hl, SPRITEANIMSTRUCT_VAR4
|
||||||
add hl, bc
|
add hl, bc
|
||||||
ld [hl], 11 * 8
|
ld [hl], 11 * TILE_WIDTH
|
||||||
ld a, 64
|
ld a, 64
|
||||||
ld [wFrameCounter], a
|
ld [wFrameCounter], a
|
||||||
.loop
|
.loop
|
||||||
|
@ -675,7 +675,7 @@ Slots_InitReelTiles:
|
|||||||
ld [hl], d
|
ld [hl], d
|
||||||
ld hl, REEL_X_COORD
|
ld hl, REEL_X_COORD
|
||||||
add hl, bc
|
add hl, bc
|
||||||
ld [hl], 6 * 8
|
ld [hl], 6 * TILE_WIDTH
|
||||||
call .OAM
|
call .OAM
|
||||||
|
|
||||||
ld bc, wReel2
|
ld bc, wReel2
|
||||||
@ -693,7 +693,7 @@ Slots_InitReelTiles:
|
|||||||
ld [hl], d
|
ld [hl], d
|
||||||
ld hl, REEL_X_COORD
|
ld hl, REEL_X_COORD
|
||||||
add hl, bc
|
add hl, bc
|
||||||
ld [hl], 10 * 8
|
ld [hl], 10 * TILE_WIDTH
|
||||||
call .OAM
|
call .OAM
|
||||||
|
|
||||||
ld bc, wReel3
|
ld bc, wReel3
|
||||||
@ -711,7 +711,7 @@ Slots_InitReelTiles:
|
|||||||
ld [hl], d
|
ld [hl], d
|
||||||
ld hl, REEL_X_COORD
|
ld hl, REEL_X_COORD
|
||||||
add hl, bc
|
add hl, bc
|
||||||
ld [hl], 14 * 8
|
ld [hl], 14 * TILE_WIDTH
|
||||||
call .OAM
|
call .OAM
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -779,7 +779,7 @@ Slots_UpdateReelPositionAndOAM:
|
|||||||
add hl, bc
|
add hl, bc
|
||||||
ld a, [hl]
|
ld a, [hl]
|
||||||
ld [wCurReelXCoord], a
|
ld [wCurReelXCoord], a
|
||||||
ld a, 10 * 8
|
ld a, 10 * TILE_WIDTH
|
||||||
ld [wCurReelYCoord], a
|
ld [wCurReelYCoord], a
|
||||||
ld hl, REEL_POSITION
|
ld hl, REEL_POSITION
|
||||||
add hl, bc
|
add hl, bc
|
||||||
@ -2010,7 +2010,7 @@ Slots_AnimateGolem:
|
|||||||
jr c, .play_sound
|
jr c, .play_sound
|
||||||
dec [hl]
|
dec [hl]
|
||||||
ld e, a
|
ld e, a
|
||||||
ld d, 14 * 8
|
ld d, 14 * TILE_WIDTH
|
||||||
farcall BattleAnim_Sine_e
|
farcall BattleAnim_Sine_e
|
||||||
ld a, e
|
ld a, e
|
||||||
ld hl, SPRITEANIMSTRUCT_YOFFSET
|
ld hl, SPRITEANIMSTRUCT_YOFFSET
|
||||||
@ -2037,7 +2037,7 @@ Slots_AnimateGolem:
|
|||||||
ld a, [hl]
|
ld a, [hl]
|
||||||
inc [hl]
|
inc [hl]
|
||||||
inc [hl]
|
inc [hl]
|
||||||
cp 9 * 8
|
cp 9 * TILE_WIDTH
|
||||||
jr nc, .restart
|
jr nc, .restart
|
||||||
and $3
|
and $3
|
||||||
ret nz
|
ret nz
|
||||||
@ -2081,7 +2081,7 @@ Slots_AnimateChansey:
|
|||||||
add hl, bc
|
add hl, bc
|
||||||
ld a, [hl]
|
ld a, [hl]
|
||||||
inc [hl]
|
inc [hl]
|
||||||
cp 13 * 8
|
cp 13 * TILE_WIDTH
|
||||||
jr z, .limit
|
jr z, .limit
|
||||||
and $f
|
and $f
|
||||||
ret nz
|
ret nz
|
||||||
|
@ -576,7 +576,7 @@ InitCGBPals::
|
|||||||
ldh [rVBK], a
|
ldh [rVBK], a
|
||||||
ld a, 1 << rBGPI_AUTO_INCREMENT
|
ld a, 1 << rBGPI_AUTO_INCREMENT
|
||||||
ldh [rBGPI], a
|
ldh [rBGPI], a
|
||||||
ld c, 4 * 8
|
ld c, 4 * TILE_WIDTH
|
||||||
.bgpals_loop
|
.bgpals_loop
|
||||||
ld a, LOW(PALRGB_WHITE)
|
ld a, LOW(PALRGB_WHITE)
|
||||||
ldh [rBGPD], a
|
ldh [rBGPD], a
|
||||||
@ -586,7 +586,7 @@ InitCGBPals::
|
|||||||
jr nz, .bgpals_loop
|
jr nz, .bgpals_loop
|
||||||
ld a, 1 << rOBPI_AUTO_INCREMENT
|
ld a, 1 << rOBPI_AUTO_INCREMENT
|
||||||
ldh [rOBPI], a
|
ldh [rOBPI], a
|
||||||
ld c, 4 * 8
|
ld c, 4 * TILE_WIDTH
|
||||||
.obpals_loop
|
.obpals_loop
|
||||||
ld a, LOW(PALRGB_WHITE)
|
ld a, LOW(PALRGB_WHITE)
|
||||||
ldh [rOBPD], a
|
ldh [rOBPD], a
|
||||||
|
@ -197,8 +197,8 @@ MoveList_InitAnimatedMonIcon:
|
|||||||
ld [wCurIcon], a
|
ld [wCurIcon], a
|
||||||
xor a
|
xor a
|
||||||
call GetIconGFX
|
call GetIconGFX
|
||||||
ld d, 3 * 8 + 2 ; depixel 3, 4, 2, 4
|
ld d, 3 * TILE_WIDTH + 2 ; depixel 3, 4, 2, 4
|
||||||
ld e, 4 * 8 + 4
|
ld e, 4 * TILE_WIDTH + 4
|
||||||
ld a, SPRITE_ANIM_INDEX_PARTY_MON
|
ld a, SPRITE_ANIM_INDEX_PARTY_MON
|
||||||
call _InitSpriteAnimStruct
|
call _InitSpriteAnimStruct
|
||||||
ld hl, SPRITEANIMSTRUCT_ANIM_SEQ_ID
|
ld hl, SPRITEANIMSTRUCT_ANIM_SEQ_ID
|
||||||
|
@ -384,7 +384,7 @@ AnimSeq_SlotsChanseyEgg:
|
|||||||
ld hl, SPRITEANIMSTRUCT_XCOORD
|
ld hl, SPRITEANIMSTRUCT_XCOORD
|
||||||
add hl, bc
|
add hl, bc
|
||||||
ld a, [hl]
|
ld a, [hl]
|
||||||
cp 15 * 8
|
cp 15 * TILE_WIDTH
|
||||||
jr c, .move_right
|
jr c, .move_right
|
||||||
call DeinitializeSprite
|
call DeinitializeSprite
|
||||||
ld a, $4
|
ld a, $4
|
||||||
@ -686,7 +686,7 @@ AnimSeq_FlyLeaf:
|
|||||||
ld hl, SPRITEANIMSTRUCT_XCOORD
|
ld hl, SPRITEANIMSTRUCT_XCOORD
|
||||||
add hl, bc
|
add hl, bc
|
||||||
ld a, [hl]
|
ld a, [hl]
|
||||||
cp -9 * 8
|
cp -9 * TILE_WIDTH
|
||||||
jr nc, .delete_leaf
|
jr nc, .delete_leaf
|
||||||
inc [hl]
|
inc [hl]
|
||||||
inc [hl]
|
inc [hl]
|
||||||
@ -715,7 +715,7 @@ AnimSeq_FlyTo:
|
|||||||
ld hl, SPRITEANIMSTRUCT_YCOORD
|
ld hl, SPRITEANIMSTRUCT_YCOORD
|
||||||
add hl, bc
|
add hl, bc
|
||||||
ld a, [hl]
|
ld a, [hl]
|
||||||
cp 10 * 8 + 4
|
cp 10 * TILE_WIDTH + 4
|
||||||
ret z
|
ret z
|
||||||
|
|
||||||
ld hl, SPRITEANIMSTRUCT_YCOORD
|
ld hl, SPRITEANIMSTRUCT_YCOORD
|
||||||
|
@ -825,10 +825,10 @@ Intro_PlacePlayerSprite:
|
|||||||
.sprites
|
.sprites
|
||||||
db 4
|
db 4
|
||||||
; y pxl, x pxl, tile offset
|
; y pxl, x pxl, tile offset
|
||||||
db 9 * 8 + 4, 9 * 8, 0
|
db 9 * TILE_WIDTH + 4, 9 * TILE_WIDTH, 0
|
||||||
db 9 * 8 + 4, 10 * 8, 1
|
db 9 * TILE_WIDTH + 4, 10 * TILE_WIDTH, 1
|
||||||
db 10 * 8 + 4, 9 * 8, 2
|
db 10 * TILE_WIDTH + 4, 9 * TILE_WIDTH, 2
|
||||||
db 10 * 8 + 4, 10 * 8, 3
|
db 10 * TILE_WIDTH + 4, 10 * TILE_WIDTH, 3
|
||||||
|
|
||||||
|
|
||||||
const_def
|
const_def
|
||||||
|
@ -365,7 +365,7 @@ NamingScreenJoypadLoop:
|
|||||||
depixel 10, 3
|
depixel 10, 3
|
||||||
call NamingScreen_IsTargetBox
|
call NamingScreen_IsTargetBox
|
||||||
jr nz, .got_cursor_position
|
jr nz, .got_cursor_position
|
||||||
ld d, 8 * 8
|
ld d, 8 * TILE_WIDTH
|
||||||
.got_cursor_position
|
.got_cursor_position
|
||||||
ld a, SPRITE_ANIM_INDEX_NAMING_SCREEN_CURSOR
|
ld a, SPRITE_ANIM_INDEX_NAMING_SCREEN_CURSOR
|
||||||
call InitSpriteAnimStruct
|
call InitSpriteAnimStruct
|
||||||
|
@ -880,12 +880,12 @@ MovementFunction_Shadow:
|
|||||||
add hl, de
|
add hl, de
|
||||||
ld a, [hl]
|
ld a, [hl]
|
||||||
maskbits NUM_DIRECTIONS
|
maskbits NUM_DIRECTIONS
|
||||||
ld d, 1 * 8 + 6
|
ld d, 1 * TILE_WIDTH + 6
|
||||||
cp DOWN
|
cp DOWN
|
||||||
jr z, .ok
|
jr z, .ok
|
||||||
cp UP
|
cp UP
|
||||||
jr z, .ok
|
jr z, .ok
|
||||||
ld d, 1 * 8 + 4
|
ld d, 1 * TILE_WIDTH + 4
|
||||||
.ok
|
.ok
|
||||||
ld hl, OBJECT_SPRITE_Y_OFFSET
|
ld hl, OBJECT_SPRITE_Y_OFFSET
|
||||||
add hl, bc
|
add hl, bc
|
||||||
@ -909,7 +909,7 @@ MovementFunction_Emote:
|
|||||||
ld [hl], 0
|
ld [hl], 0
|
||||||
ld hl, OBJECT_SPRITE_Y_OFFSET
|
ld hl, OBJECT_SPRITE_Y_OFFSET
|
||||||
add hl, bc
|
add hl, bc
|
||||||
ld [hl], -2 * 8
|
ld [hl], -2 * TILE_WIDTH
|
||||||
ld hl, OBJECT_SPRITE_X_OFFSET
|
ld hl, OBJECT_SPRITE_X_OFFSET
|
||||||
add hl, bc
|
add hl, bc
|
||||||
ld [hl], 0
|
ld [hl], 0
|
||||||
|
@ -2302,10 +2302,10 @@ Pokedex_GetArea:
|
|||||||
|
|
||||||
.PlayerOAM:
|
.PlayerOAM:
|
||||||
; y pxl, x pxl, tile offset
|
; y pxl, x pxl, tile offset
|
||||||
db -1 * 8, -1 * 8, 0 ; top left
|
db -1 * TILE_WIDTH, -1 * TILE_WIDTH, 0 ; top left
|
||||||
db -1 * 8, 0 * 8, 1 ; top right
|
db -1 * TILE_WIDTH, 0 * TILE_WIDTH, 1 ; top right
|
||||||
db 0 * 8, -1 * 8, 2 ; bottom left
|
db 0 * TILE_WIDTH, -1 * TILE_WIDTH, 2 ; bottom left
|
||||||
db 0 * 8, 0 * 8, 3 ; bottom right
|
db 0 * TILE_WIDTH, 0 * TILE_WIDTH, 3 ; bottom right
|
||||||
db $80 ; terminator
|
db $80 ; terminator
|
||||||
|
|
||||||
.CheckPlayerLocation:
|
.CheckPlayerLocation:
|
||||||
|
@ -769,9 +769,9 @@ EggHatch_CrackShell:
|
|||||||
ret nc
|
ret nc
|
||||||
swap a
|
swap a
|
||||||
srl a
|
srl a
|
||||||
add 9 * 8 + 4
|
add 9 * TILE_WIDTH + 4
|
||||||
ld d, a
|
ld d, a
|
||||||
ld e, 11 * 8
|
ld e, 11 * TILE_WIDTH
|
||||||
ld a, SPRITE_ANIM_INDEX_EGG_CRACK
|
ld a, SPRITE_ANIM_INDEX_EGG_CRACK
|
||||||
call InitSpriteAnimStruct
|
call InitSpriteAnimStruct
|
||||||
ld hl, SPRITEANIMSTRUCT_TILE_ID
|
ld hl, SPRITEANIMSTRUCT_TILE_ID
|
||||||
@ -828,7 +828,7 @@ Hatch_InitShellFragments:
|
|||||||
|
|
||||||
MACRO shell_fragment
|
MACRO shell_fragment
|
||||||
; y tile, y pxl, x tile, x pxl, frameset offset, ???
|
; y tile, y pxl, x tile, x pxl, frameset offset, ???
|
||||||
db (\1 * 8) % $100 + \2, (\3 * 8) % $100 + \4, \5 - SPRITE_ANIM_FRAMESET_EGG_HATCH_1, \6
|
db (\1 * TILE_WIDTH) % $100 + \2, (\3 * TILE_WIDTH) % $100 + \4, \5 - SPRITE_ANIM_FRAMESET_EGG_HATCH_1, \6
|
||||||
ENDM
|
ENDM
|
||||||
|
|
||||||
.SpriteData:
|
.SpriteData:
|
||||||
|
@ -53,7 +53,7 @@ HealPartyMon:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
ComputeHPBarPixels:
|
ComputeHPBarPixels:
|
||||||
; e = bc * (6 * 8) / de
|
; e = bc * HP_BAR_LENGTH_PX / de
|
||||||
ld a, b
|
ld a, b
|
||||||
or c
|
or c
|
||||||
jr z, .zero
|
jr z, .zero
|
||||||
@ -64,7 +64,7 @@ ComputeHPBarPixels:
|
|||||||
ldh [hMultiplicand + 1], a
|
ldh [hMultiplicand + 1], a
|
||||||
ld a, c
|
ld a, c
|
||||||
ldh [hMultiplicand + 2], a
|
ldh [hMultiplicand + 2], a
|
||||||
ld a, 6 * 8
|
ld a, HP_BAR_LENGTH_PX
|
||||||
ldh [hMultiplier], a
|
ldh [hMultiplier], a
|
||||||
call Multiply
|
call Multiply
|
||||||
; We need de to be under 256 because hDivisor is only 1 byte.
|
; We need de to be under 256 because hDivisor is only 1 byte.
|
||||||
|
@ -18,8 +18,8 @@ MACRO anim_obj
|
|||||||
else
|
else
|
||||||
; LEGACY: Support the tile+offset format
|
; LEGACY: Support the tile+offset format
|
||||||
db \1 ; object
|
db \1 ; object
|
||||||
db (\2) * 8 + (\3) ; x_tile, x
|
db (\2) * TILE_WIDTH + (\3) ; x_tile, x
|
||||||
db (\4) * 8 + (\5) ; y_tile, y
|
db (\4) * TILE_WIDTH + (\5) ; y_tile, y
|
||||||
db \6 ; param
|
db \6 ; param
|
||||||
endc
|
endc
|
||||||
ENDM
|
ENDM
|
||||||
|
@ -36,3 +36,5 @@ ENDM
|
|||||||
MACRO oamdelete
|
MACRO oamdelete
|
||||||
db oamdelete_command
|
db oamdelete_command
|
||||||
ENDM
|
ENDM
|
||||||
|
|
||||||
|
DEF FIRST_OAM_CMD EQU LOW(const_value + 1)
|
||||||
|
34
tools/dupeframes.py
Executable file
34
tools/dupeframes.py
Executable file
@ -0,0 +1,34 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Usage: python dupeframes.py
|
||||||
|
|
||||||
|
Check for duplicate frames in Pokemon sprites (gfx/pokemon/*/front.png).
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import glob
|
||||||
|
|
||||||
|
import png
|
||||||
|
|
||||||
|
def check_duplicate_frames(filename):
|
||||||
|
with open(filename, 'rb') as file:
|
||||||
|
width, height, rows = png.Reader(file).asRGBA8()[:3]
|
||||||
|
rows = list(rows)
|
||||||
|
if height % width:
|
||||||
|
print(f'{filename} is not a vertical strip of square frames!', file=sys.stderr)
|
||||||
|
return
|
||||||
|
num_frames = height // width
|
||||||
|
frames = [rows[i*width:(i+1)*width] for i in range(num_frames)]
|
||||||
|
for i in range(num_frames):
|
||||||
|
for j in range(i + 1, num_frames):
|
||||||
|
if frames[i] == frames[j]:
|
||||||
|
print(f'{filename}: frame {j} is a duplicate of frame {i}', file=sys.stderr)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
for filename in sorted(glob.glob('gfx/pokemon/*/front.png')):
|
||||||
|
check_duplicate_frames(filename)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
void parse_args(int argc, char *argv[], bool *strict) {
|
void parse_args(int argc, char *argv[], bool *strict) {
|
||||||
struct option long_options[] = {
|
struct option long_options[] = {
|
||||||
{"strict", no_argument, 0, 's'},
|
{"strict", no_argument, 0, 's'},
|
||||||
@ -40,31 +42,47 @@ void scan_file(const char *filename, bool strict) {
|
|||||||
fclose(f);
|
fclose(f);
|
||||||
contents[size] = '\0';
|
contents[size] = '\0';
|
||||||
|
|
||||||
for (char *ptr = contents; ptr && ptr - contents < size; ptr++) {
|
for (char *ptr = contents; ptr && ptr < contents + size; ptr++) {
|
||||||
bool is_incbin = false, is_include = false;
|
ptr = strpbrk(ptr, ";\"Ii");
|
||||||
|
if (!ptr) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
switch (*ptr) {
|
switch (*ptr) {
|
||||||
case ';':
|
case ';':
|
||||||
ptr = strchr(ptr, '\n');
|
// Skip comments until the end of the line
|
||||||
if (!ptr) {
|
ptr += strcspn(ptr + 1, "\r\n");
|
||||||
fprintf(stderr, "%s: no newline at end of file\n", filename);
|
if (*ptr) {
|
||||||
|
ptr++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '"':
|
case '"':
|
||||||
|
// Skip string literal until the closing quote
|
||||||
|
ptr += strcspn(ptr + 1, "\"");
|
||||||
|
if (*ptr) {
|
||||||
ptr++;
|
ptr++;
|
||||||
ptr = strchr(ptr, '"');
|
|
||||||
if (ptr) {
|
|
||||||
ptr++;
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "%s: unterminated string\n", filename);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'I':
|
case 'I':
|
||||||
case 'i':
|
case 'i':
|
||||||
is_incbin = !strncmp(ptr, "INCBIN", 6) || !strncmp(ptr, "incbin", 6);
|
/* empty statement between the label and the variable declaration */;
|
||||||
is_include = !strncmp(ptr, "INCLUDE", 7) || !strncmp(ptr, "include", 7);
|
// Check that an INCLUDE/INCBIN starts as its own token
|
||||||
|
char before = ptr > contents ? *(ptr - 1) : '\n';
|
||||||
|
if (!isspace((unsigned)before) && before != ':') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bool is_incbin = !strncmp(ptr, "INCBIN", 6) || !strncmp(ptr, "incbin", 6);
|
||||||
|
bool is_include = !strncmp(ptr, "INCLUDE", 7) || !strncmp(ptr, "include", 7);
|
||||||
if (is_incbin || is_include) {
|
if (is_incbin || is_include) {
|
||||||
ptr = strchr(ptr, '"');
|
// Check that an INCLUDE/INCBIN ends as its own token
|
||||||
if (ptr) {
|
ptr += is_include ? 7 : 6;
|
||||||
|
if (!isspace((unsigned)*ptr) && *ptr != '"') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ptr += strspn(ptr, " \t");
|
||||||
|
if (*ptr == '"') {
|
||||||
|
// Print the file path and recursively scan INCLUDEs
|
||||||
ptr++;
|
ptr++;
|
||||||
char *include_path = ptr;
|
char *include_path = ptr;
|
||||||
size_t length = strcspn(ptr, "\"");
|
size_t length = strcspn(ptr, "\"");
|
||||||
@ -74,6 +92,12 @@ void scan_file(const char *filename, bool strict) {
|
|||||||
if (is_include) {
|
if (is_include) {
|
||||||
scan_file(include_path, strict);
|
scan_file(include_path, strict);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "%s: no file path after INC%s\n", filename, is_include ? "LUDE" : "BIN");
|
||||||
|
// Continue to process a comment
|
||||||
|
if (*ptr == ';') {
|
||||||
|
ptr--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user