Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
effects.c File Reference

Go to the source code of this file.

Macros

#define EFFECT_GLOBALS_TLB_IDX   0x10
 
#define FX_ENTRY(name, gfx_name)
 

Typedefs

typedef s8 TlbEntry[0x1000]
 
typedef TlbEntry TlbMappablePage[15]
 

Functions

void stub_effect_delegate (EffectInstance *effect)
 Used for unbound function points in effect structs.
 
void set_effect_pos_offset (EffectInstance *effect, f32 x, f32 y, f32 z)
 
void clear_effect_data (void)
 
void func_80059D48 (void)
 
void update_effects (void)
 
void render_effects_scene (void)
 
void render_effects_UI (void)
 
EffectInstancecreate_effect_instance (EffectBlueprint *effectBp)
 
void remove_effect (EffectInstance *effectInstance)
 
void remove_all_effects (void)
 
s32 load_effect (s32 effectIndex)
 

Variables

BSS EffectSharedData gEffectSharedData [15]
 
EffectInstancegEffectInstances [96]
 
TlbMappablePage gEffectDataBuffer
 
Addr gEffectGlobals
 
s32 D_8007FEB8 [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 5, 3, 4, 13, 60, 0, 512, 0, 0, 3, 0 }
 

Macro Definition Documentation

◆ EFFECT_GLOBALS_TLB_IDX

#define EFFECT_GLOBALS_TLB_IDX   0x10

Definition at line 8 of file effects.c.

Referenced by clear_effect_data().

◆ FX_ENTRY

#define FX_ENTRY ( name,
gfx_name )
Value:
{ \
.entryPoint = name##_main, \
.dmaStart = effect_##name##_ROM_START, \
.dmaEnd = effect_##name##_ROM_END, \
.dmaDest = effect_##name##_VRAM, \
.graphicsDmaStart = gfx_name##_ROM_START, \
.graphicsDmaEnd = gfx_name##_ROM_END, \
}

Definition at line 16 of file effects.c.

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}

Typedef Documentation

◆ TlbEntry

typedef s8 TlbEntry[0x1000]

Definition at line 5 of file effects.c.

◆ TlbMappablePage

typedef TlbEntry TlbMappablePage[15]

Definition at line 6 of file effects.c.

Function Documentation

◆ stub_effect_delegate()

void stub_effect_delegate ( EffectInstance * effect)

Used for unbound function points in effect structs.

Definition at line 30 of file effects.c.

30 {
31}

Referenced by create_effect_instance(), and render_effects_UI().

◆ set_effect_pos_offset()

void set_effect_pos_offset ( EffectInstance * effect,
f32 x,
f32 y,
f32 z )

Definition at line 33 of file effects.c.

33 {
34 s32* data = effect->data.any;
35
36 ((f32*)data)[1] = x;
37 ((f32*)data)[2] = y;
38 ((f32*)data)[3] = z;
39}
EffectInstanceDataPtr data
Definition effects.h:2605

◆ clear_effect_data()

void clear_effect_data ( void )

Definition at line 41 of file effects.c.

41 {
42 s32 i;
43
44 for (i = 0; i < ARRAY_COUNT(gEffectSharedData); i++) {
46 }
47
48 for (i = 0; i < ARRAY_COUNT(gEffectInstances); i++) {
49 gEffectInstances[i] = NULL;
50 }
51
52 osUnmapTLBAll();
53 osMapTLB(EFFECT_GLOBALS_TLB_IDX, OS_PM_4K, effect_globals_VRAM, (s32)&gEffectGlobals & 0xFFFFFF, -1, -1);
54 DMA_COPY_SEGMENT(effect_globals);
55}
EffectInstance * gEffectInstances[96]
Definition effects.c:11
Addr gEffectGlobals
BSS EffectSharedData gEffectSharedData[15]
Definition effects.c:10
#define EFFECT_GLOBALS_TLB_IDX
Definition effects.c:8
#define DMA_COPY_SEGMENT(segment)
Definition macros.h:529
#define ARRAY_COUNT(arr)
Definition macros.h:40

Referenced by load_demo_battle(), load_engine_data(), load_map_by_IDs(), state_init_logos(), state_init_title_screen(), state_step_demo(), state_step_intro(), and state_step_startup().

◆ func_80059D48()

void func_80059D48 ( void )

Definition at line 57 of file effects.c.

57 {
58}

◆ update_effects()

void update_effects ( void )

Definition at line 60 of file effects.c.

