GBAlatro
A Demake of Balatro for the GBA
Loading...
Searching...
No Matches
sprite.c
1#include "sprite.h"
2
3#include "audio_utils.h"
4#include "game.h"
5#include "game_variables.h"
6#include "graphic_utils.h"
7#include "item.h"
8#include "mgba_logger.h"
9#include "pool.h"
10#include "random.h"
11#include "soundbank.h"
12#include "util.h"
13
14#include <maxmod.h>
15#include <stdlib.h>
16#include <tonc.h>
17#include <tonc_oam.h>
18
19// Damping Constants: SPRING_DAMP_NUMERATOR/2^SPRING_DAMP_DENOM_SHIFT ~ 0.699 damping factor
20//
21// SPRING_DAMP_ROUNDING = 2^(SPRING_DAMP_DENOM_SHIFT - 1) rounding for fixed-point arithmetic by
22// adding half the denominator to round instead of truncating
23#define SPRING_DAMP_NUMERATOR 179
24#define SPRING_DAMP_DENOM_SHIFT 8
25#define SPRING_DAMP_ROUNDING (1 << (SPRING_DAMP_DENOM_SHIFT - 1))
26
27OBJ_ATTR obj_buffer[MAX_SPRITES];
28OBJ_AFFINE* obj_aff_buffer = (OBJ_AFFINE*)obj_buffer;
29
30static Sprite* free_sprites[MAX_SPRITES] = {NULL};
31static bool free_affines[MAX_AFFINES] = {false};
32
33static List sprite_objects_list = LIST_DEFAULT;
34
40static int s_sprite_tids[MAX_SPRITE_TYPE] = {0};
41
47static int s_sprite_starting_layers[MAX_SPRITE_TYPE] = {0};
48
49// clang-format off
50static const int s_sprite_counts[MAX_SPRITE_TYPE] = {
51 [CARD_SPRITE] = MAX_HAND_SIZE + MAX_SELECTION_SIZE,
52 [BLIND_TOKEN_SPRITE] = MAX_BLIND_TOKEN,
53 [SKIP_TAG_SPRITE] = MAX_SKIP_TAGS,
54 [JOKER_SPRITE] = MAX_ACTIVE_JOKERS,
55 [DECK_SPRITE] = 1
56};
57static const int s_sprite_sizes[MAX_SPRITE_TYPE] = {
58 [CARD_SPRITE] = CARD_SPRITE_TILES,
59 [BLIND_TOKEN_SPRITE] = BLIND_SPRITE_TILES,
60 [SKIP_TAG_SPRITE] = SKIP_TAG_SPRITE_TILES,
61 [JOKER_SPRITE] = JOKER_SPRITE_TILES,
62 [DECK_SPRITE] = CARD_SPRITE_TILES
63};
64// clang-format on
65
66int sprite_get_tid(enum SpriteType sprite_type, s16 layer)
67{
68 return s_sprite_tids[sprite_type] + layer * s_sprite_sizes[sprite_type];
69}
70
72{
73 return s_sprite_starting_layers[sprite_type];
74}
75
76// Sprite methods
77Sprite* sprite_new(u16 a0, u16 a1, u32 tid, u32 pb, s16 sprite_index)
78{
79 Sprite* sprite = POOL_GET(Sprite);
80
81 sprite->obj = NULL;
82 sprite->aff = NULL;
83
84 if (!free_sprites[sprite_index])
85 {
86 free_sprites[sprite_index] = sprite;
87 }
88 else
89 {
90 POOL_FREE(Sprite, sprite);
91 return NULL;
92 }
93
94 if (a0 & ATTR0_AFF)
95 {
96 int aff_index = MAX_AFFINES;
97
98 for (int i = 0; i < MAX_AFFINES; i++)
99 {
100 if (!free_affines[i])
101 {
102 free_affines[i] = true;
103 aff_index = i;
104 break;
105 }
106 }
107
108 if (aff_index == MAX_AFFINES)
109 {
110 POOL_FREE(Sprite, sprite);
111 return NULL;
112 }
113
114 a1 = a1 | ATTR1_AFF_ID(aff_index);
115
116 sprite->obj = &obj_buffer[sprite_index];
117 sprite->aff = &obj_aff_buffer[aff_index];
118 obj_set_attr(sprite->obj, a0, a1, ATTR2_PALBANK(pb) | tid);
119 obj_aff_identity(&obj_aff_buffer[aff_index]);
120 }
121 else
122 {
123 sprite->obj = &obj_buffer[sprite_index];
124 obj_set_attr(sprite->obj, a0, a1, ATTR2_PALBANK(pb) | tid);
125 }
126
127 sprite->idx = sprite_index;
128
129 sprite->mode = a0 & ATTR0_MODE_MASK;
130
131 return sprite;
132}
133
134void sprite_destroy(Sprite** sprite)
135{
136 if (*sprite == NULL)
137 return;
138
139 obj_hide((*sprite)->obj);
140
141 if ((*sprite)->aff != NULL)
142 {
143 free_affines[(*sprite)->aff - obj_aff_buffer] = false;
144 }
145
146 free_sprites[(*sprite)->idx] = NULL;
147
148 POOL_FREE(Sprite, *sprite);
149
150 *sprite = NULL;
151}
152
153/* The following functions don't check sprite->obj, assuming it shouldn't be NULL
154 * if sprite != NULL since it's set in the constructor
155 */
156
158{
159 GBAL_RETURN_IF_NULL(sprite, UNDEFINED);
160
161 return (s16)(sprite->obj - obj_buffer);
162}
163
164bool sprite_get_width(Sprite* sprite, int* width)
165{
166 GBAL_RETURN_IF_NULL(sprite, false);
167 GBAL_RETURN_IF_NULL(width, false);
168
169 *width = obj_get_width(sprite->obj);
170 return true;
171}
172
173bool sprite_get_height(Sprite* sprite, int* height)
174{
175 GBAL_RETURN_IF_NULL(sprite, false);
176 GBAL_RETURN_IF_NULL(height, false);
177
178 *height = obj_get_height(sprite->obj);
179 return true;
180}
181
182bool sprite_get_dimensions(Sprite* sprite, int* width, int* height)
183{
184 GBAL_RETURN_IF_NULL(sprite, false);
185 GBAL_RETURN_IF_NULL(width, false);
186 GBAL_RETURN_IF_NULL(height, false);
187
188 const u8* size = obj_get_size(sprite->obj);
189 *width = size[0];
190 *height = size[1];
191 return true;
192}
193
194// Sprite functions
196{
197 oam_init(obj_buffer, MAX_SPRITES);
198
199 // Start at 1, since the first element has a TID and starting layer of 0
200 for (enum SpriteType sprite_type = 1; sprite_type < MAX_SPRITE_TYPE; sprite_type++)
201 {
202 s_sprite_tids[sprite_type] =
203 s_sprite_tids[sprite_type - 1] +
204 s_sprite_counts[sprite_type - 1] * s_sprite_sizes[sprite_type - 1];
205 s_sprite_starting_layers[sprite_type] =
206 s_sprite_starting_layers[sprite_type - 1] + s_sprite_counts[sprite_type - 1];
207 }
208}
209
211{
212 oam_copy(oam_mem, obj_buffer, MAX_SPRITES);
213}
214
215int sprite_get_pb(const Sprite* sprite)
216{
217 GBAL_RETURN_IF_NULL(sprite, UNDEFINED);
218
219 return (sprite->obj->attr2 & ATTR2_PALBANK_MASK) >> ATTR2_PALBANK_SHIFT;
220}
221
222void sprite_hide(Sprite* sprite)
223{
225
226 obj_hide(sprite->obj);
227}
228
230{
232
233 obj_unhide(sprite->obj, sprite->mode);
234}
235
236// SpriteObject methods
238{
239 GBAL_RETURN_IF_NULL(sprite_object, RET_NONE);
240
241 sprite_object->sprite = NULL;
242 sprite_object_reset_transform(sprite_object);
243 sprite_object->focused = false;
244
245 list_push_back(&sprite_objects_list, sprite_object);
246}
247
249{
250 GBAL_RETURN_IF_NULL(sprite_object, RET_NONE);
251
252 list_remove_data(&sprite_objects_list, sprite_object);
253 sprite_destroy(&sprite_object->sprite);
254}
255
256void sprite_object_set_sprite(SpriteObject* sprite_object, Sprite* sprite)
257{
258 GBAL_RETURN_IF_NULL(sprite_object, RET_NONE);
259
260 sprite_destroy(&sprite_object->sprite); // Destroy the old sprite if it exists
261 sprite_object->sprite = sprite;
262}
263
265{
266 GBAL_RETURN_IF_NULL(sprite_object, RET_NONE);
267
268 sprite_hide(sprite_object->sprite);
269}
270
272{
273 GBAL_RETURN_IF_NULL(sprite_object, RET_NONE);
274
275 sprite_unhide(sprite_object->sprite);
276}
277
279{
280 GBAL_RETURN_IF_NULL(sprite_object, RET_NONE);
281
282 sprite_object_position(sprite_object, 0, 0); // Target position
283 sprite_object->vx = 0;
284 sprite_object->vy = 0;
285 sprite_object->tscale = FIX_ONE; // Target scale
286 sprite_object->scale = FIX_ONE;
287 sprite_object->vscale = 0;
288 sprite_object->trotation = 0; // Target rotation
289 sprite_object->rotation = 0;
290 sprite_object->vrotation = 0;
291}
292
293/* The following functions are in the SpriteObject update loop which is called each frame
294 * so they avoid argument NULL-checks for efficiency.
295 */
296
297static inline bool sprite_object_has_velocity(const SpriteObject* sprite_object)
298{
299 return sprite_object->vx != 0 || sprite_object->vy != 0 || sprite_object->vscale != 0 ||
300 sprite_object->vrotation != 0;
301}
302
303static inline bool sprite_object_at_target(const SpriteObject* s)
304{
305 return s->x == s->tx && s->y == s->ty && s->scale == s->tscale && s->rotation == s->trotation;
306}
307
308static inline bool is_sprite_object_static(const SpriteObject* sprite_object)
309{
310 return !sprite_object_has_velocity(sprite_object) && sprite_object_at_target(sprite_object);
311}
312
313static inline IWRAM_CODE void update_sprite_position(SpriteObject* sprite_object)
314{
315 sprite_object->vx += ((sprite_object->tx - sprite_object->x) * g_game_vars.game_speed) / 8;
316 sprite_object->vy += ((sprite_object->ty - sprite_object->y) * g_game_vars.game_speed) / 8;
317
318 // Scale up the card when it's played
319 sprite_object->vscale += (sprite_object->tscale - sprite_object->scale) / 8;
320
321 // Rotate the card when it's played
322 sprite_object->vrotation += (sprite_object->trotation - sprite_object->rotation) / 8;
323
324 const FIXED epsilon = (FIX_ONE >> 6); // = 1/2^6 = 0.015625
325
326 // Snap to target position when velocity is negligible to avoid infinite approach
327 if (abs(sprite_object->vx) < epsilon && abs(sprite_object->vy) < epsilon)
328 {
329 sprite_object->vx = 0;
330 sprite_object->vy = 0;
331
332 sprite_object->x = sprite_object->tx;
333 sprite_object->y = sprite_object->ty;
334 }
335 else
336 {
337 sprite_object->vx = (sprite_object->vx * SPRING_DAMP_NUMERATOR + SPRING_DAMP_ROUNDING) >>
338 SPRING_DAMP_DENOM_SHIFT;
339 sprite_object->vy = (sprite_object->vy * SPRING_DAMP_NUMERATOR + SPRING_DAMP_ROUNDING) >>
340 SPRING_DAMP_DENOM_SHIFT;
341
342 sprite_object->x += sprite_object->vx;
343 sprite_object->y += sprite_object->vy;
344 }
345
346 // Set scale to 0 if it's close enough to the target
347 if (abs(sprite_object->vscale) < epsilon)
348 {
349 sprite_object->vscale = 0;
350 sprite_object->scale = sprite_object->tscale;
351 }
352 else
353 {
354 sprite_object->vscale =
355 (sprite_object->vscale * SPRING_DAMP_NUMERATOR + SPRING_DAMP_ROUNDING) >>
356 SPRING_DAMP_DENOM_SHIFT;
357 sprite_object->scale += sprite_object->vscale;
358 }
359
360 // For rotation, prioritize snapping to target if close enough, then zero velocity.
361 if (abs(sprite_object->vrotation) < epsilon)
362 {
363 sprite_object->vrotation = 0;
364 sprite_object->rotation = sprite_object->trotation;
365 }
366 else // Apply damping and update rotation if not yet settled
367 {
368 sprite_object->vrotation =
369 (sprite_object->vrotation * SPRING_DAMP_NUMERATOR + SPRING_DAMP_ROUNDING) >>
370 SPRING_DAMP_DENOM_SHIFT;
371 sprite_object->rotation += sprite_object->vrotation;
372 }
373
374 // Apply rotation and scale to the sprite
375 obj_aff_rotscale(
376 sprite_object->sprite->aff,
377 sprite_object->scale,
378 sprite_object->scale,
379 -sprite_object->vx + sprite_object->rotation
380 );
381}
382
383IWRAM_CODE void sprite_object_update(SpriteObject* sprite_object)
384{
385 if (!is_sprite_object_static(sprite_object))
386 update_sprite_position(sprite_object);
387
388 sprite_position(sprite_object->sprite, fx2int(sprite_object->x), fx2int(sprite_object->y));
389}
390
392{
393 SpriteObject* sprite_object = NULL;
394 ListItr itr = list_itr_create(&sprite_objects_list);
395 while ((sprite_object = list_itr_next(&itr)))
396 {
397 sprite_object_update(sprite_object);
398 }
399}
400
401#define SPRITE_SHAKE_VSCALE 0.3f
402#define SPRITE_SHAKE_VROTATION 8.0f
403void sprite_object_shake(SpriteObject* sprite_object, mm_word sound_id)
404{
405 GBAL_RETURN_IF_NULL(sprite_object, RET_NONE);
406
407 sprite_object->vscale = float2fx(SPRITE_SHAKE_VSCALE);
408 sprite_object->vrotation = float2fx(SPRITE_SHAKE_VROTATION); // Rotate the card when it's scored
409
410 if (sound_id == UNDEFINED)
411 return; // If no sound ID is provided, do nothing
412
414}
415
416void sprite_object_bounce(SpriteObject* sprite_object, FIXED strength)
417{
418 GBAL_RETURN_IF_NULL(sprite_object, RET_NONE);
419 sprite_object->vscale = strength;
420}
421
422#define SPRITE_SWAY_VROTATION -10.0f
424{
425 GBAL_RETURN_IF_NULL(sprite_object, RET_NONE);
426 sprite_object->vrotation = float2fx(SPRITE_SWAY_VROTATION);
427}
428
429void sprite_object_set_target(SpriteObject* sprite_object, BG_POINT to)
430{
431 GBAL_RETURN_IF_NULL(sprite_object, RET_NONE);
432 if (to.x == UNDEFINED || to.y == UNDEFINED)
433 return;
434
435 sprite_object->tx = int2fx(to.x);
436 sprite_object->ty = int2fx(to.y);
437}
438
440{
441 GBAL_RETURN_IF_NULL(sprite_object, NULL);
442
443 return sprite_object->sprite;
444}
445
446void sprite_object_set_focus(SpriteObject* sprite_object, bool focus)
447{
448 GBAL_RETURN_IF_NULL(sprite_object, RET_NONE);
449
450 if (sprite_object->focused == focus)
451 {
452 return;
453 }
454 sprite_object->focused = focus;
455
456 play_sfx(
457 SFX_CARD_FOCUS,
458 MM_BASE_PITCH_RATE + rng_get_u32(RNG_SEQ_MISC) % CARD_FOCUS_SFX_PITCH_OFFSET_RANGE,
460 );
461 sprite_object->ty = sprite_object->ty + int2fx((focus ? -1 : 1) * SPRITE_FOCUS_RAISE_PX);
462}
463
464bool sprite_object_get_width(SpriteObject* sprite_object, int* width)
465{
466 GBAL_RETURN_IF_NULL(sprite_object, false);
467
468 return sprite_get_width(sprite_object->sprite, width);
469}
470
471bool sprite_object_get_height(SpriteObject* sprite_object, int* height)
472{
473 GBAL_RETURN_IF_NULL(sprite_object, false);
474
475 return sprite_get_height(sprite_object->sprite, height);
476}
477
478bool sprite_object_get_dimensions(SpriteObject* sprite_object, int* width, int* height)
479{
480 GBAL_RETURN_IF_NULL(sprite_object, false);
481
482 return sprite_get_dimensions(sprite_object->sprite, width, height);
483}
484
486{
487 GBAL_RETURN_IF_NULL(sprite_object, false);
488 return sprite_object->focused;
489}
490
491static Rect sprite_object_get_text_rect_under(SpriteObject* sprite_object)
492{
493 int height = 0;
494 int width = 0;
495 Rect ret_rect = {0};
496
497 GBAL_RETURN_IF_NULL(sprite_object, ret_rect);
498
499 if (sprite_object_get_dimensions(sprite_object, &width, &height) == false)
500 {
501 // fallback
502 height = CARD_SPRITE_SIZE_PX;
503 width = CARD_SPRITE_SIZE_PX;
504 }
505
506 ret_rect.left = fx2int(sprite_object->tx);
507 ret_rect.top = fx2int(sprite_object->ty) + height + TILE_SIZE;
508 ret_rect.right = ret_rect.left + width;
509 ret_rect.bottom = ret_rect.top + TTE_CHAR_SIZE;
510
511 return ret_rect;
512}
513
514void sprite_object_print_text_under(SpriteObject* sprite_object, const char text[])
515{
516 GBAL_RETURN_IF_NULL(sprite_object, RET_NONE);
517
518 Rect text_rect = sprite_object_get_text_rect_under(sprite_object);
519 update_text_rect_to_center_str(&text_rect, text, SCREEN_LEFT);
520 tte_printf("#{P:%d,%d; cx:0x%X000}%s", text_rect.left, text_rect.top, TTE_YELLOW_PB, text);
521}
522
523void sprite_object_print_price_under(SpriteObject* sprite_object, int price)
524{
525 GBAL_RETURN_IF_NULL(sprite_object, RET_NONE);
526
527 // + 2 for null-terminator and "$"
528 char price_str_buff[INT_MAX_DIGITS + 2];
529 snprintf(price_str_buff, sizeof(price_str_buff), "$%d", price);
530 sprite_object_print_text_under(sprite_object, price_str_buff);
531}
532
534{
535 GBAL_RETURN_IF_NULL(sprite_object, RET_NONE);
536
537 Rect text_rect = sprite_object_get_text_rect_under(sprite_object);
538
539 // Add SPRITE_FOCUS_RAISE_PX to cover the focused case
540 text_rect.bottom = text_rect.bottom + SPRITE_FOCUS_RAISE_PX;
541
542 tte_erase_rect_wrapper(text_rect);
543}
Utilities for using maxmod to play sound effects.
#define MM_BASE_PITCH_RATE
The default pitch rate for the sound effect played.
Definition audio_utils.h:37
void play_sfx(mm_word id, mm_word rate, mm_byte volume)
Play a sound effect, wrapper for mmEffectEx() See https://maxmod.org/ref/functions/mm_sound_effect....
#define SFX_DEFAULT_VOLUME
Default volume for sound effects.
Definition audio_utils.h:43
Game global game variables struct definition.
Graphic utility functions.
void update_text_rect_to_center_str(Rect *rect, const char *str, enum ScreenHorzDir bias_direction)
Updates a rect so a string is centered within it.
#define TILE_SIZE
Tile size in pixels, both height and width as tiles are square.
#define TTE_CHAR_SIZE
By default TTE characters occupy a single tile.
void tte_erase_rect_wrapper(Rect rect)
A wrapper for tte_erase_rect that would use the rect struct.
The core structure for items in the shop and inventory. Provides a common API for the shop and invent...
void * list_itr_next(ListItr *itr)
Definition list.c:281
bool list_remove_data(List *list, void *data)
Definition list.c:316
#define LIST_DEFAULT
Default list declaration for empty lists.
Definition list.h:30
void list_push_back(List *list, void *data)
Definition list.c:89
ListItr list_itr_create(List *list)
Definition list.c:257
Interface to interact with the mgba logger.
Common functions to handle RNG manipulation. Using this interface has three goals:
u32 rng_get_u32(enum RngSequence key)
Get the next "randomly" generated number in the sequence corresponding to the given type.
Definition random.c:56
Sprite system for Gbalatro.
bool sprite_object_get_dimensions(SpriteObject *sprite_object, int *width, int *height)
Get the width and height of SpriteObject's registered Sprite.
Definition sprite.c:478
bool sprite_object_is_focused(SpriteObject *sprite_object)
Get the focused variable from a SpriteObject.
Definition sprite.c:485
bool sprite_get_width(Sprite *sprite, int *width)
Get a Sprite's width.
Definition sprite.c:164
INLINE void sprite_position(Sprite *sprite, int x, int y)
Set sprite position. Inlined for efficiency.
Definition sprite.h:466
void sprite_object_unhide(SpriteObject *sprite_object)
Unhides the SpriteObject by manipulating ATTR0_HIDE in OAM. The sprite's ATTR0_MODE is maintained fro...
Definition sprite.c:271
void sprite_object_set_focus(SpriteObject *sprite_object, bool focus)
Set the focus for SpriteObject Raises the object by SPRITE_FOCUS_RAISE_PX.
Definition sprite.c:446
void sprite_object_init(SpriteObject *sprite_object)
Initialize a SpriteObject to a default state. Must be called only once per SpriteObject when it is cr...
Definition sprite.c:237
void sprite_object_destroy(SpriteObject *sprite_object)
Destroy SpriteObject.
Definition sprite.c:248
void sprite_object_print_price_under(SpriteObject *sprite_object, int price)
Print the price string directly beneath a SpriteObject. More specialized version of sprite_object_pri...
Definition sprite.c:523
s16 sprite_get_layer(Sprite *sprite)
Get index of Sprite in the GBA object buffer.
Definition sprite.c:157
void sprite_object_print_text_under(SpriteObject *sprite_object, const char text[])
Print the given string directly beneath a SpriteObject. This is used only for Cards for now.
Definition sprite.c:514
int sprite_get_tid(enum SpriteType sprite_type, s16 layer)
Get the tile index of a certain SpriteType at a certain layer.
Definition sprite.c:66
void sprite_init(void)
Initialize GBAlatro sprite system.
Definition sprite.c:195
void sprite_object_bounce(SpriteObject *sprite_object, FIXED strength)
Make SpriteObject bounce by slightly increasing its size in an elastic way.
Definition sprite.c:416
void sprite_object_reset_transform(SpriteObject *sprite_object)
Reset SpriteObject's transform back to default values.
Definition sprite.c:278
int sprite_get_pb(const Sprite *sprite)
Get the palette bank of a Sprite.
Definition sprite.c:215
bool sprite_object_get_width(SpriteObject *sprite_object, int *width)
Get a SpriteObject's width.
Definition sprite.c:464
void sprite_object_set_sprite(SpriteObject *sprite_object, Sprite *sprite)
Register a Sprite to an associated SpriteObject.
Definition sprite.c:256
void sprite_object_update_all(void)
Update all SpriteObjects, to be called once per frame in the main update loop.
Definition sprite.c:391
void sprite_object_set_target(SpriteObject *sprite_object, BG_POINT to)
Set a SpriteObject's target position so that is slides across the screen between from the current pos...
Definition sprite.c:429
bool sprite_get_dimensions(Sprite *sprite, int *width, int *height)
Get a Sprite's width and height.
Definition sprite.c:182
bool sprite_object_get_height(SpriteObject *sprite_object, int *height)
Get a SpriteObject's height.
Definition sprite.c:471
INLINE void sprite_object_position(SpriteObject *sprite_object, int x, int y)
Set sprite_object position. Inlined for efficiency.
Definition sprite.h:483
void sprite_object_shake(SpriteObject *sprite_object, mm_word sound_id)
Shake SpriteObject on screen and play a sound.
Definition sprite.c:403
Sprite * sprite_new(u16 a0, u16 a1, u32 tid, u32 pb, s16 sprite_index)
Allocate and retrieve a pointer to a valid Sprite.
Definition sprite.c:77
void sprite_object_erase_text_under(SpriteObject *sprite_object)
Erase the text within the Rect directly beneath a SpriteObject. This is used only for Cards for now.
Definition sprite.c:533
bool sprite_get_height(Sprite *sprite, int *height)
Get a Sprites's height.
Definition sprite.c:173
void sprite_destroy(Sprite **sprite)
Destroy Sprite.
Definition sprite.c:134
Sprite * sprite_object_get_sprite(SpriteObject *sprite_object)
Get a SpriteObject's registered Sprite.
Definition sprite.c:439
SpriteType
The different types of sprites in the game.
Definition sprite.h:41
void sprite_hide(Sprite *sprite)
Hides the sprite by manipulating ATTR0_HIDE in OAM.
Definition sprite.c:222
void sprite_unhide(Sprite *sprite)
Unhides the sprite by manipulating ATTR0_HIDE in OAM. The sprite's ATTR0_MODE is maintained from the ...
Definition sprite.c:229
int sprite_get_starting_layer(enum SpriteType sprite_type)
Get the starting layer of a certain type of sprite.
Definition sprite.c:71
void sprite_object_sway(SpriteObject *sprite_object)
Make SpriteObject sway by slightly rotating on screen.
Definition sprite.c:423
void sprite_draw(void)
Draw Sprites to screen, to be called once per frame.
Definition sprite.c:210
IWRAM_CODE void sprite_object_update(SpriteObject *sprite_object)
Update a SpriteObject, to be called once per frame per active SpriteObject.
Definition sprite.c:383
void sprite_object_hide(SpriteObject *sprite_object)
Hides the SpriteObject by manipulating ATTR0_HIDE in OAM.
Definition sprite.c:264
An iterator into a list.
Definition list.h:91
A doubly-linked list.
Definition list.h:61
A sprite object is a sprite that is focusable and movable in animation.
Definition sprite.h:86
FIXED x
Current position.
Definition sprite.h:100
bool focused
Focused status (card specific, raise and lower card)
Definition sprite.h:140
FIXED vscale
Scale velocity AKA the rate of change of scaling ops.
Definition sprite.h:120
FIXED rotation
Actual rotation, in units for tonc's obj_aff_rotscale
Definition sprite.h:130
FIXED tx
Target position.
Definition sprite.h:95
FIXED trotation
Target rotation.
Definition sprite.h:125
FIXED vx
Velocity.
Definition sprite.h:105
FIXED scale
Current Scale, in units for tonc's obj_aff_rotscale
Definition sprite.h:115
Sprite * sprite
Sprite configuration info.
Definition sprite.h:90
FIXED tscale
Target Scale.
Definition sprite.h:110
FIXED vrotation
Rotation velocity.
Definition sprite.h:135
Sprite struct for GBA hardware specifics.
Definition sprite.h:54
OBJ_AFFINE * aff
GBA sprite affine matrices registers info.
Definition sprite.h:63
s16 idx
Sprite index in memory managed by GBAlatro.
Definition sprite.h:73
u16 mode
The mode of the sprite (regular, affine, etc.), set when the sprite is created corresponds to A0 & AT...
Definition sprite.h:79
OBJ_ATTR * obj
GBA sprite attribute registers info (A0-A2)
Definition sprite.h:58
Utilities relating around number string representation and protected arithmatic helper functions.
#define GBAL_RETURN_IF_NULL(param, ret_val)
Returns ret_val and prints a default error message if param is equal to NULL. Useful for checking arg...
Definition util.h:138
#define RET_NONE
An empty return value for RETURN_IF macros when used in void functions Expands to nothing because mac...
Definition util.h:146