Alchemy
Loading...
Searching...
No Matches

condemn.c

Go to the documentation of this file.
1/// @file
2/// Condemn.
3/// Part of effect.c, the battle effect object, compiled only through it.
4
6
7#define CONDEMN_FRAMES 132
8#define CONDEMN_BREAK_FRAME 88 ///< the panel breaks in a white flash
9#define CONDEMN_BOUNCE_FRAME 120 ///< the falling target bounces
10
11/// gCondemn_PanelX and _PanelY have seven stages for each column and row.
12#define CONDEMN_PANEL_X(column, stage) gCondemn_PanelX[(column)][(stage)]
13#define CONDEMN_PANEL_Y(row, stage) gCondemn_PanelY[(row)][(stage)]
14
15/// A tall panel (57x98) swings across the screen three times, each pass fading
16/// out through a ripple, the last over the first target; on frame 88 it
17/// shatters in a white flash into a burst of larger pieces and the target is
18/// knocked back, bouncing on frame 120.
19///
20/// Abilities: Condemn (kind 40).
21///
22/// The effect layer ripples throughout. 132 frames.
23///
24/// Opens the tiled canvas (BattleFx_BeginTiledCanvas) and adds
25/// BattleFx_ArmBg2AffineHBlankDma to feed work->bg2xLines to BG2X; decodes
26/// the burst's pieces into Ram_MapCellBuffer; moves the target's object; and
27/// reloads the battle backdrop on BG1 before it closes the layer. It never
28/// calls EFFECT_SHOW_DAMAGE, and leaves the flash timers alone.
30 void **slots;
31 void **cursor;
32 struct BattleEffectWork *work;
33 void *canvas;
34 u8 *sheet;
35 void *cells;
36 BlitterPair draw;
37 struct MotionObject *target;
38 /* FAKEMATCH: the unused second position gives the frame its native 76
39 * bytes; as a single position, 4 instructions differ in tbs-en. */
40 struct EffectPosition pos[2];
41 s32 swing[2];
42 s32 drawPanel;
43 s32 panelColumn;
44 s32 panelRow;
45 s32 zero;
46 s32 frame;
47
48 EFFECT_GET_SLOTS(slots, cursor, work, canvas);
49 /* FAKEMATCH: the zero is held in sl through the setup calls.
50 * Storing the literal 0 without the local: differ 66. */
51 zero = 0;
52 work->effect = effect;
54 REG_BG2PA = Q_8_8(1);
55 REG_BLDALPHA = BLEND_ALPHA(16, 16);
56
57 // Setup. The panel and the first two burst pictures in work->sheet, with
58 // their palette; the later pieces in PARTICLES (Ram_MapCellBuffer), whose
59 // own palette is skipped.
61 Iwram_CopyWords((void *)BG_PLTT, sheet, 128);
62 sheet = sheet + 128;
63 Resource_DecodeType01(sheet, work->sheet);
64 cells = Ram_MapCellBuffer;
66 sheet = sheet + 128;
67 Resource_DecodeType01(sheet, cells);
77 // Redraw from blank each frame.
79 // swing is the point the panel sways about, in 16.16 pixels: the first
80 // pass high up on the near side.
81 drawPanel = 1;
82 if (work->effect->side == 1) {
83 swing[0] = -0x500000;
84 } else {
85 swing[0] = 0x700000;
86 }
87 swing[1] = -0x200000;
88 for (frame = 0; frame != CONDEMN_FRAMES; frame++) {
89 s32 spin;
90 s32 screenX;
91 s32 screenY;
92 s32 ripple;
93 s32 lineOffset;
94 s32 angle;
95 s32 i;
96 s32 *scanline;
97
98 // Frame loop. The panel sways 16 pixels across and 4 up and down about
99 // the swing point, a full turn every 128 frames.
100 spin = frame << 9;
101 screenX = (swing[0] >> 16) + (((Trig_Sin(spin) * 16)) >> 16) + 48;
102 screenY = (swing[1] >> 16) + (((Trig_Cos(spin) * 4)) >> 16) + 16;
103 if (frame == CONDEMN_BREAK_FRAME) {
105 }
106 // Frame 32: the second pass, lower and further across; the panel skips
107 // a frame while it moves, and comes back opaque on frame 33.
108 if (frame == 32) {
109 if (work->effect->side == 1) {
110 swing[0] = -0x200000;
111 } else {
112 swing[0] = 0x480000;
113 }
114 swing[1] = 0x180000;
115 drawPanel = 0;
116 }
117 if (frame == 33) {
118 REG_BLDALPHA = BLEND_ALPHA(16, 16);
119 drawPanel = 1;
120 }
121 // Frame 64: the last pass, on the first target.
122 if (frame == 64) {
124 if (work->effect->side == 1) {
125 swing[0] = (pos[0].x - 128) << 16;
126 } else {
127 swing[0] = (pos[0].x - 64) << 16;
128 }
129 swing[1] = 0;
130 drawPanel = 0;
131 }
132 if (frame == 65) {
133 REG_BLDALPHA = BLEND_ALPHA(16, 16);
134 drawPanel = 1;
135 }
136 // The last 16 frames of each of the first two passes ripple harder and
137 // harder (up to 30/4 texels) as the panel fades out.
138 scanline = work->bg2xLines;
139 ripple = 0;
140 if (frame <= 31) {
141 if (frame > 15) {
142 ripple = (frame * 2) - 32;
143 REG_BLDALPHA = BLEND_ALPHA(31 - frame, 16);
144 }
145 } else if (frame <= 63) {
146 if (frame > 47) {
147 ripple = (frame * 2) - 96;
148 REG_BLDALPHA = BLEND_ALPHA(63 - frame, 16);
149 }
150 }
151 if (ripple < 0) {
152 ripple = 0;
153 }
154
155 // Every line's BG2X carries the sway, so the panel moves by scrolling
156 // the canvas rather than by where it is drawn.
157 i = 0;
158 lineOffset = (6 - screenX) << 8;
159 angle = frame << 11;
160 for (; i != 160; i++) {
161 *scanline++ = lineOffset - ((Trig_Sin(angle) * ripple) >> 10);
162 angle += 0x800;
163 }
164 if (drawPanel != 0) {
165 if (work->effect->side == 0) {
166 panelColumn = 0;
167 panelRow = 0;
168 } else {
169 panelColumn = 1;
170 /* FAKEMATCH: i is 160 here, so this is 0: a literal 0
171 * drops a stack slot and shrinks the frame (differ 452). */
172 panelRow = i >> 31;
173 }
174 // The panel until frame 91; from frame 88 the burst: a white flash
175 // (level 63 over the whole canvas, covering what was drawn) on
176 // frames 88 and 89, then larger pieces two frames each. Stage n of
177 // gCondemn_PanelX and _PanelY places picture n; the row and column
178 // are the side's.
179 if (frame <= 87) {
180 draw[work->effect->side](
181 canvas, work->sheet, CONDEMN_PANEL_X(panelColumn, 0),
182 CONDEMN_PANEL_Y(panelRow, 0) + screenY, 57, 98);
183 } else {
184 if (frame <= 91) {
185 draw[work->effect->side](
186 canvas, work->sheet, CONDEMN_PANEL_X(panelColumn, 0),
187 CONDEMN_PANEL_Y(panelRow, 0) + screenY, 57, 98);
188 }
189 draw[work->effect->side](
190 canvas, work->sheet + 0x15d2, CONDEMN_PANEL_X(panelColumn, 1),
191 CONDEMN_PANEL_Y(panelRow, 1) + screenY, 99, 69);
192 if ((frame - 88) <= 1U) {
193 Iwram_FillWords(canvas, CANVAS_BYTES, 0x3F3F3F3F);
194 }
195 if ((frame - 90) <= 1U) {
196 draw[work->effect->side](
197 canvas, work->sheet + 0x3081, CONDEMN_PANEL_X(panelColumn, 2),
198 CONDEMN_PANEL_Y(panelRow, 2) + screenY, 128, 91);
199 }
200 if ((frame - 92) <= 1U) {
201 draw[work->effect->side](
202 canvas, Ram_MapCellBuffer, CONDEMN_PANEL_X(panelColumn, 3),
203 CONDEMN_PANEL_Y(panelRow, 3) + screenY, 128, 91);
204 }
205 if ((frame - 94) <= 1U) {
206 draw[work->effect->side](canvas, Ram_MapCellBuffer + 0x2d80,
207 CONDEMN_PANEL_X(panelColumn, 4),
208 CONDEMN_PANEL_Y(panelRow, 4) + screenY, 128,
209 59);
210 }
211 if ((frame - 96) <= 1U) {
212 draw[work->effect->side](canvas, Ram_MapCellBuffer + 0x4b00,
213 CONDEMN_PANEL_X(panelColumn, 5),
214 CONDEMN_PANEL_Y(panelRow, 5) + screenY, 122,
215 29);
216 }
217 if ((frame - 98) <= 1U) {
218 draw[work->effect->side](canvas, Ram_MapCellBuffer + 0x58d2,
219 CONDEMN_PANEL_X(panelColumn, 6),
220 CONDEMN_PANEL_Y(panelRow, 6) + screenY, 76,
221 25);
222 }
223 }
224 }
225 // Frame 88: knock the target back, away from the middle of the field,
226 // to twice its x at up to 2 pixels a frame.
227 if (frame == CONDEMN_BREAK_FRAME) {
228 target = GetBattleObjectSlotFar(work->effect->actors[0])->object;
229 target->velocityY = 0x10000;
230 target->acceleration = 0x20000;
231 target->speedLimit = 0x20000;
232 target->verticalMotionStrength = 0;
233 target->autoFaceMotion = 0;
234 target->snapToTarget = 0;
235 Object_SetMoveTargetFar((struct ObjectRuntime *)target, target->x << 1, 0,
236 target->z);
238 0);
239 }
240 if (frame == CONDEMN_BOUNCE_FRAME) {
242 ->object->verticalMotionStrength = 0xAB85;
243 }
245 }
246 // Finish: the callbacks, then the battle backdrop reloaded into
247 // character blocks 2 and 3, its palettes darkened to level 24.
248 // XXX: why it is reloaded, when nothing in this effect writes those
249 // blocks; a VRAM view after the panel breaks would show what it repairs.
255}
256
257#undef CONDEMN_FRAMES
258#undef CONDEMN_BREAK_FRAME
259#undef CONDEMN_BOUNCE_FRAME
260#undef CONDEMN_PANEL_X
261#undef CONDEMN_PANEL_Y
@ POSE_DAMAGE
taking damage
Definition battle.h:176
@ COMPOSITE_FLIP_X
@ COMPOSITE_TRANSPARENT
BattleEffectDrawRectangle DrawRectangle
struct BattleWork * gBattleWork
void BattleFx_ArmBg2AffineHBlankDma(void)
Arms DMA 0 to copy one word of gBattleFxWork's bg2xLines table into BG2X at each horizontal blank,...
void BattleFx_ProcessPendingGraphicsTransfer(void)
Copies the canvas to VRAM once the effect has finished drawing a frame (transferPending): the 128x128...
Definition canvas.c:103
void BattleFx_EndCanvasLayer(void)
Closes the canvas layer: plays the closing sound, restores BG1's scroll and the projection centre,...
Definition canvas.c:490
void BattleFx_BeginTiledCanvas(s32 bgControl)
Opens the canvas layer with BG2 a wrapping 256x256 map: each row of the map is the canvas's 16 tiles ...
Definition canvas.c:463
#define CONDEMN_PANEL_X(column, stage)
gCondemn_PanelX and _PanelY have seven stages for each column and row.
Definition condemn.c:12
#define CONDEMN_BREAK_FRAME
the panel breaks in a white flash
Definition condemn.c:8
void BattleFx_RunCondemn(struct BattleEffectArgument *effect)
A tall panel (57x98) swings across the screen three times, each pass fading out through a ripple,...
Definition condemn.c:29
#define CONDEMN_BOUNCE_FRAME
the falling target bounces
Definition condemn.c:9
#define CONDEMN_PANEL_Y(row, stage)
Definition condemn.c:13
#define CONDEMN_FRAMES
Definition condemn.c:7
void ObjectGroup_UpdateMembers(s32 actorId, s32 palette, s32 animation, s32 timerSlot, s32 timerFrames)
Updates every animation group of one battler's object.
Definition dispatch.c:254
What every part of the battle effect object shares: its includes, macros and frame-loop helpers.
#define EFFECT_RELEASE_BLITTERS()
Frees the two blitters, the alternate first.
#define EFFECT_PRESENT_FRAME(work)
Ends a frame of a canvas effect: marks the canvas ready for the transfer callback,...
@ CANVAS_COPY_AND_CLEAR
copy, then fill the canvas with transferValue
#define CANVAS_BYTES
The canvas: 128x128 pixels, one byte each, in its heap slot and in VRAM at BG_CHAR_BLOCK(1).
#define EFFECT_CALLBACK_ORDER
The scheduler order of every per-frame effect callback (Scheduler_AddOrUpdateCallback sorts the frame...
#define EFFECT_SLOT(slots, slot)
A work slot read through a pointer to the effect's own slot, gWorkSlot[HEAP_SLOT_BATTLE_EFFECT].
#define EFFECT_START_TRANSFER(work, mode, value)
Sets the transfer, then starts copying the canvas to VRAM once a frame.
#define EFFECT_LOAD_BLITTER(slot, flags, mode)
Builds a blitter for the 128x128 canvas (1 << 7 pixels each way) in work slot slot: BattleFx_BuildBli...
#define EFFECT_GET_SLOTS(slots, cursor, work, canvas)
Starts at the effect's entry in the whole work-slot array.
struct BattleObj * GetBattleObjectSlotFar(s32 objectId)
Far call to BattleObjGet.
void BattleBackground_LoadFar(s32 mode, s32 resource, s32 level)
void Object_SetMoveTargetFar(struct ObjectRuntime *object, s32 x, s32 y, s32 z)
void AudioCommand_PlayFar(s32 id)
s32 Trig_Cos(s32 angle)
s32 Trig_Sin(s32 angle)
@ HEAP_SLOT_BLITTER_ALTERNATE
Definition heap_state.h:47
@ HEAP_SLOT_BLITTER
Definition heap_state.h:46
#define Q_8_8(n)
The BG2/BG3 affine matrix entries are signed 8.8 fixed point: texels stepped per screen pixel.
Definition io_reg.h:59
#define BLEND_ALPHA(top, bottom)
A REG_BLDALPHA value: top and bottom are the two targets' weights, out of 16.
Definition io_reg.h:145
#define REG_BLDALPHA
Definition io_reg.h:142
#define BG_PLTT
Definition io_reg.h:157
#define REG_BG2PA
Definition io_reg.h:61
static s32 Iwram_CopyWords(volatile void *destination, const volatile void *source, s32 size)
Definition iwram_call.h:85
static s32 Iwram_FillWords(void *destination, s32 size, u32 value)
Definition iwram_call.h:59
void EffectPosition_ProjectScaledBattler(s32 id, struct EffectPosition *position)
The screen position of a battler, scaled for the battle view, 16 pixels higher.
Definition positions.c:88
#define Ram_MapCellBuffer
Definition ram_buffer.h:10
char ResourceId_CounterRevealSheet
char ResourceId_RedCrescentSheetA
s32 Resource_DecodeType01(const void *source, void *destination)
Decodes a type-01 resource and returns its unpacked byte count.
Definition decompress.c:31
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_HEAVY_IMPACT
Definition songs.h:127
The command shared by an effect's caller, dispatcher and handlers.
s32 side
1 when the targets are the party, 0 for enemies
s16 actors[8]
the targets' unit ids, count of them
The running battle effect's work: its canvas image, 64 particles, the display registers it stages and...
struct BattleEffectArgument * effect
the command being run
struct MotionObject * object
NULL once released.
u16 background
the battle background's id
A point projected onto the screen, with its depth.
Definition effect_step.h:46
s32 x
screen pixels
Definition effect_step.h:58
An effect object that moves and draws one sprite: its position, scale, velocity and target,...
Definition motobj.h:20
s32 speedLimit
16.16 fixed-point pixels per frame
Definition motobj.h:34
u8 snapToTarget
nonzero: lands exactly on the target, else brakes in
Definition motobj.h:57
s32 velocityY
16.16 fixed-point pixels per frame
Definition motobj.h:32
s32 acceleration
Horizontal speed gained each frame towards the target, or lost braking without one,...
Definition motobj.h:37
s32 verticalMotionStrength
Gravity: taken from velocityY each frame above the ground with motionFlags bit 1, in 16....
Definition motobj.h:48
u8 autoFaceMotion
bit 0 turns the object to face where it moves
Definition motobj.h:59
One of the 64 field objects in the object pool (heap slot 5): its script, position,...
s32 z
16.16 fixed-point pixels
s32 x
16.16 fixed-point pixels
void * Resource_GetTableEntry(s32 index)
Returns the ROM address of resource index from the resource directory.
Definition system.c:150
signed int s32
Definition types.h:14
unsigned char u8
Definition types.h:11
#define EFFECT_CLIP_BOUNDS
Clips overflow on all four sides.
Definition effect.h:224
DrawRectangle BlitterPair[2]
A blitter pair: [0] built in HEAP_SLOT_BLITTER and [1] in HEAP_SLOT_BLITTER_ALTERNATE (BattleFx_Fetch...
Definition effect.h:244