13#define BRANCH_FIELD(site, target) \
14 ((((u32)(target) - (u32)(site) - 8) >> 2) & 0x00FFFFFF)
19#define BLITTER_PARTIAL_RUN(mode, flags) \
22 case COMPOSITE_COPY: \
23 if (((flags) & COMPOSITE_FLIP_X) != 0) { \
24 COPY_FROM(BattleFx_CopyReverse, 2); \
26 COPY_FROM(BattleFx_CopyForward, 2); \
29 case COMPOSITE_TRANSPARENT: \
30 if (((flags) & COMPOSITE_FLIP_X) != 0) { \
31 COPY_FROM(BattleFx_TransparentReverse, 4); \
33 COPY_FROM(BattleFx_TransparentForward, 4); \
37 if (((flags) & COMPOSITE_FLIP_X) != 0) { \
38 COPY_FROM(BattleFx_MaxReverse, 4); \
40 COPY_FROM(BattleFx_MaxForward, 4); \
43 case COMPOSITE_ADDITIVE: \
44 if (((flags) & COMPOSITE_FLIP_X) != 0) { \
45 COPY_FROM(BattleFx_AdditiveReverse, 6); \
47 COPY_FROM(BattleFx_AdditiveForward, 6); \
58#define BLITTER_WALK() \
60 if (mode == COMPOSITE_ADDITIVE) { \
61 COPY_FROM(BattleFx_Mask, 3); \
64 if ((flags & COMPOSITE_FLIP) == COMPOSITE_FLIP_X) { \
65 COPY_FROM(templateWords, 3); \
68 if ((flags & COMPOSITE_FLIP) == COMPOSITE_FLIP_Y) { \
69 COPY_FROM(templateWords, 4); \
72 if ((flags & COMPOSITE_FLIP) == COMPOSITE_FLIP) { \
73 COPY_FROM(templateWords, 3); \
76 if ((flags & COMPOSITE_FLIP) == 0) { \
77 PUT(templateWords[0]); \
81 if ((flags & COMPOSITE_CLIP_Y) != 0) { \
82 PUT(templateWords[0]); \
83 PUT(templateWords[1]); \
84 if ((flags & COMPOSITE_FLIP_Y) != 0) { \
85 PUT(templateWords[2]); \
87 PUT(templateWords[3]); \
89 PUT(templateWords[4]); \
90 PUT(templateWords[5]); \
91 PUT(templateWords[6] + (1 << heightShift)); \
92 PUT(templateWords[7] + (1 << heightShift)); \
96 PUT(*templateWords++); \
97 MARK(emptyRowsBranch); \
98 PUT(*templateWords++); \
100 if ((flags & COMPOSITE_CLIP_X) == 0) { \
101 PUT(templateWords[0] + (1 << widthShift) - 1); \
103 templateWords += 1; \
104 if ((flags & COMPOSITE_CLIP_X) != 0) { \
105 PUT(templateWords[0]); \
106 PUT(templateWords[1]); \
107 if ((flags & COMPOSITE_FLIP_X) != 0) { \
108 PUT(templateWords[2]); \
109 PUT(templateWords[3]); \
111 PUT(templateWords[4]); \
112 PUT(templateWords[5]); \
114 PUT(templateWords[6]); \
115 PUT(templateWords[7]); \
116 PUT(templateWords[8] + gBattleFx_BitOperands[widthShift]); \
117 if ((flags & COMPOSITE_FLIP_X) != 0) { \
118 PUT(templateWords[9]); \
120 PUT(templateWords[10]); \
122 PUT(templateWords[11] + gBattleFx_BitOperands[widthShift]); \
124 templateWords += 12; \
126 PUT(*templateWords++); \
127 MARK(emptyColumnsBranch); \
128 PUT(*templateWords++); \
132 PUT(*templateWords++); \
133 if ((flags & COMPOSITE_CLIP_X) == 0) { \
134 PUT(templateWords[0]); \
136 templateWords += 1; \
141 PUT(templateWords[0]); \
142 PUT(templateWords[1] + (1 << (heightShift - 3)) - 1); \
143 PUT(templateWords[2] + ((widthShift - 3) << 7)); \
144 PUT(templateWords[3]); \
145 templateWords += 4; \
147 if ((flags & COMPOSITE_CLIP_X) == 0) { \
148 PUT(templateWords[0]); \
150 templateWords += 1; \
152 PUT(*templateWords++); \
154 PUT(*templateWords++); \
155 if ((flags & COMPOSITE_FLIP_X) != 0) { \
156 PUT(templateWords[0]); \
158 PUT(templateWords[1]); \
160 templateWords += 2; \
163 BLITTER_PARTIAL_RUN(mode, flags); \
164 templateWords += 4; \
166 PUT(*templateWords++); \
167 PUT_BRANCH(partialRun); \
168 PUT(*templateWords++); \
169 if ((flags & COMPOSITE_CLIP_X) == 0) { \
170 PUT(templateWords[0]); \
171 PUT(templateWords[1]); \
173 templateWords += 2; \
176 PUT(*templateWords++); \
178 PUT(*templateWords++); \
180 MARK(fullCellLoop); \
186 case COMPOSITE_COPY: { \
189 for (i = 0; i < 8; i++) { \
190 if ((flags & COMPOSITE_FLIP_X) != 0) { \
191 COPY_FROM(BattleFx_CopyReverse, 2); \
193 COPY_FROM(BattleFx_CopyForward, 2); \
197 case COMPOSITE_TRANSPARENT: \
198 if ((flags & COMPOSITE_FLIP_X) != 0) { \
199 COPY_FROM(BattleFx_Transparent8Reverse, 25); \
201 COPY_FROM(BattleFx_Transparent8Forward, 25); \
204 case COMPOSITE_MAX: \
205 if ((flags & COMPOSITE_FLIP_X) != 0) { \
206 COPY_TWICE(BattleFx_Max4Reverse, 16); \
208 COPY_TWICE(BattleFx_Max4Forward, 16); \
211 case COMPOSITE_ADDITIVE: \
212 if ((flags & COMPOSITE_FLIP_X) != 0) { \
213 COPY_TWICE(BattleFx_ColorReverse, 14); \
215 COPY_TWICE(BattleFx_ColorForward, 14); \
219 templateWords += 4; \
221 PUT(*templateWords++); \
222 if ((flags & COMPOSITE_CLIP_X) == 0) { \
223 PUT(templateWords[0]); \
224 PUT(templateWords[1]); \
226 templateWords += 2; \
228 PUT(*templateWords++); \
229 PUT_BRANCH(fullCellLoop); \
232 PUT(*templateWords++); \
234 PUT(*templateWords++); \
235 if ((flags & COMPOSITE_FLIP_X) != 0) { \
236 PUT(templateWords[0]); \
238 PUT(templateWords[1]); \
240 templateWords += 2; \
243 BLITTER_PARTIAL_RUN(mode, flags); \
244 templateWords += 4; \
246 PUT(*templateWords++); \
247 PUT_BRANCH(partialRun); \
252 PUT_BRANCH(rowLoop); \
253 PATCH(emptyRowsBranch); \
254 PATCH(emptyColumnsBranch); \
256 PUT(*templateWords++); \
257 PUT(*templateWords++)
283 const u32 *templateWords;
285 u32 *emptyRowsBranch;
286 u32 *emptyColumnsBranch;
294#define PUT(word) wordCount++
298#define COPY_FROM(from, n) wordCount += (n)
299#define COPY_TWICE(from, n) \
302#define PUT_BRANCH(target) wordCount++
327 *codeWords++ = (word); \
333 Dma_Set(templateWords, codeWords, DMA_COPY_WORDS(n), REG_DMA3); \
335 templateWords += (n); \
337#define COPY_FROM(from, n) \
338 Dma_Set(from, codeWords, DMA_COPY_WORDS(n), REG_DMA3); \
340#define COPY_TWICE(from, n) \
342 const u32 *part = (from); \
343 Dma_Set(part, codeWords, DMA_COPY_WORDS(n), REG_DMA3); \
345 Dma_Set(part, codeWords, DMA_COPY_WORDS(n), REG_DMA3); \
348#define PUT_BRANCH(target) \
349 *codeWords = *templateWords++ + BRANCH_FIELD(codeWords, target); \
351#define MARK(site) site = codeWords
356 *(site) |= BRANCH_FIELD(site, codeWords); \
372 return templateWords == codeEnd;
383#undef BLITTER_PARTIAL_RUN
const u32 BattleFx_Composite[]
#define BLITTER_WALK()
The template walk itself, written once.
s32 BattleFx_BuildBlitter(s32 slot, s32 widthShift, s32 heightShift, s32 flags, u32 mode)
Writes a drawing routine for the canvas into heap slot slot, built from the template BattleFx_Composi...
What every part of the battle effect object shares: its includes, macros and frame-loop helpers.
u16 gBattleFx_MoteCells[]
Mote cells: particle sheets hold ten, cell n (from 0) n + 1 pixels wide and twice that tall.
void * Runtime_AllocateHeapBlock(s32 kind, s32 size)
Returns heap slot kind's block, first allocating size bytes for it (rounded up to words),...