Alchemy
Loading...
Searching...
No Matches

retreat.c

Go to the documentation of this file.
1/// @file
2/// Retreat.
3/// Part of psynergy_effects.c, compiled only through it.
4
6
7// The scene owns PSYNERGY_EFFECT_SLOT_COUNT particle slots.
8
9/// Per-frame update: spins by 0x1000 + timer * 0x50 a frame, speeding up
10/// (timer counts up) until timer * 0x50 reaches 0x1000.
11void FieldFx_UpdateSpinAngle(union FieldObject *fieldObject) {
12 struct FieldActor *obj = (struct FieldActor *)fieldObject;
13 u32 step;
14
15 step = obj->timer * 0x50;
16 obj->facing = obj->facing + step + 0x1000;
17 if (step < 0x1000)
18 obj->timer = obj->timer + 1;
19}
20
21/// Per-frame update: spins 1/8 turn a frame as it shrinks, rising a pixel a
22/// frame; released once its scale falls below 0x3000.
24 struct FieldActor *obj = (struct FieldActor *)fieldObject;
25 u32 scale;
26
27 obj->scaleY -= 0x280;
28 scale = obj->scaleX - 0x280;
29 obj->facing += 0x2000;
30 obj->y.fixed += 1 << 16;
31 obj->scaleX = scale;
32 if ((s32)scale < 0x3000)
33 obj->spriteStorageKind = 0;
34}
35
36/// Effect slot callback: a particle flies 120 pixels from the main object's
37/// screen position (8 pixels lower) in a direction within 1/8 turn of up the
38/// screen. In state 1 it flies again on arrival; in state 2 it is freed.
40 struct EffectVector pos;
41 struct FieldActor *main;
42 s32 state;
43 u32 spread;
44
45 main = ((struct BattleFxScene *)gEffectWork)->mainObject;
46 state = slot->state;
47
48 if (state == 0) {
49 pos.x = main->x.fixed;
50 pos.y = main->y.fixed;
51 pos.z = main->z.fixed;
53
54 slot->x = pos.x;
55 slot->z = pos.z + (8 << 16);
56 slot->originZ = slot->z;
57 slot->originX = slot->x;
58 pos.z = slot->originZ;
59 pos.x = slot->originX;
60
61 spread = Random16();
63 120 << 16, ((spread << 13) >> 16) - ((Random16() << 13) >> 16) + 0xc000,
64 &pos);
65
66 slot->targetX = pos.x;
67 slot->targetZ = pos.z;
68 slot->acceleration = 5 << 16;
69 slot->maxSpeed = 5 << 16;
70 slot->limitTurnStep = state;
71 slot->state++;
72
73 if ((gFrameCount & 2) != 0)
75 } else if (state == 1) {
76 if (EffectSlot_HasPendingTarget(slot) == 0)
77 slot->state--;
78 } else if (state == 2) {
79 if (EffectSlot_HasPendingTarget(slot) == 0)
81 }
82}
83
84/// Spins the main object and shrinks it while 24 particles fly out, one a
85/// frame.
86///
87/// Abilities: Retreat (field kind 15).
89 struct BattleFxScene *scene = gEffectWork;
90 struct FieldActor *obj = scene->mainObject;
91 struct EffectVector pos;
92 struct EffectSlot *slot;
93 u8 last;
94 u32 i;
95
97 Camera_MoveWithinMapBounds(-1, -1, -1, 0);
99 WaitFrames(10);
100 ObjectMotion_ArmCallback(scene->firstObjectId, 0x4000, 0);
101 WaitFrames(30);
105 WaitFrames(40);
106
107 // Start spinning.
112 obj->timer = 0;
113 WaitFrames(70);
114
115 // Start shrinking, and send particles from where it is on screen.
117 obj->motionFlags = 0;
120 pos.x = obj->x.fixed;
121 pos.y = obj->y.fixed;
122 pos.z = obj->z.fixed;
124 i = 0;
125 slot = scene->slots;
126 do {
127 s32 scale;
128 EffectSlot_Initialize(slot, 0x11c, pos.x, pos.z);
132 (Random16() * 7) >> 16);
133 scale = (Random16() >> 1) + 0x13333; // 1.2 to 1.7
134 slot->scaleY = scale;
135 slot->scaleX = scale;
136 i++;
137 WaitFrames(1);
138 slot++;
139 } while (i < PSYNERGY_EFFECT_SLOT_COUNT);
140 WaitFrames(70);
141
142 // The flying particles vanish once they arrive.
143 i = 0;
144 last = 2;
145 do {
146 if (scene->slots[i].active != 0)
147 scene->slots[i].state = last;
148 i++;
149 } while (i < PSYNERGY_EFFECT_SLOT_COUNT);
150 WaitFrames(40);
152 WaitFrames(10);
153}
154
155/// Per-frame update of a falling arc: grows toward full size as it falls 2
156/// pixels a frame on the object it follows, 9 pixels in front of it and up
157/// to 5 pixels further while small; released 10 pixels above the ground (4
158/// on the clear screen).
160 union FieldObject *fieldObject) {
161 // One shared inline kernel with constant inversion grows the positive and
162 // negative callbacks 0x74 -> 0x7c and 0x78 -> 0x7c in native English.
163 struct FieldActor *particle = (struct FieldActor *)fieldObject;
164 struct FieldActor *source;
165 s32 y;
166 s32 limit;
167 s32 scale;
168
169 limit = particle->terrainHeight + 0xA0000;
170 source = particle->linkedObject;
172 limit = particle->terrainHeight + 0x40000;
173
174 y = particle->y.fixed;
175 if (y <= limit) {
176 ObjectDispatch_ReleaseFar((struct DispatchObject *)particle);
177 return;
178 }
179
180 scale = particle->scaleX + 0xC00;
181 if (scale > 0x10000)
182 scale = 0x10000;
183 particle->scaleX = scale;
184 particle->scaleY = scale;
185 particle->x.fixed = source->x.fixed;
186 particle->y.fixed = y - 0x20000;
187 particle->z.fixed = source->z.fixed + ((0x10000 - scale) * 5) + 0x90000;
188}
189
190/// As BattleFx_UpdateDescendingParticlePositiveArc for the arc drawn upside
191/// down, 16 pixels in front of the object and up to 5 pixels nearer.
193 union FieldObject *fieldObject) {
194 struct FieldActor *particle = (struct FieldActor *)fieldObject;
195 struct FieldActor *source;
196 s32 y;
197 s32 limit;
198 s32 scale;
199
200 limit = particle->terrainHeight + 0xA0000;
201 source = particle->linkedObject;
203 limit = particle->terrainHeight + 0x40000;
204
205 y = particle->y.fixed;
206 if (y <= limit) {
207 ObjectDispatch_ReleaseFar((struct DispatchObject *)particle);
208 return;
209 }
210
211 scale = particle->scaleX + 0xC00;
212 if (scale > 0x10000)
213 scale = 0x10000;
214 particle->scaleX = scale;
215 particle->scaleY = -scale;
216 particle->x.fixed = source->x.fixed;
217 particle->y.fixed = y - 0x20000;
218 particle->z.fixed = source->z.fixed - ((0x10000 - scale) * 5) + 0x100000;
219}
220
221/// A falling arc's sprite, seen as the attribute bits, resource slot and
222/// animation that Retreat sets on it.
230 u8 size : 2;
231 union {
232 struct {
233 u16 tile : 10;
234 u16 flags08_10 : 6;
235 } half;
236 struct {
237 u8 tileLow;
238 u8 flags09_0 : 2;
239 u8 variant : 2;
240 u8 flags09_4 : 4;
241 } byte;
251};
252
253/// Spawns a pair of falling arcs (one upside down) on arc.
255 struct FieldActor *source = arc;
256 struct BattleFxScene *scene = gEffectWork;
257 struct FieldActor *leader = scene->mainObject;
258 struct FieldActor *objects[2];
259 struct FieldActor *object;
260 struct DescendingArcSprite *sprite;
261 s32 arcIndex;
262 u8 zero;
263
264 for (arcIndex = 0; arcIndex <= 1; arcIndex++) {
265 object = (struct FieldActor *)Object_CreateFar(
266 26, source->x.fixed, source->y.fixed + 0x400000, source->z.fixed);
267 objects[arcIndex] = object;
268 if (object == NULL)
269 continue;
270 object->terrainHeight = source->terrainHeight;
271 sprite = (struct DescendingArcSprite *)object->sprite;
272 object->motionFlags = 0;
273 object->timer = 0;
274 zero = 0;
275 object->linkedObject = source;
276 object->scaleY = 0x6666;
277 object->scaleX = 0x6666;
278 if (sprite == NULL)
279 continue;
281 sprite->animation = zero;
282 Resource_ResetEntry(sprite->resource);
283 sprite->resource = scene->arcTileSlot;
284 sprite->active = 1;
285 sprite->attr.half.tile = gVramBlockCache[sprite->resource].offset >> 5;
286 sprite->flags05_5 = 0;
287 sprite->layer = 1;
288 sprite->size = 2;
289 sprite->frame->frame = zero;
290 }
291 // BUG: failed allocations above leave a missing arc or sprite here.
292 // Preserve the original partial-pair behavior until recovery is established.
294 ((struct DescendingArcSprite *)objects[0]->sprite)->attr.byte.variant = 0;
296 ((struct DescendingArcSprite *)objects[1]->sprite)->attr.byte.variant =
297 ((struct DescendingArcSprite *)leader->sprite)->attr.byte.variant;
298}
void ObjectMotion_ArmCallback(s32 objectId, s32 angle, s32 wait)
The event command "actor face direction": the actor turns toward angle (0x10000 a full turn; ObjectMo...
void Camera_MoveWithinMapBounds(s32 requestedX, s32 requestedY, s32 requestedZ, s32 glide)
The event command "camera move to": sends the camera to the requested axes, 16.16 pixels (-1 keeps th...
Definition camera.c:47
u32 EffectSlot_HasPendingTarget(struct EffectSlot *effect)
Returns nonzero while an effect slot that stops at its target still has one (it has not arrived),...
void BattleFx_ClearOwnedSlot(struct EffectSlot *slot)
Frees an effect slot and its sprite.
void EffectSlot_Initialize(struct EffectSlot *effect, s32 kind, s32 x, s32 z)
Fills an effect slot with a new sprite of kind at (x, z): stopping at its target, top speed 2,...
void EffectSlot_SetCallback(struct EffectSlot *effect, EffectCallback callback)
Gives an effect slot its per-frame callback, starting at state 0.
void EffectSlot_SetObjectMode(struct EffectSlot *effect, s32 mode)
Sets the animation of an effect slot's sprite.
struct ObjectRuntime * Object_CreateFar(s32 id, s32 x, s32 y, s32 z)
Far call to FieldObject_Create.
void ObjectDispatch_ReleaseFar(struct DispatchObject *obj)
s32 AnimationObjects_SelectAnimationFar(struct AnimationObject *state, s32 flags)
void ObjectDispatch_SetSingleChildFlagsFar(struct DispatchObject *obj, u32 flags)
void ObjectDispatch_SelectAnimationFar(void *raw, s32 no)
void Animation_ApplyChildValuesFar(struct DispatchObject *obj, u32 val)
void ObjectGroup_SetChildValueUnlessFifteenFar(void *raw_parent, u32 value)
void AudioCommand_PlayFar(s32 id)
#define ACTOR_NO_TARGET
A target coordinate that is not set: the object has no target.
Definition field_obj.h:145
void WaitFrames(s32 frames)
The game's frame loop: runs frames frames and returns.
Definition frame.c:97
volatile u32 gFrameCount
Frames WaitFrames has finished.
struct GameState gGameState
void * gEffectWork
Slot 56: points to a scene-specific structure.
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
u32 Random16(void)
Advances the game's random number generator (the C library's classic linear congruential one),...
Definition math.c:10
void ObjectGroup_ApplyRandomChildValues(union FieldObject *fieldObject)
Per-frame update: sets every part of an object's sprite to param frame % 6, which cycles its colours.
Definition dispatch.c:270
void FieldEvent_Begin(void)
The event command "begin event": closes any timed notice, stops the leader, resets the message and ti...
Definition events.c:91
void BattleEffect_InitializeSharedScene(void)
Saves the palettes for the effect (once, unless an effect is already shown) and fades them toward one...
Definition setup.c:236
void BattleFx_PrepareBufferInterpolation(void)
Fades the palettes back from an effect's colours to the saved ones (or to palette 0x10001 while an ef...
Definition setup.c:275
void Camera_WorldToScreen(struct EffectVector *position)
Converts a world position (16.16 pixels) to the screen: x and z receive the screen's x and y and y be...
Definition setup.c:293
What every part of psynergy_effects.c shares: its includes and the macros and types more than one par...
#define PSYNERGY_EFFECT_SLOT_COUNT
The effect slots of a Psynergy effect's scene (gEffectWork->slots).
void FieldFx_RunRetreat(void)
Spins the main object and shrinks it while 24 particles fly out, one a frame.
Definition retreat.c:88
void FieldFx_UpdateSpinAngle(union FieldObject *fieldObject)
Per-frame update: spins by 0x1000 + timer * 0x50 a frame, speeding up (timer counts up) until timer *...
Definition retreat.c:11
void BattleFx_UpdateDescendingParticleNegativeArc(union FieldObject *fieldObject)
As BattleFx_UpdateDescendingParticlePositiveArc for the arc drawn upside down, 16 pixels in front of ...
Definition retreat.c:192
void BattleFx_UpdateDescendingObject(union FieldObject *fieldObject)
Per-frame update: spins 1/8 turn a frame as it shrinks, rising a pixel a frame; released once its sca...
Definition retreat.c:23
void BattleFx_SpawnDescendingArcParticles(struct FieldActor *arc)
Spawns a pair of falling arcs (one upside down) on arc.
Definition retreat.c:254
void BattleFx_UpdateDescendingParticlePositiveArc(union FieldObject *fieldObject)
Per-frame update of a falling arc: grows toward full size as it falls 2 pixels a frame on the object ...
Definition retreat.c:159
void BattleFx_UpdateRadialLaunch(struct EffectSlot *slot)
Effect slot callback: a particle flies 120 pixels from the main object's screen position (8 pixels lo...
Definition retreat.c:39
char SceneId_Clear
#define SE_220
Definition songs.h:215
#define SE_131
Definition songs.h:124
#define SE_246
Definition songs.h:241
#define NULL
Definition bilibin.h:6
One animation layer of a sprite: its animation id, frames, running script and timer.
Definition animspr.h:37
An animated sprite: its image and shadow, scale, rotation, size and up to four animation layers.
Definition animspr.h:108
The work of a Psynergy effect scene: its caster and target, where it takes place, the map state it re...
Definition fx_scene.h:31
s16 arcTileSlot
resource entry of Avoid's and Retreat's arcs
Definition fx_scene.h:75
s16 firstObjectId
the caster's object id
Definition fx_scene.h:38
struct EffectSlot slots[24]
Definition fx_scene.h:73
void * mainObject
the caster's object
Definition fx_scene.h:36
A falling arc's sprite, seen as the attribute bits, resource slot and animation that Retreat sets on ...
Definition retreat.c:223
struct AnimationEntry * frame
Definition retreat.c:250
union DescendingArcSprite::@070326302264055037332103030165235113044074342054 attr
A field object as the object dispatcher's far calls take it.
A particle a Psynergy effect moves and draws: its sprite, its position and target,...
Definition effect_slot.h:18
s32 scaleY
16.16 fixed point, 0x10000 full size
Definition effect_slot.h:30
s8 state
the callback's own step; 0 when it is given
Definition effect_slot.h:38
void * object
the slot's sprite, released with the slot
Definition effect_slot.h:19
s32 originX
16.16 fixed-point pixels; where the slot started
Definition effect_slot.h:24
s32 z
16.16 fixed-point pixels
Definition effect_slot.h:21
s32 x
16.16 fixed-point pixels
Definition effect_slot.h:20
s8 limitTurnStep
Clamp steering to maxTurnStep; zero faces the target directly.
Definition effect_slot.h:40
s32 originZ
16.16 fixed-point pixels; where the slot started
Definition effect_slot.h:25
s32 targetZ
16.16 fixed-point pixels; EFFECT_NO_TARGET at rest
Definition effect_slot.h:23
s32 scaleX
16.16 fixed point, 0x10000 full size
Definition effect_slot.h:29
s32 targetX
16.16 fixed-point pixels; EFFECT_NO_TARGET at rest
Definition effect_slot.h:22
s8 active
nonzero while the slot is in use
Definition effect_slot.h:44
s32 maxSpeed
16.16 fixed-point pixels per frame
Definition effect_slot.h:27
s32 acceleration
16.16 fixed-point pixels per frame, each frame
Definition effect_slot.h:28
A world position, as Camera_WorldToScreen converts it to the screen.
Definition battle.h:73
s32 y
16.16 fixed-point pixels
Definition battle.h:75
s32 z
16.16 fixed-point pixels
Definition battle.h:76
s32 x
16.16 fixed-point pixels
Definition battle.h:74
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 targetX
16.16 fixed-point pixels; ACTOR_NO_TARGET when unset
Definition field_obj.h:59
struct FieldActor * linkedObject
The object its action script follows or faces.
Definition field_obj.h:114
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
s32 terrainHeight
16.16 fixed-point pixels
Definition field_obj.h:38
u8 spriteStorageKind
Zero hides sprites; one draws a single sprite, two draws a group.
Definition field_obj.h:78
union FieldCoordinate z
16.16 fixed-point pixels
Definition field_obj.h:37
u16 facing
1/65536 turns
Definition field_obj.h:34
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
void(*) update(union FieldObject *object)
Called each frame before the object's script, while the object is live.
Definition field_obj.h:116
s16 map
the scene's map; SceneId_Clear for the world map
Definition game_state.h:49
u16 offset
bytes from the start of OBJ VRAM
Definition vram_tab.h:25
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
unsigned short u16
Definition types.h:13
unsigned char u8
Definition types.h:11
struct DescendingArcSprite::@070326302264055037332103030165235113044074342054::@366172057311017000224265030261306246063356262336 byte
struct DescendingArcSprite::@070326302264055037332103030165235113044074342054::@311162361350244237316110147377355002302351324357 half
s32 fixed
16.16 fixed-point pixels
An object on the field, read as an actor or as an effect.
s32 Resource_ResetEntry(u32 no)
Frees cache entry no: its blocks go back and the entry is marked free (offset 0xffff).
Definition vram_cache.c:106
struct VramBlockCacheEntry gVramBlockCache[]