60 {
62 EffectSharedData* sharedData;
63 s32 i;
64
65 // reset free delay for each EffectSharedData touched in previous update
66 for (i = 0, sharedData = gEffectSharedData; i < ARRAY_COUNT(gEffectSharedData); i++, sharedData++) {
67 if (sharedData->flags & FX_SHARED_DATA_LOADED) {
68 if (!(sharedData->flags & FX_SHARED_DATA_CAN_FREE)) {
69 sharedData->flags |= FX_SHARED_DATA_CAN_FREE;
70 sharedData->freeDelay = 3;
71 }
72 }
73 }
74
75 // update each EffectInstances
76 for (i = 0; i < ARRAY_COUNT(gEffectInstances); i++) {
77 EffectInstance* effectInstance = gEffectInstances[i];
78
79 if (effectInstance != NULL && (effectInstance->flags & FX_INSTANCE_FLAG_ENABLED)) {
80 effectInstance->shared->flags &= ~FX_SHARED_DATA_CAN_FREE;
81
83 if (effectInstance->flags & FX_INSTANCE_FLAG_BATTLE) {
84 effectInstance->shared->update(effectInstance);
85 effectInstance->flags |= FX_INSTANCE_FLAG_HAS_UPDATED;
86 }
87 } else {
88 if (!(effectInstance->flags & FX_INSTANCE_FLAG_BATTLE)) {
89 effectInstance->shared->update(effectInstance);
90 effectInstance->flags |= FX_INSTANCE_FLAG_HAS_UPDATED;
91 }
92 }
93 }
94 }
95
96 // free any EffectSharedData which haven't been used recently
97 for (i = 0, sharedData = gEffectSharedData; i < ARRAY_COUNT(gEffectSharedData); i++, sharedData++) {
98 if (sharedData->flags & FX_SHARED_DATA_LOADED) {
99 if (sharedData->flags & FX_SHARED_DATA_CAN_FREE) {
100 if (sharedData->freeDelay != 0) {
101 sharedData->freeDelay--;
102 } else {
103 if (sharedData->graphics != NULL) {
104 general_heap_free(sharedData->graphics);
105 sharedData->graphics = NULL;
106 }
107 sharedData->flags = 0;
108 osUnmapTLB(i);
109 }
110 }
111 }
112 }
113 }
114}
struct EffectSharedData * shared
Definition effects.h:2606
@ FX_INSTANCE_FLAG_BATTLE
Definition enums.h:3515
@ FX_INSTANCE_FLAG_ENABLED
Definition enums.h:3514
@ FX_INSTANCE_FLAG_HAS_UPDATED
Definition enums.h:3516
@ FX_SHARED_DATA_LOADED
Definition enums.h:3521
@ FX_SHARED_DATA_CAN_FREE
Definition enums.h:3522
@ CONTEXT_WORLD
Definition enums.h:3528
@ GLOBAL_OVERRIDES_800
Definition enums.h:4329
@ GLOBAL_OVERRIDES_400
Definition enums.h:4328
s32 general_heap_free(void *data)
Definition heap.c:18
void(* update)(EffectInstance *effectInst)
Definition effects.h:2663
s32 gOverrideFlags
Definition main_loop.c:11
GameStatus * gGameStatusPtr
Definition main_loop.c:32

Referenced by state_step_battle(), state_step_change_map(), state_step_enter_world(), state_step_game_over(), state_step_intro(), state_step_pause(), state_step_unpause(), and state_step_world().

◆ render_effects_scene()

void render_effects_scene ( void )

Definition at line 116 of file effects.c.

116 {
117 s32 i;
118
119 for (i = 0; i < ARRAY_COUNT(gEffectInstances); i++) {
120 EffectInstance* effectInstance = gEffectInstances[i];
121
122 if (effectInstance != NULL) {
123 if (effectInstance->flags & FX_INSTANCE_FLAG_ENABLED) {
124 if (effectInstance->flags & FX_INSTANCE_FLAG_HAS_UPDATED) {
126 if (effectInstance->flags & FX_INSTANCE_FLAG_BATTLE) {
127 effectInstance->shared->renderScene(effectInstance);
128 }
129 } else {
130 if (!(effectInstance->flags & FX_INSTANCE_FLAG_BATTLE)) {
131 effectInstance->shared->renderScene(effectInstance);
132 }
133 }
134 }
135 }
136 }
137 }
138}
void(* renderScene)(EffectInstance *effectInst)
Definition effects.h:2664

Referenced by render_frame().

◆ render_effects_UI()

void render_effects_UI ( void )

Definition at line 140 of file effects.c.

140 {
141 s32 cond = TRUE;
142 s32 i;
143
144 for (i = 0; i < ARRAY_COUNT(gEffectInstances); i++) {
145 EffectInstance* effectInstance = gEffectInstances[i];
146
147 if (effectInstance != NULL) {
148 if (effectInstance->flags & FX_INSTANCE_FLAG_ENABLED) {
149 if (effectInstance->flags & FX_INSTANCE_FLAG_HAS_UPDATED) {
150 void (*renderUI)(EffectInstance* effect);
151
152 if (gGameStatusPtr->context != CONTEXT_WORLD && !(effectInstance->flags & FX_INSTANCE_FLAG_BATTLE)) {
153 continue;
154 }
155
157 continue;
158 }
159
160 renderUI = effectInstance->shared->renderUI;
161 if (renderUI != stub_effect_delegate) {
162 if (cond) {
163 Camera* camera = &gCameras[gCurrentCameraID];
164
165 gDPPipeSync(gMainGfxPos++);
166 gSPViewport(gMainGfxPos++, &camera->vp);
167 gSPClearGeometryMode(gMainGfxPos++, G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG |
168 G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD |
169 G_SHADING_SMOOTH | G_CLIPPING | 0x40F9FA);
170 gSPSetGeometryMode(gMainGfxPos++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH);
171 gDPSetScissor(gMainGfxPos++, G_SC_NON_INTERLACE,
172 camera->viewportStartX,
173 camera->viewportStartY,
174 camera->viewportStartX + camera->viewportW,
175 camera->viewportStartY + camera->viewportH);
176 gSPClipRatio(gMainGfxPos++, FRUSTRATIO_2);
177
178 cond = FALSE;
179 if (!(camera->flags & CAMERA_FLAG_ORTHO)) {
180 gSPPerspNormalize(gMainGfxPos++, camera->perspNorm);
182 G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
183 }
184 }
185
186 renderUI(effectInstance);
187 }
188 }
189 }
190 }
191 }
192}
void stub_effect_delegate(EffectInstance *effect)
Used for unbound function points in effect structs.
Definition effects.c:30
@ CAMERA_FLAG_ORTHO
Definition enums.h:4723
s16 viewportStartX
s16 viewportStartY
void(* renderUI)(EffectInstance *effectInst)
Definition effects.h:2665
Camera gCameras[4]
Definition cam_main.c:17
Gfx * gMainGfxPos
Definition cam_main.c:15
s32 gCurrentCameraID
Definition cam_math.c:4
DisplayContext * gDisplayContext
Definition cam_main.c:16

Referenced by gfx_draw_frame().

◆ create_effect_instance()

EffectInstance * create_effect_instance ( EffectBlueprint * effectBp)

Definition at line 194 of file effects.c.

194 {
195 EffectInstance* newEffectInst;
196 EffectSharedData* sharedData;
197 s32 i;
198
199 // Search for an unused instance
200 for (i = 0; i < ARRAY_COUNT(gEffectInstances); i++) {
201 if (gEffectInstances[i] == NULL) {
202 break;
203 }
204 }
205
207
208 // Allocate space for the new instance
209 gEffectInstances[i] = newEffectInst = general_heap_malloc(sizeof(*newEffectInst));
210 ASSERT(newEffectInst != NULL);
211
212 sharedData = &gEffectSharedData[0];
213 newEffectInst->effectID = effectBp->effectID;
214 newEffectInst->flags = FX_INSTANCE_FLAG_ENABLED;
215
216 // Look for a loaded effect of the proper index
217 for (i = 0; i < ARRAY_COUNT(gEffectSharedData); i++) {
218 if ((sharedData->flags & FX_SHARED_DATA_LOADED) && (sharedData->effectIndex == effectBp->effectID)) {
219 break;
220 }
221 sharedData++;
222 }
223
225
226 // If this is the first new instance of the effect, initialize the function pointers
227 if (sharedData->instanceCounter == 0) {
228 sharedData->update = effectBp->update;
229 if (sharedData->update == NULL) {
230 sharedData->renderScene = stub_effect_delegate;
231 }
232
233 sharedData->renderScene = effectBp->renderScene;
234 if (sharedData->renderScene == NULL) {
235 sharedData->renderScene = stub_effect_delegate;
236 }
237
238 sharedData->renderUI = effectBp->renderUI;
239 if (sharedData->renderUI == NULL) {
240 sharedData->renderUI = stub_effect_delegate;
241 }
242 }
243
244 sharedData->instanceCounter++;
245 newEffectInst->shared = sharedData;
246
247 if (effectBp->init != NULL) {
248 effectBp->init(newEffectInst);
249 }
250
252 newEffectInst->flags |= FX_INSTANCE_FLAG_BATTLE;
253 }
254 return newEffectInst;
255}
#define general_heap_malloc
#define ASSERT(condition)
void(* renderUI)(EffectInstance *effectInst)
Definition effects.h:2655
void(* init)(EffectInstance *effectInst)
Definition effects.h:2652
void(* update)(EffectInstance *effectInst)
Definition effects.h:2653
void(* renderScene)(EffectInstance *effectInst)
Definition effects.h:2654

