Rangi42 / polishedcrystal

An upgrade to Pokémon Crystal. Brings features and content up to date, and adds some original content.
https://hax.iimarckus.org/topic/6874/
1.06k stars 203 forks source link

Use a `row` macro to ensure each row of a table goes with its corresponding index #612

Open Rangi42 opened 3 years ago

Rangi42 commented 3 years ago

Something like this:

 table_width: MACRO
 CURRENT_TABLE_WIDTH = \1
 if _NARG == 2
 REDEF CURRENT_TABLE_START EQUS "\2"
 else
 REDEF CURRENT_TABLE_START EQUS "._table_width\@"
 {CURRENT_TABLE_START}:
+if _NARG == 3
+row_value = \3
+elif _NARG == 2 && ISCONST(\2)
+row_value = \2
+else
+row_value = 0
+endc
 endc
 ENDM

+row: MACRO
+x = \1
+   assert row_value == x, \
+       "{CURRENT_TABLE_START}: expected row for \1 to be at value {d:x}, got {d:row_value}"
+   shift
+   if _NARG
+       \#
+   endc
+row_value = row_value + 1
+ENDM
 list_start: MACRO
 list_index = 0
 if _NARG == 1
 REDEF CURRENT_LIST_START EQUS "\1"
 else
 REDEF CURRENT_LIST_START EQUS "._list_start\@"
 {CURRENT_LIST_START}:
+if _NARG == 2
+row_value = \2
+elif _NARG == 1 && ISCONST(\1)
+row_value = \1
+else
+row_value = 0
+endc
 endc
 ENDM

 li: MACRO
    assert !STRIN(\1, "@"), STRCAT("String terminator \"@\" in list entry: ", \1)
+x = \1
+   assert row_value == x, \
+       "{CURRENT_LIST_START}: expected li for \1 to be at value {d:x}, got {d:row_value}"
+   shift
+   if _NARG
+       \#
+   endc
+row_value = row_value + 1
    db \1, "@"
 list_index = list_index + 1
 ENDM

Example usage:

ItemDescriptions:
    table_width 2, ItemDescriptions, 1
    row POKE_BALL,  dw PokeBallDesc
    row GREAT_BALL, dw GreatBallDesc
    row ULTRA_BALL, dw UltraBallDesc
    ...
item_attribute: MACRO
; constant, price, held effect, parameter, pocket, field menu, battle menu
    row \1
    dw \2
    db \3, \4, \5
    dn \6, \7
ENDM

ItemAttributes:
    table_width ITEMATTR_STRUCT_LENGTH, ItemAttributes, 1
    item_attribute POKE_BALL,  200, 0, 0, BALL, ITEMMENU_PARTY, ITEMMENU_CLOSE
    item_attribute GREAT_BALL, 600, 0, 0, BALL, ITEMMENU_PARTY, ITEMMENU_CLOSE
    item_attribute ULTRA_BALL, 800, 0, 0, BALL, ITEMMENU_PARTY, ITEMMENU_CLOSE
    ...
ItemNames::
    list_start ItemNames   ; defaults like `list_start ItemNames, 0`
    li PARK_BALL,  "Park Ball"
    li POKE_BALL,  "Poké Ball"
    li GREAT_BALL, "Great Ball"
    ...
Rangi42 commented 3 years ago

Also consider base_data_for BULBASAUR and end_base_data macros to ensure the size of each base data entry file as well as its corresponding constant.

Rangi42 commented 3 years ago

Following discussion in pret #pokecrystal with dannye, I think we should avoid doing row CONSTANT, db ...; it's potentially confusing. Let's try adding macros db_for, dw_for, dba_for, and then a row_for to be used within the already-existing table entry macros. If some tables have more complex entries like dbbw, then instead of defining dbbw_for, that's probably a cue to give that table its own entry macro with individual row_for, db, db, dw within it.