Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
cam_main.c
Go to the documentation of this file.
1#include "common.h"
2#include "camera.h"
3#include "nu/nusys.h"
4#include "hud_element.h"
5#include "dx/profiling.h"
6#include "dx/debug_menu.h"
7
8void render_models(void);
9void execute_render_tasks(void);
10void render_item_entities(void);
11
18
19void update_cameras(void) {
20 s32 sx, sy, sz;
21 s32 camID;
22
23 for (camID = 0; camID < ARRAY_COUNT(gCameras); camID++) {
24 Camera* cam = &gCameras[camID];
25
26 if (cam->flags == 0 || cam->flags & CAMERA_FLAG_DISABLED) {
27 continue;
28 }
29
30 gCurrentCamID = camID;
31
32 switch (cam->updateMode) {
33 default:
36 break;
39 break;
42 break;
45 break;
48 break;
51 break;
54 break;
55 }
56
57 guLookAtReflectF(cam->mtxViewPlayer, &gDisplayContext->lookAt, cam->lookAt_eye.x, cam->lookAt_eye.y, cam->lookAt_eye.z, cam->lookAt_obj.x, cam->lookAt_obj.y, cam->lookAt_obj.z, 0, 1.0f, 0);
58
59 if (!(cam->flags & CAMERA_FLAG_ORTHO)) {
60 if (cam->flags & CAMERA_FLAG_LEAD_PLAYER) {
62 }
63
64 guPerspectiveF(cam->mtxPerspective, &cam->perspNorm, cam->vfov, (f32) cam->viewportW / (f32) cam->viewportH, (f32) cam->nearClip, (f32) cam->farClip, 1.0f);
65
66 if (cam->flags & CAMERA_FLAG_SHAKING) {
68 }
69
70 if (cam->flags & CAMERA_FLAG_LEAD_PLAYER) {
72 }
73
75 } else {
76 f32 w = cam->viewportW;
77 f32 h = cam->viewportH;
78
79 guOrthoF(cam->mtxPerspective, -w * 0.5, w * 0.5, -h * 0.5, h * 0.5, -1000.0f, 1000.0f, 1.0f);
80 }
81
82 get_screen_coords(CAM_DEFAULT, cam->targetPos.x, cam->targetPos.y, cam->targetPos.z, &sx, &sy, &sz);
83 cam->targetScreenCoords.x = sx;
84 cam->targetScreenCoords.y = sy;
85 cam->targetScreenCoords.z = sz;
86 }
87
89}
90
91void render_frame(s32 isSecondPass) {
92 s32 firstCamID;
93 s32 lastCamID;
94 s32 camID;
95
96 if (!isSecondPass) {
99 }
100
101 // first pass: loop uses camIDs from CAM_DEFAULT to CAM_HUD - 1
102 // second pass: loop only uses CAM_HUD
103 if (isSecondPass) {
104 firstCamID = CAM_HUD;
105 lastCamID = ARRAY_COUNT(gCameras);
106 } else {
107 firstCamID = CAM_DEFAULT;
108 lastCamID = CAM_HUD;
109 }
110
111 for (camID = firstCamID; camID < lastCamID; camID++) {
112 Camera* camera = &gCameras[camID];
113
114 if (camera->flags == 0 || (camera->flags & (CAMERA_FLAG_NO_DRAW | CAMERA_FLAG_DISABLED))) {
115 continue;
116 }
117
118 gCurrentCamID = camID;
119
120 if (camera->fpDoPreRender != NULL) {
121 camera->fpDoPreRender(camera);
122 } else {
123 s32 ulx;
124 s32 uly;
125 s32 lrx;
126 s32 lry;
127
128 gSPViewport(gMainGfxPos++, &camera->vp);
129 gSPClearGeometryMode(gMainGfxPos++, G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN |
130 G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH);
131 gSPTexture(gMainGfxPos++, 0, 0, 0, G_TX_RENDERTILE, G_OFF);
132 gDPSetCycleType(gMainGfxPos++, G_CYC_1CYCLE);
133 gDPPipelineMode(gMainGfxPos++, G_PM_NPRIMITIVE);
134
135 ulx = camera->viewportStartX;
136 uly = camera->viewportStartY;
137 lrx = ulx + camera->viewportW;
138 lry = uly + camera->viewportH;
139
140 if (ulx < 0) {
141 ulx = 0;
142 }
143 if (uly < 0) {
144 uly = 0;
145 }
146 if (lrx < 1) {
147 lrx = 1;
148 }
149 if (lry < 1) {
150 lry = 1;
151 }
152
153 if (ulx > SCREEN_WIDTH - 1) {
154 ulx = SCREEN_WIDTH - 1;
155 }
156 if (uly > SCREEN_HEIGHT - 1) {
157 uly = SCREEN_HEIGHT - 1;
158 }
159 if (lrx > SCREEN_WIDTH) {
160 lrx = SCREEN_WIDTH;
161 }
162 if (lry > SCREEN_HEIGHT) {
163 lry = SCREEN_HEIGHT;
164 }
165
166 gDPSetScissor(gMainGfxPos++, G_SC_NON_INTERLACE, ulx, uly, lrx, lry);
167 gDPSetTextureLOD(gMainGfxPos++, G_TL_TILE);
168 gDPSetTextureLUT(gMainGfxPos++, G_TT_NONE);
169 gDPSetTextureDetail(gMainGfxPos++, G_TD_CLAMP);
170 gDPSetTexturePersp(gMainGfxPos++, G_TP_PERSP);
171 gDPSetTextureFilter(gMainGfxPos++, G_TF_BILERP);
172 gDPSetTextureConvert(gMainGfxPos++, G_TC_FILT);
173 gDPSetCombineMode(gMainGfxPos++, G_CC_SHADE, G_CC_SHADE);
174 gDPSetCombineKey(gMainGfxPos++, G_CK_NONE);
175 gDPSetAlphaCompare(gMainGfxPos++, G_AC_NONE);
176 gDPSetRenderMode(gMainGfxPos++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
177 gDPSetColorDither(gMainGfxPos++, G_CD_DISABLE);
178 gSPClipRatio(gMainGfxPos++, FRUSTRATIO_2);
179 gDPSetColorImage(gMainGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH,
180 osVirtualToPhysical(nuGfxCfb_ptr));
181 gDPPipeSync(gMainGfxPos++);
182
183 if (!(camera->flags & CAMERA_FLAG_ORTHO)) {
184 gSPPerspNormalize(gMainGfxPos++, camera->perspNorm);
185 }
186
188 gSPMatrix(gMainGfxPos++, &gDisplayContext->camPerspMatrix[gCurrentCamID], G_MTX_NOPUSH | G_MTX_LOAD |
189 G_MTX_PROJECTION);
190 }
191
193 guRotate(camera->mtxBillboard, -camera->curBoomYaw, 0.0f, 1.0f, 0.0f);
194
195 camera->vpAlt.vp.vtrans[0] = camera->vp.vp.vtrans[0] + gGameStatusPtr->altViewportOffset.x;
196 camera->vpAlt.vp.vtrans[1] = camera->vp.vp.vtrans[1] + gGameStatusPtr->altViewportOffset.y;
197
198 if (!(camera->flags & CAMERA_FLAG_ORTHO)) {
199 if (gCurrentCamID != CAM_HUD) {
200 if (!(camera->flags & CAMERA_FLAG_RENDER_ENTITIES)) {
204 }
205 if (!(camera->flags & CAMERA_FLAG_RENDER_MODELS)) {
207 #if DX_DEBUG_MENU
208 if (!dx_debug_should_hide_models()) {
210 }
211 #else
213 #endif
215 }
219 render_npcs();
226 #if DX_DEBUG_MENU
227 dx_debug_draw_collision();
228 #endif
231 } else {
232 guOrthoF(camera->mtxPerspective, 0.0f, SCREEN_WIDTH, -SCREEN_HEIGHT, 0.0f, -1000.0f, 1000.0f, 1.0f);
234 gSPMatrix(gMainGfxPos++, &gDisplayContext->camPerspMatrix[gCurrentCamID], G_MTX_NOPUSH |
235 G_MTX_LOAD | G_MTX_PROJECTION);
238 }
239 } else {
242 }
243
244 if (camera->fpDoPostRender != NULL) {
245 camera->fpDoPostRender(camera);
246 }
247
248 gDPPipeSync(gMainGfxPos++);
249 gDPSetColorImage(gMainGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH,
250 osVirtualToPhysical(nuGfxCfb_ptr));
251 gDPPipeSync(gMainGfxPos++);
252 }
253}
254
255void create_cameras(void) {
256 CameraInitData camData;
257 CameraInitData* camDataPtr = &camData;
258 s32 i;
259
260 CamLengthScale = 1.0f;
261
262 for (i = 0; i < ARRAY_COUNT(gCameras); i++) {
263 gCameras[i].flags = 0;
264 }
265
266 camDataPtr->flags = CAMERA_FLAG_DISABLED;
267 camDataPtr->updateMode = CAM_UPDATE_MINIMAL;
268 camDataPtr->viewWidth = 160;
269 camDataPtr->viewHeight = 120;
270 camDataPtr->viewStartX = 0;
271 camDataPtr->viewStartY = 0;
272 camDataPtr->nearClip = 8;
273 camDataPtr->farClip = 16384;
274 camDataPtr->vfov = 50;
275 initialize_next_camera(camDataPtr);
276
277 camDataPtr->flags = CAMERA_FLAG_DISABLED;
278 camDataPtr->updateMode = CAM_UPDATE_MINIMAL;
279 camDataPtr->viewWidth = 160;
280 camDataPtr->viewHeight = 120;
281 camDataPtr->viewStartX = 160;
282 camDataPtr->viewStartY = 0;
283 camDataPtr->nearClip = 8;
284 camDataPtr->farClip = 16384;
285 camDataPtr->vfov = 50;
286 initialize_next_camera(camDataPtr);
287
288 camDataPtr->flags = CAMERA_FLAG_DISABLED;
289 camDataPtr->updateMode = CAM_UPDATE_MINIMAL;
290 camDataPtr->viewWidth = 160;
291 camDataPtr->viewHeight = 120;
292 camDataPtr->viewStartX = 0;
293 camDataPtr->viewStartY = 120;
294 camDataPtr->nearClip = 8;
295 camDataPtr->farClip = 16384;
296 camDataPtr->vfov = 50;
297 initialize_next_camera(camDataPtr);
298
299 camDataPtr->flags = CAMERA_FLAG_DISABLED;
300 camDataPtr->updateMode = CAM_UPDATE_MINIMAL;
301 camDataPtr->viewWidth = 160;
302 camDataPtr->viewHeight = 120;
303 camDataPtr->viewStartX = 160;
304 camDataPtr->viewStartY = 120;
305 camDataPtr->nearClip = 8;
306 camDataPtr->farClip = 16384;
307 camDataPtr->vfov = 50;
308 initialize_next_camera(camDataPtr);
309}
310
312 Camera* camera;
313 s32 camID;
314
315 for (camID = 0; camID < ARRAY_COUNT(gCameras); camID++) {
316 camera = &gCameras[camID];
317
318 if (camera->flags == 0) {
319 break;
320 }
321 }
322
323 ASSERT(camID < ARRAY_COUNT(gCameras));
324
326 camera->moveFlags = 0;
327 camera->lookAt_eye.x = 0;
328 camera->lookAt_eye.y = 0;
329 camera->lookAt_eye.z = 0;
330 camera->lookAt_obj.x = 0;
331 camera->lookAt_obj.y = 0;
332 camera->lookAt_obj.z = -100.0f;
333 camera->curYaw = 0.0f;
334 camera->curBoomLength = 0;
335 camera->targetOffsetY = 0;
336 camera->curBoomYaw = 0.0f;
337 camera->targetBoomYaw = 0.0f;
338 camera->needsInit = TRUE;
339 camera->updateMode = initData->updateMode;
340 camera->nearClip = initData->nearClip;
341 camera->farClip = initData->farClip;
342 camera->vfov = initData->vfov;
343 camera->params.world.zoomPercent = 100;
344 set_cam_viewport(camID, initData->viewStartX, initData->viewStartY, initData->viewWidth, initData->viewHeight);
345 camera->bgColor[0] = 0;
346 camera->bgColor[1] = 0;
347 camera->bgColor[2] = 0;
348 camera->lookAt_obj_target.x = 0;
349 camera->lookAt_obj_target.y = 0;
350 camera->lookAt_obj_target.z = 0;
351 camera->targetPos.x = 0;
352 camera->targetPos.y = 0;
353 camera->targetPos.z = 0;
354 camera->fpDoPreRender = NULL;
355 camera->fpDoPostRender = NULL;
356 camera->leadAmount = 0.0f;
357 camera->targetLeadAmount = 0.0f;
358 camera->leadInterpAlpha = 0.0f;
359 camera->accumulatedStickLead = 0.0f;
360 camera->increasingLeadInterp = FALSE;
361 camera->prevLeadPosX = 0.0f;
362 camera->prevLeadPosZ = 0.0f;
363 camera->leadConstrainDir = 0;
364 camera->needsInitialConstrainDir = TRUE;
365 camera->prevLeadSettings = NULL;
366 camera->panActive = FALSE;
367 camera->useOverrideSettings = FALSE;
368 camera->leadAmtScale = 0.2f;
369 camera->moveSpeed = 1.0f;
370 return camera;
371}
372
373void set_cam_viewport(s16 id, s16 x, s16 y, s16 width, s16 height) {
374 Camera* camera = &gCameras[id];
375
376 camera->viewportW = width;
377 camera->viewportH = height;
378 camera->viewportStartX = x;
379 camera->viewportStartY = y;
380
381 camera->vp.vp.vscale[0] = 2.0f * camera->viewportW;
382 camera->vp.vp.vscale[1] = 2.0f * camera->viewportH;
383 camera->vp.vp.vscale[2] = 0x1FF;
384 camera->vp.vp.vscale[3] = 0;
385
386 camera->vp.vp.vtrans[0] = 4 * (s16) ((u16) camera->viewportStartX + (camera->viewportW / 2));
387 camera->vp.vp.vtrans[1] = (s16) ((u16) camera->viewportStartY + (camera->viewportH / 2));
388 camera->vp.vp.vtrans[1] = 4 * camera->vp.vp.vtrans[1];
389 camera->vp.vp.vtrans[2] = 0x1FF;
390 camera->vp.vp.vtrans[3] = 0;
391
392 camera->vpAlt.vp.vscale[0] = 2.0f * camera->viewportW;
393 camera->vpAlt.vp.vscale[1] = 2.0f * camera->viewportH;
394 camera->vpAlt.vp.vscale[2] = 0x1FF;
395 camera->vpAlt.vp.vscale[3] = 0;
396
397 camera->vpAlt.vp.vtrans[0] = gGameStatusPtr->altViewportOffset.x + 4 * (s16) ((u16) camera->viewportStartX + (camera->viewportW / 2));
398 camera->vpAlt.vp.vtrans[1] = gGameStatusPtr->altViewportOffset.y + 4 * (s16) ((u16) camera->viewportStartY + (camera->viewportH / 2));
399 camera->vpAlt.vp.vtrans[2] = 0x200;
400 camera->vpAlt.vp.vtrans[3] = 0;
401}
402
403void get_cam_viewport(s32 camID, u16* x, u16* y, u16* width, u16* height) {
404 *width = gCameras[camID].viewportW;
405 *height = gCameras[camID].viewportH;
406 *x = gCameras[camID].viewportStartX;
407 *y = gCameras[camID].viewportStartY;
408}
409
410void get_screen_coords(s32 camID, f32 x, f32 y, f32 z, s32* screenX, s32* screenY, s32* screenZ) {
411 Camera* camera = &gCameras[camID];
412 f32 tW;
413 f32 tZ;
414 f32 tY;
415 f32 tX;
416
417 transform_point(camera->mtxPerspective, x, y, z, 1.0f, &tX, &tY, &tZ, &tW);
418
419 *screenZ = tZ + 5000.0f;
420 if (*screenZ < 0) {
421 *screenZ = 0;
422 } else if (*screenZ > 10000) {
423 *screenZ = 10000;
424 }
425
426 if (tW < 0.01 && tW > -0.01) {
427 *screenX = 0;
428 *screenY = 0;
429 *screenZ = 0;
430 } else {
431 *screenX = camera->viewportStartX + (s32) ((1.0f + tX / tW) * camera->viewportW * 0.5f);
432 *screenY = camera->viewportStartY + (s32) ((1.0f - tY / tW) * camera->viewportH * 0.5f);
433 }
434}
435
436b32 is_outside_cam_viewport_bounds(s32 camID, s32 x, s32 y) {
437 s32 startX = gCameras[camID].viewportStartX;
438 s32 startY = gCameras[camID].viewportStartY;
439 s32 endX = startX + gCameras[camID].viewportW;
440 s32 endY = startY + gCameras[camID].viewportH;
441
442 if (x < startX) {
443 return TRUE;
444 } else if (x > endX) {
445 return TRUE;
446 } else if (y < startY) {
447 return TRUE;
448 } else if (y > endY) {
449 return TRUE;
450 } else {
451 return FALSE;
452 }
453}
454
455void get_cam_viewport_bounds(s32 camID, s32* x, s32* y, s32* width, s32* height) {
456 *x = gCameras[camID].viewportStartX;
457 *y = gCameras[camID].viewportStartY;
458 *width = gCameras[camID].viewportStartX + gCameras[camID].viewportW;
459 *height = gCameras[camID].viewportStartY + gCameras[camID].viewportH;
460}
void create_cameras(void)
Definition cam_main.c:255
void get_cam_viewport(s32 camID, u16 *x, u16 *y, u16 *width, u16 *height)
Definition cam_main.c:403
b32 is_outside_cam_viewport_bounds(s32 camID, s32 x, s32 y)
Definition cam_main.c:436
void get_screen_coords(s32 camID, f32 x, f32 y, f32 z, s32 *screenX, s32 *screenY, s32 *screenZ)
Definition cam_main.c:410
void get_cam_viewport_bounds(s32 camID, s32 *x, s32 *y, s32 *width, s32 *height)
Definition cam_main.c:455
void execute_render_tasks(void)
Definition model.c:4572
void render_frame(s32 isSecondPass)
Definition cam_main.c:91
Camera gCameras[4]
Definition cam_main.c:17
Gfx * gMainGfxPos
Definition cam_main.c:15
void update_cameras(void)
Definition cam_main.c:19
f32 CamLengthScale
Definition cam_main.c:12
Camera * initialize_next_camera(CameraInitData *initData)
Definition cam_main.c:311
void render_models(void)
Definition model.c:2710
DisplayContext * gDisplayContext
Definition cam_main.c:16
void render_item_entities(void)
s16 gCurrentCamID
Definition cam_main.c:13
void set_cam_viewport(s16 id, s16 x, s16 y, s16 width, s16 height)
Definition cam_main.c:373
u16 * nuGfxCfb_ptr
Definition cam_main.c:14
void update_camera_zone_interp(Camera *camera)
void update_camera_no_interp(Camera *)
void update_camera_unused_radial(Camera *)
void create_camera_leadplayer_matrix(Camera *)
Definition cam_math.c:476
void update_camera_unused_confined(Camera *)
void update_camera_unused_leading(Camera *)
void update_camera_minimal(Camera *)
void update_camera_interp_pos(Camera *)
Vec2b altViewportOffset
Mtx matrixStack[0x200]
s32 b32
#define transform_point
#define guOrthoF
#define guMtxF2L
#define guMtxCatF
#define guPerspectiveF
#define ASSERT(condition)
@ CAMERA_FLAG_RENDER_MODELS
Definition enums.h:4727
@ CAMERA_FLAG_DISABLED
Definition enums.h:4721
@ CAMERA_FLAG_NO_DRAW
Definition enums.h:4725
@ CAMERA_FLAG_LEAD_PLAYER
Definition enums.h:4722
@ CAMERA_FLAG_RENDER_ENTITIES
Definition enums.h:4726
@ CAMERA_FLAG_INITIALIZED
Definition enums.h:4720
@ CAMERA_FLAG_ORTHO
Definition enums.h:4724
@ CAMERA_FLAG_SHAKING
Definition enums.h:4723
@ CAM_UPDATE_MINIMAL
Definition enums.h:4741
@ CAM_UPDATE_NO_INTERP
Definition enums.h:4761
@ CAM_UPDATE_UNUSED_RADIAL
Definition enums.h:4765
@ CAM_UPDATE_FROM_ZONE
Definition enums.h:4755
@ CAM_UPDATE_UNUSED_CONFINED
Definition enums.h:4770
@ CAM_UPDATE_INTERP_POS
Definition enums.h:4747
@ CAM_UPDATE_UNUSED_LEADING
Definition enums.h:4775
@ CAM_DEFAULT
Definition enums.h:1800
@ CAM_HUD
Definition enums.h:1803
void render_entities(void)
Definition entity.c:338
void render_effects_world(void)
Definition effects.c:112
void render_workers_world(void)
Definition worker.c:137
void render_player(void)
Definition 77480.c:1489
void mdl_update_transform_matrices(void)
Definition model.c:2589
void render_transformed_hud_elements(void)
void render_npcs(void)
Renders all NPCs.
Definition npc.c:933
#define GFX_PROFILER_SWITCH(complete, begin)
Definition profiling.h:212
@ PROFILER_TIME_SUB_GFX_HUD_ELEMENTS
Definition profiling.h:67
@ PROFILER_TIME_SUB_GFX_ENTITIES
Definition profiling.h:67
@ PROFILER_TIME_SUB_GFX_WORKERS
Definition profiling.h:67
@ PROFILER_TIME_SUB_GFX_PLAYER
Definition profiling.h:67
@ PROFILER_TIME_SUB_GFX_EFFECTS
Definition profiling.h:67
@ PROFILER_TIME_SUB_GFX_MODELS
Definition profiling.h:67
@ PROFILER_TIME_SUB_GFX_RENDER_TASKS
Definition profiling.h:67
@ PROFILER_TIME_SUB_GFX_NPCS
Definition profiling.h:67
#define GFX_PROFILER_COMPLETE(which)
Definition profiling.h:217
#define GFX_PROFILER_START(which)
Definition profiling.h:216
#define SCREEN_WIDTH
Definition macros.h:105
#define ARRAY_COUNT(arr)
Definition macros.h:40
#define SCREEN_HEIGHT
Definition macros.h:106
Vec3f lookAt_obj
s16 bgColor[3]
f32 targetOffsetY
Vec3f lookAt_obj_target
s32 increasingLeadInterp
f32 leadInterpAlpha
f32 prevLeadPosX
b32 needsInitialConstrainDir
Mtx * mtxBillboard
f32 targetBoomYaw
CameraControlSettings * prevLeadSettings
s32 leadConstrainDir
s16 viewportStartX
b16 useOverrideSettings
Vec3s targetScreenCoords
void(* fpDoPreRender)(struct Camera *)
union Camera::@17 params
Matrix4f mtxViewLeading
f32 targetLeadAmount
s16 viewportStartY
void(* fpDoPostRender)(struct Camera *)
Vec3f targetPos
Matrix4f mtxViewShaking
f32 curBoomLength
Matrix4f mtxPerspective
Vec3f lookAt_eye
Matrix4f mtxViewPlayer
f32 accumulatedStickLead
f32 leadAmtScale
f32 prevLeadPosZ
GameStatus * gGameStatusPtr
Definition main_loop.c:32
u16 gMatrixListPos
Definition main_loop.c:45