Alchemy
Loading...
Searching...
No Matches

colosso_path_rival.h

Go to the documentation of this file.
1#include "battle.h"
2#include "debug.h"
3#include "field.h"
4#include "game.h"
5#include "graphics.h"
6#include "menu.h"
7#include "minigame.h"
8#include "sound.h"
9#include "system.h"
10#include "callback_scheduler.h"
11#include "colosso_gauge.h"
12#include "resource.h"
13#include "types.h"
14#include "mem.h"
15#include "field_event.h"
16#include "dma.h"
17#include "vram_block.h"
18#include "io_reg.h"
19#include "flags.h"
20
21// The Colosso finals' three courses (Colosso Log, River and Wall): the rival
22// who races Isaac by running a recorded path, and the race gauge that shows
23// how near each of them is to the finish.
24
25/// The race's work: the gauge (struct ColossoGaugeWork) and then the path, in
26/// pixels, as pairs of x and z, one pair a frame, ending with (0, 0).
27struct PathWork {
28 u8 unk00[224];
35 s16 path[0x3840];
36};
37
38/// The rival's scene callback. Mode 1 plays the path back: each frame the rival
39/// steps to the next point (mirrored across the finish when asked), turning by
40/// at most a sixteenth of a turn, and stands once still for three frames. At
41/// the path's end the rival walks to the finish, beside the first finisher's
42/// item actor or the second's, and sets FLAG_SCENE_TEMP_11 (a racer has
43/// finished). Mode 2 records the actor's own path instead, up to 0x383e
44/// halfwords, then plays it back with the rival.
45static void Colosso_UpdatePathRival(void) {
46 struct PathWork *work = (struct PathWork *)gColossoWork;
47 struct PathRecorder *rec = (struct PathRecorder *)gSceneState;
48 struct FieldActor *obj;
49 s32 x, z, d;
50 u16 *itemActor;
51
52 obj = Object_GetById(rec->actor);
53 if (obj == NULL) {
54 return;
55 }
56 if (rec->mode == 1) {
57 x = work->path[(s16)rec->pos++];
58 z = work->path[(s16)rec->pos++];
59 if (x == 0 && z == 0) {
60 s32 fz;
61 rec->mode = 9;
62 Object_SetMode(obj, 1);
63 if (work->finishX < obj->x.fixed) {
64 x = work->finishX + 0xc0000;
65 } else {
66 x = work->finishX - 0xc0000;
67 }
69 fz = work->finishZ + 0x100000;
70 itemActor = &work->finishItemActorB;
71 } else {
72 fz = work->finishZ - 0x100000;
73 itemActor = &work->finishItemActorA;
74 }
75 obj->timer = *itemActor;
76 obj->acceleration = 0x4000;
77 obj->speed = 0x10000;
78 Engine_ObjectSetPosition(obj, x, 0, fz);
81 return;
82 }
83 x <<= 16;
84 z <<= 16;
85 if (rec->mirror != 0) {
86 x = work->finishX * 2 - x;
87 }
88 if (obj->x.fixed != x || obj->z.fixed != z) {
89 {
90 u16 angle = Math_Atan2(z - obj->z.fixed, x - obj->x.fixed);
91 d = (s16)(angle - obj->facing);
92 }
93 if (d > 0x1000) {
94 d = 0x1000;
95 }
96 if (d < -0x1000) {
97 d = -0x1000;
98 }
99 obj->facing += d;
100 obj->x.fixed = x;
101 obj->z.fixed = z;
102 rec->still = 0;
103 } else {
104 rec->still++;
105 }
106 if (rec->still > 2) {
107 Object_SetMode(obj, 1);
108 } else {
109 Object_SetMode(obj, 5);
110 }
111 } else if (rec->mode == 2) {
112 x = obj->x.part.pixel;
113 z = obj->z.part.pixel;
114 work->path[(s16)rec->pos++] = x;
115 work->path[(s16)rec->pos++] = z;
116 if ((s16)rec->pos == 0x383e) {
117 work->path[(s16)rec->pos++] = 0;
118 work->path[(s16)rec->pos] = 0;
119 rec->actor = work->rivalActor;
120 rec->pos = 0;
121 rec->mode = 1;
122 }
123 }
124}
125
127
128/// The race gauge's scene callback: a bar across the top of the screen, with
129/// the finish at its centre and blinking marks for the rival and Isaac at their
130/// distances from it (a pixel of bar for 14 of course). It slides down when the
131/// race starts and back up while flag 0x106 is set; hold keeps it down.
132static void Colosso_DrawGauge(void) {
133 struct ColossoGaugeWork *gauge = (struct ColossoGaugeWork *)gColossoWork;
134 s32 *dst = (s32 *)gauge;
135 struct ColossoGaugeSprite *entry = gauge->sprites;
136 s32 tile;
137 u32 segments;
138 u32 i;
139 s32 y;
140 s32 x;
141 s32 width;
142 u8 *buf;
143 struct FieldActor *actor;
144 u32 shape;
145
146 tile = gVramBlockCache[gauge->vramBlock].offset >> 5;
147 segments = gauge->segments;
148 if (gauge->hold != 0) {
149 gauge->level = 2;
151 if (gauge->level > 0) {
152 gauge->level--;
153 }
154 } else if (gauge->level <= 1) {
155 if (++gauge->level == 1) {
157 (DMA_ENABLE << 16) | 0x10, REG_DMA3);
160 Engine_VramLoad(gauge->vramBlock, 512, buf);
161 Runtime_BumpFree(buf);
162 }
163 }
164 if (gauge->level == 0) {
166 return;
167 }
168
169 y = gauge->level * 6 - 8;
170 y &= 255;
171 width = segments * 16;
172 x = 104 - width;
173 shape = 0x8000;
174 *dst++ = 0;
175 *dst++ = (x << 16) | y | shape;
176 *dst++ = tile | 0xe400;
177 Runtime_PushSlotEntry(entry++, 255);
178 for (i = 0; i < segments; i++) {
179 x = 96 - i * 16;
180 shape = 0x40000000;
181 *dst++ = 0;
182 *dst++ = (x << 16) | y | shape;
183 *dst++ = (tile + 2) | 0xe400;
184 Runtime_PushSlotEntry(entry++, 255);
185 }
186 x = 112;
187 shape = 0x8000;
188 *dst++ = 0;
189 *dst++ = (x << 16) | y | shape;
190 *dst++ = (tile + 6) | 0xe400;
191 Runtime_PushSlotEntry(entry++, 255);
192 x = 120;
193 *dst++ = 0;
194 *dst++ = (x << 16) | y | shape | 0x10000000;
195 *dst++ = (tile + 6) | 0xe400;
196 Runtime_PushSlotEntry(entry++, 255);
197 for (i = 0; i < segments; i++) {
198 x = 128 + i * 16;
199 shape = 0x40000000;
200 *dst++ = 0;
201 *dst++ = y | (x << 16) | shape | 0x10000000;
202 *dst++ = (tile + 2) | 0xe400;
203 Runtime_PushSlotEntry(entry++, 255);
204 }
205 x = width + 128;
206 shape = 0x8000;
207 *dst++ = 0;
208 y |= x << 16;
209 y |= shape;
210 y |= 0x10000000;
211 *dst++ = y;
212 *dst++ = tile | 0xe400;
213 Runtime_PushSlotEntry(entry++, 255);
214
215 if ((gFrameCount & 15) > 4) {
216 shape = 0x40000000;
217 actor = Engine_ActorLookup(gauge->rivalActor);
218 if (actor != 0) {
219 x = ((actor->x.fixed - gauge->finishX) / 0xe0000) + 112;
220 y = ((actor->z.fixed - gauge->finishZ) / 0xe0000) + gauge->level * 6 - 4;
221 y &= 255;
222 *dst++ = 0;
223 y |= x << 16;
224 y |= shape;
225 *dst++ = y;
226 *dst++ = (tile + 12) | 0xe400;
227 Runtime_PushSlotEntry(entry++, 255);
228 }
229 actor = Engine_ActorLookup(gauge->playerActor);
230 if (actor != 0) {
231 x = ((actor->x.fixed - gauge->finishX) / 0xe0000) + 112;
232 y = ((actor->z.fixed - gauge->finishZ) / 0xe0000) + gauge->level * 6 - 4;
233 y &= 255;
234 *dst++ = 0;
235 y |= x << 16;
236 y |= shape;
237 *dst++ = y;
238 *dst++ = (tile + 8) | 0xe400;
239 Runtime_PushSlotEntry(entry++, 255);
240 }
241 }
242}
struct FieldActor * Object_GetById(s32 actor)
Returns an actor, or NULL if it does not exist.
The task scheduler: tasks, their order and the scheduler's state.
The Colosso race gauge's sprites and work.
s32 gColosso_RivalFinishScript[]
u8 gColosso_GaugeGraphics[]
static void Colosso_DrawGauge(void)
The race gauge's scene callback: a bar across the top of the screen, with the finish at its centre an...
static void Colosso_UpdatePathRival(void)
The rival's scene callback.
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
static s32 FieldResource_DecodeType01(const void *source, void *destination)
Decodes type-01 compressed data.
Definition engine_call.h:90
s32 Math_Atan2(s32 dy, s32 dx)
u16 gColosso_GaugePalette[]
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)
struct FieldActor * Engine_ActorLookup(s32 actor)
s32 Engine_VramLoad(s32 block, s32 size, const void *data)
void Engine_ObjectSetScript(struct FieldActor *object, const s32 *script)
void Engine_GameFlagSet(s32 flag)
s32 Engine_GameFlagIsSet(s32 flag)
u8 gSceneState[]
u8 * gColossoWork
Game flags, named where their meaning is shown.
#define FLAG_SCENE_TEMP_11
Definition flags.h:730
#define FLAG_MENU_OPEN
Set while the field menu is open; scenes hold their moving actors still.
Definition flags.h:23
volatile u32 gFrameCount
Frames WaitFrames has finished.
The screen blend's globals and the graphics routines.
void * Runtime_BumpAllocateAlternatePool(s32 size)
As MemAlloc, but tries EWRAM first.
Definition heap.c:140
The hardware's I/O registers and their bits, as pret names them.
#define OBJ_PLTT_COLOR(palette, color)
Definition io_reg.h:160
#define REG_DMA3
Definition io_reg.h:153
#define DMA_ENABLE
Definition io_reg.h:217
The heaps: allocating and freeing blocks.
void Runtime_BumpFree(void *buffer)
static __inline__ void * Runtime_CallAlternatePool(void *(*allocate)(s32), s32 size)
Definition mem.h:15
The reel game's title lettering.
void Runtime_PushSlotEntry(void *slotEntry, s32 slot)
Links a sprite entry into depth slot slot (clamped to 0..255) for this frame.
Definition render.c:79
#define NULL
Definition bilibin.h:6
One sprite of the race gauge's list: a link word, its position and shape attributes,...
s32 tile
OAM attribute 2: the tile, with palette 14 and priority 1.
The Colosso race gauge's work at the start of work slot 59: its sprites, how far it has slid down,...
s16 rivalActor
the actor id drawn as the rival's marker
s16 segments
16-pixel bar pieces either side of the centre
s16 hold
nonzero keeps the gauge down (level 2)
struct ColossoGaugeSprite sprites[18]
the bar, its ends and the racers
s16 playerActor
the actor id drawn as the player's marker
s16 level
0 hidden to 2 fully down; the bar's y is level * 6 - 8
s32 finishX
16.16 fixed-point pixels
s16 vramBlock
the VRAM cache entry holding the gauge's tiles
s32 finishZ
16.16 fixed-point pixels
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
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
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
The Colosso rival's path player in the scene state: its mode (1 playing, 2 recording,...
Definition field.h:75
s16 actor
Definition field.h:78
u16 pos
Definition field.h:79
s16 mirror
Definition field.h:77
s16 mode
Definition field.h:76
s16 still
frames
Definition field.h:80
The race's work: the gauge (struct ColossoGaugeWork) and then the path, in pixels,...
s16 path[0x3840]
u16 offset
bytes from the start of OBJ VRAM
Definition vram_tab.h:25
The system's routines and globals: interrupts, BIOS sound bias, random numbers and sleep.
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
unsigned char u8
Definition types.h:11
struct FieldCoordinate::@024321007066302143002254325121164243234242211074 part
s32 fixed
16.16 fixed-point pixels
Declares nothing of its own: it only includes the window, battle command, resource and VRAM table hea...
s32 VramCache_ReleaseVram(u32 no)
Gives back entry no's blocks but keeps the entry taken, with size 1, so a later VramCache_Load can re...
Definition vram_cache.c:122
struct VramBlockCacheEntry gVramBlockCache[]