gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
gbdk-lib/include/gb/metasprites.h
1 /** @file gb/metasprites.h
2
3 @anchor metasprite_main_docs
4 # Metasprite support
5
6 A metasprite is a larger sprite made up from a
7 collection of smaller individual hardware sprites.
8 Different frames of the same metasprites can share
9 tile data.
10
11 The api supports metasprites in both
12 @ref SPRITES_8x8 and @ref SPRITES_8x16 mode. If
13 8x16 mode is used then the height of the metasprite
14 must be a multiple of 16.
15
16 The origin (pivot) for the metasprite is not required
17 to be in the upper left-hand corner as with regular
18 hardware sprites.
19
20 Use the @ref utility_png2asset tool to convert single
21 or multiple frames of graphics into metasprite
22 structured data for use with the ...metasprite...()
23 functions.
24
25 # Metasprites composed of variable numbers of sprites
26
27 When using png2asset, it's common for the output of
28 different frames to be composed of different numbers
29 of hardware sprites (since it's trying to create each
30 frame as efficiently as possible). Due to that, it's
31 good practice to clear out (hide) unused sprites in the
32 shadow_OAM that have been set by previous frames.
33
34 \code
35 // Example:
36 // Hide rest of the hardware sprites, because amount
37 // of sprites differ between animation frames.
38 // (where hiwater == last hardware sprite used + 1)
39 hide_sprites_range(hiwater, MAX_HARDWARE_SPRITES);
40 \endcode
41
42 @anchor metasprite_and_sprite_properties
43 # Metasprites and sprite properties (including cgb palette)
44
45 When the move_metasprite_*() functions are called they
46 update all properties for the affected sprites in the
47 Shadow OAM. This means any existing property flags set
48 for a sprite (CGB palette, BG/WIN priority, Tile VRAM Bank)
49 will get overwritten.
50
51 How to use sprite property flags with metasprites:
52 - Primary method: Use the `base_prop` parameter for the
53 move_metasprite_*() functions.
54 - For more details about the properties on the Game Boy see: https://gbdev.io/pandocs/OAM.html#byte-3--attributesflags
55 - This can be left at zero for defaults
56 - Various `OAMF_*` flags can be used depending on the platform:
57 - @ref OAMF_BANK0, @ref OAMF_BANK1
58 - @ref OAMF_CGB_PAL0, @ref OAMF_CGB_PAL1, @ref OAMF_CGB_PAL2, @ref OAMF_CGB_PAL3,
59 @ref OAMF_CGB_PAL4, @ref OAMF_CGB_PAL5, @ref OAMF_CGB_PAL6, @ref OAMF_CGB_PAL7,
60 - @ref OAMF_PAL0, @ref OAMF_PAL1,
61 - @ref OAMF_PALMASK, @ref OAMF_PRI, @ref OAMF_XFLIP, @ref OAMF_YFLIP
62
63 - Alternate method: The metasprite structures can have the
64 property flags modified before compilation (such as with
65 `-sp <props>` in the @ref utility_png2asset "png2asset" tool).
66
67 The following functions only support hardware sprite flipping
68 on the Game Boy / Mega Duck and NES. For other consoles which
69 do not have hardware sprite flipping see the cross-platform
70 metasprite example for a workaround (with some performance penalty).
71
72 - @ref move_metasprite_flipx()
73 - @ref move_metasprite_flipy()
74 - @ref move_metasprite_flipxy()
75
76 To test for hardware support see
77 @ref HARDWARE_SPRITE_CAN_FLIP_X and @ref HARDWARE_SPRITE_CAN_FLIP_Y.
78 Also see @ref docs_consoles_supported_list for a brief summary of
79 console capabilities.
80 */
81
82 #ifndef _METASPRITES_H_INCLUDE
83 #define _METASPRITES_H_INCLUDE
84
85 #include <gb/hardware.h>
86 #include <types.h>
87 #include <stdint.h>
88
89 /** Metasprite sub-item structure
90 @param dy (int8_t) Y coordinate of the sprite relative to the metasprite origin (pivot)
91 @param dx (int8_t) X coordinate of the sprite relative to the metasprite origin (pivot)
92 @param dtile (uint8_t) Start tile relative to the metasprites own set of tiles
93 @param props (uint8_t) Property Flags
94
95 Metasprites are built from multiple metasprite_t items (one for each sub-sprite)
96 and a pool of tiles they reference. If a metasprite has multiple frames then each
97 frame will be built from some number of metasprite_t items (which may vary based
98 on how many sprites are required for that particular frame).
99
100 A metasprite frame is terminated with a {metasprite_end} entry.
101 */
102 typedef struct metasprite_t {
103 int8_t dy, dx;
104 uint8_t dtile;
105 uint8_t props;
106 } metasprite_t;
107
108 #define metasprite_end -128
109 #define METASPR_ITEM(dy,dx,dt,a) {(dy),(dx),(dt),(a)}
110 #define METASPR_TERM {metasprite_end}
111
112 extern const void * __current_metasprite;
113 extern uint8_t __current_base_tile;
114 extern uint8_t __current_base_prop;
115 extern uint8_t __render_shadow_OAM;
116
117
118 static uint8_t __move_metasprite(uint8_t id, uint16_t yx);
119 static uint8_t __move_metasprite_flipx(uint8_t id, uint16_t yx);
120 static uint8_t __move_metasprite_flipy(uint8_t id, uint16_t yx);
121 static uint8_t __move_metasprite_flipxy(uint8_t id, uint16_t yx);
122 static uint8_t __move_metasprite_vflip(uint8_t id, uint16_t yx);
123 static uint8_t __move_metasprite_hflip(uint8_t id, uint16_t yx);
124 static uint8_t __move_metasprite_hvflip(uint8_t id, uint16_t yx);
125 static void __hide_metasprite(uint8_t id);
126
127 /**
128 Hides all hardware sprites in range from <= X < to
129 @param from start OAM index
130 @param to finish OAM index (must be <= MAX_HARDWARE_SPRITES)
131
132 @see hide_sprite, MAX_HARDWARE_SPRITES
133 */
134 void hide_sprites_range(uint8_t from, uint8_t to);
135
136 /** Moves metasprite to the absolute position x and y
137
138 @param metasprite Pointer to the first struct of the metasprite (for the desired frame)
139 @param base_tile Number of the first tile where the metasprite's tiles start
140 @param base_prop Base sprite property flags (can be used to set palette, etc)
141 @param base_sprite Number of the first hardware sprite to be used by the metasprite
142 @param x Absolute x coordinate of the sprite
143 @param y Absolute y coordinate of the sprite
144
145 Moves __metasprite__ to the absolute position __x__ and __y__
146 (with __no flip__ on the X or Y axis). Hardware sprites are
147 allocated starting from __base_sprite__, using tiles
148 starting from __base_tile__.
149
150 Sets:
151 \li __current_metasprite = metasprite;
152 \li __current_base_tile = base_tile;
153
154 Note: Overwrites OAM sprite properties (such as CGB Palette), see
155 @ref metasprite_and_sprite_properties "Metasprites and sprite properties".
156
157 @return Number of hardware sprites used to draw this metasprite
158 */
159 inline uint8_t move_metasprite_ex(const metasprite_t * metasprite, uint8_t base_tile, uint8_t base_prop, uint8_t base_sprite, uint8_t x, uint8_t y) {
160 __current_metasprite = metasprite;
161 __current_base_tile = base_tile;
162 __current_base_prop = base_prop;
163 return __move_metasprite(base_sprite, (y << 8) | (uint8_t)x);
164 }
165
166 /** Obsolete. This function has been replaced by move_metasprite_ex()
167 */
168 inline uint8_t move_metasprite(const metasprite_t * metasprite, uint8_t base_tile, uint8_t base_sprite, uint8_t x, uint8_t y) {
169 __current_metasprite = metasprite;
170 __current_base_tile = base_tile;
171 __current_base_prop = 0;
172 return __move_metasprite(base_sprite, (y << 8) | (uint8_t)x);
173 }
174
175 /** Moves metasprite to the absolute position x and y, __flipped by X (horizontally)__
176
177 @param metasprite Pointer to the first struct of the metasprite (for the desired frame)
178 @param base_tile Number of the first tile where the metasprite's tiles start
179 @param base_prop Base sprite property flags (can be used to set palette, etc)
180 @param base_sprite Number of the first hardware sprite to be used by the metasprite
181 @param x Absolute x coordinate of the sprite
182 @param y Absolute y coordinate of the sprite
183
184 Same as @ref move_metasprite(), but with the metasprite flipped by X (horizontally).
185
186 Sets:
187 \li __current_metasprite = metasprite;
188 \li __current_base_tile = base_tile;
189
190 Note: Overwrites OAM sprite properties (such as CGB palette), see
191 @ref metasprite_and_sprite_properties "Metasprites and sprite properties".
192
193 This function is only available on Game Boy and related clone consoles.
194
195 @return Number of hardware sprites used to draw this metasprite
196
197 @see move_metasprite()
198 */
199 inline uint8_t move_metasprite_flipx(const metasprite_t * metasprite, uint8_t base_tile, uint8_t base_prop, uint8_t base_sprite, uint8_t x, uint8_t y) {
200 __current_metasprite = metasprite;
201 __current_base_tile = base_tile;
202 __current_base_prop = base_prop;
203 return __move_metasprite_flipx(base_sprite, (y << 8) | (uint8_t)(x - 8u));
204 }
205
206 /** Obsolete. This function has been replaced by move_metasprite_flipx()
207 */
208 inline uint8_t move_metasprite_vflip(const metasprite_t * metasprite, uint8_t base_tile, uint8_t base_sprite, uint8_t x, uint8_t y) {
209 __current_metasprite = metasprite;
210 __current_base_tile = base_tile;
211 __current_base_prop = 0;
212 return __move_metasprite_vflip(base_sprite, (y << 8) | (uint8_t)(x - 8u));
213 }
214
215
216 /** Moves metasprite to the absolute position x and y, __flipped by Y (vertically)__
217
218 @param metasprite Pointer to the first struct of the metasprite (for the desired frame)
219 @param base_tile Number of the first tile where the metasprite's tiles start
220 @param base_prop Base sprite property flags (can be used to set palette, etc)
221 @param base_sprite Number of the first hardware sprite to be used by the metasprite
222 @param x Absolute x coordinate of the sprite
223 @param y Absolute y coordinate of the sprite
224
225 Same as @ref move_metasprite(), but with the metasprite flipped by Y (vertically).
226
227 Sets:
228 \li __current_metasprite = metasprite;
229 \li __current_base_tile = base_tile;
230
231 Note: Overwrites OAM sprite properties (such as CGB palette), see
232 @ref metasprite_and_sprite_properties "Metasprites and sprite properties".
233
234 This function is only available on Game Boy and related clone consoles.
235
236 @return Number of hardware sprites used to draw this metasprite
237
238 @see move_metasprite()
239 */
240 inline uint8_t move_metasprite_flipy(const metasprite_t * metasprite, uint8_t base_tile, uint8_t base_prop, uint8_t base_sprite, uint8_t x, uint8_t y) {
241 __current_metasprite = metasprite;
242 __current_base_tile = base_tile;
243 __current_base_prop = base_prop;
244 return __move_metasprite_flipy(base_sprite, ((y - ((LCDC_REG & LCDCF_OBJ16) ? 16u : 8u)) << 8) | x);
245 }
246
247 /** Obsolete. This function has been replaced by move_metasprite_flipy()
248 */
249 inline uint8_t move_metasprite_hflip(const metasprite_t * metasprite, uint8_t base_tile, uint8_t base_sprite, uint8_t x, uint8_t y) {
250 __current_metasprite = metasprite;
251 __current_base_tile = base_tile;
252 __current_base_prop = 0;
253 return __move_metasprite_hflip(base_sprite, ((y - ((LCDC_REG & LCDCF_OBJ16) ? 16u : 8u)) << 8) | x);
254 }
255
256 /** Moves metasprite to the absolute position x and y, __flipped by X and Y (horizontally and vertically)__
257
258 @param metasprite Pointer to the first struct of the metasprite (for the desired frame)
259 @param base_tile Number of the first tile where the metasprite's tiles start
260 @param base_prop Base sprite property flags (can be used to set palette, etc)
261 @param base_sprite Number of the first hardware sprite to be used by the metasprite
262 @param x Absolute x coordinate of the sprite
263 @param y Absolute y coordinate of the sprite
264
265 Same as @ref move_metasprite(), but with the metasprite flipped by X and Y (horizontally and vertically).
266
267 Sets:
268 \li __current_metasprite = metasprite;
269 \li __current_base_tile = base_tile;
270
271 Note: Overwrites OAM sprite properties (such as CGB palette), see
272 @ref metasprite_and_sprite_properties "Metasprites and sprite properties".
273
274 This function is only available on Game Boy and related clone consoles.
275
276 @return Number of hardware sprites used to draw this metasprite
277
278 @see move_metasprite()
279 */
280 inline uint8_t move_metasprite_flipxy(const metasprite_t * metasprite, uint8_t base_tile, uint8_t base_prop, uint8_t base_sprite, uint8_t x, uint8_t y) {
281 __current_metasprite = metasprite;
282 __current_base_tile = base_tile;
283 __current_base_prop = base_prop;
284 return __move_metasprite_flipxy(base_sprite, ((y - ((LCDC_REG & LCDCF_OBJ16) ? 16u : 8u)) << 8) | (uint8_t)(x - 8));
285 }
286
287 /** Obsolete. This function has been replaced by move_metasprite_flipxy()
288 */
289 inline uint8_t move_metasprite_hvflip(const metasprite_t * metasprite, uint8_t base_tile, uint8_t base_sprite, uint8_t x, uint8_t y) {
290 __current_metasprite = metasprite;
291 __current_base_tile = base_tile;
292 __current_base_prop = 0;
293 return __move_metasprite_hvflip(base_sprite, ((y - ((LCDC_REG & LCDCF_OBJ16) ? 16u : 8u)) << 8) | (uint8_t)(x - 8));
294 }
295
296 /** Hides a metasprite from the screen
297
298 @param metasprite Pointer to first struct of the desired metasprite frame
299 @param base_sprite Number of hardware sprite to start with
300
301 Sets:
302 \li __current_metasprite = metasprite;
303
304 **/
305 inline void hide_metasprite(const metasprite_t * metasprite, uint8_t base_sprite) {
306 __current_metasprite = metasprite;
307 __hide_metasprite(base_sprite);
308 }
309
310 #endif
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.