IPHONE: The overlay will now always be in the native device resolution

svn-id: r52939
This commit is contained in:
Oystein Eftevaag 2010-09-29 00:19:13 +00:00
parent a0c0b934c7
commit ab01f42a4b
9 changed files with 394 additions and 101 deletions

View file

@ -67,12 +67,19 @@ void iphone_main(int argc, char *argv[]);
#endif #endif
// On the ObjC side // 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_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); void iPhone_initSurface(int width, int height);
bool iPhone_fetchEvent(int *outEvent, float *outX, float *outY); bool iPhone_fetchEvent(int *outEvent, float *outX, float *outY);
const char* iPhone_getDocumentsDir(); const char* iPhone_getDocumentsDir();
bool iPhone_isHighResDevice(); 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 #ifdef __cplusplus
} }

View file

@ -103,13 +103,24 @@ int main(int argc, char** argv) {
[NSThread detachNewThreadSelector:@selector(mainLoop:) toTarget:self withObject:nil]; [NSThread detachNewThreadSelector:@selector(mainLoop:) toTarget:self withObject:nil];
} }
- (void)applicationDidResume
{
}
- (void)applicationWillSuspend
{
}
- (void)applicationWillTerminate
{
}
- (void)applicationSuspend:(struct __GSEvent *)event { - (void)applicationSuspend:(struct __GSEvent *)event {
//[self setApplicationBadge:NSLocalizedString(@"ON", nil)]; //[self setApplicationBadge:NSLocalizedString(@"ON", nil)];
[_view applicationSuspend]; [_view applicationSuspend];
} }
- (void)applicationResume:(struct __GSEvent *)event { - (void)applicationResume:(struct __GSEvent *)event {
[self removeApplicationBadge];
[_view applicationResume]; [_view applicationResume];
// Workaround, need to "hide" and unhide the statusbar to properly remove it, // Workaround, need to "hide" and unhide the statusbar to properly remove it,

View file

@ -54,6 +54,8 @@
GLint _visibleWidth; GLint _visibleWidth;
GLint _visibleHeight; GLint _visibleHeight;
GLuint _screenTexture; GLuint _screenTexture;
GLuint _overlayTexture;
GLuint _mouseCursorTexture;
} }
- (id)initWithFrame:(struct CGRect)frame; - (id)initWithFrame:(struct CGRect)frame;
@ -65,6 +67,11 @@
- (void)initSurface; - (void)initSurface;
- (void)updateSurface; - (void)updateSurface;
- (void)updateMainSurface;
- (void)updateOverlaySurface;
- (void)updateMouseSurface;
-(void)updateMouseCursor;
- (id)getEvent; - (id)getEvent;

View file

@ -32,23 +32,88 @@ static int _height = 0;
static int _fullWidth; static int _fullWidth;
static int _fullHeight; static int _fullHeight;
static CGRect _screenRect; static CGRect _screenRect;
static char* _textureBuffer = 0; static char* _textureBuffer = 0;
static int _textureWidth = 0; static int _textureWidth = 0;
static int _textureHeight = 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; NSLock* _lock = nil;
static int _needsScreenUpdate = 0; static int _needsScreenUpdate = 0;
static int _overlayIsEnabled = 0;
static UITouch* _firstTouch = NULL; static UITouch* _firstTouch = NULL;
static UITouch* _secondTouch = 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 long lastTick = 0;
// static int frames = 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() { bool iPhone_isHighResDevice() {
return _fullHeight > 480; 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) { if (!_needsScreenUpdate) {
_needsScreenUpdate = 1; _needsScreenUpdate = 1;
[sharedInstance performSelectorOnMainThread:@selector(updateSurface) withObject:nil waitUntilDone: NO]; [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) { void iPhone_updateScreenRect(unsigned short* screen, int x1, int y1, int x2, int y2) {
//[_lock lock];
int y; 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); 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) { void iPhone_initSurface(int width, int height) {
_width = width; _width = width;
@ -92,6 +158,19 @@ bool iPhone_fetchEvent(int *outEvent, float *outX, float *outY) {
return true; 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() { const char* iPhone_getDocumentsDir() {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *documentsDirectory = [paths objectAtIndex:0];
@ -110,18 +189,6 @@ bool getLocalMouseCoords(CGPoint *point) {
return true; 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 @implementation iPhoneView
@ -131,7 +198,15 @@ uint getSizeNextPOT(uint size) {
} }
- (id)initWithFrame:(struct CGRect)frame { - (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; _fullWidth = frame.size.width;
_fullHeight = frame.size.height; _fullHeight = frame.size.height;
@ -143,6 +218,8 @@ uint getSizeNextPOT(uint size) {
_keyboardView = nil; _keyboardView = nil;
_context = nil; _context = nil;
_screenTexture = 0; _screenTexture = 0;
_overlayTexture = 0;
_mouseCursorTexture = 0;
return self; return self;
} }
@ -156,6 +233,8 @@ uint getSizeNextPOT(uint size) {
if (_screenTexture) if (_screenTexture)
free(_textureBuffer); free(_textureBuffer);
free(_overlayTexBuffer);
} }
- (void *)getSurface { - (void *)getSurface {
@ -181,6 +260,38 @@ uint getSizeNextPOT(uint size) {
} }
_needsScreenUpdate = 0; _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[] = { GLfloat vertices[] = {
0.0f + _heightOffset, 0.0f + _widthOffset, 0.0f + _heightOffset, 0.0f + _widthOffset,
_visibleWidth - _heightOffset, 0.0f + _widthOffset, _visibleWidth - _heightOffset, 0.0f + _widthOffset,
@ -198,20 +309,76 @@ uint getSizeNextPOT(uint size) {
0.0f, texHeight 0.0f, texHeight
}; };
glVertexPointer(2, GL_FLOAT, 0, vertices); glVertexPointer(2, GL_FLOAT, 0, vertices); printOpenGLError();
glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 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 // 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. // 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. // 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); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _textureWidth, _textureHeight, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, _textureBuffer); printOpenGLError();
//[_lock unlock]; glDisable(GL_BLEND);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); printOpenGLError();
}
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - (void)updateOverlaySurface {
glBindRenderbufferOES(GL_RENDERBUFFER_OES, _viewRenderbuffer); GLfloat vertices[] = {
[_context presentRenderbuffer:GL_RENDERBUFFER_OES]; 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 { - (void)initSurface {
@ -232,28 +399,39 @@ uint getSizeNextPOT(uint size) {
_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; _context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
if (!_context || [EAGLContext setCurrentContext:_context]) { if (!_context || [EAGLContext setCurrentContext:_context]) {
glGenFramebuffersOES(1, &_viewFramebuffer); glGenFramebuffersOES(1, &_viewFramebuffer); printOpenGLError();
glGenRenderbuffersOES(1, &_viewRenderbuffer); glGenRenderbuffersOES(1, &_viewRenderbuffer); printOpenGLError();
glBindFramebufferOES(GL_FRAMEBUFFER_OES, _viewFramebuffer); glBindFramebufferOES(GL_FRAMEBUFFER_OES, _viewFramebuffer); printOpenGLError();
glBindRenderbufferOES(GL_RENDERBUFFER_OES, _viewRenderbuffer); glBindRenderbufferOES(GL_RENDERBUFFER_OES, _viewRenderbuffer); printOpenGLError();
[_context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(id<EAGLDrawable>)self.layer]; [_context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(id<EAGLDrawable>)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_WIDTH_OES, &_backingWidth); printOpenGLError();
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &_backingHeight); glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &_backingHeight); printOpenGLError();
if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) { if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
NSLog(@"Failed to make complete framebuffer object %x.", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); NSLog(@"Failed to make complete framebuffer object %x.", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
return; return;
} }
glViewport(0, 0, _backingWidth, _backingHeight); _overlayHeight = _backingWidth;
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); _overlayWidth = _backingHeight;
_overlayTexWidth = getSizeNextPOT(_overlayHeight);
_overlayTexHeight = getSizeNextPOT(_overlayWidth);
glEnable(GL_TEXTURE_2D); int textureSize = _overlayTexWidth * _overlayTexHeight * 2;
glEnableClientState(GL_TEXTURE_COORD_ARRAY); _overlayTexBuffer = (char *)malloc(textureSize);
glEnableClientState(GL_VERTEX_ARRAY); memset(_overlayTexBuffer, 0, textureSize);
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(); glLoadIdentity();
if (orientation == UIDeviceOrientationLandscapeRight) { if (orientation == UIDeviceOrientationLandscapeRight) {
glRotatef(-90, 0, 0, 1); glRotatef(-90, 0, 0, 1); printOpenGLError();
} else if (orientation == UIDeviceOrientationLandscapeLeft) { } else if (orientation == UIDeviceOrientationLandscapeLeft) {
glRotatef(90, 0, 0, 1); glRotatef(90, 0, 0, 1); printOpenGLError();
} else { } 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) { if (_screenTexture > 0) {
glDeleteTextures(1, &_screenTexture); glDeleteTextures(1, &_screenTexture); printOpenGLError();
} }
glGenTextures(1, &_screenTexture); glGenTextures(1, &_screenTexture); printOpenGLError();
glBindTexture(GL_TEXTURE_2D, _screenTexture); glBindTexture(GL_TEXTURE_2D, _screenTexture); printOpenGLError();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 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, &_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) { if (_textureBuffer) {
free(_textureBuffer); free(_textureBuffer);
@ -286,12 +474,12 @@ uint getSizeNextPOT(uint size) {
_textureBuffer = (char*)malloc(textureSize); _textureBuffer = (char*)malloc(textureSize);
memset(_textureBuffer, 0, 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. // The color buffer is triple-buffered, so we clear it multiple times right away to avid doing any glClears later.
int clearCount = 5; int clearCount = 5;
while (clearCount-- > 0) { while (clearCount-- > 0) {
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT); printOpenGLError();
[_context presentRenderbuffer:GL_RENDERBUFFER_OES]; [_context presentRenderbuffer:GL_RENDERBUFFER_OES];
} }
@ -320,6 +508,7 @@ uint getSizeNextPOT(uint size) {
//printf("Rect: %i, %i, %i, %i\n", _widthOffset, _heightOffset, rectWidth, rectHeight); //printf("Rect: %i, %i, %i, %i\n", _widthOffset, _heightOffset, rectWidth, rectHeight);
_screenRect = CGRectMake(_widthOffset, _heightOffset, rectWidth, rectHeight); _screenRect = CGRectMake(_widthOffset, _heightOffset, rectWidth, rectHeight);
_overlayPortraitRatio = 1.0f;
} else { } else {
float ratio = (float)_height / (float)_width; float ratio = (float)_height / (float)_width;
int height = _fullWidth * ratio; int height = _fullWidth * ratio;
@ -340,6 +529,7 @@ uint getSizeNextPOT(uint size) {
[self addSubview:[_keyboardView inputView]]; [self addSubview:[_keyboardView inputView]];
[self addSubview: _keyboardView]; [self addSubview: _keyboardView];
[[_keyboardView inputView] becomeFirstResponder]; [[_keyboardView inputView] becomeFirstResponder];
_overlayPortraitRatio = (_overlayHeight * ratio) / _overlayWidth;
} }
} }
@ -421,7 +611,7 @@ uint getSizeNextPOT(uint size) {
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{ {
NSSet *allTouches = [event allTouches]; //NSSet *allTouches = [event allTouches];
for (UITouch* touch in touches) { for (UITouch* touch in touches) {
if (touch == _firstTouch) { if (touch == _firstTouch) {

View file

@ -60,16 +60,31 @@ bool OSystem_IPHONE::pollEvent(Common::Event &event) {
int y = 0; int y = 0;
switch (_screenOrientation) { switch (_screenOrientation) {
case kScreenOrientationPortrait: case kScreenOrientationPortrait:
if (_overlayVisible) {
x = (int)(xUnit * _overlayWidth);
y = (int)(yUnit * _overlayHeight);
} else {
x = (int)(xUnit * _screenWidth); x = (int)(xUnit * _screenWidth);
y = (int)(yUnit * _screenHeight); y = (int)(yUnit * _screenHeight);
}
break; break;
case kScreenOrientationLandscape: case kScreenOrientationLandscape:
if (_overlayVisible) {
x = (int)(yUnit * _overlayWidth);
y = (int)((1.0 - xUnit) * _overlayHeight);
} else {
x = (int)(yUnit * _screenWidth); x = (int)(yUnit * _screenWidth);
y = (int)((1.0 - xUnit) * _screenHeight); y = (int)((1.0 - xUnit) * _screenHeight);
}
break; break;
case kScreenOrientationFlippedLandscape: case kScreenOrientationFlippedLandscape:
if (_overlayVisible) {
x = (int)((1.0 - yUnit) * _overlayWidth);
y = (int)(xUnit * _overlayHeight);
} else {
x = (int)((1.0 - yUnit) * _screenWidth); x = (int)((1.0 - yUnit) * _screenWidth);
y = (int)(xUnit * _screenHeight); y = (int)(xUnit * _screenHeight);
}
break; break;
} }
@ -262,15 +277,18 @@ bool OSystem_IPHONE::handleEvent_mouseDragged(Common::Event &event, int x, int y
mouseNewPosX = (int)(_mouseX - deltaX / 0.5f); mouseNewPosX = (int)(_mouseX - deltaX / 0.5f);
mouseNewPosY = (int)(_mouseY - deltaY / 0.5f); mouseNewPosY = (int)(_mouseY - deltaY / 0.5f);
int widthCap = _overlayVisible ? _overlayWidth : _screenWidth;
int heightCap = _overlayVisible ? _overlayHeight : _screenHeight;
if (mouseNewPosX < 0) if (mouseNewPosX < 0)
mouseNewPosX = 0; mouseNewPosX = 0;
else if (mouseNewPosX > _screenWidth) else if (mouseNewPosX > widthCap)
mouseNewPosX = _screenWidth; mouseNewPosX = widthCap;
if (mouseNewPosY < 0) if (mouseNewPosY < 0)
mouseNewPosY = 0; mouseNewPosY = 0;
else if (mouseNewPosY > _screenHeight) else if (mouseNewPosY > heightCap)
mouseNewPosY = _screenHeight; mouseNewPosY = heightCap;
} else { } else {
mouseNewPosX = x; mouseNewPosX = x;

View file

@ -54,13 +54,13 @@ void *OSystem_IPHONE::s_soundParam = NULL;
OSystem_IPHONE::OSystem_IPHONE() : OSystem_IPHONE::OSystem_IPHONE() :
_savefile(NULL), _mixer(NULL), _timer(NULL), _offscreen(NULL), _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), _mouseHeight(0), _mouseWidth(0), _mouseBuf(NULL), _lastMouseTap(0),
_secondaryTapped(false), _lastSecondaryTap(0), _screenOrientation(kScreenOrientationFlippedLandscape), _secondaryTapped(false), _lastSecondaryTap(0), _screenOrientation(kScreenOrientationFlippedLandscape),
_needEventRestPeriod(false), _mouseClickAndDragEnabled(false), _needEventRestPeriod(false), _mouseClickAndDragEnabled(false),
_gestureStartX(-1), _gestureStartY(-1), _fullScreenIsDirty(false), _fullScreenOverlayIsDirty(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; _queuedInputEvent.type = (Common::EventType)0;
_lastDrawnMouseRect = Common::Rect(0, 0, 0, 0); _lastDrawnMouseRect = Common::Rect(0, 0, 0, 0);

View file

@ -66,6 +66,9 @@ protected:
Graphics::Surface _framebuffer; Graphics::Surface _framebuffer;
byte *_offscreen; byte *_offscreen;
OverlayColor *_overlayBuffer; OverlayColor *_overlayBuffer;
uint16 _overlayHeight;
uint16 _overlayWidth;
uint16 *_fullscreen; uint16 *_fullscreen;
uint16 _palette[256]; 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 void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
virtual int16 getOverlayHeight(); virtual int16 getOverlayHeight();
virtual int16 getOverlayWidth(); 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); virtual bool showMouse(bool visible);

View file

@ -57,10 +57,10 @@ void OSystem_IPHONE::initSize(uint width, uint height, const Graphics::PixelForm
_offscreen = (byte *)malloc(width * height); _offscreen = (byte *)malloc(width * height);
bzero(_offscreen, width * height); bzero(_offscreen, width * height);
free(_overlayBuffer); //free(_overlayBuffer);
int fullSize = _screenWidth * _screenHeight * sizeof(OverlayColor); int fullSize = _screenWidth * _screenHeight * sizeof(OverlayColor);
_overlayBuffer = (OverlayColor *)malloc(fullSize); //_overlayBuffer = (OverlayColor *)malloc(fullSize);
clearOverlay(); clearOverlay();
free(_fullscreen); free(_fullscreen);
@ -70,6 +70,14 @@ void OSystem_IPHONE::initSize(uint width, uint height, const Graphics::PixelForm
iPhone_initSurface(width, height); 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; _fullScreenIsDirty = false;
dirtyFullScreen(); dirtyFullScreen();
_mouseVisible = false; _mouseVisible = false;
@ -187,7 +195,7 @@ void OSystem_IPHONE::updateScreen() {
_fullScreenIsDirty = false; _fullScreenIsDirty = false;
_fullScreenOverlayIsDirty = false; _fullScreenOverlayIsDirty = false;
iPhone_updateScreen(); iPhone_updateScreen(_mouseX - _mouseHotspotX, _mouseY - _mouseHotspotY);
} }
void OSystem_IPHONE::internUpdateScreen() { void OSystem_IPHONE::internUpdateScreen() {
@ -222,8 +230,9 @@ void OSystem_IPHONE::internUpdateScreen() {
if (_overlayVisible) if (_overlayVisible)
drawDirtyOverlayRect(dirtyRect); drawDirtyOverlayRect(dirtyRect);
else
drawMouseCursorOnRectUpdate(dirtyRect, mouseRect); drawMouseCursorOnRectUpdate(dirtyRect, mouseRect);
updateHardwareSurfaceForRect(dirtyRect); 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); //printf("Drawing: (%i, %i) -> (%i, %i)\n", dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom);
drawDirtyOverlayRect(dirtyRect); drawDirtyOverlayRect(dirtyRect);
drawMouseCursorOnRectUpdate(dirtyRect, mouseRect); //drawMouseCursorOnRectUpdate(dirtyRect, mouseRect);
updateHardwareSurfaceForRect(dirtyRect); //updateHardwareSurfaceForRect(dirtyRect);
} }
} }
} }
@ -256,16 +265,17 @@ void OSystem_IPHONE::drawDirtyRect(const Common::Rect& dirtyRect) {
} }
void OSystem_IPHONE::drawDirtyOverlayRect(const Common::Rect& dirtyRect) { void OSystem_IPHONE::drawDirtyOverlayRect(const Common::Rect& dirtyRect) {
int h = dirtyRect.bottom - dirtyRect.top; // int h = dirtyRect.bottom - dirtyRect.top;
//
uint16 *src = (uint16 *)&_overlayBuffer[dirtyRect.top * _screenWidth + dirtyRect.left]; // uint16 *src = (uint16 *)&_overlayBuffer[dirtyRect.top * _screenWidth + dirtyRect.left];
uint16 *dst = &_fullscreen[dirtyRect.top * _screenWidth + dirtyRect.left]; // uint16 *dst = &_fullscreen[dirtyRect.top * _screenWidth + dirtyRect.left];
int x = (dirtyRect.right - dirtyRect.left) * 2; // int x = (dirtyRect.right - dirtyRect.left) * 2;
for (int y = h; y > 0; y--) { // for (int y = h; y > 0; y--) {
memcpy(dst, src, x); // memcpy(dst, src, x);
src += _screenWidth; // src += _screenWidth;
dst += _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) { 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; srcY -= top;
top = 0; top = 0;
} }
//int right = left + _mouseWidth;
int bottom = top + _mouseHeight; int bottom = top + _mouseHeight;
if (bottom > _screenWidth) if (bottom > _screenWidth)
bottom = _screenWidth; bottom = _screenWidth;
int displayWidth = _mouseWidth; int displayWidth = _mouseWidth;
if (_mouseWidth + left > _screenWidth) if (_mouseWidth + left > _screenWidth)
displayWidth = _screenWidth - left; displayWidth = _screenWidth - left;
int displayHeight = _mouseHeight; int displayHeight = _mouseHeight;
if (_mouseHeight + top > _screenHeight) if (_mouseHeight + top > _screenHeight)
displayHeight = _screenHeight - top; displayHeight = _screenHeight - top;
byte *src = &_mouseBuf[srcY * _mouseWidth + srcX]; byte *src = &_mouseBuf[srcY * _mouseWidth + srcX];
uint16 *dst = &_fullscreen[top * _screenWidth + left]; uint16 *dst = &_fullscreen[top * _screenWidth + left];
for (int y = displayHeight; y > srcY; y--) { for (int y = displayHeight; y > srcY; y--) {
@ -337,6 +350,7 @@ void OSystem_IPHONE::showOverlay() {
//printf("showOverlay()\n"); //printf("showOverlay()\n");
_overlayVisible = true; _overlayVisible = true;
dirtyFullOverlayScreen(); dirtyFullOverlayScreen();
iPhone_enableOverlay(true);
} }
void OSystem_IPHONE::hideOverlay() { void OSystem_IPHONE::hideOverlay() {
@ -344,11 +358,12 @@ void OSystem_IPHONE::hideOverlay() {
_overlayVisible = false; _overlayVisible = false;
_dirtyOverlayRects.clear(); _dirtyOverlayRects.clear();
dirtyFullScreen(); dirtyFullScreen();
iPhone_enableOverlay(false);
} }
void OSystem_IPHONE::clearOverlay() { void OSystem_IPHONE::clearOverlay() {
//printf("clearOverlay()\n"); //printf("clearOverlay()\n");
bzero(_overlayBuffer, _screenWidth * _screenHeight * sizeof(OverlayColor)); bzero(_overlayBuffer, _overlayWidth * _overlayHeight * sizeof(OverlayColor));
dirtyFullOverlayScreen(); dirtyFullOverlayScreen();
} }
@ -358,8 +373,8 @@ void OSystem_IPHONE::grabOverlay(OverlayColor *buf, int pitch) {
OverlayColor *src = _overlayBuffer; OverlayColor *src = _overlayBuffer;
do { do {
memcpy(buf, src, _screenWidth * sizeof(OverlayColor)); memcpy(buf, src, _overlayWidth * sizeof(OverlayColor));
src += _screenWidth; src += _overlayWidth;
buf += pitch; buf += pitch;
} while (--h); } while (--h);
} }
@ -380,11 +395,11 @@ void OSystem_IPHONE::copyRectToOverlay(const OverlayColor *buf, int pitch, int x
y = 0; y = 0;
} }
if (w > _screenWidth - x) if (w > _overlayWidth - x)
w = _screenWidth - x; w = _overlayWidth - x;
if (h > _screenHeight - y) if (h > _overlayHeight - y)
h = _screenHeight - y; h = _overlayHeight - y;
if (w <= 0 || h <= 0) if (w <= 0 || h <= 0)
return; 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)); _dirtyOverlayRects.push_back(Common::Rect(x, y, x + w, y + h));
} }
OverlayColor *dst = _overlayBuffer + (y * _screenWidth + x); OverlayColor *dst = _overlayBuffer + (y * _overlayWidth + x);
if (_screenWidth == pitch && pitch == w) if (_overlayWidth == pitch && pitch == w)
memcpy(dst, buf, h * w * sizeof(OverlayColor)); memcpy(dst, buf, h * w * sizeof(OverlayColor));
else { else {
do { do {
memcpy(dst, buf, w * sizeof(OverlayColor)); memcpy(dst, buf, w * sizeof(OverlayColor));
buf += pitch; buf += pitch;
dst += _screenWidth; dst += _overlayWidth;
} while (--h); } while (--h);
} }
} }
int16 OSystem_IPHONE::getOverlayHeight() { int16 OSystem_IPHONE::getOverlayHeight() {
return _screenHeight; return _overlayHeight;
} }
int16 OSystem_IPHONE::getOverlayWidth() { int16 OSystem_IPHONE::getOverlayWidth() {
return _screenWidth; return _overlayWidth;
} }
bool OSystem_IPHONE::showMouse(bool visible) { bool OSystem_IPHONE::showMouse(bool visible) {
@ -440,13 +455,31 @@ void OSystem_IPHONE::dirtyFullScreen() {
void OSystem_IPHONE::dirtyFullOverlayScreen() { void OSystem_IPHONE::dirtyFullOverlayScreen() {
if (!_fullScreenOverlayIsDirty) { if (!_fullScreenOverlayIsDirty) {
_dirtyOverlayRects.clear(); _dirtyOverlayRects.clear();
_dirtyOverlayRects.push_back(Common::Rect(0, 0, _screenWidth, _screenHeight)); _dirtyOverlayRects.push_back(Common::Rect(0, 0, _overlayWidth, _overlayHeight));
_fullScreenOverlayIsDirty = true; _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) { 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)) { if (_mouseBuf != NULL && (_mouseWidth != w || _mouseHeight != h)) {
free(_mouseBuf); free(_mouseBuf);

View file

@ -167,6 +167,30 @@ struct ColorMasks<1555> {
}; };
}; };
template<>
struct ColorMasks<5551> {
enum {
kBytesPerPixel = 2,
kAlphaBits = 1,
kRedBits = 5,
kGreenBits = 5,
kBlueBits = 5,
kAlphaShift = 0,
kRedShift = kGreenBits+kBlueBits+kAlphaBits,
kGreenShift = kBlueBits+kAlphaBits,
kBlueShift = kAlphaBits,
kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
kRedMask = ((1 << kRedBits) - 1) << kRedShift,
kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
kBlueMask = ((1 << kBlueBits) - 1) << kBlueShift,
kRedBlueMask = kRedMask | kBlueMask
};
};
template<> template<>
struct ColorMasks<4444> { struct ColorMasks<4444> {
enum { enum {