summaryrefslogtreecommitdiff
path: root/src/koopatlas/camera.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/koopatlas/camera.cpp')
-rw-r--r--src/koopatlas/camera.cpp116
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();