◆ remove_effect()

void remove_effect ( EffectInstance * effectInstance)

Definition at line 257 of file effects.c.

257 {
258 s32 i;
259
260 for (i = 0; i < ARRAY_COUNT(gEffectInstances); i++) {
261 if (gEffectInstances[i] == effectInstance) {
262 break;
263 }
264 }
265
267
268 if (effectInstance->data.any == NULL) {
269 general_heap_free(effectInstance);
270 gEffectInstances[i] = NULL;
271 } else {
272 general_heap_free(effectInstance->data.any);
273 general_heap_free(effectInstance);
274 gEffectInstances[i] = NULL;
275 }
276}

◆ remove_all_effects()

void remove_all_effects ( void )

Definition at line 278 of file effects.c.

278 {
279 s32 i;
280
281 for (i = 0; i < ARRAY_COUNT(gEffectInstances); i++) {
282 EffectInstance* effect = gEffectInstances[i];
283
284 if (effect != NULL && effect->flags & FX_INSTANCE_FLAG_BATTLE) {
285 if (effect->data.any != NULL) {
286 general_heap_free(effect->data.any);
287 }
288 general_heap_free(effect);
289 gEffectInstances[i] = NULL;
290 }
291 }
292}

Referenced by btl_state_update_end_battle(), and btl_state_update_end_demo_battle().

◆ load_effect()

s32 load_effect ( s32 effectIndex)

Definition at line 294 of file effects.c.

294 {
295 EffectTableEntry* effectEntry = &gEffectTable[effectIndex];
296 EffectSharedData* sharedData;
297 s32 i;
298
299 // Look for a loaded effect matching the desired index
300 for (i = 0, sharedData = &gEffectSharedData[0]; i < ARRAY_COUNT(gEffectSharedData); i++) {
301 if (sharedData->flags & FX_SHARED_DATA_LOADED && sharedData->effectIndex == effectIndex) {
302 break;
303 }
304 sharedData++;
305 }
306
307 // If an effect was found within the table, initialize it and return
309 sharedData->effectIndex = effectIndex;
310 sharedData->instanceCounter = 0;
311 sharedData->flags = FX_SHARED_DATA_LOADED;
312 return 1;
313 }
314
315 // If a loaded effect wasn't found, look for the first empty space
316 for (i = 0, sharedData = &gEffectSharedData[0]; i < ARRAY_COUNT(gEffectSharedData); i++) {
317 if (!(sharedData->flags & FX_SHARED_DATA_LOADED)) {
318 break;
319 }
320 sharedData++;
321 }
322
323 // If no empty space was found, panic
325
326 // Map space for the effect
327 osMapTLB(i, OS_PM_4K, effectEntry->dmaDest, (s32)(gEffectDataBuffer[i]) & 0xFFFFFF, -1, -1);
328
329 // Copy the effect into the newly mapped space
330 dma_copy(effectEntry->dmaStart, effectEntry->dmaEnd, effectEntry->dmaDest);
331
332 // If there's graphics data for the effect, allocate space and copy into the new space
333 if (effectEntry->graphicsDmaStart != NULL) {
334 void* graphics = general_heap_malloc(effectEntry->graphicsDmaEnd - effectEntry->graphicsDmaStart);
335 sharedData->graphics = graphics;
336 ASSERT(graphics != NULL);
337 dma_copy(effectEntry->graphicsDmaStart, effectEntry->graphicsDmaEnd, sharedData->graphics);
338 }
339
340 // Initialize the newly loaded effect data
341 sharedData->effectIndex = effectIndex;
342 sharedData->instanceCounter = 0;
343 sharedData->flags = FX_SHARED_DATA_LOADED;
344 return 1;
345}
TlbMappablePage gEffectDataBuffer
void * graphicsDmaStart
Definition effects.h:2674
void * graphicsDmaEnd
Definition effects.h:2675
u32 dma_copy(Addr romStart, Addr romEnd, void *vramDest)
Definition 43F0.c:443

Variable Documentation

◆ gEffectSharedData

BSS EffectSharedData gEffectSharedData[15]

Definition at line 10 of file effects.c.

Referenced by clear_effect_data(), create_effect_instance(), load_effect(), and update_effects().

◆ gEffectInstances

◆ gEffectDataBuffer

TlbMappablePage gEffectDataBuffer
extern

Referenced by load_effect().

◆ gEffectGlobals

BSS u8 gEffectGlobals
extern

Referenced by clear_effect_data().

◆ D_8007FEB8

s32 D_8007FEB8[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 5, 3, 4, 13, 60, 0, 512, 0, 0, 3, 0 }

Definition at line 27 of file effects.c.

27{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 5, 3, 4, 13, 60, 0, 512, 0, 0, 3, 0 };