Named and documented visibility test functions (func_8011C80C and func_8011CFBC) (#932)

more s->w perspective renaming
This commit is contained in:
Mr-Wiseguy 2023-02-03 03:50:48 -05:00 committed by GitHub
parent 18befa1ec6
commit a78099f909
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 266 additions and 190 deletions

View File

@ -29,11 +29,11 @@ void shim_guPositionF(float mf[4][4], float r, float p, float h, float s, float
void shim_guOrthoF(float mf[4][4], float l, float r, float b, float t, float n, float f, float scale);
void shim_guFrustumF(float mf[4][4], float l, float r, float b, float t, float n, float f, float scale);
void shim_mem_clear(void* data, s32 numBytes);
void shim_transform_point(Matrix4f mtx, f32 inX, f32 inY, f32 inZ, f32 inS, f32* outX, f32* outY, f32* outZ, f32* outS);
void shim_transform_point(Matrix4f mtx, f32 inX, f32 inY, f32 inZ, f32 inS, f32* outX, f32* outY, f32* outZ, f32* outW);
s32 shim_npc_raycast_down_sides(s32, f32*, f32*, f32*, f32*);
void shim_sfx_play_sound_at_position(s32 soundID, s32 value2, f32 posX, f32 posY, f32 posZ);
void shim_mdl_draw_hidden_panel_surface(Gfx**, u16 treeIndex);
s32 shim_func_8011CFBC(f32, f32, f32, s32, f32*, f32*);
s32 shim_is_point_visible(f32, f32, f32, s32, f32*, f32*);
void shim_draw_box(s32 flags, WindowStyle windowStyle, s32 posX, s32 posY, s32 posZ, s32 width, s32 height, u8 opacity,
u8 darkening, f32 scaleX, f32 scaleY, f32 rotX, f32 rotY, f32 rotZ, void (*fpDrawContents)(void*),
void* drawContentsArg0, Matrix4f rotScaleMtx, s32 translateX, s32 translateY, f32 (*outMtx)[4]);

View File

@ -218,7 +218,7 @@ void set_time_freeze_mode(s32);
s32 get_map_IDs_by_name(const char* mapName, s16* areaID, s16* mapID);
void get_dpad_input_radial(f32* angle, f32* magnitude);
void transform_point(Matrix4f mtx, f32 inX, f32 inY, f32 inZ, f32 inS, f32* outX, f32* outY, f32* outZ, f32* outS);
void transform_point(Matrix4f mtx, f32 inX, f32 inY, f32 inZ, f32 inS, f32* outX, f32* outY, f32* outZ, f32* outW);
void try_player_footstep_sounds(s32 arg0);
void phys_update_interact_collider(void);
void phys_reset_spin_history(void);
@ -821,7 +821,7 @@ void* load_asset_by_name(const char* assetName, u32* decompressedSize);
Gfx* mdl_get_copied_gfx(s32 copyIndex);
void mdl_get_copied_vertices(s32 copyIndex, Vtx** firstVertex, Vtx** copiedVertices, s32* numCopied);
void mdl_draw_hidden_panel_surface(Gfx** arg0, u16 treeIndex);
s32 func_8011CFBC(f32 arg0, f32 arg1, f32 arg2, s32 arg3, f32* arg4, f32* arg5);
s32 is_point_visible(f32 x, f32 y, f32 z, s32 depthQueryID, f32* screenX, f32* screenY);
void set_screen_overlay_center_worldpos(s32 idx, s32 posIdx, s32 x, s32 y, s32 z);
void* mdl_get_next_texture_address(s32);
s32 cancel_current_message(void);

View File

@ -7,7 +7,7 @@ u32 D_E0200690 = 0x1E6D3457;
void* effectFuncs[] = {
guRotateF, guTranslateF, guTranslate, guScaleF, guMtxCatF, guMtxF2L, guMtxL2F, queue_render_task,
create_effect_instance, remove_effect, general_heap_malloc, mem_clear, NULL, rand_int, clamp_angle, sin_deg,
cos_deg, atan2, npc_raycast_down_sides, load_effect, sqrtf, mdl_draw_hidden_panel_surface, func_8011CFBC,
cos_deg, atan2, npc_raycast_down_sides, load_effect, sqrtf, mdl_draw_hidden_panel_surface, is_point_visible,
guPerspectiveF, guMtxIdentF, transform_point, guLookAtHiliteF, set_screen_overlay_params_back,
set_screen_overlay_center, set_screen_overlay_center_worldpos, mdl_get_next_texture_address, guPositionF, guOrthoF,
guFrustumF, func_80138D88, draw_box, draw_msg, get_msg_width, get_background_color_blend, sfx_play_sound_at_position

View File

@ -424,11 +424,11 @@ void mem_clear(void* data, s32 numBytes) {
}
}
void transform_point(Matrix4f mtx, f32 inX, f32 inY, f32 inZ, f32 inS, f32* outX, f32* outY, f32* outZ, f32* outS) {
void transform_point(Matrix4f mtx, f32 inX, f32 inY, f32 inZ, f32 inS, f32* outX, f32* outY, f32* outZ, f32* outW) {
*outX = (mtx[0][0] * inX) + (mtx[1][0] * inY) + (mtx[2][0] * inZ) + mtx[3][0];
*outY = (mtx[0][1] * inX) + (mtx[1][1] * inY) + (mtx[2][1] * inZ) + mtx[3][1];
*outZ = (mtx[0][2] * inX) + (mtx[1][2] * inY) + (mtx[2][2] * inZ) + mtx[3][2];
*outS = (mtx[0][3] * inX) + (mtx[1][3] * inY) + (mtx[2][3] * inZ) + mtx[3][3];
*outW = (mtx[0][3] * inX) + (mtx[1][3] * inY) + (mtx[2][3] * inZ) + mtx[3][3];
}
void copy_matrix(Matrix4f src, Matrix4f dest) {

View File

@ -442,12 +442,12 @@ void get_cam_viewport(s32 camID, u16* x, u16* y, u16* width, u16* height) {
void get_screen_coords(s32 camID, f32 x, f32 y, f32 z, s32* screenX, s32* screenY, s32* screenZ) {
Camera* camera = &gCameras[camID];
f32 tS;
f32 tW;
f32 tZ;
f32 tY;
f32 tX;
transform_point(camera->perspectiveMatrix, x, y, z, 1.0f, &tX, &tY, &tZ, &tS);
transform_point(camera->perspectiveMatrix, x, y, z, 1.0f, &tX, &tY, &tZ, &tW);
*screenZ = tZ + 5000.0f;
if (*screenZ < 0) {
@ -456,14 +456,14 @@ void get_screen_coords(s32 camID, f32 x, f32 y, f32 z, s32* screenX, s32* screen
*screenZ = 10000;
}
if (tS < 0.01 && tS > -0.01) {
if (tW < 0.01 && tW > -0.01) {
*screenX = 0;
*screenY = 0;
*screenZ = 0;
} else {
tS = 1.0f / tS;
*screenX = (s32) ((camera->viewportW / 2) + (tX * tS * camera->viewportW * 0.5f)) + camera->viewportStartX;
*screenY = (s32) ((camera->viewportH / 2) - (tY * tS * camera->viewportH * 0.5f)) + camera->viewportStartY;
tW = 1.0f / tW;
*screenX = (s32) ((camera->viewportW / 2) + (tX * tW * camera->viewportW * 0.5f)) + camera->viewportStartX;
*screenY = (s32) ((camera->viewportH / 2) - (tY * tW * camera->viewportH * 0.5f)) + camera->viewportStartY;
}
}

View File

@ -29,11 +29,6 @@ typedef struct Fog {
/* 0x18 */ s32 endDistance;
} Fog; // size = 0x1C
typedef struct Struct_8011CFBC {
/* 0x00 */ s32 unk_00;
/* 0x04 */ s32 unk_04;
} Struct_8011CFBC; // size = 0x08
extern s32 D_801516FC;
extern Gfx D_8014B7F8[];
@ -447,7 +442,28 @@ Matrix4s mdl_RDPIdentity = {
}
};
Struct_8011CFBC D_8014B7A8[] = {
// The depth buffer contains values encoded in a custom 18-bit floating-point format.
// There are 3 bits of exponent, 11 bits of mantissa, and 4 bits of "dz".
// However, two of the "dz" bits are inaccessible to the CPU because it can only access 8 of the 9
// bits of each RDRAM byte (the N64 has 9-bit RAM).
// Therefore, the CPU sees it as a 16-bit value.
// Fields in floating point depth buffer format
#define DEPTH_EXPONENT_MASK 0xE000
#define DEPTH_MANTISSA_MASK 0x1FFC
#define DEPTH_DZ_MASK 0x0003
#define DEPTH_EXPONENT_SHIFT 13
#define DEPTH_MANTISSA_SHIFT 2
#define DEPTH_DZ_SHIFT 0
// Lookup table for converting depth buffer values to a 15.3 fixed-point format.
typedef struct DepthFloatFactors {
/* 0x00 */ s32 shift;
/* 0x04 */ s32 bias;
} DepthFloatFactors;
DepthFloatFactors depthFloatLookupTable[] = {
{ 6, 0x00000 },
{ 5, 0x20000 },
{ 4, 0x30000 },
@ -459,6 +475,11 @@ Struct_8011CFBC D_8014B7A8[] = {
{ 0, 0x00000 },
};
// Maximum depth value after the viewport transform.
// The multiplication by 2 comes from transforming depth from (-0.5, 0.5) to (0.0, 1.0).
// The multiplication by 32 comes from scaling the RSP does to increase depth precision.
#define MAX_VIEWPORT_DEPTH (2 * 32 * ((G_MAXZ / 2)))
s32 D_8014B7F0 = 0;
// padding?
@ -1098,7 +1119,7 @@ extern RenderTask mdl_clearRenderTasks[3][0x100];
extern s32 D_801A7000; // todo ???
extern u16 D_80153380[16];
extern u16 depthCopyBuffer[16];
void update_shadows(void);
s32 step_entity_commandlist(Entity* entity);
@ -4286,7 +4307,7 @@ void func_80116698(void) {
void render_models(void) {
RenderTask rt;
RenderTask* rtPtr = &rt;
f32 outX, outY, outZ, outS;
f32 outX, outY, outZ, outW;
f32 m00, m01, m02, m03;
f32 m10, m11, m12, m13;
f32 m20, m21, m22, m23;
@ -4308,14 +4329,15 @@ void render_models(void) {
outX = (m00 * xComp) + (m10 * yComp) + (m20 * zComp) + m30; \
outY = (m01 * xComp) + (m11 * yComp) + (m21 * zComp) + m31; \
outZ = (m02 * xComp) + (m12 * yComp) + (m22 * zComp) + m32; \
outS = (m03 * xComp) + (m13 * yComp) + (m23 * zComp) + m33; \
if (outS == 0.0f) { \
outW = (m03 * xComp) + (m13 * yComp) + (m23 * zComp) + m33; \
if (outW == 0.0f) { \
break; \
} \
outS = 1.0f / outS; \
xComp = outX * outS; \
yComp = outY * outS; \
zComp = outZ * outS; \
/* Perspective divide */ \
outW = 1.0f / outW; \
xComp = outX * outW; \
yComp = outY * outW; \
zComp = outZ * outW; \
if (zComp > -1.0f && xComp >= -1.0f && xComp <= 1.0f && yComp >= -1.0f && yComp <= 1.0f) { \
break; \
}
@ -4433,7 +4455,7 @@ void render_models(void) {
}
}
transform_point(camera->perspectiveMatrix, x, y, z, 1.0f, &outX, &outY, &outZ, &outS);
transform_point(camera->perspectiveMatrix, x, y, z, 1.0f, &outX, &outY, &outZ, &outW);
distance = outZ + 5000.0f;
if (distance < 0) {
distance = 0;
@ -4472,13 +4494,13 @@ void render_models(void) {
transform_point(
camera->perspectiveMatrix,
xComp, yComp, zComp, 1.0f,
&outX, &outY, &outZ, &outS
&outX, &outY, &outZ, &outW
);
if (outS == 0.0f) {
outS = 1.0f;
if (outW == 0.0f) {
outW = 1.0f;
}
distance = ((outZ / outS) * 10000.0f);
distance = ((outZ / outW) * 10000.0f);
if (!(transformGroup->flags & 2)) {
rtPtr->appendGfx = render_transform_group;
@ -5818,42 +5840,57 @@ void mdl_project_tex_coords(s32 modelID, Gfx* destGfx, f32 (*destMtx)[4], void*
INCLUDE_ASM(s32, "a5dd0_len_114e0", mdl_project_tex_coords);
#endif
s32 func_8011C80C(u16 arg0, s32 arg3, f32* arg4, f32* arg5) {
// Checks if the center of a model is visible.
// If `depthQueryID` is nonnegative, the depth buffer is checked to see if the model's center is occluded by geometry.
// Otherwise, the occlusion check is skipped.
// `depthQueryID` must be between 0 and the size of `depthCopyBuffer` minus 1.
// Every nonnegative value of `depthQueryID` must be unique within a frame, otherwise the result will corrupt the data
// of the previous query that shared the same ID.
// Occlusion visibility checks are always one frame out of date, as they reference the previous frame's depth buffer.
s32 is_model_center_visible(u16 modelID, s32 depthQueryID, f32* screenX, f32* screenY) {
Camera* camera = &gCameras[gCurrentCameraID];
Model* model = get_model_from_list_index(get_model_list_index_from_tree_index(arg0));
Model* model = get_model_from_list_index(get_model_list_index_from_tree_index(modelID));
f32 outX;
f32 outY;
f32 outZ;
f32 outS;
f32 outW;
s32 temp1;
s32 temp2;
u32 temp3, temp4;
u32 temp6;
s32 temp5;
Struct_8011CFBC* v1;
s32 depthExponent;
s32 depthMantissa;
u32 shiftedMantissa, mantissaBias;
u32 decodedDepth;
s32 scaledDepth;
if (arg3 >= 16) {
// If an invalid depth query id was provided, return false.
if (depthQueryID >= ARRAY_COUNT(depthCopyBuffer)) {
return FALSE;
}
transform_point(camera->perspectiveMatrix, model->center.x, model->center.y, model->center.z, 1.0f, &outX, &outY, &outZ, &outS);
if (outS == 0.0f) {
*arg4 = 0.0f;
*arg5 = 0.0f;
// Transform the model's center into clip space.
transform_point(camera->perspectiveMatrix, model->center.x, model->center.y, model->center.z, 1.0f, &outX, &outY, &outZ, &outW);
if (outW == 0.0f) {
*screenX = 0.0f;
*screenY = 0.0f;
return TRUE;
}
outS = 1.0f / outS;
outX *= outS;
outY *= -outS;
outZ *= outS;
// Perform the perspective divide (divide xyz by w) to convert to normalized device coords.
// Normalized device coords have a range of (-1, 1) on each axis.
outW = 1.0f / outW;
outX *= outW;
outY *= -outW;
outZ *= outW;
// Perform the viewport transform for x and y (convert normalized device coords to viewport coords).
// Viewport coords have a range of (0, Width) for x and (0, Height) for y.
outX = (outX * camera->viewportW + camera->viewportW) * 0.5;
outX += camera->viewportStartX;
outY = (outY * camera->viewportH + camera->viewportH) * 0.5;
outY += camera->viewportStartY;
// Convert depth from (-1, 1) to (0, 1).
outZ = (outZ + 1.0f) * 0.5;
*arg4 = (s32)outX;
*arg5 = (s32)outY;
if (arg3 < 0) {
// Write out the calculated x and y values.
*screenX = (s32)outX;
*screenY = (s32)outY;
// If a depth query wasn't requested, simply check if the point is within the view frustum.
if (depthQueryID < 0) {
if (outZ > 0.0f) {
return FALSE;
} else {
@ -5862,119 +5899,158 @@ s32 func_8011C80C(u16 arg0, s32 arg3, f32* arg4, f32* arg5) {
}
if (outX >= 0.0f && outY >= 0.0f && outX < 320.0f && outY < 240.0f) {
gDPPipeSync(gMasterGfxPos++);
gDPSetTextureImage(gMasterGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 320, osVirtualToPhysical(&nuGfxZBuffer[(s32) outY * 320]));
gDPSetTile(gMasterGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, 0x0000, G_TX_LOADTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 9, G_TX_NOLOD);
gDPLoadSync(gMasterGfxPos++);
gDPLoadTile(gMasterGfxPos++, G_TX_LOADTILE, (s32) outX * 4, 0, ((s32) outX + 3) * 4, 0);
// Load a 4x1 pixel tile of the depth buffer
gDPLoadTextureTile(gMasterGfxPos++, osVirtualToPhysical(&nuGfxZBuffer[(s32) outY * 320]), G_IM_FMT_RGBA, G_IM_SIZ_16b, 320, 1,
(s32) outX, 0, (s32) outX + 3, 0,
0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP,
9, G_TX_NOMASK,
G_TX_NOLOD, G_TX_NOLOD);
gDPPipeSync(gMasterGfxPos++);
gDPSetTile(gMasterGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, 0x0000, G_TX_RENDERTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 9, G_TX_NOLOD);
gDPSetTileSize(gMasterGfxPos++, G_TX_RENDERTILE, (s32) outX * 4, 0, ((s32) outX + 3) * 4, 0);
gDPPipeSync(gMasterGfxPos++);
gDPSetColorImage(gMasterGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 320, D_80153380);
// Set the current color image to the buffer where copied depth values are stored.
gDPSetColorImage(gMasterGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 320, depthCopyBuffer);
gDPPipeSync(gMasterGfxPos++);
// Set up 1 cycle mode and all other relevant othermode params.
// One cycle mode must be used here because only one pixel is copied, and copy mode only supports multiples of 4 pixels.
gDPSetCycleType(gMasterGfxPos++, G_CYC_1CYCLE);
gDPSetRenderMode(gMasterGfxPos++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
gDPSetCombineMode(gMasterGfxPos++, G_CC_DECALRGBA, G_CC_DECALRGBA);
gDPSetTextureFilter(gMasterGfxPos++, G_TF_POINT);
gDPSetTexturePersp(gMasterGfxPos++, G_TP_NONE);
gSPTexture(gMasterGfxPos++, -1, -1, 0, G_TX_RENDERTILE, G_ON);
gSPTexture(gMasterGfxPos++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON);
gDPSetTextureLUT(gMasterGfxPos++, G_TT_NONE);
gDPSetTextureDetail(gMasterGfxPos++, G_TD_CLAMP);
gDPSetTextureLOD(gMasterGfxPos++, G_TL_TILE);
gDPSetScissor(gMasterGfxPos++, G_SC_NON_INTERLACE, arg3, 0, arg3 + 1, 1);
gSPTextureRectangle(gMasterGfxPos++, arg3 * 4, 0 * 4, 4 * 4, 1 * 4, G_TX_RENDERTILE, (s32) outX * 32, 0, 0x0400, 0x0400);
// Adjust the scissor to only draw to the specified pixel.
gDPSetScissor(gMasterGfxPos++, G_SC_NON_INTERLACE, depthQueryID, 0, depthQueryID + 1, 1);
// Draw a texrect to copy one pixel of the loaded depth tile to the output buffer.
gSPTextureRectangle(gMasterGfxPos++, depthQueryID << 2, 0 << 2, 4 << 2, 1 << 2, G_TX_RENDERTILE, (s32) outX << 5, 0, 1 << 10, 1 << 10);
// Sync and swap the color image back to the current framebuffer.
gDPPipeSync(gMasterGfxPos++);
gDPSetColorImage(gMasterGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 320, osVirtualToPhysical(nuGfxCfb_ptr));
gDPPipeSync(gMasterGfxPos++);
// Reconfigure the frame's normal scissor.
gDPSetScissor(gMasterGfxPos++, G_SC_NON_INTERLACE, camera->viewportStartX, camera->viewportStartY, camera->viewportStartX + camera->viewportW, camera->viewportStartY + camera->viewportH);
temp1 = D_80153380[arg3] >> 13;
temp2 = (D_80153380[arg3] & 0x1FFF) / 4;
v1 = &D_8014B7A8[temp1];
temp3 = temp2 << v1->unk_00;
temp4 = v1->unk_04;
temp6 = (temp3 + temp4) / 8;
temp5 = outZ * 32704.0f;
if (temp6 < temp5) {
// The following code will use last frame's depth value, since the copy that was just written won't be executed until the current frame is drawn.
// Extract the exponent and mantissa from the depth buffer value.
depthExponent = depthCopyBuffer[depthQueryID] >> DEPTH_EXPONENT_SHIFT;
depthMantissa = (depthCopyBuffer[depthQueryID] & (DEPTH_MANTISSA_MASK | DEPTH_DZ_MASK)) >> DEPTH_MANTISSA_SHIFT;
// Convert the exponent and mantissa into a fixed-point value.
shiftedMantissa = depthMantissa << depthFloatLookupTable[depthExponent].shift;
mantissaBias = depthFloatLookupTable[depthExponent].bias;
// Remove the 3 fractional bits of precision.
decodedDepth = (shiftedMantissa + mantissaBias) >> 3;
// Convert the calculated screen depth into viewport depth.
scaledDepth = outZ * MAX_VIEWPORT_DEPTH;
if (decodedDepth < scaledDepth) {
return FALSE;
}
}
return outZ > 0.0f;
}
s32 func_8011CFBC(f32 x, f32 y, f32 z, s32 arg3, f32* arg4, f32* arg5) {
// Checks if a point is visible on screen.
// If `depthQueryID` is nonnegative, the depth buffer is checked to see if the point is occluded by geometry.
// Otherwise, the occlusion check is skipped.
// `depthQueryID` must be between 0 and the size of `depthCopyBuffer` minus 1.
// Every nonnegative value of `depthQueryID` must be unique within a frame, otherwise the result will corrupt the data
// of the previous query that shared the same ID.
// Occlusion visibility checks are always one frame out of date, as they reference the previous frame's depth buffer.
s32 is_point_visible(f32 x, f32 y, f32 z, s32 depthQueryID, f32* screenX, f32* screenY) {
Camera* camera = &gCameras[gCurrentCameraID];
f32 outX;
f32 outY;
f32 outZ;
f32 outS;
f32 outW;
s32 temp1;
s32 temp2;
u32 temp3, temp4;
u32 temp6;
s32 temp5;
Struct_8011CFBC* v1;
s32 depthExponent;
s32 depthMantissa;
u32 shiftedMantissa, mantissaBias;
u32 decodedDepth;
s32 scaledDepth;
if (arg3 >= 16) {
// If an invalid depth query id was provided, return false.
if (depthQueryID >= ARRAY_COUNT(depthCopyBuffer)) {
return FALSE;
}
transform_point(camera->perspectiveMatrix, x, y, z, 1.0f, &outX, &outY, &outZ, &outS);
if (outS == 0.0f) {
*arg4 = 0.0f;
*arg5 = 0.0f;
// Transform the point into clip space.
transform_point(camera->perspectiveMatrix, x, y, z, 1.0f, &outX, &outY, &outZ, &outW);
if (outW == 0.0f) {
*screenX = 0.0f;
*screenY = 0.0f;
return TRUE;
}
outS = 1.0f / outS;
outX *= outS;
outY *= -outS;
outZ *= outS;
// Perform the perspective divide (divide xyz by w) to convert to normalized device coords.
// Normalized device coords have a range of (-1, 1) on each axis.
outW = 1.0f / outW;
outX *= outW;
outY *= -outW;
outZ *= outW;
// Perform the viewport transform for x and y (convert normalized device coords to viewport coords).
// Viewport coords have a range of (0, Width) for x and (0, Height) for y.
outX = (outX * camera->viewportW + camera->viewportW) * 0.5;
outX += camera->viewportStartX;
outY = (outY * camera->viewportH + camera->viewportH) * 0.5;
outY += camera->viewportStartY;
// Convert depth from (-1, 1) to (0, 1).
outZ = (outZ + 1.0f) * 0.5;
*arg4 = outX;
*arg5 = outY;
if (arg3 < 0) {
// Write out the calculated x and y values.
*screenX = outX;
*screenY = outY;
// If a depth query wasn't requested, simply check if the point is within the view frustum.
if (depthQueryID < 0) {
return outZ > 0.0f;
}
if (outX >= 0.0f && outY >= 0.0f && outX < 320.0f && outY < 240.0f) {
gDPPipeSync(gMasterGfxPos++);
gDPSetTextureImage(gMasterGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 320, osVirtualToPhysical(&nuGfxZBuffer[(s32) outY * 320]));
gDPSetTile(gMasterGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, 0x0000, G_TX_LOADTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 9, G_TX_NOLOD);
gDPLoadSync(gMasterGfxPos++);
gDPLoadTile(gMasterGfxPos++, G_TX_LOADTILE, (s32) outX * 4, 0, ((s32) outX + 3) * 4, 0);
// Load a 4x1 pixel tile of the depth buffer
gDPLoadTextureTile(gMasterGfxPos++, osVirtualToPhysical(&nuGfxZBuffer[(s32) outY * 320]), G_IM_FMT_RGBA, G_IM_SIZ_16b, 320, 1,
(s32) outX, 0, (s32) outX + 3, 0,
0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP,
9, G_TX_NOMASK,
G_TX_NOLOD, G_TX_NOLOD);
gDPPipeSync(gMasterGfxPos++);
gDPSetTile(gMasterGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, 0x0000, G_TX_RENDERTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 9, G_TX_NOLOD);
gDPSetTileSize(gMasterGfxPos++, G_TX_RENDERTILE, (s32) outX * 4, 0, ((s32) outX + 3) * 4, 0);
gDPPipeSync(gMasterGfxPos++);
gDPSetColorImage(gMasterGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 320, D_80153380);
// Set the current color image to the buffer where copied depth values are stored.
gDPSetColorImage(gMasterGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 320, depthCopyBuffer);
gDPPipeSync(gMasterGfxPos++);
// Set up 1 cycle mode and all other relevant othermode params.
// One cycle mode must be used here because only one pixel is copied, and copy mode only supports multiples of 4 pixels.
gDPSetCycleType(gMasterGfxPos++, G_CYC_1CYCLE);
gDPSetRenderMode(gMasterGfxPos++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
gDPSetCombineMode(gMasterGfxPos++, G_CC_DECALRGBA, G_CC_DECALRGBA);
gDPSetTextureFilter(gMasterGfxPos++, G_TF_POINT);
gDPSetTexturePersp(gMasterGfxPos++, G_TP_NONE);
gSPTexture(gMasterGfxPos++, -1, -1, 0, G_TX_RENDERTILE, G_ON);
gSPTexture(gMasterGfxPos++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON);
gDPSetTextureLUT(gMasterGfxPos++, G_TT_NONE);
gDPSetTextureDetail(gMasterGfxPos++, G_TD_CLAMP);
gDPSetTextureLOD(gMasterGfxPos++, G_TL_TILE);
gDPSetScissor(gMasterGfxPos++, G_SC_NON_INTERLACE, arg3, 0, arg3 + 1, 1);
gSPTextureRectangle(gMasterGfxPos++, arg3 * 4, 0 * 4, (arg3 + 1) * 4, 1 * 4, G_TX_RENDERTILE, (s32) outX * 32, 0, 0x0400, 0x0400);
// Adjust the scissor to only draw to the specified pixel.
gDPSetScissor(gMasterGfxPos++, G_SC_NON_INTERLACE, depthQueryID, 0, depthQueryID + 1, 1);
// Draw a texrect to copy one pixel of the loaded depth tile to the output buffer.
gSPTextureRectangle(gMasterGfxPos++, depthQueryID << 2, 0 << 2, (depthQueryID + 1) << 2, 1 << 2, G_TX_RENDERTILE, (s32) outX << 5, 0, 1 << 10, 1 << 10);
// Sync and swap the color image back to the current framebuffer.
gDPPipeSync(gMasterGfxPos++);
gDPSetColorImage(gMasterGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 320, osVirtualToPhysical(nuGfxCfb_ptr));
gDPPipeSync(gMasterGfxPos++);
// Reconfigure the frame's normal scissor.
gDPSetScissor(gMasterGfxPos++, G_SC_NON_INTERLACE, camera->viewportStartX, camera->viewportStartY, camera->viewportStartX + camera->viewportW, camera->viewportStartY + camera->viewportH);
temp1 = D_80153380[arg3] >> 13;
temp2 = (D_80153380[arg3] & 0x1FFF) / 4;
v1 = &D_8014B7A8[temp1];
temp3 = temp2 << v1->unk_00;
temp4 = v1->unk_04;
temp6 = (temp3 + temp4) / 8;
temp5 = outZ * 32704.0f;
if (temp6 < temp5) {
// The following code will use last frame's depth value, since the copy that was just written won't be executed until the current frame is drawn.
// Extract the exponent and mantissa from the depth buffer value.
depthExponent = depthCopyBuffer[depthQueryID] >> DEPTH_EXPONENT_SHIFT;
depthMantissa = (depthCopyBuffer[depthQueryID] & (DEPTH_MANTISSA_MASK | DEPTH_DZ_MASK)) >> DEPTH_MANTISSA_SHIFT;
// Convert the exponent and mantissa into a fixed-point value.
shiftedMantissa = depthMantissa << depthFloatLookupTable[depthExponent].shift;
mantissaBias = depthFloatLookupTable[depthExponent].bias;
// Remove the 3 fractional bits of precision.
decodedDepth = (shiftedMantissa + mantissaBias) >> 3;
// Convert the calculated screen depth into viewport depth.
scaledDepth = outZ * MAX_VIEWPORT_DEPTH;
if (decodedDepth < scaledDepth) {
return FALSE;
}
}

View File

@ -165,7 +165,7 @@ void func_80032C64(Camera* camera) {
CameraControlSettings* settings2;
CameraControlSettings* settings3;
s32 s2;
f32 X, Y, Z, S;
f32 X, Y, Z, W;
f32 product;
f32 newPosX, newPosZ;
Collider* zone;
@ -189,12 +189,12 @@ void func_80032C64(Camera* camera) {
(f32)camera->viewportW / (f32)camera->viewportH, camera->nearClip, camera->farClip, 1.0f);
guMtxCatF(camera->viewMtxPlayer, camera->perspectiveMatrix, camera->perspectiveMatrix);
transform_point(camera->perspectiveMatrix, camera->targetPos.x, camera->targetPos.y, camera->targetPos.z,
1.0f, &X, &Y, &Z, &S);
if (S == 0.0f) {
S = 1.0f;
1.0f, &X, &Y, &Z, &W);
if (W == 0.0f) {
W = 1.0f;
}
S = 1.0f / S;
X *= S;
W = 1.0f / W;
X *= W;
camera->unk_52C = (X > 0.0f) ? 1 : (X < 0.0f) ? -1 : 0;
camera->unk_530 = 0;
} else {

View File

@ -412,16 +412,16 @@ void set_screen_overlay_center(s32 idx, s32 arg1, s32 arg2, s32 arg3) {
void set_screen_overlay_center_worldpos(s32 idx, s32 posIdx, s32 x, s32 y, s32 z) {
Camera* camera = &gCameras[gCurrentCameraID];
f32 tx, ty, tz, ts;
f32 tx, ty, tz, tw;
switch (idx) {
case 0:
case 1:
transform_point(camera->perspectiveMatrix, x, y, z, 1.0f, &tx, &ty, &tz, &ts);
ts = 1.0f / ts;
tx *= ts;
ty *= -ts;
tz *= ts;
transform_point(camera->perspectiveMatrix, x, y, z, 1.0f, &tx, &ty, &tz, &tw);
tw = 1.0f / tw;
tx *= tw;
ty *= -tw;
tz *= tw;
tx = (((tx * camera->viewportW) + camera->viewportW) * 0.5) + camera->viewportStartX;
ty = (((ty * camera->viewportH) + camera->viewportH) * 0.5) + camera->viewportStartY;

View File

@ -200,7 +200,7 @@ void bulb_glow_appendGfx(void* effect) {
temp_s6 = temp_s1->unk_10;
temp_s3 = temp_s1->unk_14;
var_v1 = shim_func_8011CFBC(data->pos.x, data->pos.y, data->pos.z, data->unk_1C, &sp18, &sp1C);
var_v1 = shim_is_point_visible(data->pos.x, data->pos.y, data->pos.z, data->unk_1C, &sp18, &sp1C);
if (unk_00 == 5) {
var_v1 = 1;
}

View File

@ -118,10 +118,10 @@ void flame_render(EffectInstance* effect) {
f32 outX;
f32 outY;
f32 outZ;
f32 outS;
f32 outW;
shim_transform_point(gCameras[gCurrentCameraID].perspectiveMatrix, data->pos.x, data->pos.y, data->pos.z, 1.0f,
&outX, &outY, &outZ, &outS);
&outX, &outY, &outZ, &outW);
outDist = outZ + 5000;
if (outDist < 0) {
@ -130,7 +130,7 @@ void flame_render(EffectInstance* effect) {
outDist = 10000;
}
if (outS < 0.01 && -0.01 < outS) {
if (outW < 0.01 && -0.01 < outW) {
outDist = 0;
}

View File

@ -415,7 +415,7 @@ void draw_entity_model_A(s32 modelIdx, Mtx* transformMtx) {
RenderTask* rtPtr = &rt;
Camera* camera = &gCameras[gCurrentCamID];
Matrix4f mtx;
f32 x, y, z, s;
f32 x, y, z, w;
f32 inX, inY, inZ;
if ((gGameStatusPtr->isBattle == 0) || (modelIdx & 0x800)) {
@ -433,7 +433,7 @@ void draw_entity_model_A(s32 modelIdx, Mtx* transformMtx) {
inX = mtx[3][0];
inY = mtx[3][1];
inZ = mtx[3][2];
transform_point(camera->perspectiveMatrix, inX, inY, inZ, 1.0f, &x, &y, &z, &s);
transform_point(camera->perspectiveMatrix, inX, inY, inZ, 1.0f, &x, &y, &z, &w);
rtPtr->renderMode = model->renderMode;
rtPtr->appendGfxArg = model;
rtPtr->appendGfx = (void(*)(void*))appendGfx_entity_model;
@ -453,7 +453,7 @@ void draw_entity_model_B(s32 modelIdx, Mtx* transformMtx, s32 vertexSegment, Vec
RenderTask* rtPtr = &rt;
Camera* camera = &gCameras[gCurrentCamID];
Matrix4f mtx;
f32 x, y, z, s;
f32 x, y, z, w;
f32 inX, inY, inZ;
if ((gGameStatusPtr->isBattle == 0) || (modelIdx & 0x800)) {
@ -472,7 +472,7 @@ void draw_entity_model_B(s32 modelIdx, Mtx* transformMtx, s32 vertexSegment, Vec
inX = mtx[3][0];
inY = mtx[3][1];
inZ = mtx[3][2];
transform_point(camera->perspectiveMatrix, inX, inY, inZ, 1.0f, &x, &y, &z, &s);
transform_point(camera->perspectiveMatrix, inX, inY, inZ, 1.0f, &x, &y, &z, &w);
rtPtr->renderMode = model->renderMode;
rtPtr->appendGfxArg = model;
rtPtr->appendGfx = (void(*)(void*))appendGfx_entity_model;

View File

@ -101,7 +101,7 @@ void N(UnkModelFunc001)(void) {
ModelBoundingBox* bb = (ModelBoundingBox*) model->modelNode->propertyList;
f32 bbHalfX = bb->halfSizeX;
f32 bbHalfZ = bb->halfSizeZ;
f32 outX, outY, outZ, outS;
f32 outX, outY, outZ, outW;
f32 temp_f24;
f32 temp_f26;
f32 temp_f20;
@ -109,14 +109,14 @@ void N(UnkModelFunc001)(void) {
transform_point(camera->perspectiveMatrix,
model->center.x - bbHalfX, model->center.y, model->center.z - bbHalfZ, 1.0f,
&outX, &outY, &outZ, &outS);
&outX, &outY, &outZ, &outW);
outX *= 1.0f / outS;
outY *= -(1.0f / outS);
outZ *= 1.0f / outS;
outS = 1.0f / outS;
outX *= 1.0f / outW;
outY *= -(1.0f / outW);
outZ *= 1.0f / outW;
outW = 1.0f / outW;
if (outS < 0.0f) {
if (outW < 0.0f) {
outX = 0.0f;
outY = 1.0f;
}
@ -125,16 +125,16 @@ void N(UnkModelFunc001)(void) {
transform_point(camera->perspectiveMatrix,
model->center.x - bbHalfX, model->center.y, model->center.z + bbHalfZ, 1.0f,
&outX, &outY, &outZ, &outS);
&outX, &outY, &outZ, &outW);
outX *= 1.0f / outS;
outY *= -(1.0f / outS);
outZ *= 1.0f / outS;
outS = 1.0f / outS;
outX *= 1.0f / outW;
outY *= -(1.0f / outW);
outZ *= 1.0f / outW;
outW = 1.0f / outW;
temp_f24 = temp_f20;
temp_f26 = temp_f22;
if (outS < 0.0f) {
if (outW < 0.0f) {
outX = 0.0f;
outY = 1.0f;
}
@ -157,14 +157,14 @@ void N(UnkModelFunc001)(void) {
transform_point(camera->perspectiveMatrix,
model->center.x + bbHalfX, model->center.y, model->center.z + bbHalfZ, 1.0f,
&outX, &outY, &outZ, &outS);
&outX, &outY, &outZ, &outW);
outX *= 1.0f / outS;
outY *= -(1.0f / outS);
outZ *= 1.0f / outS;
outS = 1.0f / outS;
outX *= 1.0f / outW;
outY *= -(1.0f / outW);
outZ *= 1.0f / outW;
outW = 1.0f / outW;
if (outS < 0.0f) {
if (outW < 0.0f) {
outX = 1.0f;
outY = 1.0f;
}
@ -187,14 +187,14 @@ void N(UnkModelFunc001)(void) {
transform_point(camera->perspectiveMatrix,
model->center.x + bbHalfX, model->center.y, model->center.z - bbHalfZ, 1.0f,
&outX, &outY, &outZ, &outS);
&outX, &outY, &outZ, &outW);
outX *= 1.0f / outS;
outY *= -(1.0f / outS);
outZ *= 1.0f / outS;
outS = 1.0f / outS;
outX *= 1.0f / outW;
outY *= -(1.0f / outW);
outZ *= 1.0f / outW;
outW = 1.0f / outW;
if (outS < 0.0f) {
if (outW < 0.0f) {
outX = 1.0f;
outY = 1.0f;
}

View File

@ -171,7 +171,7 @@ void N(UnkModelFunc001)(void) {
ModelBoundingBox* bb = (ModelBoundingBox*) model->modelNode->propertyList;
f32 bbHalfX = bb->halfSizeX;
f32 bbHalfZ = bb->halfSizeZ;
f32 outX, outY, outZ, outS;
f32 outX, outY, outZ, outW;
Gfx* new_var;
f32 temp_f24;
f32 temp_f26;
@ -180,14 +180,14 @@ void N(UnkModelFunc001)(void) {
transform_point(camera->perspectiveMatrix,
model->center.x - bbHalfX, model->center.y, model->center.z - bbHalfZ, 1.0f,
&outX, &outY, &outZ, &outS);
&outX, &outY, &outZ, &outW);
outX *= 1.0f / outS;
outY *= -(1.0f / outS);
outZ *= 1.0f / outS;
outS = 1.0f / outS;
outX *= 1.0f / outW;
outY *= -(1.0f / outW);
outZ *= 1.0f / outW;
outW = 1.0f / outW;
if (outS < 0.0f) {
if (outW < 0.0f) {
outX = 0.0f;
outY = 1.0f;
}
@ -196,16 +196,16 @@ void N(UnkModelFunc001)(void) {
transform_point(camera->perspectiveMatrix,
model->center.x - bbHalfX, model->center.y, model->center.z + bbHalfZ, 1.0f,
&outX, &outY, &outZ, &outS);
&outX, &outY, &outZ, &outW);
outX *= 1.0f / outS;
outY *= -(1.0f / outS);
outZ *= 1.0f / outS;
outS = 1.0f / outS;
outX *= 1.0f / outW;
outY *= -(1.0f / outW);
outZ *= 1.0f / outW;
outW = 1.0f / outW;
temp_f24 = temp_f20;
temp_f26 = temp_f22;
if (outS < 0.0f) {
if (outW < 0.0f) {
outX = 0.0f;
outY = 1.0f;
}
@ -228,14 +228,14 @@ void N(UnkModelFunc001)(void) {
transform_point(camera->perspectiveMatrix,
model->center.x + bbHalfX, model->center.y, model->center.z + bbHalfZ, 1.0f,
&outX, &outY, &outZ, &outS);
&outX, &outY, &outZ, &outW);
outX *= 1.0f / outS;
outY *= -(1.0f / outS);
outZ *= 1.0f / outS;
outS = 1.0f / outS;
outX *= 1.0f / outW;
outY *= -(1.0f / outW);
outZ *= 1.0f / outW;
outW = 1.0f / outW;
if (outS < 0.0f) {
if (outW < 0.0f) {
outX = 1.0f;
outY = 1.0f;
}
@ -258,14 +258,14 @@ void N(UnkModelFunc001)(void) {
transform_point(camera->perspectiveMatrix,
model->center.x + bbHalfX, model->center.y, model->center.z - bbHalfZ, 1.0f,
&outX, &outY, &outZ, &outS);
&outX, &outY, &outZ, &outW);
outX *= 1.0f / outS;
outY *= -(1.0f / outS);
outZ *= 1.0f / outS;
outS = 1.0f / outS;
outX *= 1.0f / outW;
outY *= -(1.0f / outW);
outZ *= 1.0f / outW;
outW = 1.0f / outW;
if (outS < 0.0f) {
if (outW < 0.0f) {
outX = 1.0f;
outY = 1.0f;
}

View File

@ -289,7 +289,7 @@ dlabel D_80153376
dlabel D_80153378
.space 8
dlabel D_80153380
dlabel depthCopyBuffer
.space 0x00000020
dlabel mdl_renderTaskLists

View File

@ -55,7 +55,7 @@ glabel bulb_glow_appendGfx
/* 37A730 E0078340 8E06000C */ lw $a2, 0xc($s0)
/* 37A734 E0078344 8E07001C */ lw $a3, 0x1c($s0)
/* 37A738 E0078348 24840008 */ addiu $a0, $a0, 8
/* 37A73C E007834C 0C08015C */ jal shim_func_8011CFBC
/* 37A73C E007834C 0C08015C */ jal shim_is_point_visible
/* 37A740 E0078350 AEA40000 */ sw $a0, ($s5)
/* 37A744 E0078354 0040182D */ daddu $v1, $v0, $zero
/* 37A748 E0078358 24020005 */ addiu $v0, $zero, 5

View File

@ -70,7 +70,7 @@ glabel motion_blur_flame_appendGfx
/* 3A2CCC E00A233C 27A2004C */ addiu $v0, $sp, 0x4c
/* 3A2CD0 E00A2340 44060000 */ mfc1 $a2, $f0
/* 3A2CD4 E00A2344 2407FFFF */ addiu $a3, $zero, -1
/* 3A2CD8 E00A2348 0C08015C */ jal shim_func_8011CFBC
/* 3A2CD8 E00A2348 0C08015C */ jal shim_is_point_visible
/* 3A2CDC E00A234C AFA20014 */ sw $v0, 0x14($sp)
/* 3A2CE0 E00A2350 080288D9 */ j .LE00A2364
/* 3A2CE4 E00A2354 0040302D */ daddu $a2, $v0, $zero

View File

@ -20,7 +20,7 @@
- shim_load_effect
- shim_sqrtf
- shim_mdl_draw_hidden_panel_surface
- shim_func_8011CFBC
- shim_is_point_visible
- shim_guPerspectiveF
- shim_guMtxIdentF
- shim_transform_point

View File

@ -4066,8 +4066,8 @@ mdl_make_local_vertex_copy = 0x8011C164; // type:func rom:0xB2864
mdl_get_copied_vertices = 0x8011C2B0; // type:func rom:0xB29B0
mdl_get_copied_gfx = 0x8011C2EC; // type:func rom:0xB29EC
mdl_project_tex_coords = 0x8011C32C; // type:func rom:0xB2A2C
func_8011C80C = 0x8011C80C; // type:func rom:0xB2F0C
func_8011CFBC = 0x8011CFBC; // type:func rom:0xB36BC
is_model_center_visible = 0x8011C80C; // type:func rom:0xB2F0C
is_point_visible = 0x8011CFBC; // type:func rom:0xB36BC
mdl_draw_hidden_panel_surface = 0x8011D72C; // type:func rom:0xB3E2C
mdl_get_next_texture_address = 0x8011D7E4; // type:func rom:0xB3EE4
mdl_set_all_fog_mode = 0x8011D82C; // type:func rom:0xB3F2C
@ -4522,7 +4522,7 @@ gRenderModelEnvB = 0x8014B765; // type:data rom:0xE1E65
D_8014B766 = 0x8014B766; // type:data rom:0xE1E66
D_8014B767 = 0x8014B767; // type:data rom:0xE1E67
mdl_RDPIdentity = 0x8014B768; // type:data rom:0xE1E68
D_8014B7A8 = 0x8014B7A8; // type:data rom:0xE1EA8
depthFloatLookupTable = 0x8014B7A8; // type:data rom:0xE1EA8
D_8014B7F0 = 0x8014B7F0; // type:data rom:0xE1EF0
D_8014B7F8 = 0x8014B7F8; // type:data rom:0xE1EF8
D_8014B820 = 0x8014B820; // type:data rom:0xE1F20
@ -4958,7 +4958,7 @@ D_80153370 = 0x80153370; // type:data rom:0xE9A70
D_80153374 = 0x80153374; // type:data rom:0xE9A74
D_80153376 = 0x80153376; // type:data rom:0xE9A76
D_80153378 = 0x80153378; // type:data rom:0xE9A78
D_80153380 = 0x80153380; // type:data rom:0xE9A80
depthCopyBuffer = 0x80153380; // type:data rom:0xE9A80
mdl_renderTaskLists = 0x801533A0; // type:data rom:0xE9AA0
mdl_renderTaskQueueIdx = 0x801533AC; // type:data rom:0xE9AAC
mdl_renderTaskCount = 0x801533B0; // type:data rom:0xE9AB0
@ -7984,7 +7984,7 @@ shim_npc_raycast_down_sides = 0xE0200530; // type:func rom:0x326000
shim_load_effect = 0xE0200540; // type:func rom:0x326010
shim_sqrtf = 0xE0200550; // type:func rom:0x326020
shim_mdl_draw_hidden_panel_surface = 0xE0200560; // type:func rom:0x326030
shim_func_8011CFBC = 0xE0200570; // type:func rom:0x326040
shim_is_point_visible = 0xE0200570; // type:func rom:0x326040
shim_guPerspectiveF = 0xE0200580; // type:func rom:0x326050
shim_guMtxIdentF = 0xE0200590; // type:func rom:0x326060
shim_transform_point = 0xE02005A0; // type:func rom:0x326070