#include "ShipUtils.h" #include #include "soh_assets.h" extern "C" { #include "z64.h" #include "functions.h" #include "macros.h" extern float OTRGetAspectRatio(); extern f32 sFontWidths[144]; extern const char* fontTbl[140]; } constexpr f32 fourByThree = 4.0f / 3.0f; // Gets the additional ratio of the screen compared to the original 4:3 ratio, clamping to 1 if smaller extern "C" f32 Ship_GetExtendedAspectRatioMultiplier() { f32 currentRatio = OTRGetAspectRatio(); return MAX(currentRatio / fourByThree, 1.0f); } // Enables Extended Culling options on specific actors by applying an inverse ratio of the draw distance slider // to the projected Z value of the actor. This tricks distance checks without having to replace hardcoded values. // Requires that Ship_ExtendedCullingActorRestoreProjectedPos is called within the same function scope. extern "C" void Ship_ExtendedCullingActorAdjustProjectedZ(Actor* actor) { s32 multiplier = CVarGetInteger("gEnhancements.Graphics.IncreaseActorDrawDistance", 1); multiplier = MAX(multiplier, 1); if (multiplier > 1) { actor->projectedPos.z /= multiplier; } } // Enables Extended Culling options on specific actors by applying an inverse ratio of the widescreen aspect ratio // to the projected X value of the actor. This tricks distance checks without having to replace hardcoded values. // Requires that Ship_ExtendedCullingActorRestoreProjectedPos is called within the same function scope. extern "C" void Ship_ExtendedCullingActorAdjustProjectedX(Actor* actor) { if (CVarGetInteger("gEnhancements.Graphics.ActorCullingAccountsForWidescreen", 0)) { f32 ratioAdjusted = Ship_GetExtendedAspectRatioMultiplier(); actor->projectedPos.x /= ratioAdjusted; } } // Restores the projectedPos values on the actor after modifications from the Extended Culling hacks // extern "C" void Ship_ExtendedCullingActorRestoreProjectedPos(PlayState* play, Actor* actor) { // f32 invW = 0.0f; // Actor_GetProjectedPos(play, &actor->world.pos, &actor->projectedPos, &invW); //} extern "C" bool Ship_IsCStringEmpty(const char* str) { return str == NULL || str[0] == '\0'; } // Build vertex coordinates for a quad command // In order of top left, top right, bottom left, then bottom right // Supports flipping the texture horizontally extern "C" void Ship_CreateQuadVertexGroup(Vtx* vtxList, s32 xStart, s32 yStart, s32 width, s32 height, u8 flippedH) { vtxList[0].v.ob[0] = xStart; vtxList[0].v.ob[1] = yStart; vtxList[0].v.tc[0] = (flippedH ? width : 0) << 5; vtxList[0].v.tc[1] = 0 << 5; vtxList[1].v.ob[0] = xStart + width; vtxList[1].v.ob[1] = yStart; vtxList[1].v.tc[0] = (flippedH ? width * 2 : width) << 5; vtxList[1].v.tc[1] = 0 << 5; vtxList[2].v.ob[0] = xStart; vtxList[2].v.ob[1] = yStart + height; vtxList[2].v.tc[0] = (flippedH ? width : 0) << 5; vtxList[2].v.tc[1] = height << 5; vtxList[3].v.ob[0] = xStart + width; vtxList[3].v.ob[1] = yStart + height; vtxList[3].v.tc[0] = (flippedH ? width * 2 : width) << 5; vtxList[3].v.tc[1] = height << 5; } extern "C" f32 Ship_GetCharFontWidth(u8 character) { u8 adjustedChar = character - ' '; if (adjustedChar >= ARRAY_COUNTU(sFontWidths)) { return 0.0f; } return sFontWidths[adjustedChar]; } extern "C" void* Ship_GetCharFontTexture(u8 character) { u8 adjustedChar = character - ' '; if (adjustedChar >= ARRAY_COUNTU(fontTbl)) { return (void*)gEmptyTexture; } return (void*)fontTbl[adjustedChar]; }