Advertisement
ISSOtm

Upcoming version of RGBDS-structs

Feb 3rd, 2019
230
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. ; MIT License
  3. ;
  4. ; Copyright (c) 2018 Eldred Habert
  5. ; Originally hosted at https://github.com/ISSOtm/rgbds-structs
  6. ;
  7. ; Permission is hereby granted, free of charge, to any person obtaining a copy
  8. ; of this software and associated documentation files (the "Software"), to deal
  9. ; in the Software without restriction, including without limitation the rights
  10. ; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. ; copies of the Software, and to permit persons to whom the Software is
  12. ; furnished to do so, subject to the following conditions:
  13. ;
  14. ; The above copyright notice and this permission notice shall be included in all
  15. ; copies or substantial portions of the Software.
  16. ;
  17. ; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. ; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. ; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. ; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. ; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. ; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23. ; SOFTWARE.
  24.  
  25.  
  26. CORRECT_BEHAVIOR equ 1 ; Undefine this to disable SHIFT workaround
  27.  
  28.  
  29. ; struct struct_name
  30. ; Begins a struct declaration
  31. struct: MACRO
  32.     IF DEF(NB_FIELDS)
  33.         FAIL "Please close struct definitions using `end_struct`"
  34.     ENDC
  35.  
  36. STRUCT_NAME equs "\1"
  37.  
  38. NB_FIELDS = 0
  39.     RSRESET
  40. ENDM
  41.  
  42. ; end_struct
  43. ; Ends a struct declaration
  44. end_struct: MACRO
  45. ; Set nb of fields
  46. STRUCT_NB_FIELDS equs "{STRUCT_NAME}_nb_fields"
  47. STRUCT_NB_FIELDS = NB_FIELDS
  48.     PURGE STRUCT_NB_FIELDS
  49.  
  50. ; Set size of struct
  51. STRUCT_SIZEOF equs "sizeof_{STRUCT_NAME}"
  52. STRUCT_SIZEOF RB 0
  53.     PURGE STRUCT_SIZEOF
  54.  
  55.     PURGE NB_FIELDS
  56.     PURGE STRUCT_NAME
  57. ENDM
  58.  
  59.  
  60. ; field_name_from_id field_id
  61. ; For internal use, please do not use externally
  62. field_name_from_id: MACRO
  63. FIELD_ID_STR equs "{\1}"
  64. STRUCT_FIELD equs STRCAT("{STRUCT_NAME}_field", STRSUB("{FIELD_ID_STR}", 2, STRLEN("{FIELD_ID_STR}") - 1))
  65. STRUCT_FIELD_NAME equs "{STRUCT_FIELD}_name"
  66. STRUCT_FIELD_TYPE equs "{STRUCT_FIELD}_type"
  67. STRUCT_FIELD_NBEL equs "{STRUCT_FIELD}_nb_el" ; Number of elements
  68. STRUCT_FIELD_SIZE equs "{STRUCT_FIELD}_size" ; sizeof(type) * nb_el
  69. ENDM
  70.  
  71.  
  72. ; new_field nb_elems, rs_type, field_name
  73. ; For internal use, please do not use externally
  74. new_field: MACRO
  75.     IF !DEF(STRUCT_NAME) || !DEF(NB_FIELDS)
  76.         FAIL "Please start defining a struct, using `define_struct`"
  77.     ENDC
  78.  
  79.     field_name_from_id NB_FIELDS
  80. ; Set field name
  81. STRUCT_FIELD_NAME equs "\"\3\""
  82.     PURGE STRUCT_FIELD_NAME
  83.  
  84. ; Set field offset
  85. STRUCT_FIELD \2 (\1)
  86. ; Alias this in a human-comprehensive manner
  87. STRUCT_FIELD_NAME equs "{STRUCT_NAME}_\3"
  88. STRUCT_FIELD_NAME = STRUCT_FIELD
  89.  
  90. ; Calculate field size
  91. CURRENT_RS RB 0
  92. STRUCT_FIELD_SIZE = CURRENT_RS - STRUCT_FIELD
  93.  
  94. ; Set properties
  95. STRUCT_FIELD_NBEL = \1
  96. STRUCT_FIELD_TYPE equs STRSUB("\2", 2, 1)
  97.  
  98.     PURGE FIELD_ID_STR
  99.     PURGE STRUCT_FIELD
  100.     PURGE STRUCT_FIELD_NAME
  101.     PURGE STRUCT_FIELD_TYPE
  102.     PURGE STRUCT_FIELD_NBEL
  103.     PURGE STRUCT_FIELD_SIZE
  104.     PURGE CURRENT_RS
  105.  
  106. NB_FIELDS = NB_FIELDS + 1
  107. ENDM
  108.  
  109. ; bytes nb_bytes, field_name
  110. ; Defines a field of N bytes
  111. bytes: MACRO
  112.     new_field \1, RB, \2
  113. ENDM
  114.  
  115. ; words nb_words, field_name
  116. ; Defines a field of N*2 bytes
  117. words: MACRO
  118.     new_field \1, RW, \2
  119. ENDM
  120.  
  121. ; longs nb_longs, field_name
  122. ; Defines a field of N*4 bytes
  123. longs: MACRO
  124.     new_field \1, RL, \2
  125. ENDM
  126.  
  127.  
  128. ; dstruct struct_type, var_name[, ...]
  129. ; Allocates space for a struct in memory
  130. ; If no further arguments are supplied, the space is simply allocated (using `ds`)
  131. ; Otherwise, the data is written to memory using the appropriate types
  132. ; For example, a struct defined with `bytes 1, Field1` and `words 3, Field2` would have four extra arguments, one byte then three words.
  133. dstruct: MACRO
  134. NB_FIELDS equs "\1_nb_fields"
  135.     IF !DEF(NB_FIELDS)
  136.         FAIL "Struct \1 isn't defined!"
  137.     ENDC
  138. STRUCT_NAME equs "\1" ; Target this struct for `field_name_from_id`
  139. VAR_NAME    equs "\2"
  140.  
  141. VAR_NAME:: ; Declare the struct's root
  142.  
  143. FIELD_ID = 0
  144.     REPT NB_FIELDS
  145.  
  146.         field_name_from_id FIELD_ID
  147. FIELD_NAME equs STRCAT("{VAR_NAME}_", STRUCT_FIELD_NAME)
  148. FIELD_NAME::
  149.         IF _NARG == 2 ; RAM definition, no data
  150.             ds STRUCT_FIELD_SIZE
  151.         ELSE
  152. TMP equs STRCAT("\{", STRCAT("{STRUCT_FIELD_TYPE}", "\}")) ; Temp var for double deref because "{{STRUCT_FIELD_TYPE}}" is a syntax error
  153. DATA_TYPE equs STRCAT("D", TMP)
  154.             PURGE TMP
  155.             PRINTT "FIELD: {FIELD_NAME}\n"
  156. IF DEF(CORRECT_BEHAVIOR)
  157. SHIFT_FIELDS equs ""
  158. ENDC
  159.             REPT STRUCT_FIELD_NBEL
  160.                 DATA_TYPE \3
  161.                 PRINTT "{DATA_TYPE} \3\n"
  162.                 SHIFT
  163. IF DEF(CORRECT_BEHAVIOR)
  164. ; Hack because RGBDS saves the macro arguments when entering REPT blocks: I have to shift them outside as well
  165. TMP equs "{SHIFT_FIELDS}\n\tSHIFT"
  166.     PURGE SHIFT_FIELDS
  167. SHIFT_FIELDS equs "{TMP}"
  168.     PURGE TMP
  169. ENDC
  170.             ENDR
  171. IF DEF(CORRECT_BEHAVIOR)
  172.     SHIFT_FIELDS
  173.     PURGE SHIFT_FIELDS
  174. ENDC
  175.             PURGE DATA_TYPE
  176.         ENDC
  177.  
  178.         ; Clean up vars for next iteration
  179.         PURGE FIELD_ID_STR
  180.         PURGE STRUCT_FIELD
  181.         PURGE STRUCT_FIELD_NAME
  182.         PURGE STRUCT_FIELD_TYPE
  183.         PURGE STRUCT_FIELD_NBEL
  184.         PURGE STRUCT_FIELD_SIZE
  185.         PURGE FIELD_NAME
  186.  
  187. FIELD_ID = FIELD_ID + 1
  188.     ENDR
  189.  
  190.  
  191.     ; Define variable's properties from struct's
  192. \2_nb_fields = NB_FIELDS
  193. sizeof_\2 = sizeof_\1
  194.  
  195.  
  196.     ; Clean up
  197.     PURGE NB_FIELDS
  198.     PURGE STRUCT_NAME
  199.     PURGE VAR_NAME
  200.     PURGE FIELD_ID
  201. ENDM
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement