Alchemy
Loading...
Searching...
No Matches

spider_web.c

Go to the documentation of this file.
1/// @file
2/// Poison Beat, Spinning Beat and Spider Web.
3/// Part of effect.c, the battle effect object, compiled only through it.
4
6
7// - The swirl swipe (Poison Beat, Spinning Beat) sweeps a swirl across the
8// first target; its two modes differ in colour, length and how the target
9// reacts.
10// - The spider web spreads four mirrored quarters of a web over the targets
11// and fades it in and out.
12
13/// A lime swipe that knocks the target back.
14///
15/// Abilities: Poison Beat (kind 382).
17 BattleFx_RunSwirlSwipe(effect, 0);
18}
19/// A magenta swipe that throws the target into the air.
20///
21/// Abilities: Spinning Beat (kind 383).
23 BattleFx_RunSwirlSwipe(effect, 1);
24}
25/// A swirling swipe across the first target, six images four frames each,
26/// from the user's side: the first four from the swirl sheet, the last two
27/// from the tail sheet. The swipe lands on frame 8.
28///
29/// Called by BattleFx_RunPoisonBeat and BattleFx_RunSpinningBeat. Decodes
30/// the tail sheet into Ram_MapCellBuffer, moves BG2X so the swipe crosses
31/// the target, and sets work->shakeFrames on the hit; mode 0 loads its
32/// colours over the first 64 of the background palette, and mode 1 throws
33/// the target's object into the air.
34///
35/// mode 0 : lime colours; the battle shows the damage at once and the target
36/// recoils. 48 frames.
37/// mode 1 : the target flashes, is thrown up on frame 13 and the battle shows
38/// the damage as it lands on frame 65. 74 frames.
40 struct BattleEffectWork *work;
41 void *canvas;
42 struct MotionObject *object;
43 struct EffectPosition position;
44 /* FAKEMATCH: only draw[0] is used: the second word fills
45 * four bytes of the frame */
46 BlitterPair draw;
47 s32 frames;
48 s32 frame;
49 s32 cell;
50 void **slots;
51 void **cursor;
52
53 EFFECT_GET_SLOTS(slots, cursor, work, canvas);
54 work->effect = effect;
56 if (work->effect->side == 1) {
60 } else {
65 }
67 1);
69 Ram_MapCellBuffer, 1, 0);
70 if (mode == 0) {
72 Iwram_CopyWords((void *)BG_PLTT, palette, 128);
73 }
74 // Trails keep 3/4 a frame.
76 object = GetBattleObjectSlotFar(work->effect->actors[0])->object;
78 // Line the canvas up so the swipe crosses the target: the target's x
79 // lands at canvas x 16 against the enemies and 112 against the party.
80 if (work->effect->side == 0)
81 REG_BG2X = (16 - position.x) << 8;
82 else
83 REG_BG2X = (112 - position.x) << 8;
84 frames = 74;
85 if (mode != 1)
86 frames = 48;
87 for (frame = 0; frame != frames; frame++) {
88 // Frame loop. The swipe's six images, from x columns chosen by the
89 // side (six a side in gSpiderWeb_CellX); the trail fades after them.
90 cell = frame / 4;
91 if (cell <= 5) {
92 if (cell <= 3)
93 draw[0](canvas, work->sheet + gSpiderWeb_Cells[cell],
94 gSpiderWeb_CellX[cell + work->effect->side * 6],
97 else
98 draw[0](canvas, Ram_MapCellBuffer + gSpiderWeb_Cells[cell],
99 gSpiderWeb_CellX[cell + work->effect->side * 6],
102 }
103 if (frame == 8) {
104 if (mode == 0) {
107 } else {
110 POSE_DAMAGE, 0, 4);
111 }
112 work->shakeFrames = 8;
113 }
114 // Mode 1 throws the target up at 12 pixels a frame on frame 13, and
115 // shows the damage as it lands on frame 65.
116 if (mode == 1) {
117 if (frame == 13) {
118 object->velocityY = 0xc0000;
119 object->verticalMotionStrength = 0x7851;
120 object->verticalMotionPhase = 0x4000;
121 }
122 if (frame == 65) {
123 work->shakeFrames = 4;
125 }
126 }
127 Camera_ApplyShake(8, 8);
128 EFFECT_END_FRAME(work);
129 }
131}
132
133#define SPIDER_WEB_FRAMES 63
134
135/// A spider web spreads over the targets, drawn as four mirrored 32x32 quarters
136/// around the point between the first and last target.
137///
138/// Abilities: Spider Web (kind 345).
139///
140/// It fades in over 8 frames; the targets flash on frame 10, the battle shows
141/// the damage on frame 32, and it fades out from frame 54.
142///
143/// Builds and frees its blitter four times a frame, one for each quarter's
144/// flip.
146 struct EffectPosition first;
147 struct EffectPosition last;
148 void *canvas;
149 struct BattleEffectWork *work;
150 s32 size;
151 s32 transparent;
152
153 // Plain, the counter's priority (20 refs over 232 insns) ties size and
154 // outranks transparent (13 over 240).
155 /* FAKEMATCH: pins the frame counter to r9, as native; plain, it takes sl and
156 * transparent r9, and 30 instructions differ in tbs-en. */
157 register s32 frame __asm__("r9");
158 s32 i;
159
160 /* FAKEMATCH: size and transparent first hold the slot table and blend
161 * register addresses, sharing their registers; as plain slot reads and
162 * REG_BLDALPHA, 56 instructions differ in tbs-en. */
164 canvas = *(void **)size;
165 work = *(struct BattleEffectWork **)(size - 4);
166 work->effect = effect;
168 transparent = (s32)&REG_BLDALPHA;
169 REG_BG2PA = Q_8_8(1);
170 *(u16 *)transparent = 0x1000; // REG_BLDALPHA: invisible to start with
173 work->effect->actors[work->effect->count - 1], &last);
174 // Centre the canvas between the first and last target.
175 first.x += (last.x - first.x) / 2;
176 REG_BG2X = (64 - first.x) << 8;
178 1);
179 // Redraw from blank each frame.
182 // transparent is COMPOSITE_TRANSPARENT, and also the 1 that marks each
183 // frame's canvas for transfer.
184 frame = 0;
185 transparent = 1;
186 size = 32;
187 do {
188 // Frame loop. The quarters meet near (64, 72): top left, top right
189 // mirrored, bottom left flipped, bottom right both.
190 if (frame <= 8)
191 REG_BLDALPHA = BLEND_ALPHA(frame << 1, 16);
192 if (frame > 53)
193 REG_BLDALPHA = BLEND_ALPHA(0x7c - (frame << 1), 16);
195 ((DrawRectangle)Ram_WorkSlot[HEAP_SLOT_BLITTER])(canvas, work->sheet, 33,
196 41, size, size);
199 EFFECT_CLIP_BOUNDS | COMPOSITE_FLIP_X, transparent);
200 ((DrawRectangle)Ram_WorkSlot[HEAP_SLOT_BLITTER])(canvas, work->sheet, 64,
201 41, size, size);
204 EFFECT_CLIP_BOUNDS | COMPOSITE_FLIP_Y, transparent);
205 ((DrawRectangle)Ram_WorkSlot[HEAP_SLOT_BLITTER])(canvas, work->sheet, 33,
206 72, size, size);
209 transparent);
210 ((DrawRectangle)Ram_WorkSlot[HEAP_SLOT_BLITTER])(canvas, work->sheet, 64,
211 72, size, size);
213 if (frame == 32)
216 if (frame == 10)
218 -1, i, 8);
219 }
221 work->transferPending = transparent;
222 WaitFrames(1);
223 frame++;
224 } while (frame != SPIDER_WEB_FRAMES);
225 // Finish: the blitter was freed each time it drew.
228}
229
230#undef SPIDER_WEB_FRAMES
@ SPRITE_COLOR_WHITE
solid colour 15, white
Definition animspr.h:26
@ POSE_DAMAGE
taking damage
Definition battle.h:176
@ COMPOSITE_FLIP_X
@ COMPOSITE_FLIP
@ COMPOSITE_FLIP_Y
@ COMPOSITE_TRANSPARENT
BattleEffectDrawRectangle DrawRectangle
#define EFFECT_FOR_EACH_TARGET(i, effect)
Loops i over the effect's targets, effect->actors[0] to effect->actors[effect->count - 1]: the loops ...
void ObjectGroup_TickMemberTimers(void)
Counts down each target's flash timer, which ObjectGroup_UpdateMembers starts; when one runs out,...
Definition canvas.c:275
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_BeginCanvasLayer(s32 bgControl)
Opens the canvas layer: starts the background palette fade, makes BG2 the canvas, alpha-blended over ...
Definition canvas.c:314
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 Resource_LoadAndDecompress(s32 id, void *dst, s32 skipPalette, s32 copyPalette)
Decompresses a resource whose first 128 bytes may be a palette.
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.
@ CANVAS_COPY_AND_CLEAR
copy, then fill the canvas with transferValue
@ CANVAS_COPY_AND_FADE
copy, keeping 50% or 75% (transferValue) of each pixel in the canvas for the next 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_FINISH_CANVAS_ONE_BLITTER()
The same for an effect that drew through one blitter.
#define EFFECT_SHOW_DAMAGE(hitSound)
Lets the battle show the damage: resumes its paused playback, which plays hitSound (an SE_ id; 0 keep...
#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.
#define EFFECT_END_FRAME(work)
The usual end of an effect frame: counts down the targets' flash timers (ObjectGroup_TickMemberTimers...
#define EFFECT_BEGIN_NARROW_CANVAS(bgControl)
Opens the canvas layer at the canvas's own width, one texel per pixel, where BattleFx_BeginCanvasLaye...
s8 gSpiderWeb_CellBiasY[]
u8 gSpiderWeb_CellHeights[]
u8 gSpiderWeb_CellX[]
u8 gSpiderWeb_CellWidths[]
u16 gSpiderWeb_Cells[]
struct BattleObj * GetBattleObjectSlotFar(s32 objectId)
Far call to BattleObjGet.
void BattleMotion_ApplyVariantMotionFar(s32 id, s32 variant)
void AudioCommand_PlayFar(s32 id)
void WaitFrames(s32 frames)
The game's frame loop: runs frames frames and returns.
Definition frame.c:97
void Camera_ApplyShake(s32 rangeX, u32 rangeY)
Shakes the battle view while gBattleFxWork's shakeFrames lasts, moving BG1 and the projection centre ...
Definition hail.c:364
@ HEAP_SLOT_BLITTER
Definition heap_state.h:46
@ HEAP_SLOT_BATTLE_CANVAS
Definition heap_state.h:43
#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 REG_BG2X
Definition io_reg.h:65
#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
void Runtime_ReleaseHeapBlock(s32 slot)
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_WorkSlot
Definition ram_buffer.h:44
#define Ram_MapCellBuffer
Definition ram_buffer.h:10
char ResourceId_LimePalette
char ResourceId_SpiderWebSheet
char ResourceId_MagentaSwirlSheet
char ResourceId_MagentaTailSheet
s32 Scheduler_RemoveCallback(SchedulerCallback callback)
Unschedules the task running callback: clears its routine and gives it order 0x7fff,...
Definition scheduler.c:146
#define SE_133
Definition songs.h:126
#define SE_143
Definition songs.h:136
#define SE_HEAVY_IMPACT
Definition songs.h:127
void BattleFx_RunSpinningBeat(struct BattleEffectArgument *effect)
A magenta swipe that throws the target into the air.
Definition spider_web.c:22
void BattleFx_RunSpiderWeb(struct BattleEffectArgument *effect)
A spider web spreads over the targets, drawn as four mirrored 32x32 quarters around the point between...
Definition spider_web.c:145
void BattleFx_RunSwirlSwipe(struct BattleEffectArgument *effect, s32 mode)
A swirling swipe across the first target, six images four frames each, from the user's side: the firs...
Definition spider_web.c:39
void BattleFx_RunPoisonBeat(struct BattleEffectArgument *effect)
A lime swipe that knocks the target back.
Definition spider_web.c:16
#define SPIDER_WEB_FRAMES
Definition spider_web.c:133
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
s32 count
targets in actors, at least 1
The running battle effect's work: its canvas image, 64 particles, the display registers it stages and...
s32 frame
frame counter some effects keep, from 0
s32 transferPending
1 once the effect has drawn a frame (EFFECT_PRESENT_FRAME); the canvas transfer callback copies the c...
s32 shakeFrames
shake frames left; Camera_ApplyShake counts down
struct BattleEffectArgument * effect
the command being run
struct MotionObject * object
NULL once released.
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
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 short u16
Definition types.h:13
#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