Alchemy
Loading...
Searching...
No Matches

animation.c

Go to the documentation of this file.
1/// @file
2/// Sprites, their animation layers and the resource slots they draw from.
3/// Part of field.c, the field object, compiled only through it.
4
5#include "../field_internal.h"
6
7enum {
9 ANIMATION_SHADOW_TILE_BYTES = 16 * 8, ///< 16x8 pixels, 256 colours
13};
14
15/// A row of gResourceSlot_NumberTable: the packed resource that holds an
16/// animation number's frames, ending at number 0.
20};
21
23
24/// Loads the frames of animation id number into resource slot slot's buffer:
25/// the resource listed for it in gResourceSlot_NumberTable, decoded, its frame
26/// offsets turned into pointers, and for variant 1-5 its pixel colours (those
27/// up to 0xdf) remapped through that variant's conversion table. Returns the
28/// image's size in pixels (width * height), or 0 when the slot or id is not
29/// known. Sets the slot's tag to (slot << 12) | number and its buffer; with
30/// a null buffer and number 0 it does only that, which is how the battle frees
31/// a slot. Called by the sprite viewer
32/// and, as ResourceSlot_LoadFar, by the battle for its enemy sprites (variant
33/// is the class's palette).
34s32 ResourceSlot_Load(u32 slot, u32 *buffer, s32 number, u32 variant) {
35 struct AnimationMetadata *metadata;
36 struct ObjectSystemWork *work;
37 struct ResourceSlot *record;
38 struct ResourceSlotNumber *entry;
39 u32 *offset;
40 u8 *pixels;
41 u8 *end;
42 u8 *colorMap;
43 u32 size;
44 u32 count;
45 u32 index;
46 u16 entryNumber;
48
49 if (slot >= RESOURCE_SLOT_COUNT)
50 return 0;
51 work = gMenuCtrlWork;
52 record = &work->slots[slot];
54 record->tag = (slot << 12) | number;
55 record->buffer = buffer;
56
57 // Resolve the animation number to its packed resource.
59 for (count = 0; count < 256; count++) {
60 s16 *numbers = &entry->number;
61
62 resource = entry->resource;
63 entryNumber = *numbers;
64 entry++;
65 if (entryNumber == 0)
66 return 0;
67 if (entryNumber == number)
68 break;
69 }
71
72 // Turn the frame-offset directory into pointers before the pixel payload.
73 offset = buffer;
74 for (count = 0; count < 256; count++) {
75 if (*offset == 0)
76 break;
77 *offset += (u32)buffer;
78 offset++;
79 }
80 if (variant != 0) {
81 index = variant - 1;
82 pixels = (u8 *)(offset + 1);
83 end = (u8 *)buffer + size;
84 if (index > 4)
85 index = 0;
86 // Values above 0xdf are kept; only the remappable palette range changes.
87 colorMap = gResourceSlot_ConversionTables[index];
88 for (; pixels < end; pixels++) {
89 u32 colorIndex = *pixels;
90
91 if (colorIndex <= 0xdf) {
92 colorIndex = colorMap[colorIndex];
93 *pixels = colorIndex;
94 }
95 }
96 }
97 return metadata->width * metadata->height;
98}
99
100/// Returns the buffer loaded into the resource slot with this tag, or 0.
101/// An animation id that carries its slot in bits 12 and up finds its frames
102/// here; called by the layer set-up functions below.
104 u32 i;
105 struct ResourceSlot *slot = gMenuCtrlWork->slots;
106
107 for (i = 0; i < RESOURCE_SLOT_COUNT; i++, slot++) {
108 if (slot->tag == tag)
109 return (s32)slot->buffer;
110 }
111 return 0;
112}
113
114/// Resets each layer of a sprite from its animation's metadata: its facing
115/// kind, frames, scripts and codec, with no frame shown and no script
116/// running. The first layer also sets the sprite's size, scale and offsets.
117/// Returns 0. Called by Animation_SetIndexAndInitObjects.
119 s32 i;
120
121 for (i = 0; i < sprite->count; i++) {
122 struct AnimationEntry *layer = sprite->entries[i];
123 struct AnimationMetadata *metadata =
125 void **frames;
126
127 if (metadata->width == 0)
128 continue;
129
130 if (i == 0) {
131 // The first layer supplies the dimensions and origin of the whole sprite.
132 sprite->width = metadata->width;
133 sprite->height = metadata->height;
134 sprite->scale = metadata->scale << 8;
135 sprite->offsetY = metadata->adjustY;
136 sprite->offsetX = metadata->adjustX;
137 }
138
139 // An animation whose metadata has no frames takes them from the resource
140 // slot loaded under its id (ResourceSlot_Load).
141 frames = metadata->frames;
142 if (frames == 0)
143 frames = (void **)Animation_LookupValueByKey(layer->animId);
144
145 layer->kind = metadata->drawKind;
146 layer->frames = frames;
147 layer->scripts = metadata->animation;
148 layer->mode = metadata->frameCodec;
149 layer->frame = 0xff;
150 layer->script = 0;
151 layer->pos = 0;
152 }
153
154 return 0;
155}
156
157/// Resets one animation layer from its animation's metadata, as
158/// Animation_InitializeObjects does for each layer. Called by the sprite
159/// viewer.
161 void **frames;
162 s32 zero;
163 struct AnimationMetadata *metadata;
164
165 if (layer != NULL) {
166 metadata = Resource_GetMetadataRecordFar(layer->animId);
167 if (metadata->width != 0) {
168 // Keep the layer inactive until an animation script is selected.
169 frames = metadata->frames;
170 if (frames == 0)
171 frames = (void **)Animation_LookupValueByKey(layer->animId);
172 layer->kind = metadata->drawKind;
173 layer->scripts = metadata->animation;
174 layer->frames = frames;
175 layer->mode = metadata->frameCodec;
176 zero = 0;
177 layer->frame = 0xff;
178 layer->script = (u8 *)zero;
179 layer->pos = zero;
180 }
181 }
182}
183
184/// Adds a layer of animation id to a sprite, in its first free layer of
185/// four. The first layer also sets the sprite's size, scale and offsets.
186/// Returns the layer, 0 when no layer record is free, or -1 when the sprite
187/// has four layers already. Called by ResourceObject_Create for a sprite's
188/// first layer, by ObjectDispatch_RegisterChildMetadata and the sprite
189/// viewer, and as ResourceMetadata_RegisterFar by the battle, the Psynergy
190/// effects and the field scene's actors.
192 s32 layerHandle = (s32)sprite->entries[0];
193 s32 freeIndex = 0;
194 struct AnimationEntry **entry;
195 struct AnimationMetadata *metadata;
196
197 // Find an unused layer slot before reserving a layer record.
198 if (layerHandle != 0) {
199 entry = &sprite->entries[0];
200 do {
201 freeIndex++;
202 if (freeIndex >= ANIMATION_LAYER_COUNT)
203 break;
204 entry++;
205 layerHandle = (s32)*entry;
206 } while (layerHandle != 0);
207 }
208 if (freeIndex == ANIMATION_LAYER_COUNT)
209 return -1;
210 layerHandle = (s32)AnimationObject_Allocate(id);
211 if (layerHandle == 0)
212 return 0;
213 sprite->entries[freeIndex] = (struct AnimationEntry *)layerHandle;
214 metadata = Resource_GetMetadataRecordFar(id);
215 // Only the first registered layer establishes the sprite's geometry.
216 if (sprite->count == 0) {
217 sprite->width = metadata->width;
218 sprite->height = metadata->height;
219 sprite->scale = metadata->scale << 8;
220 sprite->offsetY = metadata->adjustY;
221 sprite->offsetX = metadata->adjustX;
222 }
223 if (freeIndex == sprite->count)
224 sprite->count = freeIndex + 1;
225 return layerHandle;
226}
227
228/// Removes the layer handle from a sprite and clears it, trimming the
229/// sprite's layer count when no later layer remains. Called through
230/// ResourceMetadata_UnregisterFar by the battle's objects.
232 s32 laterLayers;
233 u32 index;
234 u32 i;
235
236 if (sprite != NULL && layer != 0) {
238 // Locate the handle, then trim only empty slots at the end of the list.
239 for (index = 0; index < ANIMATION_LAYER_COUNT; index++) {
240 if (layer == (s32)sprite->entries[index])
241 break;
242 }
243 if (index != ANIMATION_LAYER_COUNT) {
244 sprite->entries[index] = 0;
245 laterLayers = 0;
246 for (i = index + 1; i < ANIMATION_LAYER_COUNT; i++) {
247 if (sprite->entries[i] != 0)
248 laterLayers++;
249 }
250 if (laterLayers == 0)
251 sprite->count = index;
252 }
253 }
254}
255
256/// Removes and clears a sprite's layer number no (0-3), trimming the sprite's
257/// layer count when no later layer remains.
259 struct AnimationEntry *layer;
260 s32 laterLayers;
261 u32 i;
262
263 if (sprite != NULL && index < ANIMATION_LAYER_COUNT) {
264 layer = sprite->entries[index];
265 if (layer != NULL) {
267 sprite->entries[index] = NULL;
268 laterLayers = 0;
269 // Interior holes stay available; only trailing holes reduce the count.
270 for (i = index + 1; i < ANIMATION_LAYER_COUNT; i++) {
271 if (sprite->entries[i] != NULL)
272 laterLayers++;
273 }
274 if (laterLayers == 0)
275 sprite->count = index;
276 }
277 }
278}
279
280/// Starts the indexed animation on a layer when its metadata contains it.
281/// Bit 7 preserves the command cursor and timer; it remains part of the index.
282/// Reached through the animation script's play command
283/// (Sprite_ComposeAnimationFrame) and, as Animation_SetWorkEntryFar, from the
284/// battle's motion and objects.
285/// XXX: unlike AnimationObjects_SelectAnimation it does not mask bit 7 off,
286/// so with bit 7 set the index passes animationCount only in a set of more
287/// than 128 animations; a script that plays with bit 7 would show whether
288/// that is an original bug.
289void Animation_SetWorkEntry(struct AnimationEntry *layer, s32 animation) {
290 s32 keepPlace;
291 struct AnimationMetadata *metadata;
292 s32 scriptAddress;
293
294 keepPlace = 0x80 & animation;
295 if (layer->scripts != 0) {
296 metadata = Resource_GetMetadataRecordFar(layer->animId);
298 scriptAddress = (s32)layer->scripts[animation];
299 layer->kind = metadata->drawKind;
300 layer->script = (u8 *)scriptAddress;
302 if (keepPlace == 0) {
303 layer->pos = keepPlace;
304 layer->timer = keepPlace;
305 }
306 }
307 }
308}
309
310/// Starts animation flags & 0x7f on every layer of a sprite (bit 7 keeps
311/// each layer's place and timer), unless the sprite plays it already. The
312/// first layer's animation also sets the sprite's offsets. Returns 0.
313/// The engine's usual way to change what a sprite plays: called by the
314/// object dispatch and the player control, and as
315/// AnimationObjects_SelectAnimationFar by the battle, the shops, the menus,
316/// the battle and Psynergy effects and the scene scripts.
318 s32 animation) {
319 s32 keepPlace;
320 s32 i;
321
322 keepPlace = animation & 0x80;
323 animation &= 0x7f;
324
325 // The loop is written with goto, which keeps an 8-byte frame: as for (i = 0;
326 // i < sprite->count; i++), loop.c strength-reduces entries[i] into a spilled
327 // cursor and 16 of 76 instructions differ in tbs-en.
328 if (sprite->lastNo != animation) {
329 i = 0;
330 goto test_entry;
331 entry_loop:
332 // Only the first layer supplies the sprite's offsets.
333 {
334 struct AnimationEntry *layer = sprite->entries[i];
335 struct AnimationMetadata *metadata;
336 s32 selectedAnimation;
337
338 if (layer != 0 && layer->scripts != 0) {
339 metadata = Resource_GetMetadataRecordFar(layer->animId);
341 selectedAnimation = (s32)layer->scripts[animation];
342 layer->kind = metadata->drawKind;
343 layer->script = (u8 *)selectedAnimation;
345 if (keepPlace == 0) {
346 layer->pos = 0;
347 layer->timer = 0;
348 }
349 if (i == 0) {
350 sprite->offsetY = metadata->adjustY;
351 sprite->offsetX = metadata->adjustX;
352 }
353 }
354 }
355 }
356 i++;
357 test_entry:
358 if (i < sprite->count)
359 goto entry_loop;
360 sprite->lastNo = animation;
361 }
362 return 0;
363}
364
365/// Sets each animated layer's timer to the given duration in frames.
366/// Returns 0.
368 s32 frames) {
369 u8 count = sprite->count;
370 struct AnimationEntry **layerList;
371 s32 remaining;
372
373 if (count != 0) {
374 // The layer timer counts sixteenths of a frame.
375 frames <<= 4;
376 layerList = sprite->entries;
377 remaining = count;
378 do {
379 struct AnimationEntry *layer = *layerList++;
380 if (layer != 0 && layer->scripts != 0)
381 layer->timer = frames;
382 remaining--;
383 } while (remaining != 0);
384 }
385 return 0;
386}
387
388/// Sets the timer step, the animation speed, of each animated layer of a
389/// sprite (16 is normal speed). Called by the object dispatch and, as
390/// AnimationObjects_SetActiveTimerStepsFar, by the Sanctum, which stops a
391/// party member's icon with 0 and restarts it with 16.
393 s32 step) {
394 u8 count = sprite->count;
395 if (count != 0) {
396 struct AnimationEntry **layerList = sprite->entries;
397 s32 remaining = count;
398 do {
399 struct AnimationEntry *layer = *layerList++;
400 if (layer != 0 && layer->scripts != 0)
401 layer->step = step;
402 remaining--;
403 } while (remaining != 0);
404 }
405}
406
407/// Allocates and zeroes the 64 sprites and 64 animation layers (from the
408/// fixed blocks in mode 3, the heap otherwise), sets up the palette DMA,
409/// loads the shadow tiles into VRAM cache entry 93 and puts the sprite tile
410/// uploader in RAM. Called by ObjectSystem_Initialize.
412 void *sprites;
413 void *layers;
414 volatile u32 zero;
415
416 // World-map mode keeps the sprite and layer pools in the fixed heap blocks.
417 if (mode == 3) {
419 sizeof(struct AnimationObject));
421 sizeof(struct AnimationEntry));
422 } else {
424 sizeof(struct AnimationObject));
426 sizeof(struct AnimationEntry));
427 }
428 // Load the sprites' basic colours, clear both pools, then load the shared
429 // shadow (128 bytes: the two 8x8 tiles of a 16x8, 256-colour sprite) and
430 // the tile uploader.
432 Dma_Fill32Cell(zero, 0, sprites,
433 ANIMATION_OBJECT_COUNT * sizeof(struct AnimationObject));
434 Dma_Fill32Cell(zero, 0, layers,
435 ANIMATION_OBJECT_COUNT * sizeof(struct AnimationEntry));
440}
441
442/// Takes a free animation layer record and starts it on animation id's first
443/// animation. Returns the layer, or NULL when none is free or the id has no
444/// image. Called by ResourceMetadata_Register.
446 struct AnimationMetadata *metadata;
447 struct AnimationEntry *candidate;
448 struct AnimationEntry *found;
449 struct AnimationEntry *layer;
450 s32 i;
451 void **frames;
452 u8 **scripts;
453
454 found = NULL;
455 metadata = Resource_GetMetadataRecordFar(id);
456 candidate = gAnimationObjects[0];
457 layer = NULL;
458
459 if (metadata->width != 0) {
460 // A zero facing kind marks a free layer record.
461 for (i = 0; i < ANIMATION_OBJECT_COUNT; i++, candidate++) {
462 if (candidate->kind == 0) {
463 found = candidate;
464 break;
465 }
466 }
467 if (found != NULL) {
468 // Bind the metadata and start its first animation at command zero.
469 // UB: the word view aliases a pointer field. It keeps the zero load
470 // ahead of frames as native; reading the pointer swaps those loads.
471#ifdef UBFIX
472 frames = metadata->frames;
473#else
474 frames = (void **)*(s32 *)&metadata->frames;
475#endif
476 layer = found;
477 layer->animId = id;
478 if (frames == 0)
479 frames = (void **)Animation_LookupValueByKey(id);
480
481 scripts = metadata->animation;
482 layer->scripts = scripts;
483 layer->frames = frames;
484 layer->mode = metadata->frameCodec;
485 layer->frame = 0xff;
486 layer->script = scripts[0];
487 layer->pos = 0;
488 layer->kind = metadata->drawKind;
489 layer->param = 0;
490 }
491 }
492 return layer;
493}
494
495/// Zeroes one animation layer (struct AnimationEntry); does nothing for NULL.
496/// Zeroing kind frees the record for AnimationObject_Allocate. Called by the
497/// layer release functions here and, as ResourceMetadata_ClearRecordFar, by
498/// the Psynergy effects and scene scripts.
500 if (record != 0) {
501 Dma_Fill32(0, record, sizeof(*record));
502 }
503}
504
505// Creating and releasing animated sprites, and measuring animation lengths.
506
507/// Creates a sprite for animation id, taking one of the 64 free sprites and a
508/// VRAM cache entry for its tiles. Returns the sprite, or NULL when there is
509/// no room or the id has no image. Called by FieldObject_Create and the sprite
510/// viewer, and as ResourceObject_CreateFar by the battle, the battle effects,
511/// the Psynergy effects and the menus.
513 struct AnimationMetadata *metadata;
514 struct AnimationObject *sprite;
515 struct AnimationObject *freeSprite;
516#ifdef UBFIX
517 u32 attributes[2 * sizeof(struct AnimationSpritePart) / sizeof(u32)];
518#else
519 u32 *attribute;
520#endif
521 s32 slot;
522 s32 tile;
523 s32 i;
524 u32 shape;
525
526 freeSprite = NULL;
527 metadata = Resource_GetMetadataRecordFar(id);
528 slot = Resource_FindFreeEntry();
529 sprite = gSpriteObjects;
530 if (metadata->width == 0)
531 return NULL;
532 // A width of 0 marks a free sprite.
533 for (i = 0; i < ANIMATION_OBJECT_COUNT; i++, sprite++) {
534 if (sprite->width == 0) {
535 freeSprite = sprite;
536 break;
537 }
538 }
539 if (freeSprite == NULL)
540 return NULL;
541 if (slot == VRAM_CACHE_ENTRY_COUNT)
542 return NULL;
543 tile = VramCache_Load(slot, 0, 0);
544 if (tile == 0)
545 return NULL;
546 freeSprite->slot = slot;
547 freeSprite->rotation = 0;
548 freeSprite->flags = 1;
549
550 // The OAM shape and size bits (attributes 0 and 1) for the image's width
551 // and height in pixels.
552 switch ((u32)((metadata->width << 8) + metadata->height)) {
553 case 0x0808: // 8x8
554 shape = 0;
555 break;
556 case 0x0810: // 8x16
557 shape = 0x8000;
558 break;
559 case 0x1008: // 16x8
560 shape = 0x4000;
561 break;
562 case 0x1010: // 16x16
563 shape = 0x40000000;
564 break;
565 case 0x1020: // 16x32
566 shape = 0x80008000;
567 break;
568 case 0x2010: // 32x16
569 shape = 0x80004000;
570 break;
571 case 0x2020: // 32x32
572 shape = 0x80000000;
573 break;
574 case 0x2040: // 32x64
575 shape = 0xc0008000;
576 break;
577 case 0x4020: // 64x32
578 shape = 0xc0004000;
579 break;
580 case 0x4040: // 64x64
581 shape = 0xc0000000;
582 break;
583 default:
584 shape = 0;
585 break;
586 }
587
588 // Part 0 is the image: 256 colours, priority 2. Part 1 is its shadow: a
589 // 16x8, 256-colour sprite of the shared shadow tiles, priority 2.
590 // UB: the native word cursor aliases the sprite and crosses its members.
591 // UBFIX copies the same representation from an actual word array.
592#ifdef UBFIX
593 attributes[0] = 0;
594 attributes[1] = shape | ANIMATION_OAM_FULL_COLOR;
595 attributes[2] = tile | ANIMATION_OAM_PRIORITY_2;
596 attributes[3] = 0;
598 attributes[5] = (gVramBlockCache[ANIMATION_SHADOW_CACHE_ENTRY].offset >> 5) |
600 memcpy(freeSprite, attributes, sizeof(attributes));
601#else
602 attribute = (u32 *)freeSprite;
603 *attribute++ = 0;
604 *attribute++ = shape | ANIMATION_OAM_FULL_COLOR;
605 *attribute++ = tile | ANIMATION_OAM_PRIORITY_2;
606 *attribute++ = 0;
610#endif
611 if (ResourceMetadata_Register(sprite, id) == -1) {
612 /* FAKEMATCH(dead): a store of the byte it reloads keeps the -1 the native
613 * builds after the call and never uses; with the call alone, 2 of 152
614 * instructions differ in tbs-en. */
615 freeSprite->dirty = freeSprite->dirty;
616 }
617 return freeSprite;
618}
619
620/// Releases a sprite: its VRAM cache entry (unless retainCacheEntry is set),
621/// its four animation layers, and then zeroes its 56 bytes. Called by
622/// ObjectDispatch_Release and, as ResourceObject_ReleaseFar, by the battle
623/// and its effects, the Psynergy effects and the menus.
625 s32 remaining;
626 struct AnimationEntry **layer;
627
628 if (sprite) {
629 // Release dependent records before clearing the sprite itself.
630 if (!sprite->retainCacheEntry)
631 Resource_ResetEntry(sprite->slot);
632 layer = sprite->entries;
633 remaining = ANIMATION_LAYER_COUNT - 1;
634 do {
636 } while (--remaining >= 0);
637 Dma_Fill32(0, sprite, sizeof(*sprite));
638 }
639}
640
641/// Returns how long the first frameCount frames of animation number animation
642/// of id last: the sum of the arguments of its frame, wait and blank commands,
643/// up to frameCount of them or the first play, hold, jump or end command.
644/// Called through ResourceMetadata_SumCommandLengthsFar by the battle's
645/// staging.
647 struct AnimationMetadata *metadata;
648 u8 *script;
649 u8 command;
650 u8 duration;
651 s32 durationSum = 0;
652
653 metadata = Resource_GetMetadataRecordFar(id);
654 if (animation >= metadata->animationCount) {
655 return 0;
656 }
657 script = ((u8 **)metadata->animation)[animation];
658 // Only timed commands count; control-flow commands terminate this scan.
659 for (;;) {
660 command = script[0];
661 duration = script[1];
662 script += 2;
663 if (command == ANIM_CMD_PLAY || command == ANIM_CMD_HOLD ||
664 command == ANIM_CMD_JUMP || command == ANIM_CMD_END) {
665 break;
666 }
667 if (command == ANIM_CMD_WAIT || command == ANIM_CMD_BLANK ||
668 command < ANIM_CMD_END) {
669 durationSum += duration;
670 frameCount--;
671 if (frameCount == 0) {
672 break;
673 }
674 }
675 }
676 return durationSum;
677}
void AnimationObjects_SetActiveTimerSteps(struct AnimationObject *sprite, s32 step)
Sets the timer step, the animation speed, of each animated layer of a sprite (16 is normal speed).
Definition animation.c:392
s32 ResourceSlot_Load(u32 slot, u32 *buffer, s32 number, u32 variant)
Loads the frames of animation id number into resource slot slot's buffer: the resource listed for it ...
Definition animation.c:34
s32 ResourceMetadata_Register(struct AnimationObject *sprite, s32 id)
Adds a layer of animation id to a sprite, in its first free layer of four.
Definition animation.c:191
struct AnimationEntry * AnimationObject_Allocate(s32 id)
Takes a free animation layer record and starts it on animation id's first animation.
Definition animation.c:445
void ResourceMetadata_ClearRecord(struct AnimationEntry *record)
Zeroes one animation layer (struct AnimationEntry); does nothing for NULL.
Definition animation.c:499
void ResourceMetadata_ReleaseSlot(struct AnimationObject *sprite, u32 index)
Removes and clears a sprite's layer number no (0-3), trimming the sprite's layer count when no later ...
Definition animation.c:258
void ObjectSystem_Configure(s32 mode)
Allocates and zeroes the 64 sprites and 64 animation layers (from the fixed blocks in mode 3,...
Definition animation.c:411
s32 AnimationObjects_SelectAnimation(struct AnimationObject *sprite, s32 animation)
Starts animation flags & 0x7f on every layer of a sprite (bit 7 keeps each layer's place and timer),...
Definition animation.c:317
s32 AnimationObjects_SetActiveFrameTimers(struct AnimationObject *sprite, s32 frames)
Sets each animated layer's timer to the given duration in frames.
Definition animation.c:367
void ResourceMetadata_Unregister(struct AnimationObject *sprite, s32 layer)
Removes the layer handle from a sprite and clears it, trimming the sprite's layer count when no later...
Definition animation.c:231
s32 Animation_LookupValueByKey(s32 tag)
Returns the buffer loaded into the resource slot with this tag, or 0.
Definition animation.c:103
void ResourceObject_Release(struct AnimationObject *sprite)
Releases a sprite: its VRAM cache entry (unless retainCacheEntry is set), its four animation layers,...
Definition animation.c:624
@ ANIMATION_OAM_FULL_COLOR
Definition animation.c:10
@ ANIMATION_OAM_PRIORITY_2
Definition animation.c:11
@ ANIMATION_OAM_WIDE
Definition animation.c:12
@ ANIMATION_SHADOW_CACHE_ENTRY
Definition animation.c:8
@ ANIMATION_SHADOW_TILE_BYTES
16x8 pixels, 256 colours
Definition animation.c:9
struct ResourceSlotNumber gResourceSlot_NumberTable[]
s32 Animation_InitializeObjects(struct AnimationObject *sprite)
Resets each layer of a sprite from its animation's metadata: its facing kind, frames,...
Definition animation.c:118
s32 ResourceMetadata_SumCommandLengths(s32 id, u32 animation, s32 frameCount)
Returns how long the first frameCount frames of animation number animation of id last: the sum of the...
Definition animation.c:646
void Animation_SetWorkEntry(struct AnimationEntry *layer, s32 animation)
Starts the indexed animation on a layer when its metadata contains it.
Definition animation.c:289
void Animation_InitWorkFromMetadata(struct AnimationEntry *layer)
Resets one animation layer from its animation's metadata, as Animation_InitializeObjects does for eac...
Definition animation.c:160
struct AnimationObject * ResourceObject_Create(s32 id)
Creates a sprite for animation id, taking one of the 64 free sprites and a VRAM cache entry for its t...
Definition animation.c:512
#define Dma_Fill32Cell(cell, value, destination, size)
Dma_Fill32 through the caller's own volatile word cell, so a function that fills several blocks keeps...
Definition dma.h:42
#define Dma_Fill32(value, destination, size)
Fills size bytes at destination with the word value by DMA3.
Definition dma.h:30
struct AnimationMetadata * Resource_GetMetadataRecordFar(u32 number)
What every part of the field object shares: its includes and the few names more than one part uses.
@ ANIMATION_OBJECT_COUNT
@ RESOURCE_SLOT_COUNT
@ ANIMATION_LAYER_COUNT
@ ANIMATION_NORMAL_STEP
@ ANIM_CMD_JUMP
continue at script position arg
@ ANIM_CMD_WAIT
keep the current frame arg frames longer
@ ANIM_CMD_BLANK
show nothing for arg
@ ANIM_CMD_END
blank the layer and stop its script
@ ANIM_CMD_PLAY
switch to animation arg
@ ANIM_CMD_HOLD
stay on this command and frame for good
struct AnimationObject * gSpriteObjects
void * Runtime_AllocateBlock(s32 kind, s32 size)
As Runtime_AllocateHeapBlock, but tries EWRAM first, for blocks that need room more than speed: the b...
Definition heap.c:80
void * Runtime_AllocateHeapBlock(s32 kind, s32 size)
Returns heap slot kind's block, first allocating size bytes for it (rounded up to words),...
Definition heap.c:47
@ HEAP_SLOT_FRAME_UPLOADER
Definition heap_state.h:54
struct ObjectSystemWork * gMenuCtrlWork
#define RamCode_LoadSlot(slot, code, bytes)
Allocates a work-slot copy; release it with Runtime_ReleaseHeapBlock.
Definition ramcode.h:26
s32 Resource_DecodeType01(const void *source, void *destination)
Decodes a type-01 resource and returns its unpacked byte count.
Definition decompress.c:31
#define NULL
Definition bilibin.h:6
One animation layer of a sprite: its animation id, frames, running script and timer.
Definition animspr.h:37
u8 param
SpriteColorMode its pixels are drawn with; 0 when taken.
Definition animspr.h:45
u8 pos
byte offset of the next command in script
Definition animspr.h:51
u8 ** scripts
the metadata's command scripts, one per animation number
Definition animspr.h:49
u8 step
taken off timer each frame; 16 is normal speed
Definition animspr.h:52
u8 * script
the running script; null when stopped (ANIM_CMD_END)
Definition animspr.h:50
u8 kind
The facing table its frames follow (from the metadata, or ANIM_CMD_SET_KIND); zero marks a free layer...
Definition animspr.h:44
s16 animId
the sprite id whose metadata and frames it uses
Definition animspr.h:38
u8 mode
frame codec: 1 type-01, 3 LZ, anything else raw
Definition animspr.h:47
void ** frames
frame pointers, from the metadata or a resource slot
Definition animspr.h:48
u16 timer
Time left on the current frame in sixteenths of a frame, read signed: each timed command adds its arg...
Definition animspr.h:41
u8 frame
frame shown, frameBase plus the facing offset; 255 none
Definition animspr.h:53
An animation's metadata: the sprite's size, scale and offsets, how its frames are drawn and decoded,...
u16 scale
8.8 fixed point, 0x100 full size
An animated sprite: its image and shadow, scale, rotation, size and up to four animation layers.
Definition animspr.h:108
s8 offsetX
pixels
Definition animspr.h:121
s8 offsetY
pixels
Definition animspr.h:122
u16 rotation
1/65536 turns
Definition animspr.h:118
u8 flags
bits: 1 outlined in ObjectSystemWork's edge and fill colours | 0 shadow drawn (set when created)
Definition animspr.h:128
u8 width
pixels; zero marks a free sprite
Definition animspr.h:119
u8 height
pixels
Definition animspr.h:120
u8 lastNo
The animation number last selected, which selecting again skips.
Definition animspr.h:124
u8 slot
VRAM cache entry holding its tiles.
Definition animspr.h:112
struct AnimationEntry * entries[4]
its layers; empty ones null
Definition animspr.h:130
u8 count
layers in use, up to the last one present
Definition animspr.h:129
s32 scale
16.16 fixed point, 0x10000 full size
Definition animspr.h:111
u8 retainCacheEntry
Keeps the VRAM cache entry when it is released or off screen.
Definition animspr.h:114
u8 dirty
nonzero redraws its pixels into VRAM when next drawn
Definition animspr.h:125
The hardware sprite attributes one part of an animated sprite (its image or its shadow) is drawn with...
Definition animspr.h:84
u16 tile
first sprite tile in VRAM
Definition animspr.h:99
The object system's work: the flag that suspends sprite projection, the outline's edge and fill colou...
Definition animspr.h:66
struct ResourceSlot slots[8]
Definition animspr.h:74
A row of gResourceSlot_NumberTable: the packed resource that holds an animation number's frames,...
Definition animation.c:17
A resource slot: the tag of the animation loaded into it (slot number and animation id) and the buffe...
Definition animspr.h:59
s32 tag
(slot << 12) | animation id
Definition animspr.h:60
void * buffer
the decoded frames, their offsets made pointers
Definition animspr.h:61
u16 offset
bytes from the start of OBJ VRAM
Definition vram_tab.h:25
void * Resource_GetTableEntry(s32 index)
Returns the ROM address of resource index from the resource directory.
Definition system.c:150
u8 gResourceSlot_ConversionTables[][256]
const u8 gObject_ShadowTiles[]
struct AnimationEntry * gAnimationObjects[]
u8 Tile_CopyStridedCodeSize[]
u8 Tile_CopyStrided[]
void Palette_LoadBasicObjColors(void)
Loads the basic sprite palettes (palettes 0 to 13).
Definition text.c:199
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
signed short s16
Definition types.h:12
unsigned short u16
Definition types.h:13
unsigned char u8
Definition types.h:11
void * memcpy(void *destination, const void *source, unsigned long size)
s32 Resource_ResetEntry(u32 no)
Frees cache entry no: its blocks go back and the entry is marked free (offset 0xffff).
Definition vram_cache.c:106
s32 Resource_FindFreeEntry(void)
Returns the number of the first free cache entry, or VRAM_CACHE_ENTRY_COUNT when all are taken.
Definition vram_cache.c:211
s32 VramCache_Load(u32 no, u32 size, const void *src)
Gives cache entry no size bytes of sprite VRAM and copies src there.
Definition vram_cache.c:143
struct VramBlockCacheEntry gVramBlockCache[]
@ VRAM_CACHE_ENTRY_COUNT
Definition vram_tab.h:12