pret / pokecrystal

Disassembly of Pokémon Crystal
https://pret.github.io/pokecrystal/
2.07k stars 784 forks source link

Macros to verify trainer parties #992

Closed Rangi42 closed 2 years ago

Rangi42 commented 2 years ago

Concept: begin each party with def_trainer, and end them with end_trainer, which will declare the db -1 terminator and assert that the total party size corresponds to the TRAINERTYPE.

MACRO def_trainer
    db \1, \2 ; name, type
    DEF CURRENT_TRAINER_MON_SIZE = \
        2 * ((\2) == TRAINERTYPE_NORMAL) + \
        6 * ((\2) == TRAINERTYPE_MOVES) + \
        3 * ((\2) == TRAINERTYPE_ITEM) + \
        7 * ((\2) == TRAINERTYPE_ITEM_MOVES)
    REDEF CURRENT_TRAINER_LABEL EQUS "._def_trainer_\@"
{CURRENT_TRAINER_LABEL}:
ENDM

MACRO end_trainer
    assert (@ - {CURRENT_TRAINER_LABEL}) % CURRENT_TRAINER_MON_SIZE == 0, \
        "def_trainer: expected {d:CURRENT_TRAINER_MON_SIZE} bytes per Pokémon"
    db -1 ; end
ENDM

OfficerGroup:
    ; OFFICER (1)
    def_trainer "KEITH@", TRAINERTYPE_NORMAL
    db 17, GROWLITHE
    end_trainer

    ; OFFICER (2)
    def_trainer "DIRK@", TRAINERTYPE_NORMAL
    db 14, GROWLITHE
    db 14, GROWLITHE
    end_trainer
vulcandth commented 2 years ago

Can we add an additional end_trainer assert? Something like...

assert ((@ - {CURRENT_TRAINER_LABEL}) / CURRENT_TRAINER_MON_SIZE > 0) && \
    ((@ - {CURRENT_TRAINER_LABEL}) / CURRENT_TRAINER_MON_SIZE < PARTY_LENGTH), \
    "def_trainer: expected number of pokemon to be > 0 or <= {d:PARTY_LENGTH}"
Rangi42 commented 2 years ago

See the discussion in #pokecrystal with @mid-kid about that.

mid-kid commented 2 years ago

LGTM

Rangi42 commented 2 years ago

@aaaaaa123456789 pointed out that this could still have false negatives. This has six bytes of party data, which is enough for one mon with MOVES, but is actually three NORMAL mons:

    def_trainer "KEITH@", TRAINERTYPE_MOVES
    db 17, GROWLITHE
    db 18, GROWLITHE
    db 19, GROWLITHE
    end_trainer
mid-kid commented 2 years ago

I don't want to macroize the entire thing I don't want to macroize the entire thing I don't want to macroize the entire thing aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa We can also just, not do this :)

Rangi42 commented 2 years ago

Yeah, if it were a simple def_X/end_X macro pair like the rest I'd do it, but it's not.