Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
effects.c
Go to the documentation of this file.
1#include "common.h"
2#include "effects.h"
3#include "ld_addrs.h"
4
5typedef s8 TlbEntry[0x1000];
7
8#define EFFECT_GLOBALS_TLB_IDX 0x10
9
12
14extern Addr gEffectGlobals;
15
16#define FX_ENTRY(name, gfx_name) { \
17 .entryPoint = name##_main, \
18 .dmaStart = effect_##name##_ROM_START, \
19 .dmaEnd = effect_##name##_ROM_END, \
20 .dmaDest = effect_##name##_VRAM, \
21 .graphicsDmaStart = gfx_name##_ROM_START, \
22 .graphicsDmaEnd = gfx_name##_ROM_END, \
23}
24
25#include "effects/effect_table.c"
26
30
32 s32* data = effect->data.any;
33
34 ((f32*)data)[1] = x;
35 ((f32*)data)[2] = y;
36 ((f32*)data)[3] = z;
37}
38
40 s32 i;
41
42 for (i = 0; i < ARRAY_COUNT(gEffectSharedData); i++) {
44 }
45
46 for (i = 0; i < ARRAY_COUNT(gEffectInstances); i++) {
47 gEffectInstances[i] = nullptr;
48 }
49
53}
54
55void func_80059D48(void) {
56}
57
58void update_effects(void) {
61 s32 i;
62
63 // reset free delay for each EffectSharedData touched in previous update
65 if (sharedData->flags & FX_SHARED_DATA_LOADED) {
66 if (!(sharedData->flags & FX_SHARED_DATA_CAN_FREE)) {
68 sharedData->freeDelay = 3;
69 }
70 }
71 }
72
73 // update each EffectInstances
74 for (i = 0; i < ARRAY_COUNT(gEffectInstances); i++) {
76
77 if (effectInstance != nullptr && (effectInstance->flags & FX_INSTANCE_FLAG_ENABLED)) {
79
82 effectInstance->shared->update(effectInstance);
84 }
85 } else {
87 effectInstance->shared->update(effectInstance);
89 }
90 }
91 }
92 }
93
94 // free any EffectSharedData which haven't been used recently
96 if (sharedData->flags & FX_SHARED_DATA_LOADED) {
98 if (sharedData->freeDelay != 0) {
99 sharedData->freeDelay--;
100 } else {
101 if (sharedData->graphics != nullptr) {
102 general_heap_free(sharedData->graphics);
103 sharedData->graphics = nullptr;
104 }
105 sharedData->flags = 0;
106 osUnmapTLB(i);
107 }
108 }
109 }
110 }
111 }
112}
113
115 s32 i;
116
117 for (i = 0; i < ARRAY_COUNT(gEffectInstances); i++) {
119
120 if (effectInstance != nullptr) {
126 }
127 } else {
128 if (!(effectInstance->flags & FX_INSTANCE_FLAG_BATTLE)) {
129 effectInstance->shared->renderScene(effectInstance);
130 }
131 }
132 }
133 }
134 }
135 }
136}
137
139 s32 cond = true;
140 s32 i;
141
142 for (i = 0; i < ARRAY_COUNT(gEffectInstances); i++) {
144
145 if (effectInstance != nullptr) {
148 void (*renderUI)(EffectInstance* effect);
149
151 continue;
152 }
153
155 continue;
156 }
157
158 renderUI = effectInstance->shared->renderUI;
159 if (renderUI != stub_effect_delegate) {
160 if (cond) {
162
167 G_SHADING_SMOOTH | G_CLIPPING | 0x40F9FA);
170 camera->viewportStartX,
171 camera->viewportStartY,
172 camera->viewportStartX + camera->viewportW,
173 camera->viewportStartY + camera->viewportH);
175
176 cond = false;
177 if (!(camera->flags & CAMERA_FLAG_ORTHO)) {
178 gSPPerspNormalize(gMainGfxPos++, camera->perspNorm);
181 }
182 }
183
184 renderUI(effectInstance);
185 }
186 }
187 }
188 }
189 }
190}
191
195 s32 i;
196
197 // Search for an unused instance
198 for (i = 0; i < ARRAY_COUNT(gEffectInstances); i++) {
199 if (gEffectInstances[i] == nullptr) {
200 break;
201 }
202 }
203
205
206 // Allocate space for the new instance
208 ASSERT(newEffectInst != nullptr);
209
211 newEffectInst->effectID = effectBp->effectID;
213
214 // Look for a loaded effect of the proper index
215 for (i = 0; i < ARRAY_COUNT(gEffectSharedData); i++) {
216 if ((sharedData->flags & FX_SHARED_DATA_LOADED) && (sharedData->effectIndex == effectBp->effectID)) {
217 break;
218 }
219 sharedData++;
220 }
221
223
224 // If this is the first new instance of the effect, initialize the function pointers
225 if (sharedData->instanceCounter == 0) {
226 sharedData->update = effectBp->update;
227 if (sharedData->update == nullptr) {
228 sharedData->renderScene = stub_effect_delegate;
229 }
230
231 sharedData->renderScene = effectBp->renderScene;
232 if (sharedData->renderScene == nullptr) {
233 sharedData->renderScene = stub_effect_delegate;
234 }
235
236 sharedData->renderUI = effectBp->renderUI;
237 if (sharedData->renderUI == nullptr) {
239 }
240 }
241
242 sharedData->instanceCounter++;
243 newEffectInst->shared = sharedData;
244
245 if (effectBp->init != nullptr) {
246 effectBp->init(newEffectInst);
247 }
248
251 }
252 return newEffectInst;
253}
254
256 s32 i;
257
258 for (i = 0; i < ARRAY_COUNT(gEffectInstances); i++) {
260 break;
261 }
262 }
263
265
266 if (effectInstance->data.any == nullptr) {
268 gEffectInstances[i] = nullptr;
269 } else {
272 gEffectInstances[i] = nullptr;
273 }
274}
275
277 s32 i;
278
279 for (i = 0; i < ARRAY_COUNT(gEffectInstances); i++) {
280 EffectInstance* effect = gEffectInstances[i];
281
282 if (effect != nullptr && effect->flags & FX_INSTANCE_FLAG_BATTLE) {
283 if (effect->data.any != nullptr) {
284 general_heap_free(effect->data.any);
285 }
286 general_heap_free(effect);
287 gEffectInstances[i] = nullptr;
288 }
289 }
290}
291
292s32 load_effect(s32 effectIndex) {
295 s32 i;
296
297 // Look for a loaded effect matching the desired index
298 for (i = 0, sharedData = &gEffectSharedData[0]; i < ARRAY_COUNT(gEffectSharedData); i++) {
299 if ((sharedData->flags & FX_SHARED_DATA_LOADED) && sharedData->effectIndex == effectIndex) {
300 break;
301 }
302 sharedData++;
303 }
304
305 // If an effect was found within the table, initialize it and return
307 sharedData->effectIndex = effectIndex;
308 sharedData->instanceCounter = 0;
310 return 1;
311 }
312
313 // If a loaded effect wasn't found, look for the first empty space
314 for (i = 0, sharedData = &gEffectSharedData[0]; i < ARRAY_COUNT(gEffectSharedData); i++) {
315 if (!(sharedData->flags & FX_SHARED_DATA_LOADED)) {
316 break;
317 }
318 sharedData++;
319 }
320
321 // If no empty space was found, panic
323
324 // Map space for the effect
325 osMapTLB(i, OS_PM_4K, effectEntry->dmaDest, (s32)(gEffectDataBuffer[i]) & 0xFFFFFF, -1, -1);
326
327 // Copy the effect into the newly mapped space
328 dma_copy(effectEntry->dmaStart, effectEntry->dmaEnd, effectEntry->dmaDest);
329
330 // If there's graphics data for the effect, allocate space and copy into the new space
331 if (effectEntry->graphicsDmaStart != nullptr) {
332 void* graphics = general_heap_malloc(effectEntry->graphicsDmaEnd - effectEntry->graphicsDmaStart);
333 sharedData->graphics = graphics;
334 ASSERT(graphics != nullptr);
335 dma_copy(effectEntry->graphicsDmaStart, effectEntry->graphicsDmaEnd, sharedData->graphics);
336 }
337
338 // Initialize the newly loaded effect data
339 sharedData->effectIndex = effectIndex;
340 sharedData->instanceCounter = 0;
342 return 1;
343}
BSS s32 PopupMenu_SelectedIndex
#define general_heap_malloc
#define remove_effect
#define load_effect
#define create_effect_instance
EffectInstance * gEffectInstances[96]
Definition effects.c:11
Addr gEffectGlobals
void update_effects(void)
Definition effects.c:58
void func_80059D48(void)
Definition effects.c:55
void remove_all_effects(void)
Definition effects.c:276
void set_effect_pos_offset(EffectInstance *effect, f32 x, f32 y, f32 z)
Definition effects.c:31
void stub_effect_delegate(EffectInstance *effect)
Used for unbound function points in effect structs.
Definition effects.c:28
void clear_effect_data(void)
Definition effects.c:39
TlbEntry TlbMappablePage[15]
Definition effects.c:6
void render_effects_scene(void)
Definition effects.c:114
TlbMappablePage gEffectDataBuffer
BSS EffectSharedData gEffectSharedData[15]
Definition effects.c:10
#define EFFECT_GLOBALS_TLB_IDX
Definition effects.c:8
void render_effects_UI(void)
Definition effects.c:138
s8 TlbEntry[0x1000]
Definition effects.c:5
EffectInstanceDataPtr data
Definition effects.h:2605
struct EffectSharedData * shared
Definition effects.h:2606
#define ASSERT(condition)
@ FX_INSTANCE_FLAG_BATTLE
Definition enums.h:3549
@ FX_INSTANCE_FLAG_ENABLED
Definition enums.h:3548
@ FX_INSTANCE_FLAG_HAS_UPDATED
Definition enums.h:3550
@ CAMERA_FLAG_ORTHO
Definition enums.h:4309
@ FX_SHARED_DATA_LOADED
Definition enums.h:3555
@ FX_SHARED_DATA_CAN_FREE
Definition enums.h:3556
@ CONTEXT_WORLD
Definition enums.h:3562
@ GLOBAL_OVERRIDES_800
Definition enums.h:3915
@ GLOBAL_OVERRIDES_400
Definition enums.h:3914
u32 dma_copy(Addr romStart, Addr romEnd, void *vramDest)
Definition 43F0.c:442
s32 general_heap_free(void *data)
Definition heap.c:18
#define DMA_COPY_SEGMENT(segment)
Definition macros.h:537
#define BSS
Definition macros.h:6
#define ARRAY_COUNT(arr)
Definition macros.h:39
void(* renderScene)(EffectInstance *effectInst)
Definition effects.h:2664
void(* renderUI)(EffectInstance *effectInst)
Definition effects.h:2665
u8 Addr[]
Linker symbol address, as in ld_addrs.h.
Definition types.h:16
s32 gOverrideFlags
Definition main_loop.c:10
GameStatus * gGameStatusPtr
Definition main_loop.c:31
Camera gCameras[4]
Definition cam_main.c:16
Gfx * gMainGfxPos
Definition cam_main.c:14
s32 gCurrentCameraID
Definition cam_math.c:5
DisplayContext * gDisplayContext
Definition cam_main.c:15