Alchemy
Loading...
Searching...
No Matches

view.c

Go to the documentation of this file.
1/// @file
2/// The view bounds, zoom transitions and objects linked to an actor.
3/// Part of psynergy_effects.c, compiled only through it.
4
6
7/// The high byte of the first sprite part's OAM attribute 2.
8/// Bits 2 and 3 are its priority.
9#define SPRITE_ATTR2_HIGH(sprite) (((u8 *)(sprite))[9])
10
11/// The event command "set view bounds": the camera keeps the screen inside
12/// these map coordinates (Camera_MoveWithinMapBounds).
13void Map_SetViewBounds(s32 minX, s32 minY, s32 maxX, s32 maxY) {
14 struct MapScrollWork *work = gMapWork[0];
15
16 work->minX = minX;
17 work->minY = minY;
18 work->maxX = maxX;
19 work->maxY = maxY;
20}
21
22// Scheduler callback: moves the zoom one step from its previous value toward
23// its target, and removes itself on the last step. It waits while the camera
24// is paused.
25// The scheduler calls void(void). Plain void changes the native return from
26// pop {r1}; bx r1 to pop {r0}; bx r0 (two instructions in tbs-en).
27#ifdef UBFIX
29#else
31#endif
32 struct PerspectiveWork *work;
33 s16 *frames;
34 s32 *from;
35 s16 *step;
36 s32 zoom;
37 s32 delta;
38
39 work = gMapWork[0];
41 sizeof(struct FieldWork)))
42 ->camera->movementState != 0)
43 return;
44 frames = (s16 *)&work->zoomTransitionFrames;
45 if (*frames == 0)
46 return;
47 from = &work->previousZoom;
48 delta = work->zoom - *from;
49 step = &work->zoomTransitionStep;
50 (*step)++;
51 /* FAKEMATCH(wrapper): the division written as a call to __divsi3, an
52 * ordinary call where the operator makes a libcall block; as
53 * delta * *step / *frames, 93 of 87 instructions differ in tbs-en. */
54 zoom = *from + __divsi3(delta * *step, *frames);
55 work->distance = Iwram_MulQ16(work->farPlane, zoom);
56 gScanlinePitch = work->pitch + 1;
57 if (*step == *frames) {
58 *frames = 0;
59#ifdef UBFIX
61#else
63#endif
64 }
65}
66
67/// Starts a zoom to zoom (16.16) over frames frames, on the world map (event
68/// mode 3) only.
70 struct PerspectiveWork *work = gMapWork[0];
71 s32 inverse;
72
74 sizeof(struct FieldWork)))
75 ->mode != MODE_WORLD_MAP)
76 return;
77 {
78 inverse = Iwram_RatioMulQ14(zoom, 0x10000); // 1 / zoom
79 }
80 work->previousZoom = work->zoom;
81 work->zoom = inverse;
82 work->zoomTransitionFrames = frames;
83 work->zoomTransitionStep = 0;
84#ifdef UBFIX
86#else
88 0xc94);
89#endif
90}
91
92/// Waits for a zoom transition to end (on the world map only, at most 300
93/// frames).
95 s32 frames;
96 struct PerspectiveWork *work = gMapWork[0];
97
99 sizeof(struct FieldWork)))
100 ->mode == MODE_WORLD_MAP) {
101 frames = 0;
102 if (*(s16 *)&work->zoomTransitionFrames != 0) {
103 do {
104 WaitFrames(1);
105 frames++;
106 } while (frames < 300 && *(s16 *)&work->zoomTransitionFrames != 0);
107 }
108 }
109}
110
111// Per-frame update of a riding object: keeps it on the actor it rides (its
112// linked object), raised by the actor's sprite height (its metadata's boxX) and
113// 8 pixels. Its work holds the actor's id.
114// The hook consumer ignores the result. Plain void removes the native zero
115// result and changes its return register (three instructions in tbs-en).
116#ifdef UBFIX
117void BattleFx_CopyLinkedObjectPosition(union FieldObject *fieldObject) {
118#else
120#endif
121 void *self = (void *)fieldObject;
122 struct FieldActor *obj = self;
123 struct FieldActor *host;
124
125 host = obj->linkedObject;
126 if (host != NULL) {
127 obj->motionFlags = 0;
128 obj->x.fixed = host->x.fixed;
129 obj->y.fixed =
130 host->y.fixed +
133 ->boxX
134 << 16) +
135 (8 << 16);
136 obj->terrainHeight = host->terrainHeight;
137 obj->z.fixed = host->z.fixed;
138 }
139#ifndef UBFIX
140 return 0;
141#endif
142}
143
144/// The event command "actor show emote": shows an emote bubble (object 21)
145/// over an actor, then waits wait frames. The low 4 bits of emote pick the
146/// bubble's animation (6 also plays sound 110); with 0x100 the bubble takes
147/// sprite priority 1, otherwise the actor's.
148void BattleFx_SpawnLinked(s32 actor, s32 emote, s32 wait) {
149 struct FieldActor *target;
150
151 if ((emote & 0xff) == 6) {
153 }
154
155 target = ObjectTable_Get(actor);
156 if (target != 0) {
157 struct FieldActor *bubble = (struct FieldActor *)Object_CreateFar(
158 21, target->x.fixed, target->y.fixed, target->z.fixed);
159
160 if (bubble != 0) {
161 struct AnimationObject *sprite;
162
165 ObjectDispatch_SelectAnimationFar(bubble, emote & 15);
166 bubble->motionFlags = 0;
167 bubble->timer = 0;
168 bubble->work = actor;
169 sprite = bubble->sprite;
170#ifdef UBFIX
171 bubble->update = BattleFx_CopyLinkedObjectPosition;
172#else
173 bubble->update =
175#endif
176 sprite->flags = 0;
177 bubble->linkedObject = target;
178
179 // Replace the bubble's priority bits (2 and 3) with 1 or the actor's.
180 if ((emote & 0x100) != 0) {
181 s32 mask = 13;
182 u8 attr = SPRITE_ATTR2_HIGH(sprite);
183
184 mask = -mask;
185 mask &= attr;
186 mask |= 4;
187 SPRITE_ATTR2_HIGH(sprite) = mask;
188 } else {
189 s32 priority = 12;
190 u8 src = SPRITE_ATTR2_HIGH(target->sprite);
191 u8 dst;
192 s32 mask = 13;
193
194 priority &= src;
195 dst = SPRITE_ATTR2_HIGH(sprite);
196 mask = -mask;
197 mask &= dst;
198 mask |= priority;
199 SPRITE_ATTR2_HIGH(sprite) = mask;
200 }
201 }
203 }
204}
205
206/// The event command "actor set attached effect": with mode (the low 2 bits)
207/// 0 removes the object attached to an actor; 1 attaches one (object 209,
208/// animation 1) that stays until removed; 2 shows a one-off one (animation 2)
209/// that ends by itself. With 0x100 the object takes sprite priority 1,
210/// otherwise the actor's.
212 struct FieldActor *object = ObjectTable_Get(actor);
213 struct FieldActor *effect;
214 struct AnimationObject *visual;
215 s32 mode;
216
217 effect = 0;
218 visual = 0;
219
220 if (object == 0)
221 return;
222
223 if ((flags & 3) != 0) {
224 if ((flags & 3) == 2 || object->linkedObject == 0) {
225 effect = (struct FieldActor *)Object_CreateFar(
226 209, object->x.fixed, object->y.fixed, object->z.fixed);
227 }
228 } else {
229 effect = object->linkedObject;
230 if (effect == 0)
231 return;
233 object->linkedObject = 0;
234 return;
235 }
236
237 if (effect == 0)
238 return;
239
240 mode = flags & 3;
241 switch (mode) {
242 case 1:
244 object->linkedObject = effect;
245 effect->timer = 1;
246 break;
247 case 2:
251 effect->timer = 1;
252 break;
253 }
254
255 effect->work = actor;
256 effect->motionFlags = 0;
257#ifdef UBFIX
259#else
260 effect->update =
262#endif
263 visual = effect->sprite;
264 visual->flags = 0;
265 effect->linkedObject = object;
266
267 // Replace the effect's priority bits (2 and 3) with 1 or the actor's.
268 if (flags & 0x100) {
269 s32 mask = 13;
270 u8 attr = SPRITE_ATTR2_HIGH(visual);
271
272 mask = -mask;
273 mask &= attr;
274 mask |= 4;
275 SPRITE_ATTR2_HIGH(visual) = mask;
276 } else {
277 s32 priority = 12;
278 u8 src = SPRITE_ATTR2_HIGH(object->sprite);
279 u8 dst;
280 s32 mask = 13;
281
282 priority &= src;
283 dst = SPRITE_ATTR2_HIGH(visual);
284 mask = -mask;
285 mask &= dst;
286 mask |= priority;
287 SPRITE_ATTR2_HIGH(visual) = mask;
288 }
289}
290
291#undef SPRITE_ATTR2_HIGH
void * ObjectTable_Get(u32 actorIndex)
Returns the actor in slot index (0 to 65), or NULL.
Definition actors.c:462
const s32 gBattleFx_LinkedObjectScript[]
void(*) SchedulerCallback(void)
s32 __divsi3(s32, s32)
struct ObjectRuntime * Object_CreateFar(s32 id, s32 x, s32 y, s32 z)
Far call to FieldObject_Create.
void ObjectDispatch_ReleaseFar(struct DispatchObject *obj)
void ObjectDispatch_SelectAnimationFar(void *raw, s32 no)
void ObjectDispatch_InitializeFar(struct DispatchObject *obj, const s32 *script)
struct AnimationMetadata * Resource_GetMetadataRecordFar(u32 number)
void AudioCommand_PlayFar(s32 id)
u32 gScanlinePitch
const u8 gObjectMotion_WaitScript[]
void WaitFrames(s32 frames)
The game's frame loop: runs frames frames and returns.
Definition frame.c:97
void * gMapWork[]
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
@ HEAP_SLOT_EVENT
Definition heap_state.h:40
static s32 Iwram_RatioMulQ14(s32 divisor, s32 value)
All calls go through this layer.
Definition iwram_call.h:51
#define Iwram_MulQ16(left, right)
Definition iwram_call.h:127
struct ScenePlacement * Scene_FindActorPlacement(s32 id)
Returns the placement of actor id in the scene's placement tables, or NULL: for a party character (0 ...
Definition events.c:14
void FieldEvent_WaitFrames(s32 frames)
The event command "wait": waits the requested frames, unless debug fast forward (Event_UpdateDebugSki...
Definition events.c:55
void Map_SetViewBounds(s32 minX, s32 minY, s32 maxX, s32 maxY)
The event command "set view bounds": the camera keeps the screen inside these map coordinates (Camera...
Definition view.c:13
void BattleFx_ScheduleRatioTransition(s32 zoom, s32 frames)
Starts a zoom to zoom (16.16) over frames frames, on the world map (event mode 3) only.
Definition view.c:69
void Event_WaitForZoomTransition(void)
Waits for a zoom transition to end (on the world map only, at most 300 frames).
Definition view.c:94
void BattleFx_SpawnLinked(s32 actor, s32 emote, s32 wait)
The event command "actor show emote": shows an emote bubble (object 21) over an actor,...
Definition view.c:148
void BattleFx_ConfigureLinkedObject(s32 actor, s32 flags)
The event command "actor set attached effect": with mode (the low 2 bits) 0 removes the object attach...
Definition view.c:211
s32 BattleFx_CopyLinkedObjectPosition(union FieldObject *fieldObject)
Definition view.c:119
#define SPRITE_ATTR2_HIGH(sprite)
The high byte of the first sprite part's OAM attribute 2.
Definition view.c:9
s32 FieldFx_StepRatioTransition(void)
Definition view.c:30
What every part of psynergy_effects.c shares: its includes and the macros and types more than one par...
s32 Scheduler_AddOrUpdateCallback(SchedulerCallback callback, s32 order)
Schedules callback with order, or gives a task already running it the new order, and re-sorts the tab...
Definition scheduler.c:102
s32 Scheduler_RemoveCallback(SchedulerCallback callback)
Unschedules the task running callback: clears its routine and gives it order 0x7fff,...
Definition scheduler.c:146
#define SE_110
Definition songs.h:103
#define NULL
Definition bilibin.h:6
An animated sprite: its image and shadow, scale, rotation, size and up to four animation layers.
Definition animspr.h:108
u8 flags
bits: 1 outlined in ObjectSystemWork's edge and fill colours | 0 shadow drawn (set when created)
Definition animspr.h:128
A field object as the object dispatcher's far calls take it.
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
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
union FieldCoordinate z
16.16 fixed-point pixels
Definition field_obj.h:37
void(*) update(union FieldObject *object)
Called each frame before the object's script, while the object is live.
Definition field_obj.h:116
u16 wait
the object script's wait, in frames (ScriptMotionObject)
Definition field_obj.h:98
u16 work
The side of the player's next footprint (2 after a stop), or scene scratch.
Definition field_obj.h:112
struct AnimationObject * sprite
the sprite spin turns
Full event work allocated by Field_RunScene (heap slot 27).
The field map's work: the followed position, screen shake, tile animations, blend script,...
Definition map_scroll.h:27
s32 maxY
16.16 fixed-point pixels
Definition map_scroll.h:41
The world map's perspective view: the followed position, screen shake, view position,...
Definition perspective.h:12
s32 farPlane
0x1fe0000 at load
Definition perspective.h:52
s32 zoom
16.16 fixed point, 0x10000 full size
Definition perspective.h:55
s32 previousZoom
the zoom a transition starts from
Definition perspective.h:54
u16 pitch
1/65536 turns
Definition perspective.h:44
s16 zoomTransitionStep
frames of the transition done
Definition perspective.h:57
u16 zoomTransitionFrames
a zoom transition's length; 0 when none
Definition perspective.h:56
s32 distance
farPlane scaled by the zoom
Definition perspective.h:53
s16 sprite
The actor's sprite; 0 to 7 are the party's characters, each in its own actor slot,...
Definition field_scene.h:84
signed int s32
Definition types.h:14
signed char s8
Definition types.h:10
signed short s16
Definition types.h:12
unsigned char u8
Definition types.h:11
s32 fixed
16.16 fixed-point pixels
An object on the field, read as an actor or as an effect.
struct FieldActor actor
struct FieldEffect effect
#define MODE_WORLD_MAP
the world map
Definition object.h:78