Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
sprite_shading.c
Go to the documentation of this file.
1#include "common.h"
2#include "sprite.h"
3#include "nu/nusys.h"
4
7
13
14void appendGfx_shading_palette(Matrix4f mtx, s32 uls, s32 ult, s32 lrs, s32 lrt, s32 alpha,
15 f32 shadowX, f32 shadowY, f32 shadowZ,
16 s32 shadowR, s32 shadowG, s32 shadowB,
17 s32 highlightR, s32 highlightG, s32 highlightB,
18 s32 ambientPower, s32 otherModeLBits);
19
38
48
49void sprite_shading_set_light_source(u32 idx, s8 flags, f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, f32 falloff, s8 arg9) {
50 SpriteShadingLightSource* lightSource;
51
53 lightSource = &gSpriteShadingProfile->sources[idx];
54 lightSource->flags = flags;
55 lightSource->pos.x = x;
56 lightSource->pos.y = y;
57 lightSource->pos.z = z;
58 lightSource->rgb.r = r;
59 lightSource->rgb.g = g;
60 lightSource->rgb.b = b;
61 lightSource->falloff = falloff;
62 lightSource->unk_14 = arg9;
63 }
64}
65
66void create_shading_palette(Matrix4f mtx, s32 uls, s32 ult, s32 lrs, s32 lrt, s32 alpha, s32 otherModeLBits) {
68 SpriteShadingLightSource* lightSource;
69 f32 shadowDirX, shadowDirY, shadowDirZ;
70 f32 posX, posY, posZ;
71 f32 facingDir;
72 f32 Mxz, Myz, Mzz;
73 f32 shadowColorR, shadowColorG, shadowColorB;
74 f32 commonColorR, commonColorG, commonColorB;
75 f32 backColorR, backColorG, backColorB;
76 f32 frontColorR, frontColorG, frontColorB;
77 f32 shadowIntensity;
78 f32 lightIntensity;
79 f32 intensityScale;
80 f32 temp_f10;
81 f32 temp_f16;
82 f32 distSq;
83 f32 dx, dy, dz;
84 f32 dist;
85 f32 invDist;
86 f32 qx, qy, qz;
87 f32 wx, wy, wz;
88 f32 ex, ey, ez;
89 f32 Pxz, Pzz;
90 s32 i;
91
92 shadowDirX = 0.0f;
93 shadowDirY = 0.0f;
94 shadowDirZ = 0.0f;
95
96 posX = mtx[3][0];
97 posY = mtx[3][1];
98 posZ = mtx[3][2];
99
100 Mxz = mtx[0][2];
101 Myz = mtx[1][2];
102 Mzz = mtx[2][2];
103
104 commonColorR = 0.0f;
105 commonColorG = 0.0f;
106 commonColorB = 0.0f;
107
108 backColorR = 0.0f;
109 backColorG = 0.0f;
110 backColorB = 0.0f;
111
112 frontColorR = 0.0f;
113 frontColorG = 0.0f;
114 frontColorB = 0.0f;
115
116 shadowColorR = gSpriteShadingProfile->ambientColor.r;
117 shadowColorG = gSpriteShadingProfile->ambientColor.g;
118 shadowColorB = gSpriteShadingProfile->ambientColor.b;
119
120 Pxz = camera->mtxPerspective[0][2];
121 Pzz = camera->mtxPerspective[2][2];
122
123 if ((-Mxz * Pxz + Mzz * Pzz) < 0.0f) {
124 facingDir = 1.0f;
125 } else {
126 facingDir = -1.0f;
127 }
128
129 for (i = 0; i < ARRAY_COUNT(gSpriteShadingProfile->sources); i++) {
130 lightSource = &gSpriteShadingProfile->sources[i];
131 if (lightSource->flags & LIGHT_SOURCE_ENABLED) {
132 dx = posX - lightSource->pos.x;
133 dy = posY - lightSource->pos.y;
134 dz = posZ - lightSource->pos.z;
135
136 distSq = SQ(dx) + SQ(dy) + SQ(dz);
137
138 if (distSq != 0.0f) {
139 dist = sqrtf(distSq);
140 invDist = 1.0f / dist;
141 } else {
142 dist = 0.0f;
143 invDist = 0.0f;
144 }
145
146 // normalize dx/dy/dz
147 // they now form a normal vector pointing from light source to sprite
148 dx *= invDist;
149 dy *= invDist;
150 dz *= invDist;
151
152 // apply falloff from light source
153 if (lightSource->flags & LIGHT_SOURCE_LINEAR_FALLOFF) {
154 if ((dist == 0.0f) && (lightSource->falloff == 0.0f)) {
155 intensityScale = 1.0f;
156 } else {
157 intensityScale = 1.0f / (dist * lightSource->falloff);
158 dx *= intensityScale;
159 dy *= intensityScale;
160 dz *= intensityScale;
161 }
162 } else if (lightSource->flags & LIGHT_SOURCE_QUADRATIC_FALLOFF) {
163 if ((distSq == 0.0f) && (lightSource->falloff == 0.0f)) {
164 intensityScale = 1.0f;
165 } else {
166 intensityScale = 1.0f / (distSq * lightSource->falloff);
167 dx *= intensityScale;
168 dy *= intensityScale;
169 dz *= intensityScale;
170 }
171 } else {
172 intensityScale = 1.0f;
173 }
174
175 if (intensityScale > 1.0f) {
176 intensityScale = 1.0f;
177 }
178
179 shadowDirX += dx;
180 shadowDirY += dy;
181 shadowDirZ += dz;
182
183 if (facingDir < 0.0f) {
184 ex = Mxz;
185 ey = Myz;
186 ez = -Mzz;
187 } else {
188 ex = -Mxz;
189 ey = Myz;
190 ez = Mzz;
191 }
192 temp_f10 = ex * dx + ey * dy + ez * dz;
193
194 if (facingDir < 0.0f) {
195 wx = Mzz;
196 wy = Myz;
197 wz = Mxz;
198 } else {
199 wx = -Mzz;
200 wy = Myz;
201 wz = -Mxz;
202 }
203 temp_f16 = wx * dx + wy * dy + wz * dz;
204
205 shadowIntensity = intensityScale * fabsf(temp_f10);
206 lightIntensity = intensityScale * fabsf(temp_f16);
207 if (temp_f10 > 0.0f) {
208 commonColorR += lightSource->rgb.r * shadowIntensity;
209 commonColorG += lightSource->rgb.g * shadowIntensity;
210 commonColorB += lightSource->rgb.b * shadowIntensity;
211 if (temp_f16 > 0.0f) {
212 backColorR += lightSource->rgb.r * lightIntensity;
213 backColorG += lightSource->rgb.g * lightIntensity;
214 backColorB += lightSource->rgb.b * lightIntensity;
215 } else {
216 frontColorR += lightSource->rgb.r * lightIntensity;
217 frontColorG += lightSource->rgb.g * lightIntensity;
218 frontColorB += lightSource->rgb.b * lightIntensity;
219 }
220 } else {
221 shadowColorR += lightSource->rgb.r * shadowIntensity;
222 shadowColorG += lightSource->rgb.g * shadowIntensity;
223 shadowColorB += lightSource->rgb.b * shadowIntensity;
224 if (temp_f16 > 0.0f) {
225 backColorR += lightSource->rgb.r * lightIntensity;
226 backColorG += lightSource->rgb.g * lightIntensity;
227 backColorB += lightSource->rgb.b * lightIntensity;
228 } else {
229 frontColorR += lightSource->rgb.r * lightIntensity;
230 frontColorG += lightSource->rgb.g * lightIntensity;
231 frontColorB += lightSource->rgb.b * lightIntensity;
232 }
233 }
234 }
235 }
236
237 if (facingDir < 0.0f) {
238 qx = Mzz;
239 qy = Myz;
240 qz = Mxz;
241 } else {
242 qx = -Mzz;
243 qy = Myz;
244 qz = -Mxz;
245 }
246
247 if (qx * shadowDirX + qy * shadowDirY + qz * shadowDirZ > 0.0f) {
249 mtx,
250 uls, ult, lrs, lrt,
251 alpha,
252 shadowDirX, shadowDirY, shadowDirZ,
253 shadowColorR, shadowColorG, shadowColorB,
254 gSpriteShadingProfile->ambientColor.r + commonColorR + backColorR,
255 gSpriteShadingProfile->ambientColor.g + commonColorG + backColorG,
256 gSpriteShadingProfile->ambientColor.b + commonColorB + backColorB,
258 otherModeLBits
259 );
260 } else {
262 mtx,
263 uls, ult, lrs, lrt,
264 alpha,
265 shadowDirX, shadowDirY, shadowDirZ,
266 shadowColorR, shadowColorG, shadowColorB,
267 gSpriteShadingProfile->ambientColor.r + commonColorR + frontColorR,
268 gSpriteShadingProfile->ambientColor.g + commonColorG + frontColorG,
269 gSpriteShadingProfile->ambientColor.b + commonColorB + frontColorB,
271 otherModeLBits
272 );
273 }
274}
275
277 Matrix4f mtx,
278 s32 uls, s32 ult, s32 lrs, s32 lrt,
279 s32 alpha,
280 f32 shadowX, f32 shadowY, f32 shadowZ,
281 s32 shadowR, s32 shadowG, s32 shadowB,
282 s32 highlightR, s32 highlightG, s32 highlightB,
283 s32 ambientPower, s32 renderMode)
284{
285 Camera* camera = &gCameras[gCurrentCameraID];
286 f32 mtx01;
287 f32 mtx11;
288 f32 mtx21;
289 f32 offsetX;
290 f32 offsetY;
291 f32 shadowMag;
292 f32 var_f12_2;
293 f32 shadowXZ;
294 f32 facingDir;
295 f32 ex, ey, ez;
296 f32 pm02, pm12, pm22;
297
298 shadowMag = SQ(shadowX) + SQ(shadowY) + SQ(shadowZ);
299
300 if (shadowMag < 1.0) {
301 ambientPower *= shadowMag;
302 }
303 if (shadowMag != 0.0f) {
304 shadowMag = 1.0f / sqrtf(shadowMag);
305 }
306 shadowX *= shadowMag;
307 shadowY *= shadowMag;
308 shadowZ *= shadowMag;
309
310 if (((-mtx[0][2] * camera->mtxPerspective[0][2]) + (mtx[2][2] * camera->mtxPerspective[2][2])) < 0.0f) {
311 facingDir = 1.0f;
312 } else {
313 facingDir = -1.0f;
314 }
315
316 if (facingDir < 0.0f) {
317 ex = mtx[0][2];
318 ey = mtx[1][2];
319 ez = -mtx[2][2];
320 } else {
321 ex = -mtx[0][2];
322 ey = mtx[1][2];
323 ez = mtx[2][2];
324 }
325
326 pm02 = camera->mtxPerspective[0][2];
327 pm12 = camera->mtxPerspective[1][2];
328 pm22 = camera->mtxPerspective[2][2];
329
330 offsetX = ambientPower * ((shadowX * -pm22) + (shadowZ * pm02));
331
332 shadowXZ = SQ(shadowX) + SQ(shadowZ);
333 if (shadowXZ != 0.0f) {
334 shadowXZ = sqrtf(shadowXZ);
335 }
336 mtx01 = mtx[0][1];
337 mtx11 = mtx[1][1];
338 mtx21 = mtx[2][1];
339 var_f12_2 = SQ(mtx01) + SQ(mtx21);
340 if (var_f12_2 != 0.0f) {
341 var_f12_2 = sqrtf(var_f12_2);
342 }
343 offsetY = -((shadowXZ * var_f12_2) + (shadowY * mtx11)) * ambientPower;
344
345 if (shadowR > 255) {
346 shadowR = 255;
347 }
348 if (shadowG > 255) {
349 shadowG = 255;
350 }
351 if (shadowB > 255) {
352 shadowB = 255;
353 }
354 if (highlightR > 255) {
355 highlightR = 255;
356 }
357 if (highlightG > 255) {
358 highlightG = 255;
359 }
360 if (highlightB > 255) {
361 highlightB = 255;
362 }
363
364 gDPSetPrimColor(gMainGfxPos++, 0, 0, shadowR, shadowG, shadowB, alpha);
365 gDPSetCombineMode(gMainGfxPos++, PM_CC_53, PM_CC_54);
366 gDPSetColorImage(gMainGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH, SpriteShadingPalette);
367 gDPSetScissor(gMainGfxPos++, G_SC_NON_INTERLACE, 0, 0, 16, 1);
368
369 gSPSetOtherMode(gMainGfxPos++, G_SETOTHERMODE_H, 4, 18,
370 G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE |
371 G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE);
372
373 gDPSetRenderMode(gMainGfxPos++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
374
375 gDPSetPrimColor(gMainGfxPos++, 0, 0, shadowR, shadowG, shadowB, alpha);
376 gDPSetEnvColor(gMainGfxPos++, highlightR, highlightG, highlightB, 0);
377 gDPSetCombineMode(gMainGfxPos++, PM_CC_55, PM_CC_55);
378 gSPTextureRectangle(gMainGfxPos++, 0, 0, 16 << 2, 1 << 2, 2, 0, 0, 4 << 10, 1 << 10);
379 gDPPipeSync(gMainGfxPos++);
380 gDPSetColorImage(gMainGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH, osVirtualToPhysical(nuGfxCfb_ptr));
381
382 gDPSetScissor(
383 gMainGfxPos++, 0,
384 camera->viewportStartX,
385 camera->viewportStartY,
386 camera->viewportStartX + camera->viewportW,
387 camera->viewportStartY + camera->viewportH
388 );
389
390 gDPLoadTLUT_pal16(gMainGfxPos++, 1, SpriteShadingPalette);
391
392 gSPSetOtherMode(gMainGfxPos++, G_SETOTHERMODE_H, 4, 18,
393 G_AD_DISABLE | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_RGBA16 | G_TL_TILE |
394 G_TD_CLAMP | G_TP_PERSP | G_CYC_2CYCLE | G_PM_NPRIMITIVE);
395
396 gDPSetRenderMode(gMainGfxPos++, G_RM_PASS, renderMode);
397 gDPSetEnvColor(gMainGfxPos++, 100, 100, 100, 255);
398
399 if (alpha == 255) {
400 gDPSetCombineMode(gMainGfxPos++, PM_CC_50, PM_CC_52);
401 } else {
402 gDPSetCombineMode(gMainGfxPos++, PM_CC_51, PM_CC_52);
403 }
404
405 gDPSetTileSize(
406 gMainGfxPos++,
407 0,
408 ((uls + 0x100) << 2) + (s32)(offsetX * facingDir),
409 ((ult + 0x100) << 2) + (s32)offsetY,
410 ((lrs + 0x100 - 1) << 2) + (s32)(offsetX * facingDir),
411 ((lrt + 0x100 - 1) << 2) + (s32)offsetY
412 );
413}
414
415void func_801491E4(Matrix4f mtx, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 alpha) {
416 gDPSetPrimColor(gMainGfxPos++, 0, 0, 0, 0, 0, alpha);
417
418 if (alpha == 255) {
419 gDPSetCombineMode(gMainGfxPos++, PM_CC_WINDOW_5, G_CC_PASS2);
420 } else {
421 gDPSetCombineMode(gMainGfxPos++, PM_CC_02, G_CC_PASS2);
422 }
423}
u16 * nuGfxCfb_ptr
Definition cam_main.c:14
SpriteShadingLightSource sources[7]
f32 Matrix4f[4][4]
#define PAL_BIN
f32 falloff
Definition demo_api.c:18
s8 flags
Definition demo_api.c:15
#define sqrtf
@ LIGHT_SOURCE_DISABLED
Definition enums.h:2419
@ LIGHT_SOURCE_ENABLED
Definition enums.h:2420
@ LIGHT_SOURCE_QUADRATIC_FALLOFF
Definition enums.h:2422
@ LIGHT_SOURCE_LINEAR_FALLOFF
Definition enums.h:2421
@ CONTEXT_WORLD
Definition enums.h:3529
f32 fabsf(f32 f)
#define PM_CC_WINDOW_5
Definition macros.h:441
#define PM_CC_53
Definition macros.h:491
#define SCREEN_WIDTH
Definition macros.h:105
#define BSS
Definition macros.h:7
#define ARRAY_COUNT(arr)
Definition macros.h:40
#define PM_CC_52
Definition macros.h:489
#define PM_CC_50
Definition macros.h:487
#define PM_CC_51
Definition macros.h:488
#define PM_CC_55
Definition macros.h:493
#define SQ(x)
Definition macros.h:166
#define PM_CC_54
Definition macros.h:492
#define PM_CC_02
Definition macros.h:277
BSS SpriteShadingProfile wSpriteShadingProfileAux
BSS SpriteShadingProfile wSpriteShadingProfile
void clear_sprite_shading_data(void)
BSS SpriteShadingProfile bSpriteShadingProfile
SpriteShadingProfile * gSpriteShadingProfile
SpriteShadingProfile * gAuxSpriteShadingProfile
void appendGfx_shading_palette(Matrix4f mtx, s32 uls, s32 ult, s32 lrs, s32 lrt, s32 alpha, f32 shadowX, f32 shadowY, f32 shadowZ, s32 shadowR, s32 shadowG, s32 shadowB, s32 highlightR, s32 highlightG, s32 highlightB, s32 ambientPower, s32 otherModeLBits)
BSS PAL_BIN SpriteShadingPalette[16]
void sprite_shading_set_light_source(u32 idx, s8 flags, f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, f32 falloff, s8 arg9)
void func_801491E4(Matrix4f mtx, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 alpha)
BSS SpriteShadingProfile bSpriteShadingProfileAux
void create_shading_palette(Matrix4f mtx, s32 uls, s32 ult, s32 lrs, s32 lrt, s32 alpha, s32 otherModeLBits)
void init_sprite_shading_data(void)
s16 viewportStartX
s16 viewportStartY
Matrix4f mtxPerspective
GameStatus * gGameStatusPtr
Definition main_loop.c:32
Camera gCameras[4]
Definition cam_main.c:17
Gfx * gMainGfxPos
Definition cam_main.c:15
s32 gCurrentCameraID
Definition cam_math.c:4