aboutsummaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
authorJohannes Schickel2012-02-21 18:51:16 +0100
committerJohannes Schickel2012-02-21 18:54:26 +0100
commit80b34398174973b6d70673fce94a8a1f670c3f4d (patch)
treef8e88854cb7e89c2bba5581bc470465417310332 /backends
parentf6edcbde8ee3a052f2896c875f853526df0596b0 (diff)
downloadscummvm-rg350-80b34398174973b6d70673fce94a8a1f670c3f4d.tar.gz
scummvm-rg350-80b34398174973b6d70673fce94a8a1f670c3f4d.tar.bz2
scummvm-rg350-80b34398174973b6d70673fce94a8a1f670c3f4d.zip
IPHONE: Rewrite video screen rotation.
Now it should be a little bit more sane. Formerly the width and height was swapped in rotation mode, which resulted in the x coordinate falling into the range 0..height in landscape mode for example. This also fixes the cursor offset in the modern theme.
Diffstat (limited to 'backends')
-rw-r--r--backends/platform/iphone/iphone_video.h7
-rw-r--r--backends/platform/iphone/iphone_video.m248
2 files changed, 141 insertions, 114 deletions
diff --git a/backends/platform/iphone/iphone_video.h b/backends/platform/iphone/iphone_video.h
index 02b9c8692d..f2253f3e21 100644
--- a/backends/platform/iphone/iphone_video.h
+++ b/backends/platform/iphone/iphone_video.h
@@ -38,16 +38,9 @@
NSMutableArray *_events;
SoftKeyboard *_keyboardView;
- int _widthOffset;
- int _heightOffset;
-
EAGLContext *_context;
GLuint _viewRenderbuffer;
GLuint _viewFramebuffer;
- GLint _renderBufferWidth;
- GLint _renderBufferHeight;
- GLint _visibleWidth;
- GLint _visibleHeight;
GLuint _screenTexture;
GLuint _overlayTexture;
GLuint _mouseCursorTexture;
diff --git a/backends/platform/iphone/iphone_video.m b/backends/platform/iphone/iphone_video.m
index f7b8edd7b9..5cd9534611 100644
--- a/backends/platform/iphone/iphone_video.m
+++ b/backends/platform/iphone/iphone_video.m
@@ -57,6 +57,9 @@ static int _mouseX = 0;
static int _mouseY = 0;
static int _mouseCursorEnabled = 0;
+static GLint _renderBufferWidth;
+static GLint _renderBufferHeight;
+
#if 0
static long lastTick = 0;
static int frames = 0;
@@ -186,57 +189,64 @@ const char *iPhone_getDocumentsDir() {
return [documentsDirectory UTF8String];
}
-static bool getMouseCoords(UIDeviceOrientation orientation, CGPoint point, int *x, int *y) {
- if (_overlayIsEnabled) {
- switch (orientation) {
- case UIDeviceOrientationLandscapeLeft:
- *x = (int)point.y;
- *y = _overlayHeight - (int)point.x;
- break;
-
- case UIDeviceOrientationLandscapeRight:
- *x = _overlayWidth - (int)point.y;
- *y = (int)point.x;
- break;
-
- case UIDeviceOrientationPortrait:
- *x = (int)point.x;
- *y = (int)point.y;
- break;
-
- default:
- return false;
- }
- } else {
- if (point.x < _gameScreenRect.origin.x || point.x >= _gameScreenRect.origin.x + _gameScreenRect.size.width ||
- point.y < _gameScreenRect.origin.y || point.y >= _gameScreenRect.origin.y + _gameScreenRect.size.height) {
- return false;
- }
+/**
+ * Converts portrait mode coordinates into rotated mode coordinates.
+ */
+static bool convertToRotatedCoords(UIDeviceOrientation orientation, CGPoint point, CGPoint *result) {
+ switch (orientation) {
+ case UIDeviceOrientationLandscapeLeft:
+ result->x = point.y;
+ result->y = _renderBufferWidth - point.x;
+ return true;
- point.x = (point.x - _gameScreenRect.origin.x) / _gameScreenRect.size.width;
- point.y = (point.y - _gameScreenRect.origin.y) / _gameScreenRect.size.height;
+ case UIDeviceOrientationLandscapeRight:
+ result->x = _renderBufferHeight - point.y;
+ result->y = point.x;
+ return true;
- switch (orientation) {
- case UIDeviceOrientationLandscapeLeft:
- *x = point.y * _width;
- *y = (1.0f - point.x) * _height;
- break;
+ case UIDeviceOrientationPortrait:
+ result->x = point.x;
+ result->y = point.y;
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+static bool normalizeMouseCoords(CGPoint *point, CGRect area) {
+ if (point->x < CGRectGetMinX(area) || point->x > CGRectGetMaxX(area) ||
+ point->y < CGRectGetMinY(area) || point->y > CGRectGetMaxY(area)) {
+ return false;
+ }
+
+ point->x = (point->x - CGRectGetMinX(area)) / CGRectGetWidth(area);
+ point->y = (point->y - CGRectGetMinY(area)) / CGRectGetHeight(area);
+ return true;
+}
- case UIDeviceOrientationLandscapeRight:
- *x = (1.0f - point.y) * _width;
- *y = point.x * _height;
- break;
+static bool getMouseCoords(UIDeviceOrientation orientation, CGPoint point, int *x, int *y) {
+ if (!convertToRotatedCoords(orientation, point, &point))
+ return false;
- case UIDeviceOrientationPortrait:
- *x = point.x * _width;
- *y = point.y * _height;
- break;
+ int width, height;
+ if (_overlayIsEnabled) {
+ if (!normalizeMouseCoords(&point, _overlayRect))
+ return false;
- default:
+ width = _overlayWidth;
+ height = _overlayHeight;
+ } else {
+ if (!normalizeMouseCoords(&point, _gameScreenRect))
return false;
- }
+
+ width = _width;
+ height = _height;
}
+ *x = point.x * width;
+ *y = point.y * height;
+
return true;
}
@@ -311,7 +321,7 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {
// Since the overlay size won't change the whole run, we can
// precalculate the texture coordinates for the overlay texture here
// and just use it later on.
- _overlayTexCoords[0] = _overlayTexCoords[4] = _overlayWidth / (GLfloat)_overlayTexWidth;
+ _overlayTexCoords[2] = _overlayTexCoords[6] = _overlayWidth / (GLfloat)_overlayTexWidth;
_overlayTexCoords[5] = _overlayTexCoords[7] = _overlayHeight / (GLfloat)_overlayTexHeight;
int textureSize = _overlayTexWidth * _overlayTexHeight * 2;
@@ -477,32 +487,43 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {
int hotspotX = _mouseCursorHotspotX;
int hotspotY = _mouseCursorHotspotY;
+ CGRect *rect;
+ int maxWidth, maxHeight;
+
if (!_overlayIsEnabled) {
- const GLint gameWidth = (_visibleHeight - 2 * _widthOffset);
- const GLint gameHeight = (_visibleWidth - 2 * _heightOffset);
-
- mouseX = (_width - mouseX) / (float)_width * gameHeight + _heightOffset;
- mouseY = mouseY / (float)_height * gameWidth + _widthOffset;
- hotspotX = hotspotX / (float)_width * gameHeight;
- hotspotY = hotspotY / (float)_height * gameWidth;
- width = width / (float)_width * gameHeight;
- height = height / (float)_height * gameWidth;
+ rect = &_gameScreenRect;
+ maxWidth = _width;
+ maxHeight = _height;
} else {
- mouseX = (_overlayWidth - mouseX) / (float)_overlayWidth * _renderBufferWidth;
- mouseY = mouseY / (float)_overlayHeight * _renderBufferHeight;
- hotspotX = hotspotX / (float)_overlayWidth * _renderBufferWidth;
- hotspotY = hotspotY / (float)_overlayHeight * _renderBufferHeight;
- width = width / (float)_overlayWidth * _renderBufferWidth;
- height = height / (float)_overlayHeight * _renderBufferHeight;
+ rect = &_overlayRect;
+ maxWidth = _overlayWidth;
+ maxHeight = _overlayHeight;
}
+ const GLfloat scaleX = CGRectGetWidth(*rect) / (GLfloat)maxWidth;
+ const GLfloat scaleY = CGRectGetHeight(*rect) / (GLfloat)maxHeight;
+
+ mouseX = mouseX * scaleX;
+ mouseY = mouseY * scaleY;
+ hotspotX = hotspotX * scaleX;
+ hotspotY = hotspotY * scaleY;
+ width = width * scaleX;
+ height = height * scaleY;
+
mouseX -= hotspotX;
mouseY -= hotspotY;
+ mouseX += CGRectGetMinX(*rect);
+ mouseY += CGRectGetMinY(*rect);
+
GLfloat vertices[] = {
+ // Top left
mouseX , mouseY,
+ // Top right
mouseX + width, mouseY,
+ // Bottom left
mouseX , mouseY + height,
+ // Bottom right
mouseX + width, mouseY + height
};
@@ -512,10 +533,14 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {
float texHeight = _mouseCursorHeight / (float)getSizeNextPOT(_mouseCursorHeight);
const GLfloat texCoords[] = {
- texWidth, 0.0f,
- 0.0f, 0.0f,
- texWidth, texHeight,
- 0.0f, texHeight
+ // Top left
+ 0 , 0,
+ // Top right
+ texWidth, 0,
+ // Bottom left
+ 0 , texHeight,
+ // Bottom right
+ texWidth, texHeight
};
glVertexPointer(2, GL_FLOAT, 0, vertices); printOpenGLError();
@@ -529,7 +554,7 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {
_gameScreenTextureWidth = getSizeNextPOT(_width);
_gameScreenTextureHeight = getSizeNextPOT(_height);
- _gameScreenTexCoords[0] = _gameScreenTexCoords[4] = _width / (GLfloat)_gameScreenTextureWidth;
+ _gameScreenTexCoords[2] = _gameScreenTexCoords[6] = _width / (GLfloat)_gameScreenTextureWidth;
_gameScreenTexCoords[5] = _gameScreenTexCoords[7] = _height / (GLfloat)_gameScreenTextureHeight;
_orientation = [[UIDevice currentDevice] orientation];
@@ -549,15 +574,27 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
+ int screenWidth, screenHeight;
+
+ // Set the origin (0,0) depending on the rotation mode.
if (_orientation == UIDeviceOrientationLandscapeRight) {
- glRotatef(-90, 0, 0, 1); printOpenGLError();
+ glRotatef( 90, 0, 0, 1); printOpenGLError();
+ glOrthof(0, _renderBufferHeight, _renderBufferWidth, 0, 0, 1); printOpenGLError();
+
+ screenWidth = _renderBufferHeight;
+ screenHeight = _renderBufferWidth;
} else if (_orientation == UIDeviceOrientationLandscapeLeft) {
- glRotatef(90, 0, 0, 1); printOpenGLError();
- } else {
- glRotatef(180, 0, 0, 1); printOpenGLError();
- }
+ glRotatef(-90, 0, 0, 1); printOpenGLError();
+ glOrthof(0, _renderBufferHeight, _renderBufferWidth, 0, 0, 1); printOpenGLError();
- glOrthof(0, _renderBufferWidth, 0, _renderBufferHeight, 0, 1); printOpenGLError();
+ screenWidth = _renderBufferHeight;
+ screenHeight = _renderBufferWidth;
+ } else if (_orientation == UIDeviceOrientationPortrait) {
+ glOrthof(0, _renderBufferWidth, _renderBufferHeight, 0, 0, 1); printOpenGLError();
+
+ screenWidth = _renderBufferWidth;
+ screenHeight = _renderBufferHeight;
+ }
if (_screenTexture > 0) {
glDeleteTextures(1, &_screenTexture); printOpenGLError();
@@ -590,36 +627,39 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {
float overlayPortraitRatio;
if (_orientation == UIDeviceOrientationLandscapeLeft || _orientation == UIDeviceOrientationLandscapeRight) {
- _visibleHeight = _renderBufferHeight;
- _visibleWidth = _renderBufferWidth;
+ GLfloat gameScreenRatio = (GLfloat)_width / (GLfloat)_height;
+ GLfloat screenRatio = (GLfloat)screenWidth / (GLfloat)screenHeight;
- float ratioDifference = ((float)_height / (float)_width) / ((float)_renderBufferWidth / (float)_renderBufferHeight);
+ // These are the width/height according to the portrait layout!
int rectWidth, rectHeight;
- if (ratioDifference < 1.0f) {
- rectWidth = _renderBufferWidth * ratioDifference;
- rectHeight = _renderBufferHeight;
- _widthOffset = (_renderBufferWidth - rectWidth) / 2;
- _heightOffset = 0;
+ int xOffset, yOffset;
+
+ if (gameScreenRatio < screenRatio) {
+ // When the game screen ratio is less than the screen ratio
+ // we need to scale the width, since the game screen was higher
+ // compared to the width than our output screen is.
+ rectWidth = screenHeight * gameScreenRatio;
+ rectHeight = screenHeight;
+ xOffset = (screenWidth - rectWidth) / 2;
+ yOffset = 0;
} else {
- rectWidth = _renderBufferWidth;
- rectHeight = _renderBufferHeight / ratioDifference;
- _heightOffset = (_renderBufferHeight - rectHeight) / 2;
- _widthOffset = 0;
+ // When the game screen ratio is bigger than the screen ratio
+ // we need to scale the height, since the game screen was wider
+ // compared to the height than our output screen is.
+ rectWidth = screenWidth;
+ rectHeight = screenWidth / gameScreenRatio;
+ xOffset = 0;
+ yOffset = (screenHeight - rectHeight) / 2;
}
- //printf("Rect: %i, %i, %i, %i\n", _widthOffset, _heightOffset, rectWidth, rectHeight);
- _gameScreenRect = CGRectMake(_widthOffset, _heightOffset, rectWidth, rectHeight);
+ //printf("Rect: %i, %i, %i, %i\n", xOffset, yOffset, rectWidth, rectHeight);
+ _gameScreenRect = CGRectMake(xOffset, yOffset, rectWidth, rectHeight);
overlayPortraitRatio = 1.0f;
} else {
float ratio = (float)_height / (float)_width;
- int height = _renderBufferWidth * ratio;
- //printf("Making rect (%u, %u)\n", _renderBufferWidth, height);
- _gameScreenRect = CGRectMake(0, 0, _renderBufferWidth - 1, height - 1);
-
- _visibleHeight = height;
- _visibleWidth = _renderBufferWidth;
- _heightOffset = 0.0f;
- _widthOffset = 0.0f;
+ int height = screenWidth * ratio;
+ //printf("Making rect (%u, %u)\n", screenWidth, height);
+ _gameScreenRect = CGRectMake(0, 0, screenWidth, height);
CGRect keyFrame = CGRectMake(0.0f, 0.0f, 0.0f, 0.0f);
if (_keyboardView == nil) {
@@ -633,21 +673,15 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {
overlayPortraitRatio = (_overlayHeight * ratio) / _overlayWidth;
}
- _overlayRect = CGRectMake(0, 0, _renderBufferWidth, _renderBufferHeight * overlayPortraitRatio);
-
- _gameScreenVertCoords[0] = _heightOffset;
- _gameScreenVertCoords[1] = _widthOffset;
- _gameScreenVertCoords[2] = _visibleWidth - _heightOffset;
- _gameScreenVertCoords[3] = _widthOffset;
- _gameScreenVertCoords[4] = _heightOffset;
- _gameScreenVertCoords[5] = _visibleHeight - _widthOffset;
- _gameScreenVertCoords[6] = _visibleWidth - _heightOffset;
- _gameScreenVertCoords[7] = _visibleHeight - _widthOffset;
-
- _overlayVertCoords[2] = _overlayHeight;
- _overlayVertCoords[5] = _overlayWidth * _overlayPortraitRatio;
- _overlayVertCoords[6] = _overlayHeight;
- _overlayVertCoords[7] = _overlayWidth * _overlayPortraitRatio;
+ _overlayRect = CGRectMake(0, 0, screenWidth, screenHeight * overlayPortraitRatio);
+
+ _gameScreenVertCoords[0] = _gameScreenVertCoords[4] = CGRectGetMinX(_gameScreenRect);
+ _gameScreenVertCoords[1] = _gameScreenVertCoords[3] = CGRectGetMinY(_gameScreenRect);
+ _gameScreenVertCoords[2] = _gameScreenVertCoords[6] = CGRectGetMaxX(_gameScreenRect);
+ _gameScreenVertCoords[5] = _gameScreenVertCoords[7] = CGRectGetMaxY(_gameScreenRect);
+
+ _overlayVertCoords[2] = _overlayVertCoords[6] = CGRectGetMaxX(_overlayRect);
+ _overlayVertCoords[5] = _overlayVertCoords[7] = CGRectGetMaxY(_overlayRect);
}
- (void)clearColorBuffer {