#include "koopatlas/camera.h" #include "koopatlas/player.h" dWorldCamera_c *dWorldCamera_c::instance = 0; dWorldCamera_c *dWorldCamera_c::build() { void *buffer = AllocFromGameHeap1(sizeof(dWorldCamera_c)); dWorldCamera_c *c = new(buffer) dWorldCamera_c; instance = c; return c; } dWorldCamera_c::dWorldCamera_c() { camera3d.camPos = (Vec){0.0, 10.0, 0.0}; camera3d.target = (Vec){0.0, 0.0, 0.0}; camera3d.camUp = (Vec){0.0, 1.0, 0.0}; camera2d.camPos = (Vec){0.0, 10.0, 0.0}; camera2d.target = (Vec){0.0, 0.0, 0.0}; camera2d.camUp = (Vec){0.0, 1.0, 0.0}; camPos = (Vec){0.0, 0.0, 1.0}; camUp = (Vec){0.0, 1.0, 0.0}; projection2d.near = -20000.0f; projection2d.far = 20000.0f; currentX = 416; currentY = -224; zoomLevel = 2.8f; } int dWorldCamera_c::onCreate() { // Bad Code screen.projType = 0; screen.some_flag_bit |= 1; SSM *ssm = &ScreenSizesAndMultipliers[currentScreenSizeID]; screen.height = ssm->height; screen.width = ssm->width; screen.near = 1.0; screen.far = 20000.0; if (screen.isCentered != 1) { screen.some_flag_bit |= 1; screen.isCentered = 1; } doStuff(10000.0); generateCameraMatrices(); updateCameras(); return true; } int dWorldCamera_c::onDelete() { return true; } int dWorldCamera_c::onExecute() { if (dScKoopatlas_c::instance->warpZoneHacks) { currentX = 2040.0f; currentY = -1460.0f; zoomLevel = 3.4f; } else { daWMPlayer_c *player = daWMPlayer_c::instance; currentX = player->pos.x; currentY = player->pos.y; } calculateScreenGeometry(); doStuff(10000.0); generateCameraMatrices(); updateCameras(); return true; } int dWorldCamera_c::onDraw() { GXRenderModeObj *rmode = nw4r::g3d::G3DState::GetRenderModeObj(); nw4r::g3d::Camera cam(GetCameraByID(0)); nw4r::g3d::Camera cam2d(GetCameraByID(1)); if (rmode->field_rendering != 0) { cam.SetViewportJitter(VIGetNextField()); cam2d.SetViewportJitter(VIGetNextField()); } //cam2d.SetOrtho(rmode->efbHeight, 0.0f, 0.0f, rmode->fbWidth * (IsWideScreen() ? 1.3333334f : 1.0f), -100000.0f, 100000.0f); return true; } void dWorldCamera_c::calculateScreenGeometry() { zoomDivisor = 1.0 / zoomLevel; screenWidth = GlobalScreenWidth / zoomDivisor; screenHeight = GlobalScreenHeight / zoomDivisor; screenLeft = currentX - (screenWidth * 0.5); screenTop = currentY + (screenHeight * 0.5); } void dWorldCamera_c::doStuff(float something) { camTarget = (Vec){ screenLeft + (screenWidth * 0.5), (screenTop - screenHeight) + (screenHeight * 0.5), 0.0 }; camPos = (Vec){camTarget.x, camTarget.y, something}; } void dWorldCamera_c::generateCameraMatrices() { float orthoTop = screenHeight * 0.5; float orthoLeft = -screenWidth * 0.5; float orthoBottom = -orthoTop; float orthoRight = -orthoLeft; camera3d.camPos = camPos; camera3d.target = camTarget; camera3d.camUp = camUp; camera3d.calculateMatrix(); screen.setOrtho(orthoTop, orthoBottom, orthoLeft, orthoRight, -100000.0f, 100000.0f); VEC2 crap = GetSomeSizeRelatedBULLSHIT(); Vec calcedAboutRatio = CalculateSomethingAboutRatio(orthoTop, orthoBottom, orthoLeft, orthoRight); screen._44 = CalculateSomethingElseAboutRatio(); screen.width = crap.x; screen.some_flag_bit |= 1; screen.height = crap.y; screen.horizontalMultiplier = calcedAboutRatio.x; screen.verticalMultiplier = calcedAboutRatio.y; screen.unk3 = calcedAboutRatio.z; camera2d.camPos = (Vec){0.0, 0.0, 0.0}; camera2d.target = (Vec){0.0, 0.0, -100.0}; camera2d.camUp = camUp; camera2d.calculateMatrix(); GXRenderModeObj *rmode = nw4r::g3d::G3DState::GetRenderModeObj(); projection2d.setVolume(rmode->efbHeight, 0.0, 0.0, rmode->fbWidth * (IsWideScreen() ? 1.3333334f : 1.0f)); } void dWorldCamera_c::updateCameras() { nw4r::g3d::Camera cam0(GetCameraByID(0)); camera3d.assignToNW4RCamera(cam0); screen.loadIntoCamera(cam0); nw4r::g3d::Camera cam1(GetCameraByID(1)); projection2d.setOrthoOntoCamera(cam1); camera2d.assignToNW4RCamera(cam1); }