aboutsummaryrefslogtreecommitdiff
path: root/backends/platform/iphone/iphone_video.m
diff options
context:
space:
mode:
Diffstat (limited to 'backends/platform/iphone/iphone_video.m')
-rw-r--r--backends/platform/iphone/iphone_video.m292
1 files changed, 241 insertions, 51 deletions
diff --git a/backends/platform/iphone/iphone_video.m b/backends/platform/iphone/iphone_video.m
index cd8b38acb3..821d3de634 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<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_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) {