diff options
Diffstat (limited to 'src/koopatlas/camera.cpp')
-rw-r--r-- | src/koopatlas/camera.cpp | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/src/koopatlas/camera.cpp b/src/koopatlas/camera.cpp new file mode 100644 index 0000000..a4c642f --- /dev/null +++ b/src/koopatlas/camera.cpp @@ -0,0 +1,191 @@ +#include "koopatlas/camera.h" +#include "koopatlas/player.h" + +dWorldCamera_c *dWorldCamera_c::instance = 0; + +dWorldCamera_c *dWorldCamera_c::build() { + OSReport("Creating WorldCamera\n"); + + void *buffer = AllocFromGameHeap1(sizeof(dWorldCamera_c)); + dWorldCamera_c *c = new(buffer) dWorldCamera_c; + + OSReport("Created WorldCamera @ %p\n", 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 = 1.0; + projection2d.far = 20000.0; + + currentX = 0; + currentY = 0; + zoomLevel = 1; +} + + + +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() { + int nowPressed = Remocon_GetPressed(GetActiveRemocon()); + bool change = false; + if (nowPressed & WPAD_LEFT) { + currentX -= 16; + change = true; + } + if (nowPressed & WPAD_RIGHT) { + currentX += 16; + change = true; + } + if (nowPressed & WPAD_UP) { + currentY += 16; + change = true; + } + if (nowPressed & WPAD_DOWN) { + currentY -= 16; + change = true; + } + if (nowPressed & WPAD_B) { + zoomLevel -= 0.02; + change = true; + } + if (nowPressed & WPAD_A) { + zoomLevel += 0.02; + change = true; + } + if (change) { + OSReport("%f, %f (%f)\n", currentX, currentY, zoomLevel); + } + 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 : 0)); +} + + +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); +} + |