Alchemy
Loading...
Searching...
No Matches

kolima_forest_bend.c

Go to the documentation of this file.
1/// @file
2/// Kolima Forest's bend, between the river and Tret's tree. A floodgate switch
3/// raises and lowers the river: with the water high the logs float (26 pixels
4/// up) and can be rolled along it; with it low they lie on the riverbed. A
5/// short log slides between two places, and a sign warns the party off the
6/// switch.
7///
8/// The water level, the short log's place and each log's cells are kept in
9/// gSceneState (gKolimaForestBendLayout, gKolimaForestBendReturned and
10/// gKolimaForestBendRecords), so they survive a battle.
11
13#include "flags.h"
14#include "unit/import.h"
17#include "unit/object/object.h"
19#include "unit/field/field.h"
21#include "battle.h"
22#include "debug.h"
23#include "field.h"
24#include "game.h"
25#include "graphics.h"
26#include "menu.h"
27#include "minigame.h"
28#include "sound.h"
29#include "system.h"
30#include "mapcopy.h"
31#include "types.h"
32#include "field_event.h"
33#include "engine_call.h"
34#include "scene.h"
35#include "mem.h"
36#include "call.h"
37#include "dma.h"
38#include "map.h"
39#include "io_reg.h"
40#include "irq.h"
41#include "text/msg_ids.h"
42#include "field_scene.h"
43#include "map_scroll.h"
44#include "macros.h"
45#include "songs.h"
46#include "item_ids.h"
47#include "heap_state.h"
48
49enum {
50 SHORT_LOG = 8, ///< slides between x 72 and x 104
52 SIGN = 10 ///< reads a warning. "Do not touch Floodgate Switch!"
53};
54
56static void KolimaForestBend_CreateLogs(struct BendLog *log);
57static void KolimaForestBend_RollLog(struct BendLog *logs);
58
59/// Where the party enters from the river and from Tret's tree.
62}
63
64const struct SceneRegion *KolimaForestBend_GetRegions(void) { return 0; }
65
66/// The paths back to the river and on to Tret's tree.
68
69/// The short log, the switch and the sign.
72}
73
74/// The logs, the switch, the sign, the jump and the chest.
77}
78
79/// Walking into a log: it rolls ahead, and the cells of the logs are marked
80/// again where they now lie.
81static void KolimaForestBend_PushLog(void) {
83 Map_CopyCellAttributes(0, 0x40, 0x20, 0x20, 0, 0);
86}
87
88/// Walking south into the gap: the leader jumps across.
90
91#include "common/map_panel.h"
92
93/// Gives the short log's column of cells its collision: column 4 at the
94/// west place, column 6 at the east.
96 if (*(s16 *)gKolimaForestBendReturned == 1) {
97 Map_CopyCellAttributes(0, 0, 1, 4, 4, 9);
98 } else {
99 Map_CopyCellAttributes(0, 0, 1, 4, 6, 9);
100 }
101}
102
103/// Draws the river at its level and sets each log to match: high water floats
104/// the logs 26 pixels up over their own cells, low water lays them on the
105/// riverbed.
107 struct FieldActor *piece;
108 struct BendLog *record = gKolimaForestBendRecords;
109
110 if (*gKolimaForestBendLayout != 0) {
111 Map_CopyCells(65, 53, 2, 1, 79, 29);
112 Map_CopyCells(65, 40, 2, 4, 15, 28);
113 } else {
114 Map_CopyCells(65, 50, 2, 5, 79, 25);
115 }
116
117 if (*gKolimaForestBendLayout != 0) {
118 Map_CopyCells(0, 32, 32, 32, 32, 0);
119 Map_CopyCells(32, 32, 32, 32, 64, 0);
120 Map_CopyCellAttributes(0, 32, 32, 32, 0, 0);
121 } else {
122 Map_CopyCells(0, 64, 32, 32, 32, 0);
123 Map_CopyCells(32, 64, 32, 32, 64, 0);
124 Map_CopyCellAttributes(0, 64, 32, 32, 0, 0);
125 }
126
127 // Each log floats or rests, and on high water its four cells are drawn.
128 while (record->sprite != -1) {
129 piece = record->actor;
130
131 if (*gKolimaForestBendLayout == 1) {
132 Object_SetMode(piece, 4);
133 piece->priorityFlags = 3;
134 piece->motionFlags = 0;
135 piece->y.fixed = PIXELS(26);
136
137 if (record->vertical != 0) {
138 Map_CopyCells(68, 40, 1, 4, record->x + 32, record->z);
139 } else {
140 Map_CopyCells(70, 40, 4, 1, record->x + 32, record->z);
141 }
142 } else {
143 Object_SetMode(piece, 1);
144 piece->priorityFlags = 1;
145 piece->motionFlags = 2;
146 piece->y.fixed = 0;
147 }
148 record++;
149 }
150
151 Map_CopyCells(70, 42, 1, 1, 10, 50);
152
153 if (*gKolimaForestBendLayout == 1) {
154 Map_CopyCellAttributes(0, 32, 32, 32, 0, 0);
156 } else {
157 Map_CopyCellAttributes(0, 64, 32, 32, 0, 0);
159 }
160
162}
163
164/// HBlank callback: selects the captured shake scroll above the split line.
166 u16 line;
167 u32 *source;
168 volatile u32 *destination;
169
170 line = REG_VCOUNT;
171 source = (u32 *)((u8 *)gBgScroll + 4);
172 destination = (volatile u32 *)0x04000014;
173
174 if (line == 227 || line <= 52) {
175 if ((((u32)Engine_RandomNext() * 100) >> 16) <
178 }
179 }
180
181 *destination = *source++;
182 destination = (volatile u32 *)0x04000018;
183 *destination++ = *source++;
184 *destination = *source;
185}
186
187/// Captures three background scroll pairs and adds the vertical shake offset.
189 u32 *destination;
190 const u32 *source;
191 u16 *scroll;
192
193 source = (const u32 *)((u8 *)gBgScroll + 4);
194 destination = gKolimaForestBend_ShakeScroll;
195 *destination++ = *source++;
196 *destination++ = *source++;
197 *destination = *source;
199 scroll[1] += 0xb0;
200 scroll[3] += 0xb0;
201 scroll[5] += 0xb0;
202}
203
204/// Searching the floodgate switch flips it. "Isaac flipped the switch." The
205/// camera turns to the floodgate, which opens or closes; the ground rumbles
206/// and the top of the screen shakes harder for 100 frames, and the river rises
207/// or falls.
209 s32 nextShakeChance;
210
212 Engine_CameraSetSpeed(0x10000, 0x2000);
213 Engine_CameraMoveTo(PIXELS(264), -1, PIXELS(448), 1);
215 Engine_MessageShowCentered(MsgFieldFlippedSwitch, 1);
217 if (*gKolimaForestBendLayout == 0) {
219 Map_CopyCells(77, 34, 1, 2, 83, 25);
221 Map_CopyCells(78, 34, 1, 2, 83, 25);
223 Map_CopyCells(79, 34, 1, 2, 83, 25);
224 Engine_TaskWait(30);
225 Map_CopyCells(67, 34, 2, 5, 79, 25);
227 Map_CopyCells(69, 34, 2, 5, 79, 25);
231 Map_CopyCells(71, 34, 2, 5, 79, 25);
233 Map_CopyCells(73, 34, 2, 5, 79, 25);
234 Map_CopyCells(75, 38, 2, 1, 79, 29);
236 Map_CopyCells(77, 38, 2, 1, 79, 29);
238 Map_CopyCells(79, 38, 2, 1, 79, 29);
240 Map_CopyCells(65, 53, 2, 1, 79, 29);
241 Map_CopyCells(65, 40, 2, 4, 15, 28);
242 } else {
244 Map_CopyCells(78, 34, 1, 2, 83, 25);
246 Map_CopyCells(77, 34, 1, 2, 83, 25);
248 Map_CopyCells(76, 34, 1, 2, 83, 25);
249 Engine_TaskWait(30);
250 Map_CopyCells(65, 45, 2, 4, 15, 28);
251 Map_CopyCells(71, 50, 2, 5, 79, 25);
255 Map_CopyCells(69, 50, 2, 5, 79, 25);
257 Map_CopyCells(67, 50, 2, 5, 79, 25);
259 Map_CopyCells(65, 50, 2, 5, 79, 25);
260 Engine_TaskWait(30);
261 }
262 if (*gKolimaForestBendLayout == 0) {
263 Map_DrawCellPanel(9, 19, 16, 5, *gKolimaForestBendLayout, 9, 30);
264 Map_DrawCellPanel(9, 51, 16, 5, 1, 9, 30);
265 Map_DrawCellPanel(41, 51, 16, 5, 2, 9, 30);
266 } else {
267 Map_DrawCellPanel(9, 19, 16, 5, 0, 9, 30);
268 Map_DrawCellPanel(9, 83, 16, 5, 1, 9, 30);
269 Map_DrawCellPanel(41, 83, 16, 5, 2, 9, 30);
270 }
271
272 // The shake: each frame captures the scroll, and the HBlank handler shows
273 // the upper lines shifted, more often as the chance climbs to 100%.
280 do {
282 nextShakeChance = (gKolimaForestBend_ShakeChance + 1);
284 } while (nextShakeChance <= 100);
286 if (*gKolimaForestBendLayout == 0) {
287 Map_DrawCellPanel(9, 19, 16, 5, *gKolimaForestBendLayout, 9, 19);
288 Map_DrawCellPanel(9, 51, 16, 5, 1, 9, 19);
289 Map_DrawCellPanel(41, 51, 16, 5, 2, 9, 19);
290 } else {
291 Map_DrawCellPanel(9, 19, 16, 5, 0, 9, 19);
292 Map_DrawCellPanel(9, 83, 16, 5, 1, 9, 19);
293 Map_DrawCellPanel(41, 83, 16, 5, 2, 9, 19);
294 }
303}
304
305/// Walking west into the short log: the leader shoves it west to x 72.
307
312 Actor_SetSpeed(SHORT_LOG, 0x8000, 0x3333);
317 Actor_SetSpeed(0, 0x4ccc, 0x3333);
325 Map_CopyCellAttributes(5, 9, 1, 4, 6, 9);
326 Map_CopyCellAttributes(0, 0, 1, 4, 4, 9);
329}
330
331/// Walking east into the short log: the leader shoves it east to x 104.
333
338 Actor_SetSpeed(SHORT_LOG, 0x8000, 0x3333);
343 Actor_SetSpeed(0, 0x4ccc, 0x3333);
351 Map_CopyCellAttributes(5, 9, 1, 4, 4, 9);
352 Map_CopyCellAttributes(0, 0, 1, 4, 6, 9);
355}
356
357/// On entry: the logs' records come back from gSceneState, or on a first visit
358/// from the defaults with the water high; the logs are made and the river is
359/// drawn at its level. The forest keeps its cursed colours until the curse is
360/// lifted.
362 struct FieldActor *actor;
363
366 // The return flag and water level occupy the first two halfwords.
367 gKolimaForestBendRecords = (struct BendLog *)(gSceneState + 2 * sizeof(u16));
368 Map_CopyCells(32, 0, 64, 32, 0, 64);
369 Map_CopyCellAttributes(0, 0, 32, 32, 0, 64);
370 Map_CopyCellAttributes(32, 0, 32, 32, 0, 32);
373 (DMA_ENABLE | DMA_32BIT) << 16 | 0x12, REG_DMA3);
376 }
383 actor->radius = 8;
384 actor->scaleX = 0xc000;
385 actor->scaleY = 0xc000;
389 return 0;
390}
391
392/// Makes each log at the middle of its four cells, standing on the ground.
393static void KolimaForestBend_CreateLogs(struct BendLog *entry) {
394 struct FieldActor *actor;
395 s32 height;
396 s32 x;
397 s32 z;
398
399 for (; entry->sprite != -1; entry++) {
400 if (entry->vertical == 0) {
401 x = (entry->x << 20) + 0x200000;
402 z = (entry->z << 20) + 0x80000;
403 } else {
404 x = (entry->x << 20) + 0x80000;
405 z = (entry->z << 20) + 0x200000;
406 }
407 actor = Engine_ObjectCreate(entry->sprite, x, 0, z);
408 if (actor == NULL)
409 return;
410 entry->actor = actor;
411 Object_SetMode(actor, 1);
413 actor->collisionFlags = 0;
414 actor->radius = 32;
415 height = Map_GetTerrainHeight(0, actor->x.part.pixel, actor->z.part.pixel)
416 << 16;
417 /* FAKEMATCH: y is updated through an s32 lvalue, since the union's s16
418 * member would order the next entry load after this store; held as union
419 * FieldObject, 4 instructions differ in tbs-en. */
420 *(s32 *)&actor->y += height;
421 actor->terrainHeight = height;
422 }
423}
424
425/// Writes a collision code into the four cells of each log.
426void State_StampRecordCells(const struct BendLog *records, s32 value) {
427
428 const struct BendLog *record = records;
429 if (record->sprite == -1)
430 return;
431 do {
432 s32 column = record->x;
433 s32 row = record->z;
434 s32 along = record->vertical;
435 s32 i;
436 for (i = 3; i >= 0; i--) {
437 u8 *cell;
438 cell = ((u8 *)gMapCellBuffer) + ((column + (row << 7)) << 2);
439 cell[2] = value;
440 if (along == 0)
441 column++;
442 else
443 row++;
444 }
445 record++;
446 } while (record->sprite != -1);
447}
448
449/// The log lying across the cell, or none.
450static struct BendLog *KolimaForestBend_FindLogAt(struct BendLog *run, s32 x,
451 s32 y) {
452 while (run->sprite != -1) {
453 s32 x0 = run->x;
454 s32 x1 = x0;
455 s32 y0 = run->z;
456 s32 y1 = y0;
457
458 if (run->vertical == 0)
459 x1 += 3;
460 else
461 y1 += 3;
462
463 if (x >= x0 && x <= x1 && y >= y0 && y <= y1)
464 return run;
465 run++;
466 }
467 return 0;
468}
469
470/// Whether four cells from the one given, across or down, are free for a log:
471/// none is marked 0xff or holds a wall.
473 s32 i;
474
475 for (i = 0; i <= 3; i++) {
476 struct MapCell *cell = &((struct MapCell *)gMapCellBuffer)[x + (z << 7)];
477
478 if (cell->collisionCode == 0xff ||
479 *(u8 *)((cell->attributeB << 2) + (s32)gMapCollision) != 0) {
480 return -1;
481 }
482 if (mode == 0) {
483 x++;
484 } else {
485 z++;
486 }
487 }
488 return 0;
489}
490
491/// Finds the log ahead of the leader and rolls it on, a cell at a time, up to
492/// eleven cells or until a cell is not free; the leader follows its shove.
493static void KolimaForestBend_RollLog(struct BendLog *runs) {
494 struct FieldActor *actor;
495 struct FieldWork *work;
496 struct BendLog *run;
497 s32 point[3];
498 s32 facing;
499 s32 moved;
500 s32 i;
501 s32 x;
502 s32 z;
503 s32 quarter;
504
505 moved = 0;
507 facing = (actor->facing + 0x2000) & 0xc000;
508 SET_VECTOR(point, (actor->x.fixed & 0xfff00000) + 0x80000, actor->y.fixed,
509 (actor->z.fixed & 0xfff00000) + 0x80000);
510 Vector_AddPolarOffset(0x100000, facing, point);
511 run = KolimaForestBend_FindLogAt(runs, point[0] / 0x100000,
512 point[2] / 0x100000);
513 if (run == 0)
514 return;
515 for (i = 0; i <= 10; i++) {
516 point[0] = run->x << 20;
517 point[2] = run->z << 20;
518 Vector_AddPolarOffset(0x100000, facing, point);
519 if (KolimaForestBend_CheckLogFits(point[0] / 0x100000, point[2] / 0x100000,
520 run->vertical) != 0)
521 break;
522 moved = 1;
523 if (run->vertical == 0) {
524 x = point[0] + 0x200000;
525 z = point[2] + 0x80000;
526 } else {
527 x = point[0] + 0x80000;
528 z = point[2] + 0x200000;
529 }
530 run->x = point[0] / 0x100000;
531 run->z = point[2] / 0x100000;
532 }
533 if (moved == 0)
534 return;
535 SET_VECTOR(point, (actor->x.fixed & 0xfff00000) + 0x80000, actor->y.fixed,
536 (actor->z.fixed & 0xfff00000) + 0x80000);
537 Vector_AddPolarOffset(0x80000, facing, point);
538 actor = run->actor;
539 quarter = facing / 0x4000;
543 actor->speed = 0x8000;
544 actor->acceleration = 0x3333;
550 work = Runtime_AllocateBlock(HEAP_SLOT_EVENT, sizeof(*work));
552 Actor_SetSpeed(0, 0x4ccc, 0x3333);
563}
564
566
567/// The logs on a first visit, as struct BendLog: sprite 0xcd runs north to
568/// south and 0xcf west to east.
569// clang-format off
571 {0xcd, 11, 9, 1, NULL},
572 {0xcf, 12, 12, 0, NULL},
573 {0xcf, 17, 12, 0, NULL},
574 {0xcd, 13, 13, 1, NULL},
575 {0xcf, 10, 18, 0, NULL},
576 {-1},
577};
578
580
582
584
586 { 0, CONDITION_ALWAYS, 407, 0, 276, FACING_WEST, 0, -1, -1, -1, -1, 0 },
587 { 1, CONDITION_ALWAYS, 50, 32, 369, FACING_EAST, 0, -1, -1, -1, -1, 0 },
588 { 2, CONDITION_ALWAYS, 162, 32, 84, FACING_SOUTH, 0, -1, -1, -1, -1, 0 },
589 { SCENE_TABLE_END },
590};
591
592/// Exit 1 to the river (scene 42), exit 2 to Tret's tree (scene 44).
594 SCENE_EXITS(43),
595 SCENE_EXIT(1, 42, 2),
596 SCENE_EXIT(2, 44, 1),
598};
599
601 { 0xcd, CONDITION_ALWAYS, 7,
602 PIXELS(104), 0, PIXELS(176), FACING_SOUTH, TALK_KEEP_FACING, 0 },
603 { 0xd6, CONDITION_ALWAYS, 7,
604 PIXELS(256), 0, PIXELS(464), FACING_SOUTH, TALK_KEEP_FACING, 0 },
606 PIXELS(348), 0, PIXELS(456), FACING_SOUTH, TALK_KEEP_FACING, 0 },
607 { SCENE_TABLE_END },
608};
609// clang-format on
610
622 {EVENT_TALK, SIGN, CONDITION_ALWAYS, MSGNO(MsgKolimaDoNotTouchFloodgate)},
625 // A Fur Coat (item 0x5b).
628};
struct FieldActor * Object_GetById(s32 actor)
Returns an actor, or NULL if it does not exist.
The battle animation state, render objects and effect entries, and the palette buffer work.
Calls through a function pointer, by argument count.
s32 Field_TryJumpForward(void)
Makes the leader jump two tiles forward, over the tile in front, when the map allows it (Map_CheckObj...
Definition climbing.c:25
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.
DMA channel registers, and the DMA and CPU fills.
static __inline__ void Dma_Set(const volatile void *source, volatile void *destination, u32 control, volatile u32 *channel)
Starts a DMA transfer: stores the source, destination and control words into channel's registers with...
Definition dma.h:62
The engine call layer: one typed inline for each of the thirteen main-image routines below that the s...
static s32 FieldScheduler_AddCallback(SchedulerCallback callback, s32 priority)
Registers a main-image scheduler callback.
Definition engine_call.h:36
void ObjectDispatch_StartCamera(struct DispatchObject *object, s32 linkedObjectHandle)
Starts an object on the camera script (SC_CAMERA).
Definition objects.c:480
s16 * gKolimaForestBendLayout
struct BendLog * gKolimaForestBendRecords
u32 gKolimaForestBend_ShakeScroll[]
u16 * gKolimaForestBendReturned
u32 gKolimaForestBend_ShakeChance
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)
void Object_SetMode(struct FieldActor *object, s32 animation)
void Engine_MessageShowCentered(s32 message, s32 flags)
void Engine_CameraSetSpeed(s32 speed, s32 acceleration)
void Engine_CameraMoveTo(s32 fixed_x, s32 fixed_y, s32 fixed_z, s32 pan)
s32 Engine_TaskRemoveCallback(void(*callback)(void))
static void Actor_SetDestinationOffset(s32 actor, s32 dx, s32 dz)
void Engine_ActorSetDestination(s32 actor, s32 x, s32 z)
void Engine_CameraWaitForMove(void)
void Engine_ActorWaitForMove(s32 actor)
static void Map_CopyCellAttributes(s32 srcX, s32 srcY, s32 width, s32 height, s32 destX, s32 destY)
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)
s32 Engine_GameFlagIsSet(s32 flag)
u8 gSceneState[]
static void Actor_SetSpeed(s32 actor, s32 speed, s32 acceleration)
void Engine_MapRedraw(void)
static void Actor_SetPosition(s32 actor, s32 fixed_x, s32 fixed_z)
void Engine_ActorSetDestinationOffset(s32 actor, s32 dx, s32 dz)
void Engine_EventWait(s32 frames)
@ TRANSITION_WINDOW
Definition field_obj.h:17
#define SCENE_TRANSITION(style, variant)
Definition field_obj.h:20
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_EXIT
@ EVENT_TALK
#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
#define EVENT_SCRIPT(script)
#define EVENT_TOUCH_WALKING
@ 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_SOUTH
Definition field_scene.h:28
@ FACING_WEST
Definition field_scene.h:30
#define PIXELS(value)
@ SEARCH_UNNAMED
@ SEARCH_CHEST
Game flags, named where their meaning is shown.
#define FLAG_KEEP_PARTY_POSITION
Definition flags.h:93
#define FLAG_KOLIMA_CURSE_LIFTED
Definition flags.h:103
void Runtime_SetIrqHandler(u32 irq, s32 vcount, InterruptHandler handler)
Installs handler for interrupt irq and enables that interrupt, or with a null handler disables it and...
Definition frame.c:37
struct EffectStep gMapCellBuffer[]
Map cells; battle effects reuse this as a particle array.
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.
The hardware's I/O registers and their bits, as pret names them.
#define REG_VCOUNT
Definition io_reg.h:19
#define DMA_32BIT
Definition io_reg.h:210
#define REG_DMA3
Definition io_reg.h:153
#define DMA_ENABLE
Definition io_reg.h:217
The hardware's interrupt sources and the interrupt handler table.
@ IRQ_HBLANK
Definition irq.h:14
Item numbers, named from the English release.
@ ITEM_FUR_COAT
Definition item_ids.h:25
static void KolimaForestBend_DrawWaterLevel(void)
Draws the river at its level and sets each log to match: high water floats the logs 26 pixels up over...
const struct SceneRegion * KolimaForestBend_GetRegions(void)
static void KolimaForestBend_ShakeLines(void)
HBlank callback: selects the captured shake scroll above the split line.
struct SceneEvent gKolimaForestBendEvents[]
u8 gKolimaForestBend_PushAnimations[]
const struct SceneEntrance * KolimaForestBend_GetEntrances(void)
Where the party enters from the river and from Tret's tree.
struct BendLog gKolimaForestBend_DefaultRecords[]
The logs on a first visit, as struct BendLog: sprite 0xcd runs north to south and 0xcf west to east.
static void KolimaForestBend_PushShortLogWest(void)
Walking west into the short log: the leader shoves it west to x 72.
static void KolimaForestBend_PushShortLogEast(void)
Walking east into the short log: the leader shoves it east to x 104.
@ SHORT_LOG
slides between x 72 and x 104
@ FLOODGATE_SWITCH
@ SIGN
reads a warning. "Do not touch Floodgate Switch!"
u32 gKolimaForestBendExits[]
Exit 1 to the river (scene 42), exit 2 to Tret's tree (scene 44).
static void KolimaForestBend_MarkShortLogCells(void)
Gives the short log's column of cells its collision: column 4 at the west place, column 6 at the east...
static void KolimaForestBend_CaptureShakeScroll(void)
Captures three background scroll pairs and adds the vertical shake offset.
struct ScenePlacement gKolimaForestBendPlacements[]
struct SceneEntrance gKolimaForestBendEntrances[]
static void KolimaForestBend_JumpSouth(void)
Walking south into the gap: the leader jumps across.
static void KolimaForestBend_FlipFloodgateSwitch(void)
Searching the floodgate switch flips it.
s8 gKolimaForestBend_PushStepX[]
static void KolimaForestBend_RollLog(struct BendLog *logs)
Finds the log ahead of the leader and rolls it on, a cell at a time, up to eleven cells or until a ce...
static void KolimaForestBend_CreateLogs(struct BendLog *log)
Makes each log at the middle of its four cells, standing on the ground.
s32 KolimaForestBend_Initialize(void)
On entry: the logs' records come back from gSceneState, or on a first visit from the defaults with th...
const struct SceneEvent * KolimaForestBend_GetEvents(void)
The logs, the switch, the sign, the jump and the chest.
static struct BendLog * KolimaForestBend_FindLogAt(struct BendLog *run, s32 x, s32 y)
The log lying across the cell, or none.
const u32 * KolimaForestBend_GetExits(void)
The paths back to the river and on to Tret's tree.
static s32 KolimaForestBend_CheckLogFits(s32 x, s32 z, s32 mode)
Whether four cells from the one given, across or down, are free for a log: none is marked 0xff or hol...
void State_StampRecordCells(const struct BendLog *records, s32 value)
Writes a collision code into the four cells of each log.
s8 gKolimaForestBend_PushStepZ[]
static void KolimaForestBend_PushLog(void)
Walking into a log: it rolls ahead, and the cells of the logs are marked again where they now lie.
const struct ScenePlacement * KolimaForestBend_GetPlacements(void)
The short log, the switch and the sign.
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
Maps: their cells, layers, animations and blend scripts, and the map state.
u8 gMapCollision[]
static void Map_DrawCellPanel(s32 x, s32 y, s32 width, s32 height, s32 plane, s32 destX, s32 destY)
Draws the width by height cells at cell (x, y) of the map into screen block 5 from cell (destX,...
Definition map_panel.h:13
The map layers' scroll work and the background scroll values.
struct BgScroll gBgScroll[]
Declares nothing of its own: it only includes edition.h and types.h.
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.
void FieldObject_WaitForMove(void *fieldObject)
Waits a frame at a time until a field object has arrived at its target, at most 600 frames.
FIELD_AT_OFFSET and the entity and camera views older scene code reads.
Song and sound effect ids, indices into gSound_SongTable.
#define SE_213
Definition songs.h:208
#define SE_240
Definition songs.h:235
#define SE_239
Definition songs.h:234
#define SE_232
Definition songs.h:227
#define SE_288
Definition songs.h:281
#define SE_231
Definition songs.h:226
#define SE_230
Definition songs.h:225
#define SE_289
Definition songs.h:282
void Engine_ActorSetAnimation()
struct EventWork * gEventWork
void Engine_EventEnd(void)
void Engine_AudioPlayCue()
void Engine_EventBegin(void)
void Engine_TaskWait()
#define NULL
Definition bilibin.h:6
void KolimaPalette_Curse(s32 strength)
Keeps the healthy colours, curses the background palettes 0 to 13 (all but colours 1 to 7 of palette ...
A log's saved record: its sprite, first map cell and orientation, then its actor once created.
s16 sprite
sprite number; -1 ends the list
struct FieldActor * actor
created for this row; NULL in the defaults
s16 z
map cells
s16 x
map cells
s16 vertical
nonzero runs north to south; zero west to east
A field object as the object dispatcher's far calls take it.
s32 startTransition
SCENE_TRANSITION(style, variant).
Definition event_work.h:43
A field actor: a person or thing on the field with a position, motion toward a target,...
Definition field_obj.h:30
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
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 terrainHeight
16.16 fixed-point pixels
Definition field_obj.h:38
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
s32 scaleX
16.16 fixed point, 0x10000 full size
Definition field_obj.h:39
s32 scaleY
16.16 fixed point, 0x10000 full size
Definition field_obj.h:40
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
Full event work allocated by Field_RunScene (heap slot 27).
struct ObjectRuntime * camera
the object the map view follows
One cell of a map layer: its metatile and flags, its collision code and an attribute indexing the col...
Definition map.h:13
u8 attributeB
Indexes the 4-byte collision entries (gMapCollision): terrain kind in the first byte's low four bits,...
Definition map.h:21
u8 collisionCode
The step code: 1 to 239 scene events, 240 and 241 encounter ground, 250 hazard, 252 to 254 for Field_...
Definition map.h:18
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 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 char s8
Definition types.h:10
signed short s16
Definition types.h:12
unsigned short u16
Definition types.h:13
unsigned char u8
Definition types.h:11
struct FieldCoordinate::@024321007066302143002254325121164243234242211074 part
s32 fixed
16.16 fixed-point pixels