diff --git a/mm/2s2h/BenPort.cpp b/mm/2s2h/BenPort.cpp index b951c89ee..634fb1baf 100644 --- a/mm/2s2h/BenPort.cpp +++ b/mm/2s2h/BenPort.cpp @@ -610,12 +610,17 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) { float divisor_num = 0.0f; +// Batch a coordinate to have its depth read later by OTRGetPixelDepth extern "C" void OTRGetPixelDepthPrepare(float x, float y) { - OTRGlobals::Instance->context->GetWindow()->GetPixelDepthPrepare(x, y); + // Invert the Y value to match the origin values used in the renderer + float adjustedY = SCREEN_HEIGHT - y; + OTRGlobals::Instance->context->GetWindow()->GetPixelDepthPrepare(x, adjustedY); } extern "C" uint16_t OTRGetPixelDepth(float x, float y) { - return OTRGlobals::Instance->context->GetWindow()->GetPixelDepth(x, y); + // Invert the Y value to match the origin values used in the renderer + float adjustedY = SCREEN_HEIGHT - y; + return OTRGlobals::Instance->context->GetWindow()->GetPixelDepth(x, adjustedY); } extern "C" uint32_t ResourceMgr_GetNumGameVersions() { diff --git a/mm/include/functions.h b/mm/include/functions.h index b77f4a7c8..a7f79fa38 100644 --- a/mm/include/functions.h +++ b/mm/include/functions.h @@ -1323,6 +1323,9 @@ void osContGetReadData(OSContPad* pad); void PadMgr_ThreadEntry(); void Heaps_Alloc(void); // #endregion +// #region 2S2H [Port] New methods added for porting +void Lights_GlowCheckPrepare(PlayState* play); +// #endregion // #region 2S2H [Port] Stubbed methods void osSetThreadPri(OSThread* thread, OSPri p); OSPri osGetThreadPri(OSThread* t); diff --git a/mm/src/code/sys_cfb.c b/mm/src/code/sys_cfb.c index 98a99ceba..66350d666 100644 --- a/mm/src/code/sys_cfb.c +++ b/mm/src/code/sys_cfb.c @@ -121,6 +121,9 @@ void* SysCfb_GetWorkBuffer(void) { } u16 SysCfb_GetZBufferPixel(s32 x, s32 y) { + // 2S2H [Port] Get the zbuffer pixel value from the renderer directly + return OTRGetPixelDepth(x, y); +#if 0 u16* zBuff = SysCfb_GetZBuffer(); u16 val; @@ -130,8 +133,12 @@ u16 SysCfb_GetZBufferPixel(s32 x, s32 y) { val = 0; } return val; +#endif } s32 SysCfb_GetZBufferInt(s32 x, s32 y) { - return Environment_ZBufValToFixedPoint(SysCfb_GetZBufferPixel(x, y) << 2) >> 3; + // 2S2H [Port] The value from the renderer does not need to be converted to a fixed point + // Simply shifting is all we need to get the proper value + return SysCfb_GetZBufferPixel(x, y) >> 1; + // return Environment_ZBufValToFixedPoint(SysCfb_GetZBufferPixel(x, y) << 2) >> 3; } diff --git a/mm/src/code/z_kankyo.c b/mm/src/code/z_kankyo.c index e2255504a..d2b120555 100644 --- a/mm/src/code/z_kankyo.c +++ b/mm/src/code/z_kankyo.c @@ -490,6 +490,10 @@ void Environment_JumpForwardInTime(void); void Environment_GraphCallback(GraphicsContext* gfxCtx, void* arg) { PlayState* play = (PlayState*)arg; + // 2S2H [Port] Batch all the coordinates that need their depth checked by calling prepare + OTRGetPixelDepthPrepare(sSunDepthTestX, sSunDepthTestY); + Lights_GlowCheckPrepare(play); + sSunScreenDepth = SysCfb_GetZBufferPixel(sSunDepthTestX, sSunDepthTestY); Lights_GlowCheck(play); } diff --git a/mm/src/code/z_lights.c b/mm/src/code/z_lights.c index 9936a0c2d..b60090d06 100644 --- a/mm/src/code/z_lights.c +++ b/mm/src/code/z_lights.c @@ -372,6 +372,35 @@ Lights* Lights_New(GraphicsContext* gfxCtx, u8 ambientR, u8 ambientG, u8 ambient return lights; } +// 2S2H [Port] Similar to Lights_GlowCheck, but only submits the coordinates to the depth prepare +// for batching and then will be read after when Lights_GlowCheck is called +void Lights_GlowCheckPrepare(PlayState* play) { + LightNode* light = play->lightCtx.listHead; + + while (light != NULL) { + LightPoint* params = &light->info->params.point; + + if (light->info->type == LIGHT_POINT_GLOW) { + Vec3f worldPos; + Vec3f projectedPos; + f32 invW; + + worldPos.x = params->x; + worldPos.y = params->y; + worldPos.z = params->z; + Actor_GetProjectedPos(play, &worldPos, &projectedPos, &invW); + + if ((projectedPos.z > 1) && (fabsf(projectedPos.x * invW) < 1) && (fabsf(projectedPos.y * invW) < 1)) { + s32 screenPosX = PROJECTED_TO_SCREEN_X(projectedPos, invW); + s32 screenPosY = PROJECTED_TO_SCREEN_Y(projectedPos, invW); + OTRGetPixelDepthPrepare(screenPosX, screenPosY); + } + } + + light = light->next; + } +} + void Lights_GlowCheck(PlayState* play) { LightNode* light = play->lightCtx.listHead;