Alchemy
Loading...
Searching...
No Matches

colosso_river.c

Go to the documentation of this file.
1/// @file
2/// A Colosso finals course: Isaac races another warrior through the Rock
3/// Challenge, the Pipeworks, the Broken Bridge and the Lumber Water Crossing
4/// Area to the arena, where the two fight.
5
6#include "script.h"
7#include "version.h"
8#include "game_state.h"
9#include "io_write_queue.h"
10#include "scene_ids.h"
11#include "vram_tab.h"
12#include "unit/import.h"
18#include "unit/object/object.h"
20#include "unit/field/field.h"
21#include "unit/game/game.h"
22#include "unit/window/window.h"
24#include "unit/menu/menu.h"
25#include "unit/sound/sound.h"
28#include "battle.h"
29#include "keystate.h"
30#include "debug.h"
31#include "field.h"
32#include "game.h"
33#include "graphics.h"
34#include "menu.h"
35#include "minigame.h"
36#include "sound.h"
37#include "system.h"
38#include "mem.h"
39#include "types.h"
40#include "callback_scheduler.h"
41#include "field_event.h"
42#include "field_service.h"
43#include "field_scene.h"
44#include "staged_actor.h"
45#include "resource_ids.h"
46#include "text/msg_ids.h"
47#include "battle_unit.h"
48#include "resource.h"
49#include "object_runtime.h"
50#include "ability_ids.h"
51#include "edition.h"
52#include "item_ids.h"
53#include "objcmd.h"
54#include "field_obj.h"
55#include "heap_state.h"
56#include "field_runtime.h"
57#include "fixed_math.h"
58#include "colosso_gauge.h"
59#include "macros.h"
60#include "flags.h"
61#include "songs.h"
62
63// Keep native call forms while UBFIX uses the declared void contracts.
64#ifdef UBFIX
65#define COLOSSO_RIVER_FACE_DIRECTION Engine_ActorFaceDirection
66#define COLOSSO_RIVER_PLACE_STAGED_PAIR ColossoRiver_MoveActorPairByOffset
67#define COLOSSO_RIVER_SELECT_MODE_BLOCK ColossoRiver_SelectPresentationScript
68#define COLOSSO_RIVER_APPLY_MATCHING_SLOT_VALUES Scene_GiveAndEquipItem
69#else
70#define COLOSSO_RIVER_FACE_DIRECTION ((s32 (*)())Engine_ActorFaceDirection)
71#define COLOSSO_RIVER_PLACE_STAGED_PAIR \
72 ((s32 (*)())ColossoRiver_MoveActorPairByOffset)
73#define COLOSSO_RIVER_SELECT_MODE_BLOCK \
74 ((s32 (*)())ColossoRiver_SelectPresentationScript)
75#define COLOSSO_RIVER_APPLY_MATCHING_SLOT_VALUES \
76 ((s32 (*)(s32, s32))Scene_GiveAndEquipItem)
77#endif
78
79static void ColossoRiver_ExplainFinalsRules(s32 guide);
81static void ColossoRiver_ShowMatchResult(s32 result);
82static void ColossoRiver_NoOp(void);
83static void ColossoRiver_WaitForStageReady(void);
84static s32 ColossoRiver_CollectFinishItem(s32 firstItem, s32 secondItem);
85static void ColossoRiver_PushObjectAhead(void);
86
87typedef void (*SceneTask)(void);
88
89/// The course's actors, by the guide's and attendants' explanations: four
90/// stages (the Rock Challenge, the Pipeworks, the Broken Bridge and the Lumber
91/// Water Crossing Area) lead to the arena where the two warriors fight.
92enum {
93 OPPONENT = 8, ///< the warrior racing Isaac to the arena
94 ROCK_A = 9, ///< the Rock Challenge's three rocks
95 ROCK_B = 10,
96 ROCK_C = 11,
97 PIPEWORKS_BLOCK = 12, ///< pushed west to let water into the Pipeworks
98 PIPE_WEST = 13, ///< the Pipeworks' two pipes, a kind of scale
101 BRIDGE_OPERATOR = 16, ///< works the Broken Bridge
102 LOG_NORTH_SOUTH = 17, ///< the Lumber Water Crossing Area's two logs
104 GUIDE = 19, ///< explains the finals
109 PRIZE_A = 24, ///< the arena's Iron Shield and Padded Gloves
111};
112
115}
116
117const struct SceneRegion *ColossoRiver_GetRegions(void) { return 0; }
118
120
123}
124
125/// Advances the bridge animation and its walkable collision cells.
127 switch ((u32)gColossoRiver_Countdown) {
128 case 66:
129 Engine_MapCopyCellsLayered(92, 31, 2, 2, 50, 38);
130 Engine_MapCopyCellsLayered(92, 31, 2, 2, 54, 38);
132 break;
133 case 60:
134 Engine_MapCopyCellsLayered(92, 33, 2, 2, 50, 38);
135 Engine_MapCopyCellsLayered(92, 33, 2, 2, 54, 38);
136 Map_CopyCellAttributes(50, 25, 6, 1, 50, 12);
138 break;
139 case 6:
140 Engine_MapCopyCellsLayered(92, 31, 2, 2, 50, 38);
141 Engine_MapCopyCellsLayered(92, 31, 2, 2, 54, 38);
143 break;
144 case 0:
145 Engine_MapCopyCellsLayered(92, 29, 2, 2, 50, 38);
146 Engine_MapCopyCellsLayered(92, 29, 2, 2, 54, 38);
148 Map_CopyCellAttributes(50, 24, 6, 1, 50, 12);
150 break;
151 }
153}
154
155/// Stops the bridge task and restores its closed frame.
157 SceneTask task;
158
162 task();
163}
164
165/// Starts the bridge's repeating opening sequence.
169}
170
171/// Waits for the crossing window, bounded by one bridge cycle.
173 s32 i;
174
175 Engine_TaskWait(10);
176 i = 0;
177 if (gColossoRiver_Countdown != 22) {
178 do {
180 i++;
181 if (i > 119) {
182 break;
183 }
184 } while (gColossoRiver_Countdown != 22);
185 }
186}
187
188/// After a rock is moved: a rock resting on the floor becomes a step (the
189/// second rock's column is kept in byte flag 0x310).
190static void Event_SettleRocks(void) {
191
192 struct FieldActor *actor;
193 s32 blocked;
194
195 Map_CopyCellAttributes(27, 13, 3, 1, 23, 12);
196 actor = Object_GetById(ROCK_A);
197 blocked = Map_GetTerrainHeight(0, actor->x.fixed, actor->z.fixed);
198 if (actor->y.fixed == 0 && blocked == 0) {
200 actor->motionFlags = 0;
201 {
202 s32 x = actor->x.fixed >> 20;
203 s32 y = actor->z.fixed >> 20;
204
205 Map_CopyCellAttributes(14, 13, 1, 1, x, y);
206 }
207 }
208 actor = Object_GetById(ROCK_B);
209 {
210 s32 x = actor->x.fixed >> 20;
211
213 }
214 {
215 s32 x = actor->x.fixed >> 20;
216 s32 y = actor->z.fixed >> 20;
217
218 Map_CopyCellAttributes(14, 13, 1, 1, x, y);
219 }
220}
221
222/// Walking into a rock pushes it one cell.
223static void Event_PushRock(void) {
224
227}
228
229/// Growth on the plant: it grows and its cell becomes walkable (0x303 keeps it
230/// grown).
231static void Event_GrowPlant(void) {
232 {
233
234 Map_CopyCellAttributes(47, 24, 1, 1, 47, 12);
235 }
236 Engine_GameFlagSet(0x303);
237}
238
239/// Douse on the west pipe: the camera turns to the Pipeworks and the two pipes
240/// rise as it fills (0x301).
241static void Event_DousePipe(void) {
242 struct FieldActor *actor;
243 s32 none;
244
245 GameFlag_Set(0x301);
246 actor = Object_GetById(PIPE_WEST);
248 Camera_SetSpeed(PIXELS(2), PIXELS(1) / 4);
249 Camera_MoveTo(PIXELS(600), -1, PIXELS(200), 1);
250 Object_SetMode(actor, 3);
252 none = 0;
253 actor->motionFlags = none;
254 actor->acceleration = PIXELS(2) / 5;
255 actor->speed = PIXELS(4) / 5;
256 FieldObject_SetPosition(actor, actor->x.fixed, PIXELS(8), actor->z.fixed);
257 actor = Actor_Get(PIPE_EAST);
258 actor->motionFlags = none;
259 actor->acceleration = PIXELS(2) / 5;
260 actor->speed = PIXELS(4) / 5;
261 Engine_ObjectSetPosition(actor, actor->x.fixed, PIXELS(32), actor->z.fixed);
264 Map_CopyCellAttributes(43, 12, 1, 1, 41, 12);
266}
267
268/// Moves the leader and a course object together between cell centers.
269static void ColossoRiver_MoveActorPairByOffset(s32 actorId, s32 dx, s32 dz) {
270 struct FieldActor *leader;
271 struct FieldActor *actor;
272 s32 x;
273 s32 z;
274
276 actor = Object_GetById(actorId);
278 {
279 x = ((leader->x.fixed + (dx << 16)) & 0xFFF00000) + PIXELS(8);
280 z = ((leader->z.fixed + (dz << 16)) & 0xFFF00000) + PIXELS(8);
281
282 leader->speed = PIXELS(1);
283 leader->acceleration = PIXELS(1) / 2;
284 Engine_ObjectSetPosition(leader, x, leader->y.fixed, z);
285 }
286 Object_SetMode(leader, 27);
287 {
288 x = ((actor->x.fixed + (dx << 16)) & 0xFFF00000) + PIXELS(8);
289 z = ((actor->z.fixed + (dz << 16)) & 0xFFF00000) + PIXELS(8);
290
291 actor->speed = PIXELS(1);
292 actor->acceleration = PIXELS(1) / 2;
293 Engine_ObjectSetPosition(actor, x, actor->y.fixed, z);
294 }
295 if (dx < 0 || dz < 0) {
296 Object_SetMode(actor, 4);
297 } else {
298 Object_SetMode(actor, 3);
299 }
302 Object_SetMode(actor, 2);
305}
306
307/// Walking into the north-south log rolls it, with the leader, to the other
308/// bank.
309static void Event_RollLogNorthSouth(void) {
310 struct FieldActor *actor;
311 s32 row;
312 s32 offset;
313
315 row = actor->z.fixed >> 20;
316 offset = -48;
317 if (row <= 8) {
318 offset = 48;
319 }
320 Map_CopyCellAttributes(67, 8, 3, 1, 64, row);
323 row = actor->z.fixed >> 20;
324 Map_CopyCellAttributes(64, 24, 3, 1, 64, row);
325}
326
327/// Walking into the east-west log rolls it, with the leader, the way the pad
328/// is held.
329static void Event_RollLogEastWest(void) {
330 struct FieldActor *actor;
331 s32 column;
332 s32 offset;
333 s32 direction;
334
336 column = actor->x.fixed >> 20;
337 if ((gKeysHeld & KEY_LEFT) != 0) {
338 direction = -1;
339 }
340 if ((gKeysHeld & KEY_RIGHT) != 0) {
341 direction = 1;
342 }
344 offset = actor->z.fixed >> 20;
345 if (column == 63) {
346 if (offset == 11) {
347 return;
348 }
349 offset = 160;
350 } else if (column == 67) {
351 if (offset == 11 && direction == -1) {
352 return;
353 }
354 offset = 96;
355 } else {
356 if (offset == 11) {
357 offset = 96;
358 } else {
359 offset = 160;
360 }
361 offset = -offset;
362 }
363 Map_CopyCellAttributes(72, 9, 1, 3, column, 9);
366 column = actor->x.fixed >> 20;
367 Map_CopyCellAttributes(63, 25, 1, 3, column, 9);
368}
369
370/// Runs the five frames that show water entering the Pipeworks channel.
371static inline void ColossoRiver_AnimatePipeworksWater(void) {
372 Map_CopyCells(96, 29, 1, 3, 34, 38);
374 Map_CopyCells(97, 29, 1, 3, 34, 38);
376 Map_CopyCells(98, 29, 1, 3, 34, 38);
378 Map_CopyCells(99, 29, 1, 3, 34, 38);
380 Map_CopyCells(100, 29, 1, 3, 34, 38);
381}
382
383/// Pushing the Pipeworks block west: water runs into the channel, and the first
384/// time the pipes rise (0x302, 0x301).
385static void Event_PushPipeworksBlock(void) {
386 s32 leaderId;
387 struct FieldActor *leader;
388 struct FieldActor *actor;
389 s32 none;
390
391 leaderId = gGameState.selectedActor;
392 leader = Object_GetById(leaderId);
394 GameFlag_Set(0x302);
396 Engine_ActorSetAnimation(leaderId, 8);
398 actor->speed = PIXELS(1) / 2;
399 actor->acceleration = PIXELS(1) / 5;
401 Object_SetMode(actor, 2);
402 Engine_ObjectSetPosition(actor, actor->x.fixed - PIXELS(48), 0,
403 actor->z.fixed);
405 Engine_ActorSetAnimation(leaderId, 2);
408 HEAP_SLOT_EVENT, sizeof(struct FieldWork)))
409 ->viewCenter,
410 (s32)actor);
411 Actor_SetSpeed(leaderId, PIXELS(3) / 10, PIXELS(1) / 5);
412 Engine_ObjectSetPosition(leader, leader->x.fixed - PIXELS(24), 0,
413 leader->z.fixed);
414 Engine_ActorWaitForMove(leaderId);
415 Engine_ActorSetAnimation(leaderId, 1);
417 Object_SetMode(actor, 1);
422 Map_CopyCellAttributes(37, 7, 1, 4, 34, 7);
423 Map_CopyCellAttributes(36, 7, 1, 4, 37, 7);
424 none = GameFlag_IsSet(0x301);
425 if (none != 0) {
427 Camera_SetSpeed(PIXELS(2), PIXELS(1) / 4);
428 Camera_MoveTo(PIXELS(552), -1, PIXELS(200), 1);
433 return;
434 }
435 GameFlag_Set(0x301);
437 Camera_SetSpeed(PIXELS(2), PIXELS(1) / 4);
438 Camera_MoveTo(PIXELS(600), -1, PIXELS(200), 1);
440 actor = Object_GetById(PIPE_WEST);
441 actor->motionFlags = none;
442 actor->acceleration = PIXELS(2) / 5;
443 actor->speed = PIXELS(4) / 5;
444 Engine_ObjectSetPosition(actor, actor->x.fixed, PIXELS(8), actor->z.fixed);
445 Object_SetMode(actor, 3);
447 actor = Object_GetById(PIPE_EAST);
448 actor->motionFlags = none;
449 actor->acceleration = PIXELS(2) / 5;
450 actor->speed = PIXELS(4) / 5;
451 Engine_ObjectSetPosition(actor, actor->x.fixed, PIXELS(32), actor->z.fixed);
455 Map_CopyCellAttributes(43, 12, 1, 1, 41, 12);
456}
457
459
460/// Reaching the arena: the leader takes a prize (the Iron Shield if first, the
461/// Padded Gloves if second), and he and his opponent face off and fight.
462/// FLAG_SCENE_TEMP_11 says the arena was already reached; the arena's touch
463/// works while FLAG_SCENE_TEMP_10 is clear.
464static void Event_ReachArena(void) {
465 s32 approach;
466 s32 n;
467 s32 base;
468
469 base = 0;
472 approach = ColossoRiver_CollectFinishItem(120, 127);
474 n = 9;
475 do {
477 n = n - 1;
478 } while (n >= 0);
480 Actor_WalkTo(OPPONENT, 1320, 192);
492 Actor_WalkToAndWait(OPPONENT, 1312, 192);
496 /* FAKEMATCH: base is 0 from the top of the function, so 0 - approach + 1 is
497 * built as movs #0, subs, adds #1, as the native does. 1 - approach or
498 * -approach + 1 folds into movs #1, subs (differ 7 in tbs-en). */
499 Field_RequestBattleFromEncounterTable(72, base - approach + 1);
504}
505
506/// Walking into something: a rock is pushed, anything else is checked.
507static void Event_PushRockOrCheckAhead(void) {
508
509 if (Colosso_FindActorAhead() == 0) {
511 } else {
513 }
514}
515
518}
519
520/// Back from the battle: the two warriors stand in the arena as the result is
521/// shown.
523
530 Actor_FaceActor(OPPONENT, 0x4000, 0);
532 if (result < 0) {
535 } else {
538 }
540 Camera_MoveTo(PIXELS(1304), 0, PIXELS(128), 0);
543}
544
545/// Marks actors standing in the course's finish terrain.
547 struct FieldActor *courseActor;
548 s32 column;
549 s32 row;
550
551 courseActor = Object_GetById(actor);
552 if (courseActor != 0) {
553 column = courseActor->x.fixed >> 19;
554 row = courseActor->z.fixed >> 19;
555 if (column >= 94 && column <= 95 && row > 23 && row <= 26) {
556 courseActor->terrainId = 1;
557 }
558 }
559}
560
561/// Restores the stages as they were left, then by the arrival: the race (1 and
562/// 2), the guide's explanation (3), or the match won (4) or lost (5).
564 struct FieldActor *actor;
565 s32 hit;
566 s32 x;
567 u8 zero;
568 s32 col;
569
572 actor = Object_GetById(ROCK_A);
573 hit = Map_GetTerrainHeight(0, actor->x.fixed, actor->z.fixed);
574 if (actor->y.fixed == 0 && hit == 0) {
575 actor->priorityFlags = 2;
576 actor->motionFlags = hit;
577 Map_CopyCellAttributes(14, 13, 1, 1, actor->x.fixed >> 20,
578 actor->z.fixed >> 20);
579 }
580 x = FieldGameFlag_GetByte(0x310);
581 if (x == 0) {
582 x = 25;
583 }
584 actor = Object_GetById(ROCK_B);
585 actor->x.fixed = (x << 20) + PIXELS(8);
586 actor->motionFlags = 0;
587 actor->priorityFlags = 2;
588 Map_CopyCellAttributes(14, 13, 1, 1, x, 12);
591 actor->terrainId = 1;
592 zero = 0;
593 if (Engine_GameFlagIsSet(0x303)) {
594 Object_SetMode(actor, 4);
596 actor->collisionFlags = zero;
597 actor->priorityFlags = 3;
598 Map_CopyCellAttributes(47, 24, 1, 1, 47, 12);
599 }
601 col = actor->z.fixed >> 20;
602 actor->motionFlags = zero;
603 actor->priorityFlags = 2;
604 Map_CopyCellAttributes(64, 24, 3, 1, 64, col);
606 col = actor->x.fixed >> 20;
607 actor->motionFlags = zero;
608 actor->priorityFlags = 2;
609 Map_CopyCellAttributes(63, 25, 1, 3, col, 9);
610 if (Engine_GameFlagIsSet(0x302)) {
611 Map_CopyCellAttributes(37, 7, 1, 4, 34, 7);
612 Map_CopyCellAttributes(36, 7, 1, 4, 37, 7);
613 Map_CopyCells(100, 29, 1, 3, 34, 38);
614 }
615 actor = Object_GetById(PIPE_WEST);
616 if (Engine_GameFlagIsSet(0x301)) {
617 Map_CopyCellAttributes(43, 12, 1, 1, 41, 12);
618 actor->motionFlags = zero;
619 actor->acceleration = PIXELS(2) / 5;
620 actor->speed = PIXELS(4) / 5;
621 actor->y.fixed = PIXELS(8);
622 Object_SetMode(actor, 3);
623 } else {
624 Object_SetMode(actor, 2);
625 }
629 // Select competition, support, explanation, or post-battle arrival.
630 switch (gGameState.entrance) {
631 case 1:
632 Colosso_StartRaceGauge(0, 8, 4, PIXELS(1304), PIXELS(192), 24, 25);
633 Map_CopyCellsLayered(127, 0, 1, 2, 19, 2);
647 }
652 break;
653 case 2:
661 }
662 break;
663 case 3:
667 }
668 break;
669 case 4:
672 break;
673 case 5:
676 break;
677 }
678 return 0;
679}
680
681/// The guide shows the party the first finals course: the race through the
682/// stages to the arena, the prizes there, and where the companions cheer from.
684 struct FieldActor *actor;
685 s32 x;
686 s32 z;
687
688 actor = Object_GetById(guide);
689 x = actor->x.part.pixel;
690 z = actor->z.part.pixel;
692 Actor_SetSpeed(guide, PIXELS(1), PIXELS(1) / 2);
694 Actor_SetSpeed(GARET, PIXELS(1), PIXELS(1) / 2);
695 Actor_SetSpeed(IVAN, PIXELS(1), PIXELS(1) / 2);
696 Actor_SetSpeed(MIA, PIXELS(1), PIXELS(1) / 2);
697 Engine_ActorSetPosition(ACTOR_PARTY_LEADER, x << 16, (z << 16) - PIXELS(48));
698 Actor_SetPosition(GARET, (x << 16) - PIXELS(16), (z << 16) - PIXELS(40));
699 Actor_SetPosition(IVAN, (x << 16) + PIXELS(16), (z << 16) - PIXELS(40));
700 Actor_SetPosition(MIA, x << 16, (z << 16) - PIXELS(32));
701 Actor_SetPosition(guide, x << 16, (z << 16) - PIXELS(80));
703 actor->facing = FACING_NORTH;
707 Engine_EventSetMessage(MsgColossoSiteFirstFinalsBattle);
708 Event_ShowMessage(guide, 0);
709 Actor_ShowEmote(MIA, 0x101, 60);
712 Event_ShowMessage(guide, 0);
713 Actor_ShowEmote(IVAN, 0x101, 60);
715 Actor_FaceActor(guide, IVAN, 0);
718 Event_ShowMessage(guide, 0);
719 Actor_ShowEmote(GARET, 0x101, 60);
721 Actor_ShowEmote(MIA, 0x101, 60);
723 Actor_ShowEmote(guide, 0x102, 60);
724 // Pan over each stage while the guide explains the finals rules.
725 if (Event_AskYesNo(guide, 0) == 0) {
726 do {
727 Engine_EventSetMessage(MsgColossoWarriorsEnterFinalsWithoutAny);
736 Event_ShowMessage(guide, 0);
739 Event_ShowMessage(guide, 0);
740 Camera_SetSpeed(PIXELS(3), PIXELS(3) / 8);
741 Camera_MoveTo(PIXELS(312), -1, PIXELS(104), 1);
743 Event_ShowMessage(guide, 0);
744 Camera_SetSpeed(PIXELS(3) / 2, PIXELS(3) / 16);
745 Camera_MoveTo(PIXELS(776), -1, PIXELS(104), 1);
746 Event_ShowMessage(guide, 0);
748 Event_ShowMessage(guide, 0);
749 Camera_SetSpeed(PIXELS(3), PIXELS(3) / 8);
750 Camera_MoveTo(PIXELS(1240), -1, PIXELS(168), 1);
752 Actor_FaceActor(guide, 0x6000, 0);
753 Event_ShowMessage(guide, 0);
754 Camera_MoveTo(PIXELS(1304), -1, PIXELS(168), 1);
757 Event_ShowMessage(guide, 0);
758 Event_ShowMessage(guide, 0);
759 Event_ShowMessage(guide, 0);
762 } while (Event_AskYesNo(guide, 0) != 0);
764 Engine_EventSetMessage(MsgColossoAskAttendantsForExplanationsStages);
765 Event_ShowMessage(guide, 0);
766 }
767 // Explain the party's support role, then gather them behind Isaac.
768 Engine_EventSetMessage(MsgColossoIsaacYoureContestantInFinals);
770 Event_ShowMessage(guide, 0);
790 if (actor != 0) {
791 Actor_SetDestination(GARET, actor->x.part.pixel, actor->z.part.pixel);
792 }
795 if (actor != 0) {
796 Actor_SetDestination(IVAN, actor->x.part.pixel, actor->z.part.pixel);
797 }
800 if (actor != 0) {
801 Actor_SetDestination(MIA, actor->x.part.pixel, actor->z.part.pixel);
802 }
803 Actor_WalkToAndWait(guide, x - 16, z - 64);
805 Actor_SetPosition(IVAN, 0, 0);
806 Actor_SetPosition(MIA, 0, 0);
807 Actor_WalkToAndWait(guide, x - 16, z - 16);
808 Actor_WalkToAndWait(guide, x, z);
811}
812
813/// The Rock Challenge's attendant: the first time, a warrior shows how to push
814/// the rocks into steps; then the objective.
815static void Event_TalkToRockAttendant(s32 scene) {
816 s32 path;
817
818 if (gGameState.entrance == 2) {
820 } else {
822 path = Colosso_GreetAtStage(scene, 1);
823 if (path == 0) {
824 Engine_EventSetMessage(MsgColossoCallRockChallenge);
825 Camera_SetSpeed(PIXELS(3), PIXELS(3) / 8);
826 Camera_MoveTo(PIXELS(328), -1, PIXELS(168), 1);
828 Engine_EventShowMessage(scene, 0);
829 Colosso_FadeInCompetitor(0, 280, 200);
834 Engine_EventShowMessage(scene, 0);
840 Colosso_WalkActorToAndStand(0, 296, 184);
841 Colosso_WalkActorToAndStand(0, 296, 152);
842 Colosso_WalkActorToAndStand(0, 312, 152);
858 Engine_EventShowMessage(scene, 0);
863 } else if (path == 1) {
864 Engine_EventSetMessage(MsgColossoObjectiveStageClear);
865 Engine_EventShowMessage(scene, 0);
866 }
867 Colosso_OfferCheeringSpot(path, scene, 1);
869 }
870}
871
872/// Moves a Pipeworks actor with the speed used throughout its demonstration.
873static inline void ColossoRiver_SetPipeHeight(struct FieldActor *actor,
874 s32 height) {
875 actor->motionFlags = 0;
876 actor->acceleration = PIXELS(2) / 5;
877 actor->speed = PIXELS(4) / 5;
878 Engine_ObjectSetPosition(actor, actor->x.fixed, height, actor->z.fixed);
879}
880
881/// The Pipeworks' attendant: a marker shows how the pipes rise and fall like
882/// scales; then the objective.
883static void Event_TalkToPipeworksAttendant(s32 attendant) {
884 s32 path;
885 struct FieldActor *second;
886 struct FieldActor *first;
887
888 if (gGameState.entrance == 2) {
889 Colosso_AskDoneCheering(attendant);
890 } else {
892 path = Colosso_GreetAtStage(attendant, 2);
893 if (path == 0) {
894 Engine_EventSetMessage(MsgColossoAreaCalledPipeworks);
896 Camera_MoveTo(PIXELS(592), -1, PIXELS(120), 1);
899 Engine_CameraSetSpeed(PIXELS(3) / 2, PIXELS(3) / 16);
900 Engine_CameraMoveTo(PIXELS(608), -1, PIXELS(216), 1);
902 Engine_EventShowMessage(attendant, 0);
903 Colosso_ShowPointer(56, 64, 0);
905 Colosso_MovePointer(160, 96, 10);
907 Engine_EventShowMessage(attendant, 0);
910 first = Object_GetById(PIPE_WEST);
912 second = Object_GetById(PIPE_EAST);
916 first = Object_GetById(PIPE_WEST);
918 second = Actor_Get(PIPE_EAST);
922 Engine_EventShowMessage(attendant, 0);
923 Colosso_ShowPointer(56, 64, 0);
925 Colosso_MovePointer(160, 96, 10);
927 Colosso_MovePointer(56, 64, 10);
929 Engine_EventShowMessage(attendant, 0);
933 Colosso_RepeatStageNumber(attendant, 2);
934 } else if (path == 1) {
935 Engine_EventSetMessage(MsgColossoObjectiveMakeGood);
936 Engine_EventShowMessage(attendant, 0);
937 }
938 Colosso_OfferCheeringSpot(path, attendant, 2);
940 }
941}
942
943/// The Broken Bridge's attendant: a warrior times his crossing; then the
944/// objective.
946 s32 path;
947
948 if (gGameState.entrance == 2) {
950 } else {
952 path = Colosso_GreetAtStage(scene, 3);
953 if (path == 0) {
954 Engine_EventSetMessage(MsgColossoTheyCallBrokenBridge);
956 Camera_SetSpeed(PIXELS(3), PIXELS(3) / 8);
957 Camera_MoveTo(PIXELS(840), -1, PIXELS(216), 1);
959 Event_ShowMessage(scene, 0);
962 Event_ShowMessage(scene, 0);
963 Colosso_FadeInCompetitor(0, 736, 200);
964 // UB: the void target is called through an incompatible return type.
965 /* FAKEMATCH: called as returning a value, the call sets r0 after both
966 * other arguments; as a direct call, 3 instructions differ in
967 * tbs-en. */
974 Event_ShowMessage(scene, 0);
978 } else if (path == 1) {
979 Engine_EventSetMessage(MsgColossoOperatorBridgeWillAlsoCheer);
980 Event_ShowMessage(scene, 0);
981 }
982 Colosso_OfferCheeringSpot(path, scene, 3);
984 }
985}
986
987/// The Lumber Water Crossing Area's attendant: a warrior rolls a log across;
988/// then the objective.
990 s32 path;
991
992 if (gGameState.entrance == 2) {
994 return;
995 }
997 path = Colosso_GreetAtStage(scene, 4);
998 if (path == 0) {
999 Engine_EventSetMessage(MsgColossoPlaceNormallyCalledLumberWater);
1000 Camera_SetSpeed(PIXELS(3), PIXELS(3) / 8);
1001 Camera_MoveTo(PIXELS(1088), -1, PIXELS(168), 1);
1003 Event_ShowMessage(scene, 0);
1004 Colosso_ShowPointer(120, 72, 0);
1005 Event_ShowMessage(scene, 0);
1007 Engine_EventWait(15);
1008 Colosso_FadeInCompetitor(0, 984, 200);
1010 Event_ShowMessage(scene, 0);
1014 Colosso_WalkActorToAndStand(0, 1000, 192);
1015 Colosso_WalkActorToAndStand(0, 1000, 176);
1016 Colosso_WalkActorToAndStand(0, 1016, 168);
1017 Engine_EventWait(15);
1018 // UB: the void target is called through an incompatible return type.
1019 /* FAKEMATCH: called through a cast to the s32 call type the bytes show, its
1020 * result discarded, for the native argument order; as a direct call, 3
1021 * instructions differ in tbs-en. */
1023 Camera_MoveTo(PIXELS(1088), -1, PIXELS(168), 1);
1025 Engine_EventWait(10);
1028 Engine_EventWait(10);
1031 Event_ShowMessage(scene, 0);
1035 Colosso_RepeatStageNumber(scene, 4);
1036 } else if (path == 1) {
1037 Engine_EventSetMessage(MsgColossoLogsKeyClearingStage);
1038 Event_ShowMessage(scene, 0);
1039 }
1040 Colosso_OfferCheeringSpot(path, scene, 4);
1042}
1043
1044/// Sets the leader's movement speed for the shared Colosso dialogue.
1045static inline void InitializeActorZero(void) {
1047}
1048
1049/// Sets an attendant's movement speed for the shared Colosso dialogue.
1050static inline void InitializeSelectedActor(s32 actorId) {
1051 Engine_ActorSetSpeed(actorId, PIXELS(1), PIXELS(1) / 2);
1052}
1053
1054/// Advances to the next message in the current explanation.
1055static __inline__ void AdvanceMessage(s32 amount) {
1056 gEventWork->message += amount;
1057}
1058
1059#include "common/colosso_solo.h"
1060#include "common/item_equip.h"
1061#include "common/colosso_task.h"
1062
1063/// Selects a presentation script and resets its playback state.
1065 const s16 *script;
1066
1068 gColosso_LetteringParam = (param << 4);
1069
1070 FieldScheduler_AddCallback(Colosso_UpdateLettering, 0xc80);
1071
1072 script = gColossoRiver_RoundSpans;
1073 if (mode == 2) {
1075 }
1076 if (mode == 4) {
1078 }
1079 if (mode == 3) {
1080 if (param != 0) {
1081 script = gColossoRiver_SpanB;
1082 } else {
1083 script = gColossoRiver_SpanA;
1084 }
1085 }
1086
1088 gColosso_LetteringScript = (s16 *)script;
1092}
1093
1094/// The match opens: portraits of the warriors and the round announced.
1096 if (round == 0) {
1100 Engine_EventWait(30);
1102 Colosso_LoadLettering(0);
1104 Engine_EventWait(120);
1106 } else {
1111 gColossoRiver_RoundSpans[15] = round * 60;
1112 Engine_EventWait(30);
1113 Engine_AudioPlayCue(round + 90);
1114 Colosso_LoadLettering(round);
1116 Engine_EventWait(120);
1117 while (AudioCommand_GetStateByte() != 0) {
1118 Engine_TaskWait(1);
1119 }
1121 Colosso_LoadLettering(5);
1124 Engine_EventWait(60);
1127 Engine_EventWait(60);
1128 Colosso_LoadLettering(6);
1131 Engine_EventWait(60);
1132 Colosso_LoadLettering(7);
1137 Engine_GameFlagSet(0x123);
1138 }
1139}
1140
1141/// The result: the winner's portrait and fanfare, then the course closes.
1143
1144 s32 kind;
1145
1149 gColossoRiver_SpanA[13] = result * 60;
1150 STORE_CONST(gColossoRiver_SpanB[13]) = (result < 0 ? -result : result) * 60;
1151 if (result < 0) {
1152 Engine_EventWait(30);
1154 Colosso_LoadLettering(8);
1155 // UB: the void target is called through an incompatible return type.
1156 /* FAKEMATCH: called through a cast to the s32 call type the bytes show, its
1157 * result discarded, for the native argument order; as a direct call, 2
1158 * instructions differ in tbs-en. */
1160 Engine_EventWait(-result * 60 + 60);
1161 kind = 0;
1162 } else {
1163 Engine_EventWait(30);
1164 Engine_AudioPlayCue(result + 90);
1165 Colosso_LoadLettering(4);
1166 // UB: the void target is called through an incompatible return type.
1167 /* FAKEMATCH: called through a cast to the s32 call type the bytes show, its
1168 * result discarded, for the native argument order; as a direct call, 2
1169 * instructions differ in tbs-en. */
1171 Engine_EventWait(result * 60 + 60);
1172 kind = 8;
1173 }
1174 Engine_ActorShowEmote(kind, 0x105, 0);
1175 while (AudioCommand_GetStateByte() != 0) {
1176 Engine_TaskWait(1);
1177 }
1179 Engine_EventWait(30);
1183}
1184
1185#include "common/colosso_marker.h"
1187
1188/// Writes eight hexadecimal digits and a terminating null.
1189UNUSED static void Text_WriteU32AsHex(u8 *buf, u32 value) {
1190 s32 i;
1191
1192 buf += 8;
1193 *buf = 0;
1194 buf--;
1195 for (i = 7; i >= 0; i--) {
1196 *buf = gHexDigits[value & 15];
1197 value >>= 4;
1198 buf--;
1199 }
1200}
1201
1202static void ColossoRiver_NoOp(void) {}
1203
1204/// Marks the shared stage state ready for the waiting event.
1206 s16 *ready = (s16 *)gSceneState;
1207 u16 nine = 9;
1208
1209 *ready = nine;
1210}
1211
1212/// Waits until the stage's setup task reports readiness.
1214 s16 *ready = (s16 *)gSceneState;
1215
1216 while (*ready != 9) {
1217 Engine_TaskWait(1);
1218 }
1219}
1220
1221/// Occasionally spawns an animated effect around the finish item.
1222static void ColossoRiver_SpawnRandomEffect(union FieldObject *fieldObject) {
1223 struct FieldActor *actor = (struct FieldActor *)fieldObject;
1224 s32 position[3];
1225 u32 chance;
1226
1227 if (actor->velocityY >= -255 && actor->velocityY <= 255) {
1228 actor->motionFlags = 0;
1229 }
1230 chance = Engine_RandomNext();
1231 if (chance * 100 >> 16 <= 9) {
1232 struct FieldActor *effect;
1233 s32 radius;
1234 s32 angle;
1235
1236 SET_VECTOR(position, actor->x.fixed, actor->y.fixed, actor->z.fixed);
1238 angle = Engine_RandomNext();
1239 Vector_AddPolarOffset(radius << 4, angle, position);
1240 {
1241 s32 x = position[0];
1242 s32 y = position[1];
1243 s32 z = position[2];
1244
1245 effect = Engine_ObjectCreate(285, x, y, z);
1246 }
1247 if (effect != 0) {
1248 effect->motionFlags = 0;
1249 Engine_ActorSetSpriteFlags(effect, 0);
1251 Object_SetMode(effect, 1);
1252 Object_SetMode(effect, 0);
1253 }
1254 }
1255}
1256
1257/// Presents the collected item above its collector and signals completion.
1258static s32
1260 struct FieldActor *collector = (struct FieldActor *)interpreter;
1261 struct FieldActor *itemActor = Object_GetById(collector->timer);
1262
1263 Engine_ObjectSetPosition(itemActor, collector->x.fixed,
1264 collector->y.fixed + PIXELS(36), collector->z.fixed);
1265 itemActor->motionFlags = 0;
1268 collector->timer = 0;
1269 return 0;
1270}
1271
1272/// Moves to the selected finish item and presents it to the party.
1273static s32 ColossoRiver_CollectFinishItem(s32 firstItem, s32 secondItem) {
1274
1275 struct ColossoGaugeWork *work = (struct ColossoGaugeWork *)gColossoWork;
1276 struct FieldActor *actor;
1277 s32 flag;
1278 s32 x;
1279 s32 z;
1280 u16 *itemActor;
1281 s16 *pendingItemActor;
1282
1284
1286
1287 if (work->finishX < actor->x.fixed) {
1288 x = work->finishX + PIXELS(12);
1289 } else {
1290 x = work->finishX - PIXELS(12);
1291 }
1292
1293 if (flag != 0) {
1294 z = work->finishZ + PIXELS(16);
1295 itemActor = &work->finishItemActorB;
1296 } else {
1297 z = work->finishZ - PIXELS(16);
1298 itemActor = &work->finishItemActorA;
1299 }
1300
1301 pendingItemActor = &actor->timer;
1302 *pendingItemActor = *itemActor;
1303 actor->acceleration = PIXELS(1) / 4;
1304 actor->speed = PIXELS(1);
1305
1306 Engine_ObjectSetPosition(actor, x, 0, z);
1309
1310 while (*pendingItemActor != 0) {
1311 Engine_TaskWait(1);
1312 }
1313
1314 if (flag == 0) {
1315 // UB: the void target is called through an incompatible return type.
1316 /* FAKEMATCH: the void function is called as returning s32, the call the
1317 * bytes show; by its prototype, 2 instructions differ in tbs-en. */
1319 UiWork_PushValueSlot(firstItem, 2);
1320 } else {
1321 // UB: the void target is called through an incompatible return type.
1322 /* FAKEMATCH: the same call as returning s32; by its prototype, 2
1323 * instructions differ in tbs-en. */
1325 UiWork_PushValueSlot(secondItem, 2);
1326 }
1327
1329 Engine_MessageShowCentered(MsgColossoIsaacGotItem, 3);
1331
1332 return flag;
1333}
1334
1336#include "common/colosso_setup.h"
1338#include "common/object_findslot.h"
1339
1340/// Checks the next cell and pushes its object one step if clear.
1342
1343 struct FieldActor *subject;
1344 struct FieldActor *target;
1345 struct FieldActor *blocker;
1346 u32 packedStep;
1347 u32 direction;
1348 struct FieldPosition position;
1349 s32 zero;
1350 s32 actorId;
1351
1352 actorId = gGameState.selectedActor;
1353 subject = Object_GetById(actorId);
1354
1355 direction = subject->facing >> 12;
1356
1357 packedStep = gColossoRiver_DirectionSteps[direction];
1358 position.x = subject->x.fixed + (packedStep & 0xffff0000);
1359 position.y = subject->y.fixed;
1360 packedStep <<= 16;
1361 position.z = subject->z.fixed + packedStep;
1362
1363 target = SceneData_FindSlotAtPosition(&position, subject);
1364 if (target == 0) {
1365 return;
1366 }
1367
1368 packedStep = gColossoRiver_DirectionSteps[direction];
1369 position.x = target->x.fixed + (packedStep & 0xffff0000);
1370 position.y = target->y.fixed;
1371 packedStep <<= 16;
1372 position.z = target->z.fixed + packedStep;
1373
1374 blocker = SceneData_FindSlotAtPosition(&position, target);
1375 if (blocker != 0 && (blocker->collisionFlags & 1) != 0) {
1376 return;
1377 }
1378
1379 position.x = target->x.fixed;
1380 position.y = target->y.fixed + PIXELS(16);
1381 position.z = target->z.fixed;
1382
1383 blocker = SceneData_FindSlotAtPosition(&position, target);
1384 if (blocker != 0 && (blocker->collisionFlags & 1) != 0) {
1385 return;
1386 }
1387
1388 target->terrainId = 2;
1389 zero = 0;
1390
1391 packedStep = gColossoRiver_DirectionSteps[direction];
1392 position.x = target->x.fixed + (packedStep & 0xffff0000);
1393 position.y = target->y.fixed;
1394 packedStep <<= 16;
1395 position.z = target->z.fixed + packedStep;
1396
1397 if (FieldObject_CheckMovementCollision(target, &position) > 0) {
1398 return;
1399 }
1400
1401 Object_SetMode(subject, 8);
1402 Engine_TaskWait(15);
1403
1404 target->speed = PIXELS(1) / 5;
1405 target->acceleration = PIXELS(1) / 5;
1406 Engine_ObjectSetPosition(target, position.x, position.y, position.z);
1407
1408 subject->speed = PIXELS(1) / 5;
1409 subject->acceleration = PIXELS(1) / 5;
1410 Engine_ObjectSetPosition(subject, position.x, position.y, position.z);
1411
1415
1416 target->x.fixed = position.x;
1417 target->z.fixed = position.z;
1418 target->velocityX = zero;
1419 target->velocityZ = zero;
1420
1421 Object_SetMode(subject, 1);
1422}
1423
1425
1426// clang-format off
1428#if LANGUAGE == LANGUAGE_JAPANESE || LANGUAGE == LANGUAGE_ENGLISH
1429 0, 32, 32, 32, 96, 64, 64, 64, 128, 0,
1430#else
1431 0, 32, 32, 32, 96, 64, 64, 160, 128, 0,
1432#endif
1433};
1434
1436 0x1000, 512, 1, 0x2000, 0, 1, 0x1000, 256,
1437 6, 0x2000, 16, 6, 0x7fff, 30, 0x2000, 0,
1438 30, 0x7fff, 30, -1,
1439};
1440
1442 0x1000, 128, 1, 0x2000, 0, 1, 0x1000, 256,
1443 6, 0x2000, 16, 6, 0x7fff, 60, 0x1000, 384,
1444 6, 0x7fff, 6, 0x1000, 240, 6, 0x7fff, 6,
1445 0x1000, 368, 6, 0x7fff, 6, 0x1000, 224, 6,
1446 0x7fff, 6, 0x2000, 0, 30, 0x1000, 352, 6,
1447 0x7fff, 6, 0x1000, 208, 6, 0x7fff, 6, 0x1000,
1448 336, 6, 0x7fff, 6, 0x1000, 192, 6, 0x7fff,
1449 6, 0x1000, 320, 6, 0x7fff, 6, -1,
1450};
1451
1452char gHexDigits[20] = "0123456789ABCDEF";
1453
1455 SC_ADD(SW_Y, -PIXELS(1) / 4),
1456 SC_WAIT(1),
1457 SC_LOOP(60, SC_TOP),
1458 SC_FREE,
1459};
1460
1463 SC_LABEL(1),
1464 SC_WAIT(10),
1465 SC_SET(SW_SCALE_X, (11 * Q16_ONE) / 8),
1466 SC_SET(SW_SCALE_Y, (11 * Q16_ONE) / 8),
1467 SC_WAIT(2),
1468 SC_SET(SW_SCALE_X, (3 * Q16_ONE) / 2),
1469 SC_SET(SW_SCALE_Y, (3 * Q16_ONE) / 2),
1470 SC_WAIT(2),
1471 SC_SET(SW_SCALE_X, (9 * Q16_ONE) / 8),
1472 SC_SET(SW_SCALE_Y, (9 * Q16_ONE) / 8),
1473 SC_WAIT(2),
1476 SC_WAIT(2),
1477 SC_SET(SW_SCALE_X, (11 * Q16_ONE) / 8),
1478 SC_SET(SW_SCALE_Y, (11 * Q16_ONE) / 8),
1479 SC_WAIT(2),
1480 SC_SET(SW_SCALE_X, (3 * Q16_ONE) / 2),
1481 SC_SET(SW_SCALE_Y, (3 * Q16_ONE) / 2),
1482 SC_WAIT(2),
1483 SC_SET(SW_SCALE_X, (9 * Q16_ONE) / 8),
1484 SC_SET(SW_SCALE_Y, (9 * Q16_ONE) / 8),
1485 SC_WAIT(2),
1488 SC_WAIT(2),
1489 SC_WAIT(50),
1490 SC_LOOP(2, SC_TO(1)),
1491 SC_POS(0, 0, 0),
1492 SC_SET(SW_HOOK, 0),
1493 SC_END,
1494};
1495
1496/// Pixel steps by direction: X in the upper halfword, Z in the lower.
1497#define DIRECTION_STEP(x, z) ((u32)(x) << 16 | (u16)(z))
1498
1500 DIRECTION_STEP(16, 0),
1501 DIRECTION_STEP(16, 0),
1502 DIRECTION_STEP(16, 0),
1503 DIRECTION_STEP(0, 16),
1504 DIRECTION_STEP(0, 16),
1505 DIRECTION_STEP(0, 16),
1506 DIRECTION_STEP(0, 16),
1507 DIRECTION_STEP(-16, 0),
1508 DIRECTION_STEP(-16, 0),
1509 DIRECTION_STEP(-16, 0),
1510 DIRECTION_STEP(-16, 0),
1511 DIRECTION_STEP(0, -16),
1512 DIRECTION_STEP(0, -16),
1513 DIRECTION_STEP(0, -16),
1514 DIRECTION_STEP(0, -16),
1515 DIRECTION_STEP(16, 0),
1516};
1517
1519 { 0, CONDITION_ALWAYS, 920, 0, 200, FACING_SOUTH, 0, -1, -1, -1, -1, 0 },
1520 { 1, CONDITION_ALWAYS, 312, 0, 104, FACING_SOUTH, 0, -1, -1, -1, -1, 0 },
1521 { SCENE_TABLE_END },
1522};
1523
1525 SCENE_EXITS(143),
1526 SCENE_EXIT(10, 143, 1),
1527 SCENE_EXIT(11, 140, 12),
1528 SCENE_EXIT(4, 140, 21),
1529 SCENE_EXIT(5, 138, 98),
1531};
1532
1535 PIXELS(312), 0, PIXELS(104), FACING_SOUTH, TALK_FACE_PARTY, 0 },
1537 0, 0, 0, FACING_NORTH, TALK_FACE_PARTY, 0 },
1539 0, 0, 0, FACING_NORTH, TALK_FACE_PARTY, 0 },
1541 0, 0, 0, FACING_NORTH, TALK_FACE_PARTY, 0 },
1543 0, 0, 0, FACING_WEST, TALK_FACE_PARTY, 0 },
1545 PIXELS(312), 0, PIXELS(168), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1547 PIXELS(408), 0, PIXELS(200), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1549 PIXELS(456), 0, PIXELS(184), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1550 { 0xe5, CONDITION_ALWAYS, 7,
1551 PIXELS(601), 0, PIXELS(146), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1552 { 0x122, CONDITION_ALWAYS, 7,
1553 PIXELS(552), 0, PIXELS(200), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1554 { 0x122, CONDITION_ALWAYS, 7,
1555 PIXELS(664), 0, PIXELS(200), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1557 PIXELS(760), 0, PIXELS(194), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1559 PIXELS(944), 0, PIXELS(216), FACING_WEST, TALK_KEEP_FACING, 0 },
1560 { 0xec, CONDITION_ALWAYS, 7,
1561 PIXELS(1048), 0, PIXELS(136), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1562 { 0xed, CONDITION_ALWAYS, 7,
1563 PIXELS(1016), 0, PIXELS(168), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1573 PIXELS(1080), 0, PIXELS(312), FACING_SOUTH, TALK_FACE_PARTY_AND_BACK, 0 },
1575 PIXELS(1304), 0, PIXELS(176), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1577 PIXELS(1304), 0, PIXELS(208), FACING_SOUTH, TALK_KEEP_FACING, 0 },
1578 { SCENE_TABLE_END },
1579};
1580
1582
1593 { SEARCH(SEARCH_CHEST), 100, 0x308, FIND_ITEM(ITEM_NUT) },
1594 { SEARCH(SEARCH_CHEST), 101, 0x309, FIND_ITEM(ITEM_OIL_DROP) },
1595 { 0x8413, 103, 0x30a, FIND_ITEM(ITEM_NUT) },
1606 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), GUIDE, CONDITION_ALWAYS, MSGNO(MsgColossoRiverThisYearsFinalsAreIncredibleThis) },
1607 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), ROCK_ATTENDANT, CONDITION_ALWAYS, MSGNO(MsgColossoRiverMovingSuchAHugeRockMust) },
1608 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), PIPEWORKS_ATTENDANT, CONDITION_ALWAYS, MSGNO(MsgColossoRiverTheresOnlyOneFinalAndThis) },
1609 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), BRIDGE_ATTENDANT, CONDITION_ALWAYS, MSGNO(MsgColossoRiverDidYouSeeHisMovesOut) },
1610 { PSYNERGY_ON_ACTOR(ABILITY_MIND_READ), LUMBER_ATTENDANT, CONDITION_ALWAYS, MSGNO(MsgColossoRiverHowManyWarriorsHaveSwallowedTheir) },
1612 { SCENE_EVENTS_END },
1613};
1614
1616
1618#if LANGUAGE == LANGUAGE_JAPANESE
1619 0x4000, -188, 2048, 0x1000, 256, 1, 0x2000, 16,
1620#else
1621 0x4000, -188, 2048, 0x1000, 384, 1, 0x2000, 16,
1622#endif
1623 1, 0x7fff, 14, 0x3000, 0, 20, 0x7fff, 60,
1624 0x3000, 2048, 20, 0x7fff, 60, -1,
1625};
1626
1628#if LANGUAGE == LANGUAGE_FRENCH
1629 0x1000, 512, 1, 0x2000, 0, 1, 0x1000, 384,
1630 6, 0x2000, 16, 6, 0x7fff, 6, 0x1000, 512,
1631 6, 0x7fff, 6, 0x1000, 384, 6, 0x7fff, 6,
1632 0x1000, 512, 6, 0x7fff, 6, 0x1000, 384, 6,
1633 0x7fff, 6, 0x2000, 0, 30, 0x1000, 512, 6,
1634 0x7fff, 6, 0x1000, 384, 6, 0x7fff, 6, 0x1000,
1635 512, 6, 0x7fff, 6, 0x1000, 384, 6, 0x7fff,
1636 6, 0x1000, 512, 6, 0x7fff, 6, -1,
1637#elif LANGUAGE == LANGUAGE_SPANISH || LANGUAGE == LANGUAGE_ITALIAN
1638 0x1000, 384, 1, 0x2000, 0, 1, 0x1000, 256,
1639 6, 0x2000, 16, 6, 0x7fff, 6, 0x1000, 384,
1640 6, 0x7fff, 6, 0x1000, 256, 6, 0x7fff, 6,
1641 0x1000, 384, 6, 0x7fff, 6, 0x1000, 256, 6,
1642 0x7fff, 6, 0x2000, 0, 30, 0x1000, 384, 6,
1643 0x7fff, 6, 0x1000, 256, 6, 0x7fff, 6, 0x1000,
1644 384, 6, 0x7fff, 6, 0x1000, 256, 6, 0x7fff,
1645 6, 0x1000, 384, 6, 0x7fff, 6, -1,
1646#else
1647 0x1000, 512, 1, 0x2000, 0, 1, 0x1000, 256,
1648 6, 0x2000, 16, 6, 0x7fff, 6, 0x1000, 384,
1649 6, 0x7fff, 6, 0x1000, 256, 6, 0x7fff, 6,
1650 0x1000, 384, 6, 0x7fff, 6, 0x1000, 256, 6,
1651 0x7fff, 6, 0x2000, 0, 30, 0x1000, 384, 6,
1652 0x7fff, 6, 0x1000, 256, 6, 0x7fff, 6, 0x1000,
1653 384, 6, 0x7fff, 6, 0x1000, 256, 6, 0x7fff,
1654 6, 0x1000, 384, 6, 0x7fff, 6, -1,
1655#endif
1656};
1657
1659 0x1000, 128, 1, 0x2000, 0, 1, 0x1000, 256,
1660 6, 0x2000, 16, 6, 0x7fff, 60, 0x1000, 384,
1661 6, 0x7fff, 6, 0x1000, 272, 6, 0x7fff, 6,
1662 0x1000, 400, 6, 0x7fff, 6, 0x1000, 288, 6,
1663 0x7fff, 6, 0x2000, 0, 30, 0x1000, 416, 6,
1664 0x7fff, 6, 0x1000, 304, 6, 0x7fff, 6, 0x1000,
1665 432, 6, 0x7fff, 6, 0x1000, 320, 6, 0x7fff,
1666 6, 0x1000, 448, 6, 0x7fff, 6, -1,
1667};
1668// clang-format on
1669
1671
1673 SC_ARG(2),
1674 SC_SYNC,
1675 SC_ARG(1),
1676 SC_WAIT(6),
1678 SC_WAIT(3),
1679 SC_ARG(10),
1680 SC_WAIT(150),
1682 SC_ARG(1),
1683 SC_END,
1684};
1685
1687 SC_ARG(2),
1688 SC_SYNC,
1689 SC_ARG(1),
1690 SC_WAIT(6),
1692 SC_WAIT(3),
1693 SC_ARG(28),
1694 SC_WAIT(150),
1696 SC_ARG(1),
1697 SC_END,
1698};
Ability numbers, named from the English release.
@ ABILITY_DOUSE
Definition ability_ids.h:12
@ ABILITY_MIND_READ
Definition ability_ids.h:16
@ ABILITY_MOVE
Definition ability_ids.h:15
@ ABILITY_GROWTH
Definition ability_ids.h:10
void Object_RefreshSelectorById(u32 objectId)
Waits, at most 300 frames, for an actor's script to reach its end (command 0x10).
void Object_LinkObjectAndSetCallback(u32 objectId, u32 linkedObjectId)
Makes an actor follow another (the linked action script): writes its linkedObject.
struct FieldActor * Object_GetById(s32 actor)
Returns an actor, or NULL if it does not exist.
#define DIRECTION_STEP(dx, dz)
Pixel step by direction: X in the upper halfword, Z in the lower.
BattleUnit, a party member's or enemy's battle state, with the elements, abilities and actions it use...
static void Event_GrowPlant(void)
Growth on the entrance section's target: the plant grows and its cell's collision changes; 0x305 keep...
The task scheduler: tasks, their order and the scheduler's state.
#define GARET
Jerald.
#define MIA
Mary.
#define IVAN
Ivan.
The Colosso race gauge's sprites and work.
s16 gColosso_MarkerSlot
const u8 gColosso_LetteringPaletteOffsets[]
static void Event_ReachArena(void)
Reaching the arena: the leader takes a prize (the Claymore if first, the Hunter's Sword if second),...
s16 gColosso_LetteringSlot
@ PRIZE_A
the arena's Claymore and Hunter's Sword
@ OPPONENT
the warrior racing Isaac to the arena
Definition colosso_log.c:93
@ GUIDE
explains the third course
@ GROWTH_PLANT
@ PRIZE_B
s32 gColosso_RivalFinishScript[]
static void Event_SettleRocks(void)
A rock resting on the floor becomes a step (FLAG_SCENE_TEMP_14 to _16).
static void Event_PushRock(void)
Walking into a rock pushes it.
static void ColossoRiver_UpdateBrokenBridge(void)
Advances the bridge animation and its walkable collision cells.
static void ColossoRiver_MarkCourseTerrain(s32 actor)
Marks actors standing in the course's finish terrain.
const u32 * ColossoRiver_GetExits(void)
u32 gColossoRiver_DirectionSteps[]
const s16 gColossoRiver_SpanB[]
static void ColossoRiver_RestoreMatchResult(s32 result)
Back from the battle: the two warriors stand in the arena as the result is shown.
static void ColossoRiver_SpawnRandomEffect(union FieldObject *fieldObject)
Occasionally spawns an animated effect around the finish item.
static void Event_RollLogNorthSouth(void)
Walking into the north-south log rolls it, with the leader, to the other bank.
const struct SceneRegion * ColossoRiver_GetRegions(void)
static void ColossoRiver_PushObjectAhead(void)
Checks the next cell and pushes its object one step if clear.
s32 gColossoRiver_Countdown
s32 gColossoRiver_ScriptA[]
static void Event_TalkToLumberAttendant(s32 scene)
The Lumber Water Crossing Area's attendant: a warrior rolls a log across; then the objective.
#define COLOSSO_RIVER_FACE_DIRECTION
static void InitializeSelectedActor(s32 actorId)
Sets an attendant's movement speed for the shared Colosso dialogue.
static void InitializeActorZero(void)
Sets the leader's movement speed for the shared Colosso dialogue.
static void ColossoRiver_SelectPresentationScript(u32 mode, u32 param)
Selects a presentation script and resets its playback state.
static void ColossoRiver_MoveActorPairByOffset(s32 actorId, s32 dx, s32 dz)
Moves the leader and a course object together between cell centers.
static __inline__ void AdvanceMessage(s32 amount)
Advances to the next message in the current explanation.
const s16 gColossoRiver_ModeRecordTwo[]
static void Event_TalkToPipeworksAttendant(s32 attendant)
The Pipeworks' attendant: a marker shows how the pipes rise and fall like scales; then the objective.
struct SceneEvent gColossoRiver_Events[]
const struct SceneEntrance * ColossoRiver_GetEntrances(void)
const struct SceneEvent * ColossoRiver_GetEvents(void)
static void Event_PushPipeworksBlock(void)
Pushing the Pipeworks block west: water runs into the channel, and the first time the pipes rise (0x3...
s16 gColossoRiver_RoundSpans[]
static void ColossoRiver_WaitForBridgeOpening(void)
Waits for the crossing window, bounded by one bridge cycle.
static void ColossoRiver_StartBrokenBridge(void)
Starts the bridge's repeating opening sequence.
#define COLOSSO_RIVER_SELECT_MODE_BLOCK
static void ColossoRiver_NoOp(void)
static void ColossoRiver_WaitForStageReady(void)
Waits until the stage's setup task reports readiness.
static void Event_TalkToBridgeAttendant(s32 scene)
The Broken Bridge's attendant: a warrior times his crossing; then the objective.
static UNUSED void ColossoRiver_MarkStageReady(void)
Marks the shared stage state ready for the waiting event.
static void Event_DousePipe(void)
Douse on the west pipe: the camera turns to the Pipeworks and the two pipes rise as it fills (0x301).
static void Event_TalkToRockAttendant(s32 scene)
The Rock Challenge's attendant: the first time, a warrior shows how to push the rocks into steps; the...
char gHexDigits[20]
static void Event_PushRockOrCheckAhead(void)
Walking into something: a rock is pushed, anything else is checked.
struct SceneEntrance gColossoRiver_Entrances[]
static UNUSED void Text_WriteU32AsHex(u8 *buf, u32 value)
Writes eight hexadecimal digits and a terminating null.
static UNUSED void ColossoRiver_SetCourseFlag(void)
static s32 ColossoRiver_CollectFinishItem(s32 firstItem, s32 secondItem)
Moves to the selected finish item and presents it to the party.
s16 gColossoRiver_SpanA[]
s32 gColossoRiver_ApproachScript[]
const struct ScenePlacement * ColossoRiver_GetPlacements(void)
static void ColossoRiver_ExplainFinalsRules(s32 guide)
The guide shows the party the first finals course: the race through the stages to the arena,...
void(*) SceneTask(void)
s16 gColossoRiver_ModeRecordFour[]
static void ColossoRiver_ResetBrokenBridge(void)
Stops the bridge task and restores its closed frame.
#define COLOSSO_RIVER_APPLY_MATCHING_SLOT_VALUES
static void ColossoRiver_AnimatePipeworksWater(void)
Runs the five frames that show water entering the Pipeworks channel.
struct ScenePlacement gColossoRiver_Placements[]
u32 gColossoRiver_Exits[]
#define COLOSSO_RIVER_PLACE_STAGED_PAIR
s32 gColossoRiver_ScriptB[]
static void ColossoRiver_SetPipeHeight(struct FieldActor *actor, s32 height)
Moves a Pipeworks actor with the speed used throughout its demonstration.
static void Event_RollLogEastWest(void)
Walking into the east-west log rolls it, with the leader, the way the pad is held.
static void ColossoRiver_ShowMatchResult(s32 result)
The result: the winner's portrait and fanfare, then the course closes.
static void ColossoRiver_ShowRoundIntroduction(s32 round)
The match opens: portraits of the warriors and the round announced.
@ PIPEWORKS_ATTENDANT
@ ROCK_A
the Rock Challenge's three rocks
@ LUMBER_ATTENDANT
@ PIPEWORKS_BLOCK
pushed west to let water into the Pipeworks
@ PIPE_EAST
@ ROCK_B
@ LOG_NORTH_SOUTH
the Lumber Water Crossing Area's two logs
@ BRIDGE_ATTENDANT
@ ROCK_C
@ PIPE_WEST
the Pipeworks' two pipes, a kind of scale
@ LOG_EAST_WEST
@ ROCK_ATTENDANT
@ BRIDGE_OPERATOR
works the Broken Bridge
static s32 ColossoRiver_PlaceFinishItemAboveActor(struct ScriptInterpreter *interpreter)
Presents the collected item above its collector and signals completion.
s32 ColossoRiver_Initialize(void)
Restores the stages as they were left, then by the arrival: the race (1 and 2), the guide's explanati...
The Colosso finals' three courses (Colosso Log, River and Wall): a helper for the race gauge that no ...
s16 gColosso_ModeMoveTarget
s16 * gColosso_LetteringScript
s16 gColosso_LetteringTimer
s32 gColosso_LetteringPosition
s16 gColosso_ModeMoveDuration
s16 gColosso_LetteringParam
s16 gColosso_LetteringMode
void Engine_ActorSetSpriteFlags(struct FieldActor *, s32)
struct FieldActor * Engine_ObjectCreate(s32, s32, s32, s32)
The engine calls the debug menus import, and their palette swatch tiles.
The edition's language, for C to compare (LANGUAGE == LANGUAGE_GERMAN).
static s32 FieldScheduler_AddCallback(SchedulerCallback callback, s32 priority)
Registers a main-image scheduler callback.
Definition engine_call.h:36
static s32 FieldObject_CheckMovementCollision(struct FieldActor *actor, struct FieldPosition *position)
Definition engine_call.h:66
static s32 FieldGameFlag_GetByte(s32 flag)
Definition engine_call.h:71
static void FieldGameFlag_SetByte(s32 flag, s32 value)
Definition engine_call.h:75
void ObjectDispatch_StartCamera(struct DispatchObject *object, s32 linkedObjectHandle)
Starts an object on the camera script (SC_CAMERA).
Definition objects.c:480
void ObjectDispatch_WaitForValue16(void *rawObject)
Waits until the object's script reaches SC_END (0x10), at most 300 frames.
Definition objects.c:495
The scene script layer: the engine services a scene's events call, declared once (Engine_EventBegin,...
void Engine_ObjectSetPosition(struct FieldActor *object, s32 fixed_x, s32 fixed_y, s32 fixed_z)
s32 Engine_LeaderCheckAhead(void)
static void Actor_SetDestination(s32 actor, s32 x, s32 z)
static void Actor_FaceDirection(s32 actor, s32 facing, s32 frames)
void Engine_ActorSetAnimationAndWait(s32 actor, s32 animation)
void Object_SetMode(struct FieldActor *object, s32 animation)
void Engine_MessageShowCentered(s32 message, s32 flags)
#define GameFlag_IsSet
void Engine_CameraSetSpeed(s32 speed, s32 acceleration)
static void Actor_WalkToAndWait(s32 actor, s32 x, s32 z)
static void Camera_SetSpeed(s32 speed, s32 acceleration)
void Engine_CameraMoveTo(s32 fixed_x, s32 fixed_y, s32 fixed_z, s32 pan)
s32 Engine_TaskRemoveCallback(void(*callback)(void))
void Engine_ActorSetSpeed(s32 actor, s32 speed, s32 acceleration)
void Engine_ActorFaceDirection(s32 actor, s32 facing, s32 frames)
void Engine_EventCloseScreen(void)
void Engine_ActorWalkToAndWait(s32 actor, s32 x, s32 z)
static void Actor_FaceActor(s32 actor, s32 target, s32 frames)
static void Actor_WalkTo(s32 actor, s32 x, s32 z)
void Engine_EventWaitForScreen(void)
#define GameFlag_Set
void Engine_ActorDestroy(s32 actor)
static void Actor_ShowEmote(s32 actor, s32 emote, s32 frames)
void Engine_MapCopyCellsLayered(s32 srcX, s32 srcY, s32 destX, s32 destY, s32 width, s32 height)
void Engine_ObjectSetScript(struct FieldActor *object, const s32 *script)
void Engine_EventOpenScreen(void)
void Engine_GameFlagSet(s32 flag)
void Engine_CameraWaitForMove(void)
void Engine_ActorWaitForMove(s32 actor)
void Engine_CameraFollowActor(s32 actor, s32 keep_position)
static void Map_CopyCellAttributes(s32 srcX, s32 srcY, s32 width, s32 height, s32 destX, s32 destY)
void Engine_ActorRunRepeatedMotion(s32 actor, s32 repeats)
static void Event_ShowMessage(s32 speaker, s32 flags)
s32 Engine_RandomNext()
static void Event_PlayCue(s32 cue)
static void Map_CopyCells(s32 srcX, s32 srcY, s32 width, s32 height, s32 destX, s32 destY)
#define STORE_CONST(place)
Definition field_event.h:29
s32 Engine_GameFlagIsSet(s32 flag)
u8 gSceneState[]
void Engine_ActorStartRepeatedMotion(s32 actor, s32 repeats)
static s32 Event_AskYesNo(s32 speaker, s32 flags)
static void Actor_SetSpeed(s32 actor, s32 speed, s32 acceleration)
u8 * gColossoWork
static void Camera_MoveTo(s32 fixed_x, s32 fixed_y, s32 fixed_z, s32 pan)
static void Actor_SetPosition(s32 actor, s32 fixed_x, s32 fixed_z)
static void Map_CopyCellsLayered(s32 srcX, s32 srcY, s32 destX, s32 destY, s32 width, s32 height)
void Engine_ActorFaceEachOther(s32 actor, s32 other, s32 frames)
void Engine_EventWait(s32 frames)
static struct FieldActor * Actor_Get(s32 actor)
Field objects and actors, and the scene transition styles.
@ ACTOR_PRIORITY_UNDERFOOT
The depth sort treats it as 320 pixels higher on the screen.
Definition field_obj.h:155
The field's runtime work: map cells, scene records and regions, map markers and FieldWork.
The scene table formats: entrances, exits, placements and events, and the macros that write them.
#define SCENE_EVENTS_END
#define FIND_ITEM(item)
@ EVENT_TOUCH
@ EVENT_TALK
@ EVENT_RAISED
#define SCENE_EXITS(scene)
Definition field_scene.h:72
#define SCENE_EXIT(exit, scene, entrance)
Definition field_scene.h:73
@ ACTOR_PARTY_LEADER
@ SCENE_TABLE_END
Definition field_scene.h:43
@ CONDITION_ALWAYS
Definition field_scene.h:44
@ TALK_KEEP_FACING
@ TALK_FACE_PARTY
@ TALK_FACE_PARTY_AND_BACK
#define PSYNERGY_ON_ACTOR(ability)
#define EVENT_SCRIPT(script)
@ ACTOR_STAND
#define SEARCH(target)
#define SCENE_EXITS_END
Definition field_scene.h:77
#define TOUCH_WALKING_INTO(facing)
@ FACING_EAST
Definition field_scene.h:26
@ FACING_NORTH
Definition field_scene.h:32
@ FACING_NORTHWEST
Definition field_scene.h:31
@ FACING_SOUTH
Definition field_scene.h:28
@ FACING_WEST
Definition field_scene.h:30
#define TOUCH_WALKING
#define PIXELS(value)
@ SEARCH_CHEST
The scene service layer: one typed inline for each engine service a scene calls by its own name,...
static void FieldObject_SetPosition(struct FieldActor *object, s32 fixed_x, s32 fixed_y, s32 fixed_z)
16.16 fixed-point constants, sine and cosine, and the library division.
#define Q16_ONE
One in the engine's signed 16.16 fixed-point format.
Definition fixed_math.h:10
Game flags, named where their meaning is shown.
#define FLAG_KEEP_MUSIC
The next scene keeps the music that is playing; scene.c clears FLAG_KEEP_MUSIC as it does,...
Definition flags.h:35
#define FLAG_RETREAT_BLOCKED
Retreat is blocked, from Psynergy or an item.
Definition flags.h:55
#define FLAG_SCENE_TEMP_11
Definition flags.h:730
#define FLAG_KEEP_PARTY_POSITION
Definition flags.h:93
#define FLAG_SCENE_TEMP_10
Definition flags.h:729
GameState, the game's state: play time, coins, the scene and the leader's position,...
#define Battle_SetStart(mode)
Sets the battle start type.
Definition game_state.h:164
struct GameState gGameState
The screen blend's globals and the graphics routines.
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
The heap's work slots and HeapState.
@ HEAP_SLOT_EVENT
Definition heap_state.h:40
The main-image routines scene overlays import.
@ KEY_LEFT
Definition io_reg.h:248
@ KEY_RIGHT
Definition io_reg.h:247
The register write queue that VBlank carries out after each finished frame.
Colosso Log, River and Wall, and Goma Cave's entrance: giving a character an item and putting it on.
Item numbers, named from the English release.
@ ITEM_NUT
Definition item_ids.h:41
@ ITEM_OIL_DROP
Definition item_ids.h:79
The keypad state the VBlank interrupt keeps.
volatile u32 gKeysHeld
Keys down now.
Small statement macros both games use for positions, velocities and bounds.
#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
void Vector_AddPolarOffset(s32 radius, s32 angle, void *position)
Moves the point position by radius in direction angle on the ground plane: x by the cosine,...
Definition math.c:23
The heaps: allocating and freeing blocks.
The reel game's title lettering.
Field object scripts: one s32 command word, then its operands, as gScriptObject_CommandTable runs the...
#define SC_LABEL(n)
Branch destination.
Definition objcmd.h:11
#define SC_SET(w, v)
Write a work value.
Definition objcmd.h:37
#define SC_LOOP(n, to)
Repeat up to n times.
Definition objcmd.h:28
#define SC_POS(x, y, z)
Set position.
Definition objcmd.h:18
#define SC_FREE
Release.
Definition objcmd.h:43
#define SC_SYNC
Wait for arrival.
Definition objcmd.h:17
#define SC_TO(n)
Definition objcmd.h:12
#define SC_ADD(w, v)
Definition objcmd.h:38
#define SC_ARG(v)
Definition objcmd.h:44
#define SC_WAIT(n)
Wait n frames.
Definition objcmd.h:16
#define SC_TOP
Script start.
Definition objcmd.h:13
#define SC_END
Return to the main script.
Definition objcmd.h:32
@ SW_SCALE_Y
Definition objcmd.h:63
@ SW_FACING
Definition objcmd.h:57
@ SW_Y
Definition objcmd.h:59
@ SW_SCALE_X
Definition objcmd.h:62
@ SW_HOOK
Definition objcmd.h:84
#define SC_CALL(fn)
Definition objcmd.h:50
void FieldObject_WaitForMove(void *fieldObject)
Waits a frame at a time until a field object has arrived at its target, at most 600 frames.
ObjectRuntime, a field object's runtime state, and the object snapshots.
void Field_RequestBattleFromEncounterTable(s32 zoneNo, s32 slotNo)
Sets up a battle with enemy group slot of encounter table zone.
Definition requests.c:14
void Event_SetDefeatDestination(s32 scene, s32 entrance)
Sets where the party wakes up after losing a battle (gGameState.defeatScene and defeatEntrance).
Definition requests.c:70
void Event_SetNextDestination(s32 scene, s32 entrance)
Sets the scene and entrance that the field goes to next (gGameState.nextScene and nextEntrance).
Definition requests.c:61
Resource numbers, named where their contents are known.
char ResourceId_RivalPathA
void Audio_PlayCueFromEventWork(void)
Starts the current scene's field music, chosen by Scene_ResolveInteractionResult.
Definition scene.c:355
Scene numbers, named after their places.
char SceneId_ColossoRiver
The field object script interpreter and the operands its commands read.
Song and sound effect ids, indices into gSound_SongTable.
#define SE_213
Definition songs.h:208
#define SE_239
Definition songs.h:234
#define SE_247
Definition songs.h:242
#define MUS_086
Definition songs.h:85
#define MUS_089
Definition songs.h:88
#define MUS_TREASURE_FOUND
Definition songs.h:82
#define SE_288
Definition songs.h:281
#define SE_226
Definition songs.h:221
#define MUS_017
Definition songs.h:27
#define MUS_019
Definition songs.h:29
#define SE_237
Definition songs.h:232
#define SE_238
Definition songs.h:233
#define SE_236
Definition songs.h:231
#define SE_289
Definition songs.h:282
s32 AudioCommand_GetStateByte(void)
Returns the remaining delay before BGM can be restored after a fanfare.
Definition sound.c:261
void Engine_ActorSetAnimation()
struct EventWork * gEventWork
void Engine_EventRequestExit()
void Engine_ActorSetPosition(u32 actor, s32 x, s32 z)
void Engine_EventEnd(void)
void Engine_AudioPlayCue()
void Engine_EventBegin(void)
void Engine_ActorShowEmote()
void Engine_TaskWait()
void Engine_EventSetMessage()
void Engine_EventShowMessage()
Colosso Log, River and Wall, and Crossbone Isle's platform rooms: an actor drawn as an item's menu ic...
void Colosso_ShowItemIcon(s32 id, s32 item)
Replaces the picture of actor id, when it has a sprite of its own, with the icon of item: the icon's ...
void Colosso_ShowPointer(u32 x, u32 y, u32 style)
Shows the pointer at screen pixel (x, y), drawn at priority style & 3.
void Colosso_MovePointer(u32 x, u32 y, u32 duration)
Glides the pointer to screen pixel (x, y) over duration frames.
void OverlayObject_ResetMotionFields(s32 actor)
Stops the actor where it is: no velocity and no destination.
void Colosso_FadeInCompetitor(s32 id, s32 x, s32 z)
Isaac (id) appears at pixel (x, z) on the stage, facing south: he fades in through the backgrounds wh...
void Colosso_HidePointer(void)
Hides the pointer and frees its VRAM block.
void Colosso_WalkActorToAndStand(s32 actorId, s32 x, s32 z)
Walks the actor at 1.25 pixels a frame to pixel (x, z), waits until it arrives and stands it there.
void Colosso_RestoreCompetitor(s32 id)
Puts Isaac (id) back where Colosso_FadeInCompetitor found him: he stands (or turns south,...
void * Colosso_FindActorAhead(void)
Returns the placed actor standing one cell, or else two cells, ahead of the actor the player moves (s...
Colosso Log and Colosso River: setting up a race against the rival, with the race gauge at the top of...
void Colosso_StartRaceGauge(s32 playerActor, s32 rivalActor, s32 segments, s32 finishX, s32 finishZ, s32 finishItemActorA, s32 finishItemActorB)
Starts the race gauge (struct ColossoGaugeWork, in work slot 59): Isaac and the rival as playerActor ...
void Colosso_StartRival(s32 resource)
Decodes the rival's recorded path (resource) after the gauge's work and, unless the party returns to ...
void Colosso_OfferCheeringSpot(s32 mode, s32 guide, s32 stage)
The guide at a stage, with the mode Colosso_GreetAtStage returned: offer a friend's cheering at the s...
void Colosso_RepeatStageNumber(s32 speaker, s32 competitor)
A stage's guide, after describing the stage, names it again: the copy of that line after it in the te...
void Colosso_AskDoneCheering(s32 id)
A stage's guide, talking to a friend who looks around alone, asks whether they are done cheering.
static void Colosso_TakePlaceForMatch(void)
Raised event 99: the nearest actor with animation 165 level with or below the friend on the map calls...
void Colosso_PlaceFriendsAtCheeringSpots(void)
Puts Garet, Ivan and Mia back at the cells where they chose to cheer, at the centre of each cell.
void Colosso_ClearCheeringSpots(void)
Forgets where Garet, Ivan and Mia cheer from.
s32 Colosso_GreetAtStage(s32 speaker, s32 competitor)
A stage's guide names the stage and decides what to do next.
void Colosso_ControlCharacterAlone(s32 id)
Makes the character the party's only member, the one the player moves and the camera follows,...
void Colosso_RaiseTakePlaceOnPsynergy(void)
A scene callback while a friend looks around the course alone (entrance 2): when the Psynergy request...
static void Colosso_AskReadyToRace(s32 actorId)
The guide at the course's start.
The pushable actors' movement probes and footprint bounds.
The Colosso race gauge's work at the start of work slot 59: its sprites, how far it has slid down,...
A field object as the object dispatcher's far calls take it.
The running scene's event work: its placement and event tables, its actors, the triggers and exit it ...
Definition event_work.h:20
s32 startTransition
SCENE_TRANSITION(style, variant).
Definition event_work.h:43
u16 message
the next message, advanced as each window opens
Definition event_work.h:47
A field actor: a person or thing on the field with a position, motion toward a target,...
Definition field_obj.h:30
s16 timer
The parameter its action script reads (a follow distance or an angle to face), the player's frames to...
Definition field_obj.h:109
s32 speed
speed limit, 16.16 fixed-point pixels per frame
Definition field_obj.h:55
u16 radius
Collision radius in pixels: 16, or half the sprite metadata's boxY, when created; the overlap checks ...
Definition field_obj.h:43
u8 motionFlags
ActorMotionFlag bits; zero is free flight in 3D, and 3 is set on creation.
Definition field_obj.h:83
union FieldCoordinate x
16.16 fixed-point pixels
Definition field_obj.h:35
s32 velocityX
16.16 fixed-point pixels per frame
Definition field_obj.h:52
union FieldCoordinate y
16.16 fixed-point pixels
Definition field_obj.h:36
u8 priorityFlags
ActorPriorityFlag bits, read by the scrolling camera.
Definition field_obj.h:51
s32 velocityY
16.16 fixed-point pixels per frame
Definition field_obj.h:53
union FieldCoordinate z
16.16 fixed-point pixels
Definition field_obj.h:37
u16 facing
1/65536 turns
Definition field_obj.h:34
s32 acceleration
Added toward the target each frame, or taken off the speed when there is none, in 16....
Definition field_obj.h:58
u16 work
The side of the player's next footprint (2 after a stop), or scene scratch.
Definition field_obj.h:112
u8 collisionFlags
bits: 7 refuses to move into a solid object | 4 nearer for Psynergy targets | 3 never a talk or Psyne...
Definition field_obj.h:91
s32 velocityZ
16.16 fixed-point pixels per frame
Definition field_obj.h:54
u8 terrainId
The map layer (0 to 3) its ground height is read from, which the scrolling camera updates from the ce...
Definition field_obj.h:47
A position on the field.
s32 z
16.16 fixed-point pixels
Full event work allocated by Field_RunScene (heap slot 27).
s16 entrance
Definition game_state.h:37
s32 selectedActor
the leader: its unit and its actor
Definition game_state.h:59
A scene entrance: where and facing which way the party arrives, and the camera's bounds there (-1 for...
Definition field_scene.h:54
A scene event: its kind and detail, the trigger it answers, its condition and its value (a message or...
An actor a scene places: its sprite, the condition for placing it, how it behaves,...
Definition field_scene.h:81
A scene's exit region: the box that, while its condition holds, takes the party leader out through it...
The prefix that command handlers read from a field object's 0x70-byte slot.
Definition script.h:16
The system's routines and globals: interrupts, BIOS sound bias, random numbers and sleep.
s32 Map_GetTerrainHeight(s32 layer, s32 x, s32 y)
Returns the ground height of a layer at (x, y) in 16.16 pixels: the height function of the cell's ter...
Definition terrain.c:343
The integer types, TRUE, UNUSED and the fixed-address macros.
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
#define UNUSED
Definition types.h:22
unsigned char u8
Definition types.h:11
struct FieldCoordinate::@024321007066302143002254325121164243234242211074 part
s32 fixed
16.16 fixed-point pixels
An object on the field, read as an actor or as an effect.
void Party_RestoreHpPp(s32 cureConditions)
Restores every party member's HP and PP; with cureConditions 1 it also cures poison and haunting.
Definition units.c:662
The patch levels: our groups of the measured changes from the Japanese release.
The sprite VRAM block cache and its owners.
void UiWork_PushValueSlot(u32 value, u32 kind)
Adds a message argument of kind (MSG_ARG_) with value to the first free place of the argument table; ...
Definition messages.c:216