Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; MIT License
- ;
- ; Copyright (c) 2018 Eldred Habert
- ; Originally hosted at https://github.com/ISSOtm/rgbds-structs
- ;
- ; Permission is hereby granted, free of charge, to any person obtaining a copy
- ; of this software and associated documentation files (the "Software"), to deal
- ; in the Software without restriction, including without limitation the rights
- ; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- ; copies of the Software, and to permit persons to whom the Software is
- ; furnished to do so, subject to the following conditions:
- ;
- ; The above copyright notice and this permission notice shall be included in all
- ; copies or substantial portions of the Software.
- ;
- ; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- ; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- ; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- ; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- ; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- ; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- ; SOFTWARE.
- CORRECT_BEHAVIOR equ 1 ; Undefine this to disable SHIFT workaround
- ; struct struct_name
- ; Begins a struct declaration
- struct: MACRO
- IF DEF(NB_FIELDS)
- FAIL "Please close struct definitions using `end_struct`"
- ENDC
- STRUCT_NAME equs "\1"
- NB_FIELDS = 0
- RSRESET
- ENDM
- ; end_struct
- ; Ends a struct declaration
- end_struct: MACRO
- ; Set nb of fields
- STRUCT_NB_FIELDS equs "{STRUCT_NAME}_nb_fields"
- STRUCT_NB_FIELDS = NB_FIELDS
- PURGE STRUCT_NB_FIELDS
- ; Set size of struct
- STRUCT_SIZEOF equs "sizeof_{STRUCT_NAME}"
- STRUCT_SIZEOF RB 0
- PURGE STRUCT_SIZEOF
- PURGE NB_FIELDS
- PURGE STRUCT_NAME
- ENDM
- ; field_name_from_id field_id
- ; For internal use, please do not use externally
- field_name_from_id: MACRO
- FIELD_ID_STR equs "{\1}"
- STRUCT_FIELD equs STRCAT("{STRUCT_NAME}_field", STRSUB("{FIELD_ID_STR}", 2, STRLEN("{FIELD_ID_STR}") - 1))
- STRUCT_FIELD_NAME equs "{STRUCT_FIELD}_name"
- STRUCT_FIELD_TYPE equs "{STRUCT_FIELD}_type"
- STRUCT_FIELD_NBEL equs "{STRUCT_FIELD}_nb_el" ; Number of elements
- STRUCT_FIELD_SIZE equs "{STRUCT_FIELD}_size" ; sizeof(type) * nb_el
- ENDM
- ; new_field nb_elems, rs_type, field_name
- ; For internal use, please do not use externally
- new_field: MACRO
- IF !DEF(STRUCT_NAME) || !DEF(NB_FIELDS)
- FAIL "Please start defining a struct, using `define_struct`"
- ENDC
- field_name_from_id NB_FIELDS
- ; Set field name
- STRUCT_FIELD_NAME equs "\"\3\""
- PURGE STRUCT_FIELD_NAME
- ; Set field offset
- STRUCT_FIELD \2 (\1)
- ; Alias this in a human-comprehensive manner
- STRUCT_FIELD_NAME equs "{STRUCT_NAME}_\3"
- STRUCT_FIELD_NAME = STRUCT_FIELD
- ; Calculate field size
- CURRENT_RS RB 0
- STRUCT_FIELD_SIZE = CURRENT_RS - STRUCT_FIELD
- ; Set properties
- STRUCT_FIELD_NBEL = \1
- STRUCT_FIELD_TYPE equs STRSUB("\2", 2, 1)
- PURGE FIELD_ID_STR
- PURGE STRUCT_FIELD
- PURGE STRUCT_FIELD_NAME
- PURGE STRUCT_FIELD_TYPE
- PURGE STRUCT_FIELD_NBEL
- PURGE STRUCT_FIELD_SIZE
- PURGE CURRENT_RS
- NB_FIELDS = NB_FIELDS + 1
- ENDM
- ; bytes nb_bytes, field_name
- ; Defines a field of N bytes
- bytes: MACRO
- new_field \1, RB, \2
- ENDM
- ; words nb_words, field_name
- ; Defines a field of N*2 bytes
- words: MACRO
- new_field \1, RW, \2
- ENDM
- ; longs nb_longs, field_name
- ; Defines a field of N*4 bytes
- longs: MACRO
- new_field \1, RL, \2
- ENDM
- ; dstruct struct_type, var_name[, ...]
- ; Allocates space for a struct in memory
- ; If no further arguments are supplied, the space is simply allocated (using `ds`)
- ; Otherwise, the data is written to memory using the appropriate types
- ; For example, a struct defined with `bytes 1, Field1` and `words 3, Field2` would have four extra arguments, one byte then three words.
- dstruct: MACRO
- NB_FIELDS equs "\1_nb_fields"
- IF !DEF(NB_FIELDS)
- FAIL "Struct \1 isn't defined!"
- ENDC
- STRUCT_NAME equs "\1" ; Target this struct for `field_name_from_id`
- VAR_NAME equs "\2"
- VAR_NAME:: ; Declare the struct's root
- FIELD_ID = 0
- REPT NB_FIELDS
- field_name_from_id FIELD_ID
- FIELD_NAME equs STRCAT("{VAR_NAME}_", STRUCT_FIELD_NAME)
- FIELD_NAME::
- IF _NARG == 2 ; RAM definition, no data
- ds STRUCT_FIELD_SIZE
- ELSE
- TMP equs STRCAT("\{", STRCAT("{STRUCT_FIELD_TYPE}", "\}")) ; Temp var for double deref because "{{STRUCT_FIELD_TYPE}}" is a syntax error
- DATA_TYPE equs STRCAT("D", TMP)
- PURGE TMP
- PRINTT "FIELD: {FIELD_NAME}\n"
- IF DEF(CORRECT_BEHAVIOR)
- SHIFT_FIELDS equs ""
- ENDC
- REPT STRUCT_FIELD_NBEL
- DATA_TYPE \3
- PRINTT "{DATA_TYPE} \3\n"
- SHIFT
- IF DEF(CORRECT_BEHAVIOR)
- ; Hack because RGBDS saves the macro arguments when entering REPT blocks: I have to shift them outside as well
- TMP equs "{SHIFT_FIELDS}\n\tSHIFT"
- PURGE SHIFT_FIELDS
- SHIFT_FIELDS equs "{TMP}"
- PURGE TMP
- ENDC
- ENDR
- IF DEF(CORRECT_BEHAVIOR)
- SHIFT_FIELDS
- PURGE SHIFT_FIELDS
- ENDC
- PURGE DATA_TYPE
- ENDC
- ; Clean up vars for next iteration
- PURGE FIELD_ID_STR
- PURGE STRUCT_FIELD
- PURGE STRUCT_FIELD_NAME
- PURGE STRUCT_FIELD_TYPE
- PURGE STRUCT_FIELD_NBEL
- PURGE STRUCT_FIELD_SIZE
- PURGE FIELD_NAME
- FIELD_ID = FIELD_ID + 1
- ENDR
- ; Define variable's properties from struct's
- \2_nb_fields = NB_FIELDS
- sizeof_\2 = sizeof_\1
- ; Clean up
- PURGE NB_FIELDS
- PURGE STRUCT_NAME
- PURGE VAR_NAME
- PURGE FIELD_ID
- ENDM
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement