Alchemy
Loading...
Searching...
No Matches

objects.c

Go to the documentation of this file.
1/// @file
2/// Each frame's sprite priorities, the status icons, the poses and the
3/// sprites of the battle objects.
4/// Part of battle.c, the battle object, compiled only through it.
5
7
8#define UNIT_MAX 14 ///< the party's and the enemies' units together
9
10/// Runs each frame of a battle: advances every unit's status icon, lifts an
11/// airborne unit's effect sprite above the others, and draws whichever side is
12/// nearer the camera in front. Runs as a scheduler callback (priority 0xc80)
13/// that Battle_RunEncounter adds after the entry transition and removes as
14/// the battle ends. Writes each battle object's icon state and its sprites'
15/// priorities.
17 // The two side walks stay separate: a shared priority helper changes EN
18 // register allocation despite the same 0x1ac-byte extent.
19 u16 unitIds[UNIT_MAX];
20 // The party's, then the enemies': 1 for the side in front, 2 behind.
21 s32 sidePriorities[2];
22 s32 unitIndex;
23 s32 recordIndex;
24 s32 count;
25 struct MotionObject *object;
26 struct AnimationObject *record;
27 struct AnimationObject **records;
28
29 // Every unit's status icon.
31 unitIndex = 0;
32 if (unitIds[unitIndex] != BATTLE_UNIT_LIST_END) {
33 for (;;) {
34 struct BattleObj *slot = BattleObjGet(unitIds[unitIndex]);
35
36 if (slot != 0) {
37 object = slot->object;
38
40 if (slot->effectEntry != 0) {
41 record = GetMotionRecord(object, 0);
42
43 if (record != 0) {
44 struct SpriteEntry *effect;
45 s32 effectPriority = 0;
46
47 // Off the ground.
48 if (object->y != 0)
49 effectPriority = 9;
50 effect = slot->effectEntry;
51 if (effect->priority != effectPriority) {
52 effect->priority = effectPriority;
53 record->dirty = 1;
54 }
55 }
56 }
57 }
58 unitIndex++;
59 if (unitIndex >= UNIT_MAX || unitIds[unitIndex] == BATTLE_UNIT_LIST_END)
60 break;
61 }
62 }
63
64 // The camera's turn decides which side is in front: with the yaw in the
65 // first half turn (as a signed halfword), the party.
66 if ((s16)gCameraWork->yaw >= 0) {
67 sidePriorities[0] = 1;
68 sidePriorities[1] = 2;
69 } else {
70 sidePriorities[0] = 2;
71 sidePriorities[1] = 1;
72 }
73
74 // The party.
75 {
77 for (unitIndex = 0; unitIndex < count; unitIndex++) {
78 struct BattleObj *slot = BattleObjGet(unitIds[unitIndex]);
79
80 if (slot != 0) {
81 object = slot->object;
82
84 case RECORDS_SINGLE: {
85 record = object->records;
86 record->image.priority = sidePriorities[0];
87 break;
88 }
89 case RECORDS_TABLE: {
90 records = (struct AnimationObject **)object->records;
91 for (recordIndex = 0; recordIndex < RECORDS_TABLE_SIZE;
92 recordIndex++) {
93 record = *records++;
94 if (record != 0)
95 record->image.priority = sidePriorities[0];
96 }
97 break;
98 }
99 }
100 }
101 }
102 }
103
104 // The enemies.
105 {
107 for (unitIndex = 0; unitIndex < count; unitIndex++) {
108 struct BattleObj *slot = BattleObjGet(unitIds[unitIndex]);
109
110 if (slot != 0) {
111 object = slot->object;
112
114 case RECORDS_SINGLE: {
115 record = object->records;
116 record->image.priority = sidePriorities[1];
117 break;
118 }
119 case RECORDS_TABLE: {
120 records = (struct AnimationObject **)object->records;
121 for (recordIndex = 0; recordIndex < RECORDS_TABLE_SIZE;
122 recordIndex++) {
123 record = *records++;
124 if (record != 0)
125 record->image.priority = sidePriorities[1];
126 }
127 break;
128 }
129 }
130 }
131 }
132 }
133}
134
135// The status icons' bits in BattleObj.activeConditions
136#define ICON_POISON 0x01
137#define ICON_VENOM 0x02 ///< deadly poison
138#define ICON_STUN 0x04
139#define ICON_PSY_SEAL 0x08
140#define ICON_SLEEP 0x10
141#define ICON_DELUSION 0x20
142#define ICON_HAUNT 0x40
143#define ICON_GRIM_REAPER 6 ///< the curse's turns left, 1 to 7, as bits 7 to 13
144
145#define ICON_MAX 14 ///< the kinds of icon
146
147/// Builds the status icon bits of unit id's ailments into its battle
148/// object's activeConditions, which BattleStatusIcon_Cycle shows. Called
149/// wherever a unit's statuses may have changed: BattleEv_DispatchQueued,
150/// BattleEvent_Playback, Battle_ProcessRoundEnd, BattleActor_ResetRuntimeFields
151/// and BattleActor_SpawnObjectsForList.
152#ifdef UBFIX
153void BattleUnit_BuildStatusFlags(s32 unitId, struct BattleObj *battleObject) {
154#else
155s32 BattleUnit_BuildStatusFlags(s32 unitId, struct BattleObj *battleObject) {
156#endif
157 struct BattleUnit *unit = UnitGetFar(unitId);
158 s8 poison = unit->poison;
159 u32 flags = 0;
160
161 if (poison == POISON_NORMAL)
162 flags = ICON_POISON;
163 // Deadly poison: poison is ICON_VENOM.
164 if (poison == POISON_DEADLY)
165 flags |= poison;
166 if (unit->delusion != 0)
167 flags |= ICON_DELUSION;
168 if (unit->stun != 0) {
169 s32 classId;
170 flags |= ICON_STUN;
171 classId = unit->classId;
172 // Kraken and Fusion Dragon never show it; Summon_LayoutPositions also
173 // stands these two classes nearer the party (enemies.tsv rows 113, 140).
174 if (classId == 121 || classId == 148)
175 flags &= ~ICON_STUN;
176 }
177 if (unit->psySeal != 0)
178 flags |= ICON_PSY_SEAL;
179 if (unit->haunt != 0)
180 flags |= ICON_HAUNT;
181 if (unit->sleep != 0)
182 flags |= ICON_SLEEP;
183 if (unit->grimReaper != 0)
184 flags |= 1 << (unit->grimReaper + ICON_GRIM_REAPER);
185 battleObject->activeConditions = flags;
186}
187
188/// The frames each status icon shows before the next one's turn.
189#define ICON_CYCLE_FRAMES 80
190
191/// The icons' first animations, for units 32 pixels wide and for the rest.
192#define ICON_ANIM_NARROW 340
193#define ICON_ANIM_WIDE 355
194
195/// Shows a unit's status icons one after another, each for
196/// ICON_CYCLE_FRAMES frames, switching at once when the shown status ends,
197/// and removes the icon when no status is left. Called each frame for every
198/// unit by BattleActor_UpdateSpritePriorities. Changes the battle object's
199/// cycleTimer, selectedCondition, animation and animationEntry, and
200/// registers or unregisters the icon on its first sprite.
201#ifdef UBFIX
202void BattleStatusIcon_Cycle(struct BattleObj *battleObject) {
203#else
204s32 BattleStatusIcon_Cycle(struct BattleObj *battleObject) {
205#endif
206 struct AnimationEntry *shownIcon;
207 struct AnimationEntry *icon;
208 struct AnimationObject *record;
209 struct MotionObject *owner;
210 s32 iconAnimation;
211 s32 iconHandle;
212 s32 previousCondition;
213 s32 changed = 0;
214
215 if (battleObject->cycleTimer >= 0)
216 battleObject->cycleTimer--;
217
218 // Move on when the time is up, when the shown status has ended, or when a
219 // status appears with no icon shown.
220 shownIcon = (struct AnimationEntry *)battleObject->animationEntry;
221 if ((shownIcon == 0 ? (s16)battleObject->activeConditions != 0
222 : (((s16)battleObject->activeConditions >>
223 battleObject->selectedCondition) &
224 1) == 0) ||
225 battleObject->cycleTimer == 0) {
226 iconAnimation = -1;
227 owner = battleObject->object;
228 if ((s16)battleObject->activeConditions != 0) {
229 // The next status after the shown one, wrapping around.
230 previousCondition = battleObject->selectedCondition;
231 for (iconAnimation = previousCondition + 1;; iconAnimation++) {
232 if (iconAnimation > ICON_MAX - 1)
233 iconAnimation = 0;
234 if ((((s16)battleObject->activeConditions >> iconAnimation) & 1) != 0)
235 break;
236 }
237
238 if (previousCondition != iconAnimation || shownIcon == 0) {
239 battleObject->selectedCondition = iconAnimation;
240 changed = 1;
241 }
242 battleObject->cycleTimer = ICON_CYCLE_FRAMES;
243 } else {
244 changed = 1;
245 }
246
247 // Swap the icon on the unit's first sprite; iconAnimation is -1 when no
248 // status is left.
249 record = GetMotionRecord(owner, 0);
250 if (record != 0) {
251 // Units 32 pixels wide take their own set of icon animations.
252 if (iconAnimation >= 0) {
253 if (record->width == 32)
254 iconAnimation += ICON_ANIM_NARROW;
255 else
256 iconAnimation += ICON_ANIM_WIDE;
257 }
258
259 if (battleObject->animationEntry != 0 && changed != 0) {
261 (s32)battleObject->animationEntry);
262 battleObject->animationEntry = 0;
263 }
264
265 if (iconAnimation >= 0 && changed != 0) {
266 // The handle is stored first and cleared again when registration fails.
267 iconHandle = ResourceMetadata_RegisterFar(record, iconAnimation);
268 battleObject->animationEntry = (struct SpriteEntry *)iconHandle;
269 if (iconHandle == -1)
270 battleObject->animationEntry = 0;
271 icon = (struct AnimationEntry *)battleObject->animationEntry;
272 if (icon != 0) {
273 icon->priority = 3;
275 }
276 }
277
278 record->dirty = 1;
279 if (iconAnimation >= 0)
280 battleObject->animation = iconAnimation;
281 else
282 battleObject->animation = 0;
283 }
284 }
285}
286
287/// Sets unit id's pose to match its state: held (asleep, stunned or unable
288/// to move) or down, else standing; then gives its sprites their palette
289/// row, 14 to 17 by unit. Called by BattleActor_SpawnObjectsForList,
290/// BattleEv_DispatchQueued, BattleEvent_Playback and Battle_ProcessRoundEnd.
291#ifdef UBFIX
293#else
295#endif
296 struct BattleUnit *unit;
297 s32 pose;
298
299 unit = UnitGetFar(unitId);
300 pose = POSE_STANDING;
301 if (unit->hp != 0) {
302 if (unit->sleep != 0 || unit->stun != 0 || unit->immobile != 0)
303 pose = (unit->side != BATTLE_UNIT_ENEMY) * POSE_PARTY_HELD;
304 } else {
305 // 4 for a party member, 5 for an enemy: pose is POSE_STANDING (1, the
306 // enemy side's value) here, so the xor is 0 only for an enemy.
307 s32 notEnemy = unit->side ^ pose;
308 pose = (u32)(-notEnemy | notEnemy) >> 31;
309 pose = POSE_ENEMY_DOWN - pose;
310 }
311
312 ObjectDispatch_SelectAnimationFar(BattleObjGet(unitId)->object, pose);
314 (struct DispatchObject *)BattleObjGet(unitId)->object, (unitId & 3) + 14);
315}
316
317/// Releases every sprite unitId's object holds and leaves it with none,
318/// clearing the battle object's animationEntry and effectEntry. Called by
319/// BattleActor_SpawnObjectsForList; BATTLE.S also gives it an unnamed
320/// overlay veneer, which nothing in the source calls.
322 struct BattleObj *battleObject;
323 struct MotionObject *object;
324 s32 recordIndex;
325 struct AnimationObject *record;
326
327 battleObject = BattleObjGet(unitId);
328 if (battleObject != NULL) {
329 object = battleObject->object;
330 if (object != NULL) {
331 battleObject->animationEntry = 0;
332 battleObject->effectEntry = 0;
333 recordIndex = 0;
334 while ((record = GetMotionRecord(object, recordIndex)) != NULL) {
336 recordIndex += 1;
337 }
338 object->recordStorageKind = RECORDS_NONE;
339 object->records = NULL;
340 }
341 }
342}
343
344/// The sprite unit 32 pixels wide use for an effect.
345#define NARROW_EFFECT_SPRITE 0x1ff
346
347/// Readies the sprites of the units in list: releases those of every place
348/// list lacks, then creates each listed unit's sprites (body, weapon, status
349/// icon and effect; or the two parts of a two-part enemy) unless it has
350/// them, building its status icons and setting its pose. With refreshPoses,
351/// sets every listed unit's pose again afterwards. Called by BattleObjPut
352/// (refreshing) and BattleParty_ListAllUnitsAndSubmit, by the staging and
353/// entry transition code, and through its far stub by
354/// BattleFx_SelectLivingTargets. Writes the objects' records, their storage
355/// kind and height, and the battle objects' icon and effect entries.
356void BattleActor_SpawnObjectsForList(s16 *unitIds, s32 refreshPoses) {
357 s32 unitIndex;
358 s32 unitId;
359 struct BattleObj *battleObject;
360 struct MotionObject *object;
361 struct AnimationObject *record;
362 struct SpriteEntry *entry;
363 struct AnimationObject **records;
364 s32 spriteId;
365 s32 releasedUnitId;
366
367 // Release the sprites of the places no listed unit holds.
368 for (unitIndex = 0; unitIndex < UNIT_MAX; unitIndex++) {
369 if (!BattlePlacement_ContainsId(unitIds, unitIndex)) {
370 releasedUnitId = unitIndex + FIRST_ENEMY_UNIT - 8;
371 if (unitIndex <= 7)
372 releasedUnitId = unitIndex;
373 ReleaseBattleObjectRecords(releasedUnitId);
374 }
375 }
376 // A frame passes between releasing and creating sprites, except inside a
377 // main-loop task (gSchedulerStatus is set while WaitFrames runs them),
378 // which cannot wait.
379 if (gSchedulerStatus == 0)
380 WaitFrames(1);
381
382 for (unitIndex = 0; unitIndex < UNIT_MAX &&
383 (unitId = unitIds[unitIndex]) != BATTLE_UNIT_LIST_END;
384 unitIndex++) {
385 if (unitId == BATTLE_UNIT_REMOVED)
386 continue;
387 battleObject = BattleObjGet(unitId);
388 if (battleObject == 0)
389 continue;
390 BattleUnit_BuildStatusFlags(unitId, battleObject);
391 object = battleObject->object;
392 if (object == 0)
393 continue;
394 if (object->recordStorageKind != RECORDS_NONE)
395 continue;
396 if ((battleObject->resource & SPRITE_ID_MASK) ==
398 (battleObject->resource & SPRITE_ID_MASK) ==
400 // A two-part enemy: a table of its two sprites, kept in the menu
401 // control work. Its height is half the first part's box.
402 // BUG: a failed create leaves record null, and its flags are still
403 // written.
404 records = (struct AnimationObject **)gMenuCtrlWork->unk08 +
406 spriteId = battleObject->resource;
407 object->recordStorageKind = RECORDS_TABLE;
408 object->records = records;
409 Iwram_ClearWords(records, 16);
410 record = ResourceObject_CreateFar(spriteId);
411 if (record != 0) {
412 record->scale = Iwram_MulQ16(record->scale, battleObject->scale);
413 object->height = Resource_GetMetadataRecordFar(spriteId)->boxY >> 1;
414 *records = record;
415 records++;
416 }
417 record->flags = 0;
418 record = ResourceObject_CreateFar(spriteId + SPRITE_SECOND_PART);
419 if (record != 0) {
420 record->scale = Iwram_MulQ16(record->scale, battleObject->scale);
421 *records = record;
422 }
423 record->flags = 0;
424 } else {
425 // The body, then the weapon, the status icon and the effect on it.
426 // Entry priorities: 0 the effect, 1 the body and weapon, 3 the icon.
427 record = ResourceObject_CreateFar(battleObject->resource);
428 if (record != 0) {
429 object->recordStorageKind = RECORDS_SINGLE;
430 object->records = record;
431 record->scale = Iwram_MulQ16(record->scale, battleObject->scale);
432 entry = (struct SpriteEntry *)record->entries[0];
433 entry->priority = 1;
434 entry->palette = battleObject->palette;
435 if ((spriteId = battleObject->overlay) != 0) {
436 entry = (struct SpriteEntry *)ResourceMetadata_RegisterFar(record,
437 spriteId);
438 entry->priority = 1;
439 }
440 if ((spriteId = battleObject->animation) != 0) {
441 entry = (struct SpriteEntry *)ResourceMetadata_RegisterFar(record,
442 spriteId);
443 battleObject->animationEntry = entry;
444 Animation_SetWorkEntryFar((struct AnimationEntry *)entry, 0);
445 entry->priority = 3;
446 }
447 if ((spriteId = battleObject->effect) != 0) {
448 if (record->width == 32)
449 spriteId = NARROW_EFFECT_SPRITE;
450 entry = (struct SpriteEntry *)ResourceMetadata_RegisterFar(record,
451 spriteId);
452 battleObject->effectEntry = entry;
453 entry->priority = 0;
454 record->flags = 0;
455 }
456 }
457 }
459 }
460
461 if (refreshPoses) {
462 unitIndex = 0;
463 if ((spriteId = unitIds[0]) != BATTLE_UNIT_LIST_END) {
464 for (;;) {
465 if (unitIds[unitIndex] != BATTLE_UNIT_REMOVED &&
466 (battleObject = BattleObjGet(spriteId)) != 0 &&
467 (object = battleObject->object) != 0)
469 unitIndex++;
470 if (unitIndex >= UNIT_MAX ||
471 (spriteId = unitIds[unitIndex]) == BATTLE_UNIT_LIST_END)
472 break;
473 }
474 }
475 }
476}
477
478/// Returns unitId's battle object, through its place, or null for a
479/// unit with no place. Called throughout the battle parts.
480struct BattleObj *BattleObjGet(s32 unitId) {
481 struct BattleWork *battle = gBattleWork;
482 struct BattleObj *objects = battle->slots;
483 s32 placementIndex;
484 // Enemy unit ids 128 to 133 index placement 8 to 13.
485 if (unitId > 7) {
486 unitId -= FIRST_ENEMY_UNIT - 8;
487 }
488 placementIndex = unitId;
489 if (battle->placement[placementIndex] == 0xFF) {
490 return NULL;
491 }
492 return &objects[battle->placement[placementIndex]];
493}
494
495/// Detaches the scripts from the four sprite entries of one sprite. Called
496/// only by ResetBattleObjectRecordGroups.
497void ResetMotionRecordGroup(void *recordGroup) {
498 struct AnimationObject *record = recordGroup;
499 s32 entryIndex;
500
501 if (record != NULL) {
502 for (entryIndex = 0; entryIndex < 4; entryIndex++) {
503 if (record->entries[entryIndex] != NULL)
504 record->entries[entryIndex]->script = NULL;
505 }
506 }
507}
508
509/// Detaches the scripts from every sprite of a battle object. Nothing in the
510/// source calls it.
512 s32 storageKind;
513 s32 remaining;
514 void **recordGroups;
515 void *recordGroup;
516
517 if (object != NULL) {
518 storageKind = object->recordStorageKind & RECORDS_KIND_MASK;
519 switch (storageKind) {
520 case RECORDS_SINGLE:
522 return;
523 case RECORDS_TABLE:
524 recordGroups = object->records;
525 remaining = RECORDS_TABLE_SIZE - 1;
526 do {
527 recordGroup = *recordGroups++;
528 if (recordGroup != NULL) {
529 ResetMotionRecordGroup(recordGroup);
530 }
531 remaining -= 1;
532 } while (remaining >= 0);
533 break;
534 }
535 }
536}
537
538/// Frees the enemy sprite slots unitId holds and marks its object
539/// for release at the end of the round (BattleMotion_DestroyAllSlotObjects),
540/// setting its active field. Called when a unit leaves the battle: by
541/// BattleEvent_Playback, BattlePres_RunEscape, BattleMotion_ShowDowned,
542/// BattleActor_DestroyTemporaryObject and the auto battle.
544 struct BattleObj *battleObject;
546 battleObject = BattleObjGet(unitId);
547 battleObject->active = 1;
548 return 0;
549}
550
551/// Releases the object of every unit marked by BattleObj_MarkForRelease,
552/// leaving its battle object with no object. Called by Battle_RunEncounter
553/// at the end of each round and by BattlePresentation_DispatchAction.
554#ifdef UBFIX
556#else
558#endif
559 s32 unitId;
560 s32 placementIndex;
561 struct BattleObj *battleObject;
562
563 placementIndex = 0;
564 do {
565 unitId = placementIndex + FIRST_ENEMY_UNIT - 8;
566 if (placementIndex <= 7) {
567 unitId = placementIndex;
568 }
569 battleObject = BattleObjGet(unitId);
570 if ((battleObject != NULL) && (battleObject->active != 0)) {
571 ObjectDispatch_ReleaseFar((struct DispatchObject *)battleObject->object);
572 battleObject->object = NULL;
573 battleObject->active = 0;
574 }
575 placementIndex += 1;
576 } while (placementIndex < UNIT_MAX);
577}
578
579/// Writes the battlefield spot of place (its anchor, on the ground) to
580/// position. Nothing in the source calls it.
582 struct BattleWork *battle = gBattleWork;
583
584 SET_POSITION(position, battle->slots[place].anchorX, 0,
585 battle->slots[place].anchorZ);
586 return 0;
587}
588
589/// Sets up the camera's view for projecting points; under
590/// FLAG_CHOOSING_COMMANDS, through the extra transform
591/// gCamera_FlagTransformWork first. Called by the three projections,
592/// BattleMotion_ProjectPosition, BattleMotion_ProjectScaledPosition and
593/// BattleMotion_ProjectConditionalPosition. Replaces the transform state.
594#ifdef UBFIX
596#else
598#endif
599 struct BattleCamera *camera = gCameraWork;
603 Transform_ApplyLookAt(camera->eye, camera->pos);
604 } else {
605 Transform_SetLookAt(camera->eye, camera->pos);
606 }
607}
608
609/// Projects unit id's position onto the screen, into projected. Reached
610/// through its far stub from EffectPosition_ProjectBattler.
612 struct MotionObject *object = BattleObjGet(unitId)->object;
613 struct AnimationObject *record = GetMotionRecord(object, 0);
614 s32 position[3];
615 s32 projectionScale;
616
618 SET_VECTOR(position, object->x, object->y, object->z);
619 projectionScale = Render_ProjectPoint(position, projected);
620 // The sprite's projected scale is worked out and thrown away; compare
621 // BattleMotion_ProjectScaledPosition, which keeps it.
622 (void)Iwram_MulQ16(projectionScale, record->scale);
623 return 0;
624}
625
626/// Returns sprite recordIndex of an object (0 only, for a single sprite), or
627/// null when it has no such sprite. Called throughout the battle parts.
628void *GetMotionRecord(struct MotionObject *object, s32 recordIndex) {
629 s32 storageKind = object->recordStorageKind & RECORDS_KIND_MASK;
630 if (storageKind == RECORDS_SINGLE) {
631 if (recordIndex == 0) {
632 return object->records;
633 }
634 } else if (storageKind == RECORDS_TABLE) {
635 return ((void **)object->records)[recordIndex];
636 }
637 return NULL;
638}
639
640/// Puts the battle camera at its default view of the battlefield's centre.
641/// Called by Battle_RunEncounter as the battle is set up and by
642/// BattlePresentation_BuildActions. Writes the camera's yaw, pitch,
643/// distance, position and eye, and the transform state.
645 struct BattleCamera *camera = gCameraWork;
646 struct FixedPointPosition eyeOffset;
647
648 // Yaw 0x3000 (in 1/65536 turns), pitch 0xfe00, distance 0x1fe0000.
649 camera->yaw = 192 << 6;
650 camera->pitch = 254 << 8;
651 camera->distance = 255 << 17;
652 SET_VECTOR(camera->pos, 0, 0, 0);
653 camera->followPos = 0;
654 camera->unk18 = 0;
655
660
661 eyeOffset.x = 0;
662 eyeOffset.y = 0;
663 eyeOffset.z = camera->distance;
664 Iwram_TransformVector(&eyeOffset, (s32 *)camera);
665}
s32 BattleParty_ListActorIds(s32 sideMask, u16 *unitIds)
Lists the units in the battle's unit lists on the sides in sideMask, party first, skipping those remo...
Definition encounter.c:510
s32 BattleMotion_ProjectPosition(s32 unitId, s32 *projected)
Projects unit id's position onto the screen, into projected.
Definition objects.c:611
#define ICON_SLEEP
Definition objects.c:140
#define ICON_DELUSION
Definition objects.c:141
void Camera_InitDefaultTransform(void)
Puts the battle camera at its default view of the battlefield's centre.
Definition objects.c:644
void BattleActor_UpdateSpritePriorities(void)
Runs each frame of a battle: advances every unit's status icon, lifts an airborne unit's effect sprit...
Definition objects.c:16
#define ICON_STUN
Definition objects.c:138
#define UNIT_MAX
the party's and the enemies' units together
Definition objects.c:8
void ResetMotionRecordGroup(void *recordGroup)
Detaches the scripts from the four sprite entries of one sprite.
Definition objects.c:497
void BattleActor_SpawnObjectsForList(s16 *unitIds, s32 refreshPoses)
Readies the sprites of the units in list: releases those of every place list lacks,...
Definition objects.c:356
#define ICON_PSY_SEAL
Definition objects.c:139
s32 BattlePres_SetActorModeAndAction(s32 unitId)
Sets unit id's pose to match its state: held (asleep, stunned or unable to move) or down,...
Definition objects.c:294
s32 Battle_GetWorkEntryPair(s32 place, struct FixedPointPosition *position)
Writes the battlefield spot of place (its anchor, on the ground) to position.
Definition objects.c:581
struct BattleObj * BattleObjGet(s32 unitId)
Returns unitId's battle object, through its place, or null for a unit with no place.
Definition objects.c:480
s32 BattleStatusIcon_Cycle(struct BattleObj *battleObject)
Shows a unit's status icons one after another, each for ICON_CYCLE_FRAMES frames, switching at once w...
Definition objects.c:204
#define ICON_HAUNT
Definition objects.c:142
#define NARROW_EFFECT_SPRITE
The sprite unit 32 pixels wide use for an effect.
Definition objects.c:345
void ResetBattleObjectRecordGroups(struct MotionObject *object)
Detaches the scripts from every sprite of a battle object.
Definition objects.c:511
s32 Camera_ApplyTransformByFlag(void)
Sets up the camera's view for projecting points; under FLAG_CHOOSING_COMMANDS, through the extra tran...
Definition objects.c:597
#define ICON_ANIM_WIDE
Definition objects.c:193
s32 BattleUnit_BuildStatusFlags(s32 unitId, struct BattleObj *battleObject)
Builds the status icon bits of unit id's ailments into its battle object's activeConditions,...
Definition objects.c:155
s32 BattleObj_MarkForRelease(s32 unitId)
Frees the enemy sprite slots unitId holds and marks its object for release at the end of the round (B...
Definition objects.c:543
#define ICON_POISON
Definition objects.c:136
void * BattleMotion_DestroyAllSlotObjects(void)
Releases the object of every unit marked by BattleObj_MarkForRelease, leaving its battle object with ...
Definition objects.c:557
#define ICON_GRIM_REAPER
the curse's turns left, 1 to 7, as bits 7 to 13
Definition objects.c:143
#define ICON_CYCLE_FRAMES
The frames each status icon shows before the next one's turn.
Definition objects.c:189
void * GetMotionRecord(struct MotionObject *object, s32 recordIndex)
Returns sprite recordIndex of an object (0 only, for a single sprite), or null when it has no such sp...
Definition objects.c:628
#define ICON_MAX
the kinds of icon
Definition objects.c:145
void ReleaseBattleObjectRecords(s32 unitId)
Releases every sprite unitId's object holds and leaves it with none, clearing the battle object's ani...
Definition objects.c:321
#define ICON_ANIM_NARROW
The icons' first animations, for units 32 pixels wide and for the rest.
Definition objects.c:192
s32 BattleMotion_ReleaseObjectSlotByValue(s32 unitId)
Frees every enemy sprite slot unit unitId holds, unloading its sprite.
Definition sprites.c:141
u8 gCamera_FlagTransformWork[]
@ POSE_PARTY_HELD
asleep, stunned or held; also a downed member
Definition battle.h:175
@ POSE_ENEMY_DOWN
a downed enemy stays in its damage pose
Definition battle.h:177
@ POSE_STANDING
Definition battle.h:174
struct BattleCamera * gCameraWork
What every part of the battle object shares: its includes, in their original order,...
#define POISON_DEADLY
#define RECORDS_KIND_MASK
#define FIRST_ENEMY_UNIT
Unit ids from 128 are the enemies'; in a link battle the opponent's party takes the first three.
#define SPRITE_WITH_SECOND_PART_B
#define RECORDS_SINGLE
#define RECORDS_TABLE
#define RECORDS_NONE
#define RECORDS_TABLE_SIZE
#define POISON_NORMAL
BattleUnit.poison: the poison takes a tenth of the maximum HP at the end of each turn,...
#define SPRITE_WITH_SECOND_PART_A
The two battle sprites whose next sprite is loaded with them (into a second free place),...
@ BATTLE_UNIT_LIST_END
ends the list
@ BATTLE_UNIT_REMOVED
a place whose unit has left the battle
@ BATTLE_UNIT_ENEMY
@ BATTLE_SIDE_PARTY
@ BATTLE_SIDE_ENEMIES
@ BATTLE_SIDE_BOTH
struct BattleWork * gBattleWork
volatile u8 gSchedulerStatus
void ResourceMetadata_UnregisterFar(struct AnimationObject *state, s32 handle)
void ObjectDispatch_ReleaseFar(struct DispatchObject *obj)
struct AnimationObject * ResourceObject_CreateFar(s32 id)
void ObjectDispatch_SelectAnimationFar(void *raw, s32 no)
s32 ResourceMetadata_RegisterFar(struct AnimationObject *state, s32 id)
void ObjectDispatch_SetAnimationSpeedFar(struct DispatchObject *obj, s32 val)
void ResourceObject_ReleaseFar(struct AnimationObject *sprite)
void Animation_SetWorkEntryFar(struct AnimationEntry *work, s32 no)
struct BattleUnit * UnitGetFar(u32 owner)
s32 GameFlag_TestFar(s32 flag)
struct AnimationMetadata * Resource_GetMetadataRecordFar(u32 number)
#define FLAG_CHOOSING_COMMANDS
set while the commands are chosen
Definition flags.h:67
void WaitFrames(s32 frames)
The game's frame loop: runs frames frames and returns.
Definition frame.c:97
#define SPRITE_SECOND_PART
Definition resource.h:14
#define SPRITE_ID_MASK
A battle sprite id's low twelve bits; the two-part sprites' second part is their id + 0x2001.
Definition resource.h:13
#define Iwram_MulQ16(left, right)
Definition iwram_call.h:127
static s32 Iwram_TransformVector(const void *vector, s32 *result)
Definition iwram_call.h:65
static s32 Iwram_ClearWords(void *destination, s32 size)
Definition iwram_call.h:55
static void Iwram_TransformMatrix(const s32 *matrix)
Definition iwram_call.h:69
#define SET_POSITION(p, px, py, pz)
Sets the position or the velocity of a particle, a piece of debris or an object in one statement.
Definition macros.h:16
#define SET_VECTOR(v, x, y, z)
Sets the x, y and z of a three-part vector: a position about to be projected, a per-frame step,...
Definition macros.h:12
struct ObjectSystemWork * gMenuCtrlWork
s32 BattlePlacement_ContainsId(s16 *list, s32 place)
Returns 1 if the unit at place is in list.
Definition placement.c:436
#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 * script
the running script; null when stopped (ANIM_CMD_END)
Definition animspr.h:50
u8 priority
drawing order 0 to 3 among the layers; above 3 not drawn
Definition animspr.h:46
An animated sprite: its image and shadow, scale, rotation, size and up to four animation layers.
Definition animspr.h:108
struct AnimationSpritePart image
Definition animspr.h:109
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
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 dirty
nonzero redraws its pixels into VRAM when next drawn
Definition animspr.h:125
u16 priority
2 when created
Definition animspr.h:100
The battle camera: its eye, the focus it turns about, and its pitch, yaw and distance.
u16 pitch
1/65536 turns
s32 distance
eye to focus, 16.16 fixed-point pixels
u16 yaw
1/65536 turns
s32 * followPos
when set, the focus followed instead of pos
s32 pos[3]
the focus, 16.16 fixed-point pixels
s32 eye[3]
The eye, 16.16 fixed-point pixels: written each frame distance behind the focus along the turned view...
s32 unk18
cleared beside followPos; not read by name in TBS
A unit's place on the battlefield: its sprite object, resources and animations, its anchor spot and s...
struct SpriteEntry * effectEntry
the effect sprite, or NULL
struct MotionObject * object
NULL once released.
u16 animation
the status icon's animation shown; 0 for none
u16 activeConditions
a bit per status with an icon (ICON_)
u8 selectedCondition
the status whose icon is shown
s8 cycleTimer
frames until the next status icon
u16 resource
the unit's sprite
s32 palette
the unit sprite's palette
s32 scale
16.16 fixed point, 0x10000 full size
u16 effect
an effect sprite drawn with the unit
s16 active
Set by BattleObj_MarkForRelease: the object is released with the others by BattleMotion_DestroyAllSlo...
struct SpriteEntry * animationEntry
the status icon's sprite, or NULL
s32 anchorZ
16.16 fixed-point pixels
u16 overlay
a second sprite drawn over it, the weapon; 0 for none
s32 anchorX
16.16 fixed-point pixels
A unit in battle: a party member's or an enemy's stats, Psynergy, items, Djinn and ailments.
u8 immobile
set by Ground: the next action is lost
u8 grimReaper
The Grim Reaper's countdown: 7 when cursed, down one at each turn's end; at 0 the unit falls.
u8 psySeal
bits: 7..3 Luff (16 when cast, minus 8 a turn) | 2..0 Bind's turns (7 when cast).
u8 side
BATTLE_UNIT_ABSENT (0), BATTLE_UNIT_ENEMY (1) or BATTLE_UNIT_PARTY (2).
s8 poison
1 poisoned, 2 deadly poison
u8 haunt
set while an evil spirit grips the unit
s16 hp
current HP, 0 when downed
u8 classId
Who the unit is: a character's id (ISAAC to JENNA, below 8) or an enemy's id (BattleUnitSet).
u8 delusion
Delusion to sleep: the turns each status has left, 7 when it lands; each may end sooner at the end of...
The battle's own work: its enemies, units and their objects, the turn's actions, the spoils,...
Definition battle_work.h:71
struct BattleObj slots[14]
u8 placement[14]
Each unit's index in slots, enemies from 8; 0xff for none.
A field object as the object dispatcher's far calls take it.
A position in three coordinates, each in 16.16 fixed point.
s32 z
16.16 fixed point
s32 x
16.16 fixed point
s32 y
16.16 fixed point
An effect object that moves and draws one sprite: its position, scale, velocity and target,...
Definition motobj.h:20
s32 z
16.16 fixed-point pixels
Definition motobj.h:25
s32 y
16.16 fixed-point pixels
Definition motobj.h:24
void * records
one sprite, or a table of up to four (recordStorageKind)
Definition motobj.h:50
u8 recordStorageKind
bits: 3..0 RECORDS_NONE, RECORDS_SINGLE or RECORDS_TABLE
Definition motobj.h:52
s32 x
16.16 fixed-point pixels
Definition motobj.h:23
s32 count
sprite group tables taken from unk08
Definition animspr.h:73
u8 unk08[0x10]
the sprite group tables, taken in turn by count
Definition animspr.h:72
A sprite of an animation record, as battle objects set its palette and drawing priority.
Definition motobj.h:68
u8 priority
Definition motobj.h:71
u8 palette
Definition motobj.h:70
void SceneTransform_ApplyYaw(s32 angle)
Rotates gTransform about the Y axis by angle.
Definition transform.c:113
s32 Render_ProjectPoint(const void *point, s32 *screen)
Reads three word-aligned coordinates from point, transforms them by gTransform and projects them to t...
Definition transform.c:364
void SceneTransform_ApplyPitch(s32 angle)
Rotates gTransform about the X axis by angle.
Definition transform.c:97
void SceneTransform_ApplyPosition(const s32 *position)
Translates gTransform by position (x, y, z in 16.16).
Definition transform.c:145
void Transform_ApplyLookAt(s32 *eye, s32 *target)
Multiplies the camera at eye looking at target into gTransform.
Definition transform.c:324
void Render_ResetTransformState(void)
Allocates the one-level save area (heap slot HEAP_SLOT_TRANSFORM_STACK), clears gTransformStackDepth ...
Definition transform.c:19
void Transform_SetLookAt(s32 *eye, s32 *target)
Makes the camera at eye looking at target the whole of gTransform.
Definition transform.c:318
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
signed char s8
Definition types.h:10
signed short s16
Definition types.h:12
unsigned short u16
Definition types.h:13