diff options
Diffstat (limited to '')
-rw-r--r-- | src/koopatlas/camera.cpp | 116 |
1 files changed, 114 insertions, 2 deletions
diff --git a/src/koopatlas/camera.cpp b/src/koopatlas/camera.cpp index d98bff0..f80ebcc 100644 --- a/src/koopatlas/camera.cpp +++ b/src/koopatlas/camera.cpp @@ -31,7 +31,9 @@ dWorldCamera_c::dWorldCamera_c() { currentX = 416; currentY = -224; - zoomLevel = 2.8f; + zoomLevel = STD_ZOOM; + + followPlayer = true; } @@ -70,7 +72,31 @@ int dWorldCamera_c::onExecute() { currentX = 2040.0f; currentY = -1460.0f; zoomLevel = 3.4f; - } else { + + } else if (panning) { + // Calculate where we are +#define SMOOTHSTEP(x) ((x) * (x) * (3 - 2 * (x))) + float stepRatio = panCurrentStep / panTotalSteps; + stepRatio = 1.0f - SMOOTHSTEP(stepRatio); + //OSReport("PAN: Step %f / %f ---- Ratio: %f", panCurrentStep, panTotalSteps, stepRatio); + //OSReport("From %f, %f to %f, %f --- Zoom: %f to %f\n", panFromX, panFromY, panToX, panToY, panFromZoom, panToZoom); + + currentX = (panFromX * stepRatio) + (panToX * (1.0f - stepRatio)); + currentY = (panFromY * stepRatio) + (panToY * (1.0f - stepRatio)); + zoomLevel = (panFromZoom * stepRatio) + (panToZoom * (1.0f - stepRatio)); + //OSReport("Calculated: %f, %f with zoom %f\n", currentX, currentY, zoomLevel); + + panCurrentStep += 1.0f; + + if (panCurrentStep > panTotalSteps) { + // YAY, we reached the end + panning = false; + currentX = panToX; + currentY = panToY; + zoomLevel = panToZoom; + } + + } else if (followPlayer) { daWMPlayer_c *player = daWMPlayer_c::instance; currentX = player->pos.x; currentY = player->pos.y; @@ -83,6 +109,92 @@ int dWorldCamera_c::onExecute() { return true; } +void dWorldCamera_c::panToBounds(float left, float top, float right, float bottom) { + // Pad it a bit + left -= 64.0f; + right += 64.0f; + top -= 48.0f; + bottom += 48.0f; + + //OSReport("Panning camera to bounds %f,%f to %f,%f\n", left, top, right, bottom); + + // Figure out the centre x/y we want + float width = right - left; + float height = bottom - top; + + float desiredCentreX = left + (width * 0.5f); + float desiredCentreY = -(top + (height * 0.5f)); + + //OSReport("Size: %f x %f ; Desired Centre: %f, %f\n", width, height, desiredCentreX, desiredCentreY); + + // Our default zoom is 2.8 + float minScreenWidth = GlobalScreenWidth * 1.2f; + float minScreenHeight = GlobalScreenHeight * 1.2f; + float maxScreenWidth = GlobalScreenWidth * 4.0f; + float maxScreenHeight = GlobalScreenHeight * 4.0f; + + //OSReport("Screen Sizes: Minimum possible %f x %f ; Maximum possible %f x %f\n", minScreenWidth, minScreenHeight, maxScreenWidth, maxScreenHeight); + + // First off, gotta cap it to the ratio + float screenRatio = GlobalScreenWidth / GlobalScreenHeight; + float boundsRatio = width / height; + float correctedWidth = width, correctedHeight = height; + float desiredZoomLevel; + //OSReport("Actual screen size is %f x %f --- Screen Ratio: %f, Bounds Ratio: %f\n", GlobalScreenWidth, GlobalScreenHeight, screenRatio, boundsRatio); + + float widthScale = width / GlobalScreenWidth; + float heightScale = height / GlobalScreenHeight; + + if (heightScale > widthScale) { + // Thing is constrained on the top/bottom + desiredZoomLevel = heightScale; + } else { + // Thing is constrained on the left/right + desiredZoomLevel = widthScale; + } + + //OSReport("Desired zoom level is %f\n", desiredZoomLevel); + + // Cap the zoom + if (desiredZoomLevel < 2.0f) + desiredZoomLevel = 2.0f; + if (desiredZoomLevel > 4.5f) + desiredZoomLevel = 4.5f; + //OSReport("After capping: %f\n", desiredZoomLevel); + + // And we're almost there YAY + panToPosition(desiredCentreX, desiredCentreY, desiredZoomLevel); +} + + +void dWorldCamera_c::panToPosition(float x, float y, float zoom) { + panFromX = currentX; + panFromY = currentY; + panFromZoom = zoomLevel; + + panToX = x; + panToY = y; + panToZoom = zoom; + + float xDiff = abs(panToX - panFromX); + float yDiff = abs(panToY - panFromY); + + float panLength = sqrtf((xDiff*xDiff) + (yDiff*yDiff)); + float panSteps = panLength / 2.3f; + float scaleSteps = abs(panToZoom - panFromZoom) / 0.1f; + float stepCount = max(panSteps, scaleSteps); + + //OSReport("Pan length: %f over %f steps\n", panLength, panSteps); + //OSReport("Scale steps: %f\n", scaleSteps); + //OSReport("Step Count: %f\n", stepCount); + + panCurrentStep = 0.0f; + panTotalSteps = stepCount; + + panning = true; + followPlayer = false; +} + int dWorldCamera_c::onDraw() { GXRenderModeObj *rmode = nw4r::g3d::G3DState::GetRenderModeObj(); |