From ab01f42a4bf33192c43bdae49ddfa9040d013c68 Mon Sep 17 00:00:00 2001 From: Oystein Eftevaag Date: Wed, 29 Sep 2010 00:19:13 +0000 Subject: IPHONE: The overlay will now always be in the native device resolution svn-id: r52939 --- backends/platform/iphone/iphone_common.h | 9 +- backends/platform/iphone/iphone_main.m | 15 +- backends/platform/iphone/iphone_video.h | 7 + backends/platform/iphone/iphone_video.m | 292 +++++++++++++++++++++++++------ backends/platform/iphone/osys_events.cpp | 38 ++-- backends/platform/iphone/osys_main.cpp | 6 +- backends/platform/iphone/osys_main.h | 5 +- backends/platform/iphone/osys_video.cpp | 99 +++++++---- 8 files changed, 370 insertions(+), 101 deletions(-) (limited to 'backends/platform/iphone') diff --git a/backends/platform/iphone/iphone_common.h b/backends/platform/iphone/iphone_common.h index 1f5ed01982..7c7770f443 100644 --- a/backends/platform/iphone/iphone_common.h +++ b/backends/platform/iphone/iphone_common.h @@ -67,12 +67,19 @@ void iphone_main(int argc, char *argv[]); #endif // On the ObjC side -void iPhone_updateScreen(); +void iPhone_updateScreen(int mouseX, int mouseY); void iPhone_updateScreenRect(unsigned short* screen, int x1, int y1, int x2, int y2); +void iPhone_updateOverlayRect(unsigned short* screen, int x1, int y1, int x2, int y2); void iPhone_initSurface(int width, int height); bool iPhone_fetchEvent(int *outEvent, float *outX, float *outY); const char* iPhone_getDocumentsDir(); bool iPhone_isHighResDevice(); +int iPhone_getScreenHeight(); +int iPhone_getScreenWidth(); +void iPhone_enableOverlay(int state); +void iPhone_setMouseCursor(short* buffer, int width, int height); + +uint getSizeNextPOT(uint size); #ifdef __cplusplus } diff --git a/backends/platform/iphone/iphone_main.m b/backends/platform/iphone/iphone_main.m index d8992de5bb..5a5ec95090 100644 --- a/backends/platform/iphone/iphone_main.m +++ b/backends/platform/iphone/iphone_main.m @@ -103,15 +103,26 @@ int main(int argc, char** argv) { [NSThread detachNewThreadSelector:@selector(mainLoop:) toTarget:self withObject:nil]; } +- (void)applicationDidResume +{ +} + +- (void)applicationWillSuspend +{ +} + +- (void)applicationWillTerminate +{ +} + - (void)applicationSuspend:(struct __GSEvent *)event { //[self setApplicationBadge:NSLocalizedString(@"ON", nil)]; [_view applicationSuspend]; } - (void)applicationResume:(struct __GSEvent *)event { - [self removeApplicationBadge]; [_view applicationResume]; - + // Workaround, need to "hide" and unhide the statusbar to properly remove it, // since the Springboard has put it back without apparently flagging our application. [self setStatusBarHidden:YES animated:YES]; diff --git a/backends/platform/iphone/iphone_video.h b/backends/platform/iphone/iphone_video.h index 1060a2a223..aed15ecfd5 100644 --- a/backends/platform/iphone/iphone_video.h +++ b/backends/platform/iphone/iphone_video.h @@ -54,6 +54,8 @@ GLint _visibleWidth; GLint _visibleHeight; GLuint _screenTexture; + GLuint _overlayTexture; + GLuint _mouseCursorTexture; } - (id)initWithFrame:(struct CGRect)frame; @@ -65,6 +67,11 @@ - (void)initSurface; - (void)updateSurface; +- (void)updateMainSurface; +- (void)updateOverlaySurface; +- (void)updateMouseSurface; + +-(void)updateMouseCursor; - (id)getEvent; diff --git a/backends/platform/iphone/iphone_video.m b/backends/platform/iphone/iphone_video.m index cd8b38acb3..9704b302fb 100644 --- a/backends/platform/iphone/iphone_video.m +++ b/backends/platform/iphone/iphone_video.m @@ -32,23 +32,88 @@ static int _height = 0; static int _fullWidth; static int _fullHeight; static CGRect _screenRect; + static char* _textureBuffer = 0; static int _textureWidth = 0; static int _textureHeight = 0; + +static char* _overlayTexBuffer = 0; +static int _overlayTexWidth = 0; +static int _overlayTexHeight = 0; +static int _overlayWidth = 0; +static int _overlayHeight = 0; +static float _overlayPortraitRatio = 1.0f; + NSLock* _lock = nil; static int _needsScreenUpdate = 0; +static int _overlayIsEnabled = 0; static UITouch* _firstTouch = NULL; static UITouch* _secondTouch = NULL; +static short* _mouseCursor = NULL; +static int _mouseCursorHeight = 0; +static int _mouseCursorWidth = 0; +static int _mouseX = 0; +static int _mouseY = 0; + // static long lastTick = 0; // static int frames = 0; +#define printOpenGLError() printOglError(__FILE__, __LINE__) + +int printOglError(const char *file, int line) +{ + int retCode = 0; + + // returns 1 if an OpenGL error occurred, 0 otherwise. + GLenum glErr = glGetError(); + while( glErr != GL_NO_ERROR) + { + fprintf(stderr, "glError: %u (%s: %d)\n", glErr, file, line ); + retCode = 1; + glErr = glGetError(); + } + return retCode; +} + +void iPhone_setMouseCursor(short* buffer, int width, int height) { + _mouseCursor = buffer; + + _mouseCursorWidth = width; + _mouseCursorHeight = height; + + [sharedInstance performSelectorOnMainThread:@selector(updateMouseCursor) withObject:nil waitUntilDone: YES]; +} + +void iPhone_enableOverlay(int state) { + _overlayIsEnabled = state; +} + +int iPhone_getScreenHeight() { + return _overlayHeight; +} + +int iPhone_getScreenWidth() { + return _overlayWidth; +} + bool iPhone_isHighResDevice() { return _fullHeight > 480; } -void iPhone_updateScreen() { +void iPhone_updateScreen(int mouseX, int mouseY) { + //printf("Mouse: (%i, %i)\n", mouseX, mouseY); + + //_mouseX = _overlayHeight - (float)mouseX / _width * _overlayHeight; + //_mouseY = (float)mouseY / _height * _overlayWidth; + + //_mouseX = _overlayHeight - mouseX; + //_mouseY = mouseY; + + _mouseX = (_overlayWidth - mouseX) / (float)_overlayWidth * _overlayHeight; + _mouseY = mouseY / (float)_overlayHeight * _overlayWidth; + if (!_needsScreenUpdate) { _needsScreenUpdate = 1; [sharedInstance performSelectorOnMainThread:@selector(updateSurface) withObject:nil waitUntilDone: NO]; @@ -56,16 +121,17 @@ void iPhone_updateScreen() { } void iPhone_updateScreenRect(unsigned short* screen, int x1, int y1, int x2, int y2) { - //[_lock lock]; - int y; - for (y = y1; y < y2; ++y) { + for (y = y1; y < y2; ++y) memcpy(&_textureBuffer[(y * _textureWidth + x1 )* 2], &screen[y * _width + x1], (x2 - x1) * 2); - } - - //[_lock unlock]; } +void iPhone_updateOverlayRect(unsigned short* screen, int x1, int y1, int x2, int y2) { + int y; + //printf("Overlaywidth: %u, fullwidth %u\n", _overlayWidth, _fullWidth); + for (y = y1; y < y2; ++y) + memcpy(&_overlayTexBuffer[(y * _overlayTexWidth + x1 )* 2], &screen[y * _overlayWidth + x1], (x2 - x1) * 2); +} void iPhone_initSurface(int width, int height) { _width = width; @@ -92,6 +158,19 @@ bool iPhone_fetchEvent(int *outEvent, float *outX, float *outY) { return true; } +uint getSizeNextPOT(uint size) { + if ((size & (size - 1)) || !size) { + int log = 0; + + while (size >>= 1) + ++log; + + size = (2 << log); + } + + return size; +} + const char* iPhone_getDocumentsDir() { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; @@ -110,18 +189,6 @@ bool getLocalMouseCoords(CGPoint *point) { return true; } -uint getSizeNextPOT(uint size) { - if ((size & (size - 1)) || !size) { - int log = 0; - - while (size >>= 1) - ++log; - - size = (2 << log); - } - - return size; -} @implementation iPhoneView @@ -131,7 +198,15 @@ uint getSizeNextPOT(uint size) { } - (id)initWithFrame:(struct CGRect)frame { - [super initWithFrame: frame]; + self = [super initWithFrame: frame]; + + if([[UIScreen mainScreen] respondsToSelector: NSSelectorFromString(@"scale")]) + { + if([self respondsToSelector: NSSelectorFromString(@"contentScaleFactor")]) + { + //self.contentScaleFactor = [[UIScreen mainScreen] scale]; + } + } _fullWidth = frame.size.width; _fullHeight = frame.size.height; @@ -143,6 +218,8 @@ uint getSizeNextPOT(uint size) { _keyboardView = nil; _context = nil; _screenTexture = 0; + _overlayTexture = 0; + _mouseCursorTexture = 0; return self; } @@ -156,6 +233,8 @@ uint getSizeNextPOT(uint size) { if (_screenTexture) free(_textureBuffer); + + free(_overlayTexBuffer); } - (void *)getSurface { @@ -181,6 +260,38 @@ uint getSizeNextPOT(uint size) { } _needsScreenUpdate = 0; + if (_overlayIsEnabled) { + glClear(GL_COLOR_BUFFER_BIT); printOpenGLError(); + } + + [self updateMainSurface]; + + if (_overlayIsEnabled) { + [self updateOverlaySurface]; + [self updateMouseSurface]; + } + + glBindRenderbufferOES(GL_RENDERBUFFER_OES, _viewRenderbuffer); printOpenGLError(); + [_context presentRenderbuffer:GL_RENDERBUFFER_OES]; + +} + +-(void)updateMouseCursor { + if (_mouseCursorTexture == 0) { + glGenTextures(1, &_mouseCursorTexture); printOpenGLError(); + glBindTexture(GL_TEXTURE_2D, _mouseCursorTexture); printOpenGLError(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); printOpenGLError(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); printOpenGLError(); + } + + glBindTexture(GL_TEXTURE_2D, _mouseCursorTexture); printOpenGLError(); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getSizeNextPOT(_mouseCursorWidth), getSizeNextPOT(_mouseCursorHeight), 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, _mouseCursor); printOpenGLError(); + + free(_mouseCursor); + _mouseCursor = NULL; +} + +- (void)updateMainSurface { GLfloat vertices[] = { 0.0f + _heightOffset, 0.0f + _widthOffset, _visibleWidth - _heightOffset, 0.0f + _widthOffset, @@ -198,20 +309,76 @@ uint getSizeNextPOT(uint size) { 0.0f, texHeight }; - glVertexPointer(2, GL_FLOAT, 0, vertices); - glTexCoordPointer(2, GL_FLOAT, 0, texCoords); + glVertexPointer(2, GL_FLOAT, 0, vertices); printOpenGLError(); + glTexCoordPointer(2, GL_FLOAT, 0, texCoords); printOpenGLError(); + + glBindTexture(GL_TEXTURE_2D, _screenTexture); printOpenGLError(); - //[_lock lock]; // Unfortunately we have to update the whole texture every frame, since glTexSubImage2D is actually slower in all cases // due to the iPhone internals having to convert the whole texture back from its internal format when used. // In the future we could use several tiled textures instead. - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _textureWidth, _textureHeight, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, _textureBuffer); - //[_lock unlock]; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _textureWidth, _textureHeight, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, _textureBuffer); printOpenGLError(); + glDisable(GL_BLEND); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); printOpenGLError(); +} - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glBindRenderbufferOES(GL_RENDERBUFFER_OES, _viewRenderbuffer); - [_context presentRenderbuffer:GL_RENDERBUFFER_OES]; +- (void)updateOverlaySurface { + GLfloat vertices[] = { + 0.0f, 0.0f, + _overlayHeight, 0.0f, + 0.0f, _overlayWidth * _overlayPortraitRatio, + _overlayHeight, _overlayWidth * _overlayPortraitRatio + }; + + float texWidth = _overlayWidth / (float)_overlayTexWidth; + float texHeight = _overlayHeight / (float)_overlayTexHeight; + + const GLfloat texCoords[] = { + texWidth, 0.0f, + 0.0f, 0.0f, + texWidth, texHeight, + 0.0f, texHeight + }; + + glVertexPointer(2, GL_FLOAT, 0, vertices); printOpenGLError(); + glTexCoordPointer(2, GL_FLOAT, 0, texCoords); printOpenGLError(); + glBindTexture(GL_TEXTURE_2D, _overlayTexture); printOpenGLError(); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _overlayTexWidth, _overlayTexHeight, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, _overlayTexBuffer); printOpenGLError(); + glEnable(GL_BLEND); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); printOpenGLError(); +} + +- (void)updateMouseSurface { + + int width = _mouseCursorWidth / (float)_backingWidth * _backingHeight; + int height = _mouseCursorHeight / (float)_backingHeight * _backingWidth; + + GLfloat vertices[] = { + _mouseX, _mouseY, + _mouseX + height, _mouseY, + _mouseX, _mouseY + width, + _mouseX + height, _mouseY + width + }; + + //printf("Cursor: width %u height %u\n", _mouseCursorWidth, _mouseCursorHeight); + + float texWidth = _mouseCursorWidth / (float)getSizeNextPOT(_mouseCursorWidth); + float texHeight = _mouseCursorHeight / (float)getSizeNextPOT(_mouseCursorHeight); + + const GLfloat texCoords[] = { + texWidth, 0.0f, + 0.0f, 0.0f, + texWidth, texHeight, + 0.0f, texHeight + }; + + glVertexPointer(2, GL_FLOAT, 0, vertices); printOpenGLError(); + glTexCoordPointer(2, GL_FLOAT, 0, texCoords); printOpenGLError(); + + glBindTexture(GL_TEXTURE_2D, _mouseCursorTexture); printOpenGLError(); + glEnable(GL_BLEND); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); printOpenGLError(); } - (void)initSurface { @@ -232,28 +399,39 @@ uint getSizeNextPOT(uint size) { _context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; if (!_context || [EAGLContext setCurrentContext:_context]) { - glGenFramebuffersOES(1, &_viewFramebuffer); - glGenRenderbuffersOES(1, &_viewRenderbuffer); + glGenFramebuffersOES(1, &_viewFramebuffer); printOpenGLError(); + glGenRenderbuffersOES(1, &_viewRenderbuffer); printOpenGLError(); - glBindFramebufferOES(GL_FRAMEBUFFER_OES, _viewFramebuffer); - glBindRenderbufferOES(GL_RENDERBUFFER_OES, _viewRenderbuffer); + glBindFramebufferOES(GL_FRAMEBUFFER_OES, _viewFramebuffer); printOpenGLError(); + glBindRenderbufferOES(GL_RENDERBUFFER_OES, _viewRenderbuffer); printOpenGLError(); [_context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(id)self.layer]; - glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, _viewRenderbuffer); + glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, _viewRenderbuffer); printOpenGLError(); - glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &_backingWidth); - glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &_backingHeight); + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &_backingWidth); printOpenGLError(); + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &_backingHeight); printOpenGLError(); if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) { NSLog(@"Failed to make complete framebuffer object %x.", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); return; } - glViewport(0, 0, _backingWidth, _backingHeight); - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + _overlayHeight = _backingWidth; + _overlayWidth = _backingHeight; + _overlayTexWidth = getSizeNextPOT(_overlayHeight); + _overlayTexHeight = getSizeNextPOT(_overlayWidth); + + int textureSize = _overlayTexWidth * _overlayTexHeight * 2; + _overlayTexBuffer = (char *)malloc(textureSize); + memset(_overlayTexBuffer, 0, textureSize); - glEnable(GL_TEXTURE_2D); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_VERTEX_ARRAY); + glViewport(0, 0, _backingWidth, _backingHeight); printOpenGLError(); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); printOpenGLError(); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glEnable(GL_TEXTURE_2D); printOpenGLError(); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); printOpenGLError(); + glEnableClientState(GL_VERTEX_ARRAY); printOpenGLError(); } } @@ -261,22 +439,32 @@ uint getSizeNextPOT(uint size) { glLoadIdentity(); if (orientation == UIDeviceOrientationLandscapeRight) { - glRotatef(-90, 0, 0, 1); + glRotatef(-90, 0, 0, 1); printOpenGLError(); } else if (orientation == UIDeviceOrientationLandscapeLeft) { - glRotatef(90, 0, 0, 1); + glRotatef(90, 0, 0, 1); printOpenGLError(); } else { - glRotatef(180, 0, 0, 1); + glRotatef(180, 0, 0, 1); printOpenGLError(); } - glOrthof(0, _backingWidth, 0, _backingHeight, 0, 1); + glOrthof(0, _backingWidth, 0, _backingHeight, 0, 1); printOpenGLError(); if (_screenTexture > 0) { - glDeleteTextures(1, &_screenTexture); + glDeleteTextures(1, &_screenTexture); printOpenGLError(); + } + + glGenTextures(1, &_screenTexture); printOpenGLError(); + glBindTexture(GL_TEXTURE_2D, _screenTexture); printOpenGLError(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); printOpenGLError(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); printOpenGLError(); + + if (_overlayTexture > 0) { + glDeleteTextures(1, &_overlayTexture); printOpenGLError(); } - glGenTextures(1, &_screenTexture); - glBindTexture(GL_TEXTURE_2D, _screenTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glGenTextures(1, &_overlayTexture); printOpenGLError(); + glBindTexture(GL_TEXTURE_2D, _overlayTexture); printOpenGLError(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); printOpenGLError(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); printOpenGLError(); if (_textureBuffer) { free(_textureBuffer); @@ -286,12 +474,12 @@ uint getSizeNextPOT(uint size) { _textureBuffer = (char*)malloc(textureSize); memset(_textureBuffer, 0, textureSize); - glBindRenderbufferOES(GL_RENDERBUFFER_OES, _viewRenderbuffer); + glBindRenderbufferOES(GL_RENDERBUFFER_OES, _viewRenderbuffer); printOpenGLError(); // The color buffer is triple-buffered, so we clear it multiple times right away to avid doing any glClears later. int clearCount = 5; while (clearCount-- > 0) { - glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT); printOpenGLError(); [_context presentRenderbuffer:GL_RENDERBUFFER_OES]; } @@ -320,6 +508,7 @@ uint getSizeNextPOT(uint size) { //printf("Rect: %i, %i, %i, %i\n", _widthOffset, _heightOffset, rectWidth, rectHeight); _screenRect = CGRectMake(_widthOffset, _heightOffset, rectWidth, rectHeight); + _overlayPortraitRatio = 1.0f; } else { float ratio = (float)_height / (float)_width; int height = _fullWidth * ratio; @@ -340,6 +529,7 @@ uint getSizeNextPOT(uint size) { [self addSubview:[_keyboardView inputView]]; [self addSubview: _keyboardView]; [[_keyboardView inputView] becomeFirstResponder]; + _overlayPortraitRatio = (_overlayHeight * ratio) / _overlayWidth; } } @@ -421,7 +611,7 @@ uint getSizeNextPOT(uint size) { - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { - NSSet *allTouches = [event allTouches]; + //NSSet *allTouches = [event allTouches]; for (UITouch* touch in touches) { if (touch == _firstTouch) { diff --git a/backends/platform/iphone/osys_events.cpp b/backends/platform/iphone/osys_events.cpp index c1c7ffdc0c..f1e3b9ba62 100644 --- a/backends/platform/iphone/osys_events.cpp +++ b/backends/platform/iphone/osys_events.cpp @@ -60,16 +60,31 @@ bool OSystem_IPHONE::pollEvent(Common::Event &event) { int y = 0; switch (_screenOrientation) { case kScreenOrientationPortrait: - x = (int)(xUnit * _screenWidth); - y = (int)(yUnit * _screenHeight); + if (_overlayVisible) { + x = (int)(xUnit * _overlayWidth); + y = (int)(yUnit * _overlayHeight); + } else { + x = (int)(xUnit * _screenWidth); + y = (int)(yUnit * _screenHeight); + } break; case kScreenOrientationLandscape: - x = (int)(yUnit * _screenWidth); - y = (int)((1.0 - xUnit) * _screenHeight); + if (_overlayVisible) { + x = (int)(yUnit * _overlayWidth); + y = (int)((1.0 - xUnit) * _overlayHeight); + } else { + x = (int)(yUnit * _screenWidth); + y = (int)((1.0 - xUnit) * _screenHeight); + } break; case kScreenOrientationFlippedLandscape: - x = (int)((1.0 - yUnit) * _screenWidth); - y = (int)(xUnit * _screenHeight); + if (_overlayVisible) { + x = (int)((1.0 - yUnit) * _overlayWidth); + y = (int)(xUnit * _overlayHeight); + } else { + x = (int)((1.0 - yUnit) * _screenWidth); + y = (int)(xUnit * _screenHeight); + } break; } @@ -262,15 +277,18 @@ bool OSystem_IPHONE::handleEvent_mouseDragged(Common::Event &event, int x, int y mouseNewPosX = (int)(_mouseX - deltaX / 0.5f); mouseNewPosY = (int)(_mouseY - deltaY / 0.5f); + int widthCap = _overlayVisible ? _overlayWidth : _screenWidth; + int heightCap = _overlayVisible ? _overlayHeight : _screenHeight; + if (mouseNewPosX < 0) mouseNewPosX = 0; - else if (mouseNewPosX > _screenWidth) - mouseNewPosX = _screenWidth; + else if (mouseNewPosX > widthCap) + mouseNewPosX = widthCap; if (mouseNewPosY < 0) mouseNewPosY = 0; - else if (mouseNewPosY > _screenHeight) - mouseNewPosY = _screenHeight; + else if (mouseNewPosY > heightCap) + mouseNewPosY = heightCap; } else { mouseNewPosX = x; diff --git a/backends/platform/iphone/osys_main.cpp b/backends/platform/iphone/osys_main.cpp index 6c26b6ca8d..a1fb8f0d5e 100644 --- a/backends/platform/iphone/osys_main.cpp +++ b/backends/platform/iphone/osys_main.cpp @@ -54,13 +54,13 @@ void *OSystem_IPHONE::s_soundParam = NULL; OSystem_IPHONE::OSystem_IPHONE() : _savefile(NULL), _mixer(NULL), _timer(NULL), _offscreen(NULL), - _overlayVisible(false), _overlayBuffer(NULL), _fullscreen(NULL), + _overlayVisible(false), _fullscreen(NULL), _mouseHeight(0), _mouseWidth(0), _mouseBuf(NULL), _lastMouseTap(0), _secondaryTapped(false), _lastSecondaryTap(0), _screenOrientation(kScreenOrientationFlippedLandscape), _needEventRestPeriod(false), _mouseClickAndDragEnabled(false), _gestureStartX(-1), _gestureStartY(-1), _fullScreenIsDirty(false), _fullScreenOverlayIsDirty(false), - _mouseDirty(false), _timeSuspended(0), _lastDragPosX(-1), _lastDragPosY(-1), _screenChangeCount(0) - + _mouseDirty(false), _timeSuspended(0), _lastDragPosX(-1), _lastDragPosY(-1), _screenChangeCount(0), + _overlayHeight(0), _overlayWidth(0), _overlayBuffer(0) { _queuedInputEvent.type = (Common::EventType)0; _lastDrawnMouseRect = Common::Rect(0, 0, 0, 0); diff --git a/backends/platform/iphone/osys_main.h b/backends/platform/iphone/osys_main.h index 3c80c83998..c925078b46 100644 --- a/backends/platform/iphone/osys_main.h +++ b/backends/platform/iphone/osys_main.h @@ -66,6 +66,9 @@ protected: Graphics::Surface _framebuffer; byte *_offscreen; OverlayColor *_overlayBuffer; + uint16 _overlayHeight; + uint16 _overlayWidth; + uint16 *_fullscreen; uint16 _palette[256]; @@ -144,7 +147,7 @@ public: virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h); virtual int16 getOverlayHeight(); virtual int16 getOverlayWidth(); - virtual Graphics::PixelFormat getOverlayFormat() const { return Graphics::createPixelFormat<565>(); } + virtual Graphics::PixelFormat getOverlayFormat() const { return Graphics::createPixelFormat<5551>(); } virtual bool showMouse(bool visible); diff --git a/backends/platform/iphone/osys_video.cpp b/backends/platform/iphone/osys_video.cpp index 76c2031758..18acb77524 100644 --- a/backends/platform/iphone/osys_video.cpp +++ b/backends/platform/iphone/osys_video.cpp @@ -57,10 +57,10 @@ void OSystem_IPHONE::initSize(uint width, uint height, const Graphics::PixelForm _offscreen = (byte *)malloc(width * height); bzero(_offscreen, width * height); - free(_overlayBuffer); + //free(_overlayBuffer); int fullSize = _screenWidth * _screenHeight * sizeof(OverlayColor); - _overlayBuffer = (OverlayColor *)malloc(fullSize); + //_overlayBuffer = (OverlayColor *)malloc(fullSize); clearOverlay(); free(_fullscreen); @@ -70,6 +70,14 @@ void OSystem_IPHONE::initSize(uint width, uint height, const Graphics::PixelForm iPhone_initSurface(width, height); + if (_overlayBuffer == NULL) { + _overlayHeight = iPhone_getScreenHeight(); + _overlayWidth = iPhone_getScreenWidth(); + + printf("Overlay: (%u x %u)\n", _overlayWidth, _overlayHeight); + _overlayBuffer = new OverlayColor[_overlayHeight * _overlayWidth]; + } + _fullScreenIsDirty = false; dirtyFullScreen(); _mouseVisible = false; @@ -187,7 +195,7 @@ void OSystem_IPHONE::updateScreen() { _fullScreenIsDirty = false; _fullScreenOverlayIsDirty = false; - iPhone_updateScreen(); + iPhone_updateScreen(_mouseX - _mouseHotspotX, _mouseY - _mouseHotspotY); } void OSystem_IPHONE::internUpdateScreen() { @@ -222,8 +230,9 @@ void OSystem_IPHONE::internUpdateScreen() { if (_overlayVisible) drawDirtyOverlayRect(dirtyRect); + else + drawMouseCursorOnRectUpdate(dirtyRect, mouseRect); - drawMouseCursorOnRectUpdate(dirtyRect, mouseRect); updateHardwareSurfaceForRect(dirtyRect); } @@ -234,8 +243,8 @@ void OSystem_IPHONE::internUpdateScreen() { //printf("Drawing: (%i, %i) -> (%i, %i)\n", dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom); drawDirtyOverlayRect(dirtyRect); - drawMouseCursorOnRectUpdate(dirtyRect, mouseRect); - updateHardwareSurfaceForRect(dirtyRect); + //drawMouseCursorOnRectUpdate(dirtyRect, mouseRect); + //updateHardwareSurfaceForRect(dirtyRect); } } } @@ -256,16 +265,17 @@ void OSystem_IPHONE::drawDirtyRect(const Common::Rect& dirtyRect) { } void OSystem_IPHONE::drawDirtyOverlayRect(const Common::Rect& dirtyRect) { - int h = dirtyRect.bottom - dirtyRect.top; - - uint16 *src = (uint16 *)&_overlayBuffer[dirtyRect.top * _screenWidth + dirtyRect.left]; - uint16 *dst = &_fullscreen[dirtyRect.top * _screenWidth + dirtyRect.left]; - int x = (dirtyRect.right - dirtyRect.left) * 2; - for (int y = h; y > 0; y--) { - memcpy(dst, src, x); - src += _screenWidth; - dst += _screenWidth; - } + // int h = dirtyRect.bottom - dirtyRect.top; + // + // uint16 *src = (uint16 *)&_overlayBuffer[dirtyRect.top * _screenWidth + dirtyRect.left]; + // uint16 *dst = &_fullscreen[dirtyRect.top * _screenWidth + dirtyRect.left]; + // int x = (dirtyRect.right - dirtyRect.left) * 2; + // for (int y = h; y > 0; y--) { + // memcpy(dst, src, x); + // src += _screenWidth; + // dst += _screenWidth; + // } + iPhone_updateOverlayRect(_overlayBuffer, dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom ); } void OSystem_IPHONE::drawMouseCursorOnRectUpdate(const Common::Rect& updatedRect, const Common::Rect& mouseRect) { @@ -283,16 +293,19 @@ void OSystem_IPHONE::drawMouseCursorOnRectUpdate(const Common::Rect& updatedRect srcY -= top; top = 0; } - //int right = left + _mouseWidth; + int bottom = top + _mouseHeight; if (bottom > _screenWidth) bottom = _screenWidth; - int displayWidth = _mouseWidth; + + int displayWidth = _mouseWidth; if (_mouseWidth + left > _screenWidth) displayWidth = _screenWidth - left; - int displayHeight = _mouseHeight; + + int displayHeight = _mouseHeight; if (_mouseHeight + top > _screenHeight) displayHeight = _screenHeight - top; + byte *src = &_mouseBuf[srcY * _mouseWidth + srcX]; uint16 *dst = &_fullscreen[top * _screenWidth + left]; for (int y = displayHeight; y > srcY; y--) { @@ -337,6 +350,7 @@ void OSystem_IPHONE::showOverlay() { //printf("showOverlay()\n"); _overlayVisible = true; dirtyFullOverlayScreen(); + iPhone_enableOverlay(true); } void OSystem_IPHONE::hideOverlay() { @@ -344,11 +358,12 @@ void OSystem_IPHONE::hideOverlay() { _overlayVisible = false; _dirtyOverlayRects.clear(); dirtyFullScreen(); + iPhone_enableOverlay(false); } void OSystem_IPHONE::clearOverlay() { //printf("clearOverlay()\n"); - bzero(_overlayBuffer, _screenWidth * _screenHeight * sizeof(OverlayColor)); + bzero(_overlayBuffer, _overlayWidth * _overlayHeight * sizeof(OverlayColor)); dirtyFullOverlayScreen(); } @@ -358,8 +373,8 @@ void OSystem_IPHONE::grabOverlay(OverlayColor *buf, int pitch) { OverlayColor *src = _overlayBuffer; do { - memcpy(buf, src, _screenWidth * sizeof(OverlayColor)); - src += _screenWidth; + memcpy(buf, src, _overlayWidth * sizeof(OverlayColor)); + src += _overlayWidth; buf += pitch; } while (--h); } @@ -380,11 +395,11 @@ void OSystem_IPHONE::copyRectToOverlay(const OverlayColor *buf, int pitch, int x y = 0; } - if (w > _screenWidth - x) - w = _screenWidth - x; + if (w > _overlayWidth - x) + w = _overlayWidth - x; - if (h > _screenHeight - y) - h = _screenHeight - y; + if (h > _overlayHeight - y) + h = _overlayHeight - y; if (w <= 0 || h <= 0) return; @@ -393,24 +408,24 @@ void OSystem_IPHONE::copyRectToOverlay(const OverlayColor *buf, int pitch, int x _dirtyOverlayRects.push_back(Common::Rect(x, y, x + w, y + h)); } - OverlayColor *dst = _overlayBuffer + (y * _screenWidth + x); - if (_screenWidth == pitch && pitch == w) + OverlayColor *dst = _overlayBuffer + (y * _overlayWidth + x); + if (_overlayWidth == pitch && pitch == w) memcpy(dst, buf, h * w * sizeof(OverlayColor)); else { do { memcpy(dst, buf, w * sizeof(OverlayColor)); buf += pitch; - dst += _screenWidth; + dst += _overlayWidth; } while (--h); } } int16 OSystem_IPHONE::getOverlayHeight() { - return _screenHeight; + return _overlayHeight; } int16 OSystem_IPHONE::getOverlayWidth() { - return _screenWidth; + return _overlayWidth; } bool OSystem_IPHONE::showMouse(bool visible) { @@ -440,13 +455,31 @@ void OSystem_IPHONE::dirtyFullScreen() { void OSystem_IPHONE::dirtyFullOverlayScreen() { if (!_fullScreenOverlayIsDirty) { _dirtyOverlayRects.clear(); - _dirtyOverlayRects.push_back(Common::Rect(0, 0, _screenWidth, _screenHeight)); + _dirtyOverlayRects.push_back(Common::Rect(0, 0, _overlayWidth, _overlayHeight)); _fullScreenOverlayIsDirty = true; } } void OSystem_IPHONE::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) { - //printf("setMouseCursor(%i, %i)\n", hotspotX, hotspotY); + //printf("setMouseCursor(%i, %i, scale %u)\n", hotspotX, hotspotY, cursorTargetScale); + + int texWidth = getSizeNextPOT(w); + int texHeight = getSizeNextPOT(h); + int bufferSize = texWidth * texHeight * sizeof(int16); + int16* mouseBuf = (int16*)malloc(bufferSize); + memset(mouseBuf, 0, bufferSize); + + for (int x = 0; x < w; ++x) { + for (int y = 0; y < h; ++y) { + byte color = buf[y * w + x]; + if (color != keycolor) + mouseBuf[y * texWidth + x] = _palette[color] | 0x1; + else + mouseBuf[y * texWidth + x] = 0x0; + } + } + + iPhone_setMouseCursor(mouseBuf, w, h); if (_mouseBuf != NULL && (_mouseWidth != w || _mouseHeight != h)) { free(_mouseBuf); -- cgit v1.2.3