diff options
Diffstat (limited to 'backends')
| -rw-r--r-- | backends/keymapper/hardware-key.h | 19 | ||||
| -rw-r--r-- | backends/keymapper/keymap.cpp | 6 | ||||
| -rw-r--r-- | backends/keymapper/keymapper.cpp | 2 | ||||
| -rw-r--r-- | backends/platform/iphone/iphone_common.h | 42 | ||||
| -rw-r--r-- | backends/platform/iphone/iphone_main.mm | 3 | ||||
| -rw-r--r-- | backends/platform/iphone/iphone_video.h | 25 | ||||
| -rw-r--r-- | backends/platform/iphone/iphone_video.mm | 553 | ||||
| -rw-r--r-- | backends/platform/iphone/osys_events.cpp | 50 | ||||
| -rw-r--r-- | backends/platform/iphone/osys_main.cpp | 8 | ||||
| -rw-r--r-- | backends/platform/iphone/osys_main.h | 21 | ||||
| -rw-r--r-- | backends/platform/iphone/osys_video.mm (renamed from backends/platform/iphone/osys_video.cpp) | 194 | 
11 files changed, 422 insertions, 501 deletions
diff --git a/backends/keymapper/hardware-key.h b/backends/keymapper/hardware-key.h index 8c46ee6358..9fd8d1981a 100644 --- a/backends/keymapper/hardware-key.h +++ b/backends/keymapper/hardware-key.h @@ -31,14 +31,12 @@  namespace Common { -#define HWKEY_ID_SIZE (30) -  /**  * Describes an available hardware key  */  struct HardwareKey {  	/** unique id used for saving/loading to config */ -	char hwKeyId[HWKEY_ID_SIZE]; +	String id;  	/** Human readable description */  	String description; @@ -49,11 +47,8 @@ struct HardwareKey {  	*/  	KeyState key; -	HardwareKey(const char *i, KeyState ky = KeyState(), String desc = "") -		: key(ky), description(desc) { -		assert(i); -		Common::strlcpy(hwKeyId, i, HWKEY_ID_SIZE); -	} +	HardwareKey(String i, KeyState ky = KeyState(), String desc = "") +		: id(i), key(ky), description(desc) { }  };  /** @@ -108,11 +103,11 @@ public:  		_keys.push_back(key);  	} -	const HardwareKey *findHardwareKey(const char *id) const { +	const HardwareKey *findHardwareKey(String id) const {  		List<const HardwareKey *>::const_iterator it;  		for (it = _keys.begin(); it != _keys.end(); it++) { -			if (strncmp((*it)->hwKeyId, id, HWKEY_ID_SIZE) == 0) +			if ((*it)->id == id)  				return (*it);  		}  		return 0; @@ -175,8 +170,8 @@ private:  		List<const HardwareKey *>::iterator it;  		for (it = _keys.begin(); it != _keys.end(); it++) { -			if (strncmp((*it)->hwKeyId, key->hwKeyId, HWKEY_ID_SIZE) == 0) -				error("Error adding HardwareKey '%s' - id of %s already in use!", key->description.c_str(), key->hwKeyId); +			if ((*it)->id == key->id) +				error("Error adding HardwareKey '%s' - id of %s already in use!", key->description.c_str(), key->id.c_str());  			else if ((*it)->key == key->key)  				error("Error adding HardwareKey '%s' - key already in use!", key->description.c_str());  		} diff --git a/backends/keymapper/keymap.cpp b/backends/keymapper/keymap.cpp index 5bee1a246d..3913fd149e 100644 --- a/backends/keymapper/keymap.cpp +++ b/backends/keymapper/keymap.cpp @@ -185,12 +185,10 @@ void Keymap::saveMappings() {  		actIdLen = (actIdLen > ACTION_ID_SIZE) ? ACTION_ID_SIZE : actIdLen;  		String actId((*it)->id, (*it)->id + actIdLen); -		char hwId[HWKEY_ID_SIZE+1]; - -		memset(hwId, 0, HWKEY_ID_SIZE+1); +		String hwId = "";  		if ((*it)->getMappedKey()) { -			memcpy(hwId, (*it)->getMappedKey()->hwKeyId, HWKEY_ID_SIZE); +			hwId = (*it)->getMappedKey()->id;  		}  		_configDomain->setVal(prefix + actId, hwId);  	} diff --git a/backends/keymapper/keymapper.cpp b/backends/keymapper/keymapper.cpp index aafdd604a2..189f862469 100644 --- a/backends/keymapper/keymapper.cpp +++ b/backends/keymapper/keymapper.cpp @@ -119,7 +119,7 @@ void Keymapper::cleanupGameKeymaps() {  	// the game specific (=deleted) ones.  	Stack<MapRecord> newStack; -	for (int i = 0; i < _activeMaps.size(); i++) { +	for (Stack<MapRecord>::size_type i = 0; i < _activeMaps.size(); i++) {  		if (_activeMaps[i].global)  			newStack.push(_activeMaps[i]);  	} diff --git a/backends/platform/iphone/iphone_common.h b/backends/platform/iphone/iphone_common.h index 5a46a6dde6..4dd9407064 100644 --- a/backends/platform/iphone/iphone_common.h +++ b/backends/platform/iphone/iphone_common.h @@ -23,6 +23,8 @@  #ifndef BACKENDS_PLATFORM_IPHONE_IPHONE_COMMON_H  #define BACKENDS_PLATFORM_IPHONE_IPHONE_COMMON_H +#include "graphics/surface.h" +  enum InputEvent {  	kInputMouseDown,  	kInputMouseUp, @@ -55,21 +57,39 @@ enum GraphicsModes {  	kGraphicsModeNone = 1  }; +struct VideoContext { +	VideoContext() : screenWidth(), screenHeight(), overlayVisible(false), +	                 overlayWidth(), overlayHeight(), mouseX(), mouseY(), +	                 mouseHotspotX(), mouseHotspotY(), mouseWidth(), mouseHeight(), +	                 mouseIsVisible(), graphicsMode(kGraphicsModeLinear), shakeOffsetY() { +	} + +	// Game screen state +	uint screenWidth, screenHeight; +	Graphics::Surface screenTexture; + +	// Overlay state +	bool overlayVisible; +	uint overlayWidth, overlayHeight; +	Graphics::Surface overlayTexture; + +	// Mouse cursor state +	uint mouseX, mouseY; +	int mouseHotspotX, mouseHotspotY; +	uint mouseWidth, mouseHeight; +	bool mouseIsVisible; +	Graphics::Surface mouseTexture; + +	// Misc state +	GraphicsModes graphicsMode; +	int shakeOffsetY; +}; +  // On the ObjC side -void iPhone_setGraphicsMode(GraphicsModes mode); -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); -void iPhone_setShakeOffset(int offset); +void iPhone_updateScreen();  bool iPhone_fetchEvent(int *outEvent, int *outX, int *outY);  const char *iPhone_getDocumentsDir();  bool iPhone_isHighResDevice(); -int iPhone_getScreenHeight(); -int iPhone_getScreenWidth(); -void iPhone_enableOverlay(int state); -void iPhone_showCursor(int state); -void iPhone_setMouseCursor(unsigned short *buffer, int width, int height, int hotspotX, int hotspotY);  uint getSizeNextPOT(uint size); diff --git a/backends/platform/iphone/iphone_main.mm b/backends/platform/iphone/iphone_main.mm index 1559ef8a6e..20406e6342 100644 --- a/backends/platform/iphone/iphone_main.mm +++ b/backends/platform/iphone/iphone_main.mm @@ -20,6 +20,9 @@   *   */ +// Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL +  #include <UIKit/UIKit.h>  #include <Foundation/NSThread.h> diff --git a/backends/platform/iphone/iphone_video.h b/backends/platform/iphone/iphone_video.h index 43a643ab4a..168f9a4244 100644 --- a/backends/platform/iphone/iphone_video.h +++ b/backends/platform/iphone/iphone_video.h @@ -32,9 +32,11 @@  #include <OpenGLES/ES1/glext.h>  #include "iphone_keyboard.h" +#include "iphone_common.h"  @interface iPhoneView : UIView { -	void *_screenSurface; +	VideoContext _videoContext; +  	NSMutableArray *_events;  	SoftKeyboard *_keyboardView; @@ -47,18 +49,31 @@  	UIDeviceOrientation _orientation; +	GLint _renderBufferWidth; +	GLint _renderBufferHeight; +  	GLfloat _gameScreenVertCoords[4 * 2];  	GLfloat _gameScreenTexCoords[4 * 2]; +	CGRect _gameScreenRect;  	GLfloat _overlayVertCoords[4 * 2];  	GLfloat _overlayTexCoords[4 * 2]; +	CGRect _overlayRect; + +	GLfloat _mouseVertCoords[4 * 2]; +	GLfloat _mouseTexCoords[4 * 2]; +	GLint _mouseHotspotX, _mouseHotspotY; +	GLint _mouseWidth, _mouseHeight; +	GLfloat _mouseScaleX, _mouseScaleY; + +	int _scaledShakeOffsetY;  }  - (id)initWithFrame:(struct CGRect)frame; -- (void)drawRect:(CGRect)frame; +- (VideoContext *)getVideoContext; -- (void *)getSurface; +- (void)drawRect:(CGRect)frame;  - (void)initSurface;  - (void)setViewTransformation; @@ -71,6 +86,8 @@  - (void)updateMouseSurface;  - (void)clearColorBuffer; +- (void)notifyMouseMove; +- (void)updateMouseCursorScaling;  - (void)updateMouseCursor;  - (id)getEvent; @@ -83,4 +100,6 @@  @end +extern iPhoneView *g_iPhoneViewInstance; +  #endif diff --git a/backends/platform/iphone/iphone_video.mm b/backends/platform/iphone/iphone_video.mm index 86365cbefe..3aa76681ab 100644 --- a/backends/platform/iphone/iphone_video.mm +++ b/backends/platform/iphone/iphone_video.mm @@ -20,49 +20,22 @@   *   */ +// Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL +  #include "iphone_video.h" -#include "iphone_common.h" -static iPhoneView *sharedInstance = nil; -static GraphicsModes _graphicsMode = kGraphicsModeLinear; -static int _width = 0; -static int _height = 0; +#include "graphics/colormasks.h" + +iPhoneView *g_iPhoneViewInstance = nil;  static int _fullWidth;  static int _fullHeight; -static CGRect _gameScreenRect; - -static char *_gameScreenTextureBuffer = 0; -static int _gameScreenTextureWidth = 0; -static int _gameScreenTextureHeight = 0; - -static char *_overlayTexBuffer = 0; -static int _overlayTexWidth = 0; -static int _overlayTexHeight = 0; -static int _overlayWidth = 0; -static int _overlayHeight = 0; -static CGRect _overlayRect;  static int _needsScreenUpdate = 0; -static int _overlayIsEnabled = 0;  static UITouch *_firstTouch = NULL;  static UITouch *_secondTouch = NULL; -static unsigned short *_mouseCursor = NULL; -static int _mouseCursorHeight = 0; -static int _mouseCursorWidth = 0; -static int _mouseCursorHotspotX = 0; -static int _mouseCursorHotspotY = 0; -static int _mouseX = 0; -static int _mouseY = 0; -static int _mouseCursorEnabled = 0; - -static GLint _renderBufferWidth; -static GLint _renderBufferHeight; - -static int _shakeOffsetY; -static int _scaledShakeOffsetY; -  #if 0  static long lastTick = 0;  static int frames = 0; @@ -83,83 +56,20 @@ int printOglError(const char *file, int line) {  	return retCode;  } -void iPhone_setGraphicsMode(GraphicsModes mode) { -	_graphicsMode = mode; - -	[sharedInstance performSelectorOnMainThread:@selector(setGraphicsMode) withObject:nil waitUntilDone: YES]; -} - -void iPhone_showCursor(int state) { -	_mouseCursorEnabled = state; -} - -void iPhone_setMouseCursor(unsigned short *buffer, int width, int height, int hotspotX, int hotspotY) { -	_mouseCursor = buffer; - -	_mouseCursorWidth = width; -	_mouseCursorHeight = height; - -	_mouseCursorHotspotX = hotspotX; -	_mouseCursorHotspotY = hotspotY; - -	[sharedInstance performSelectorOnMainThread:@selector(updateMouseCursor) withObject:nil waitUntilDone: YES]; -} - -void iPhone_enableOverlay(int state) { -	_overlayIsEnabled = state; - -	[sharedInstance performSelectorOnMainThread:@selector(clearColorBuffer) withObject:nil waitUntilDone: YES]; -} - -int iPhone_getScreenHeight() { -	return _overlayHeight; -} - -int iPhone_getScreenWidth() { -	return _overlayWidth; -} -  bool iPhone_isHighResDevice() {  	return _fullHeight > 480;  } -void iPhone_updateScreen(int mouseX, int mouseY) { +void iPhone_updateScreen() {  	//printf("Mouse: (%i, %i)\n", mouseX, mouseY); - -	_mouseX = mouseX; -	_mouseY = mouseY; -  	if (!_needsScreenUpdate) {  		_needsScreenUpdate = 1; -		[sharedInstance performSelectorOnMainThread:@selector(updateSurface) withObject:nil waitUntilDone: NO]; +		[g_iPhoneViewInstance performSelectorOnMainThread:@selector(updateSurface) withObject:nil waitUntilDone: NO];  	}  } -void iPhone_updateScreenRect(unsigned short *screen, int x1, int y1, int x2, int y2) { -	for (int y = y1; y < y2; ++y) -		memcpy(&_gameScreenTextureBuffer[(y * _gameScreenTextureWidth + x1) * 2], &screen[y * _width + x1], (x2 - x1) * 2); -} - -void iPhone_updateOverlayRect(unsigned short *screen, int x1, int y1, int x2, int y2) { -	//printf("Overlaywidth: %u, fullwidth %u\n", _overlayWidth, _fullWidth); -	for (int 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; -	_height = height; -	_shakeOffsetY = 0; -	[sharedInstance performSelectorOnMainThread:@selector(initSurface) withObject:nil waitUntilDone: YES]; -} - -void iPhone_setShakeOffset(int offset) { -	_shakeOffsetY = offset; -	[sharedInstance performSelectorOnMainThread:@selector(setViewTransformation) withObject:nil waitUntilDone: YES]; -} -  bool iPhone_fetchEvent(int *outEvent, int *outX, int *outY) { -	id event = [sharedInstance getEvent]; +	id event = [g_iPhoneViewInstance getEvent];  	if (event == nil) {  		return false;  	} @@ -196,92 +106,16 @@ const char *iPhone_getDocumentsDir() {  	return [documentsDirectory UTF8String];  } -/** - * 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; - -	case UIDeviceOrientationLandscapeRight: -		result->x = _renderBufferHeight - point.y; -		result->y = point.x; -		return true; - -	case UIDeviceOrientationPortrait: -		result->x = point.x; -		result->y = point.y; -		return true; - -	default: -		return false; -	} -} - -static bool getMouseCoords(UIDeviceOrientation orientation, CGPoint point, int *x, int *y) { -	if (!convertToRotatedCoords(orientation, point, &point)) -		return false; - -	CGRect *area; -	int width, height, offsetY; -	if (_overlayIsEnabled) { -		area = &_overlayRect; -		width = _overlayWidth; -		height = _overlayHeight; -		offsetY = _shakeOffsetY; -	} else { -		area = &_gameScreenRect; -		width = _width; -		height = _height; -		offsetY = _scaledShakeOffsetY; -	} - -	point.x = (point.x - CGRectGetMinX(*area)) / CGRectGetWidth(*area); -	point.y = (point.y - CGRectGetMinY(*area)) / CGRectGetHeight(*area); - -	*x = (int)(point.x * width); -	// offsetY describes the translation of the screen in the upward direction, -	// thus we need to add it here. -	*y = (int)(point.y * height + offsetY); - -	// Clip coordinates -	if (*x < 0 || *x > CGRectGetWidth(*area) || *y < 0 || *y > CGRectGetHeight(*area)) -			return false; - -	return true; -} - -static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) { -	if (!tex) -		return; - -	glBindTexture(GL_TEXTURE_2D, tex); printOpenGLError(); - -	GLint filter = GL_LINEAR; - -	switch (mode) { -	case kGraphicsModeLinear: -		filter = GL_LINEAR; -		break; - -	case kGraphicsModeNone: -		filter = GL_NEAREST; -		break; -	} - -	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); printOpenGLError(); -	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); printOpenGLError(); -} -  @implementation iPhoneView  + (Class)layerClass {  	return [CAEAGLLayer class];  } +- (VideoContext *)getVideoContext { +	return &_videoContext; +} +  - (void)createContext {  	CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; @@ -317,20 +151,18 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {  			return;  		} -		_overlayHeight = _renderBufferWidth; -		_overlayWidth = _renderBufferHeight; -		_overlayTexWidth = getSizeNextPOT(_overlayHeight); -		_overlayTexHeight = getSizeNextPOT(_overlayWidth); +		_videoContext.overlayHeight = _renderBufferWidth; +		_videoContext.overlayWidth = _renderBufferHeight; +		uint overlayTextureWidth = getSizeNextPOT(_videoContext.overlayHeight); +		uint overlayTextureHeight = getSizeNextPOT(_videoContext.overlayWidth);  		// 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[2] = _overlayTexCoords[6] = _overlayWidth / (GLfloat)_overlayTexWidth; -		_overlayTexCoords[5] = _overlayTexCoords[7] = _overlayHeight / (GLfloat)_overlayTexHeight; +		_overlayTexCoords[2] = _overlayTexCoords[6] = _videoContext.overlayWidth / (GLfloat)overlayTextureWidth; +		_overlayTexCoords[5] = _overlayTexCoords[7] = _videoContext.overlayHeight / (GLfloat)overlayTextureHeight; -		int textureSize = _overlayTexWidth * _overlayTexHeight * 2; -		_overlayTexBuffer = (char *)malloc(textureSize); -		memset(_overlayTexBuffer, 0, textureSize); +		_videoContext.overlayTexture.create(overlayTextureWidth, overlayTextureHeight, Graphics::createPixelFormat<5551>());  		glViewport(0, 0, _renderBufferWidth, _renderBufferHeight); printOpenGLError();  		glClearColor(0.0f, 0.0f, 0.0f, 1.0f); printOpenGLError(); @@ -356,13 +188,15 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {  	_fullWidth = (int)frame.size.width;  	_fullHeight = (int)frame.size.height; -	sharedInstance = self; +	g_iPhoneViewInstance = self;  	_keyboardView = nil;  	_screenTexture = 0;  	_overlayTexture = 0;  	_mouseCursorTexture = 0; +	_scaledShakeOffsetY = 0; +  	_gameScreenVertCoords[0] = _gameScreenVertCoords[1] =  	    _gameScreenVertCoords[2] = _gameScreenVertCoords[3] =  	    _gameScreenVertCoords[4] = _gameScreenVertCoords[5] = @@ -383,6 +217,16 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {  	    _overlayTexCoords[4] = _overlayTexCoords[5] =  	    _overlayTexCoords[6] = _overlayTexCoords[7] = 0; +	_mouseVertCoords[0] = _mouseVertCoords[1] = +	    _mouseVertCoords[2] = _mouseVertCoords[3] = +	    _mouseVertCoords[4] = _mouseVertCoords[5] = +	    _mouseVertCoords[6] = _mouseVertCoords[7] = 0; + +	_mouseTexCoords[0] = _mouseTexCoords[1] = +	    _mouseTexCoords[2] = _mouseTexCoords[3] = +	    _mouseTexCoords[4] = _mouseTexCoords[5] = +	    _mouseTexCoords[6] = _mouseTexCoords[7] = 0; +  	// Initialize the OpenGL ES context  	[self createContext]; @@ -396,12 +240,9 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {  		[_keyboardView dealloc];  	} -	free(_gameScreenTextureBuffer); -	free(_overlayTexBuffer); -} - -- (void *)getSurface { -	return _screenSurface; +	_videoContext.screenTexture.free(); +	_videoContext.overlayTexture.free(); +	_videoContext.mouseTexture.free();  }  - (void)drawRect:(CGRect)frame { @@ -419,10 +260,32 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {  #endif  } +- (void)setFilterModeForTexture:(GLuint)tex { +	if (!tex) +		return; + +	glBindTexture(GL_TEXTURE_2D, tex); printOpenGLError(); + +	GLint filter = GL_LINEAR; + +	switch (_videoContext.graphicsMode) { +	case kGraphicsModeLinear: +		filter = GL_LINEAR; +		break; + +	case kGraphicsModeNone: +		filter = GL_NEAREST; +		break; +	} + +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); printOpenGLError(); +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); printOpenGLError(); +} +  - (void)setGraphicsMode { -	setFilterModeForTexture(_screenTexture, _graphicsMode); -	setFilterModeForTexture(_overlayTexture, _graphicsMode); -	setFilterModeForTexture(_mouseCursorTexture, _graphicsMode); +	[self setFilterModeForTexture:_screenTexture]; +	[self setFilterModeForTexture:_overlayTexture]; +	[self setFilterModeForTexture:_mouseCursorTexture];  }  - (void)updateSurface { @@ -435,10 +298,10 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {  	[self updateMainSurface]; -	if (_overlayIsEnabled) +	if (_videoContext.overlayVisible)  		[self updateOverlaySurface]; -	if (_mouseCursorEnabled) +	if (_videoContext.mouseIsVisible)  		[self updateMouseSurface];  	glBindRenderbufferOES(GL_RENDERBUFFER_OES, _viewRenderbuffer); printOpenGLError(); @@ -446,17 +309,70 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {  } +- (void)notifyMouseMove { +	const GLint mouseX = (GLint)(_videoContext.mouseX * _mouseScaleX) - _mouseHotspotX; +	const GLint mouseY = (GLint)(_videoContext.mouseY * _mouseScaleY) - _mouseHotspotY; + +	_mouseVertCoords[0] = _mouseVertCoords[4] = mouseX; +	_mouseVertCoords[1] = _mouseVertCoords[3] = mouseY; +	_mouseVertCoords[2] = _mouseVertCoords[6] = mouseX + _mouseWidth; +	_mouseVertCoords[5] = _mouseVertCoords[7] = mouseY + _mouseHeight; +} + +- (void)updateMouseCursorScaling { +	CGRect *rect; +	int maxWidth, maxHeight; + +	if (!_videoContext.overlayVisible) { +		rect = &_gameScreenRect; +		maxWidth = _videoContext.screenWidth; +		maxHeight = _videoContext.screenHeight; +	} else { +		rect = &_overlayRect; +		maxWidth = _videoContext.overlayWidth; +		maxHeight = _videoContext.overlayHeight; +	} + +	if (!maxWidth || !maxHeight) { +		printf("WARNING: updateMouseCursorScaling called when screen was not ready (%d)!\n", _videoContext.overlayVisible); +		return; +	} + +	_mouseScaleX = CGRectGetWidth(*rect) / (GLfloat)maxWidth; +	_mouseScaleY = CGRectGetHeight(*rect) / (GLfloat)maxHeight; + +	_mouseWidth = (GLint)(_videoContext.mouseWidth * _mouseScaleX); +	_mouseHeight = (GLint)(_videoContext.mouseHeight * _mouseScaleY); + +	_mouseHotspotX = (GLint)(_videoContext.mouseHotspotX * _mouseScaleX); +	_mouseHotspotY = (GLint)(_videoContext.mouseHotspotY * _mouseScaleY); + +	// We subtract the screen offset to the hotspot here to simplify the +	// screen offset handling in the mouse code. Note the subtraction here +	// makes sure that the offset actually gets added to the mouse position, +	// since the hotspot offset is substracted from the position. +	_mouseHotspotX -= (GLint)CGRectGetMinX(*rect); +	_mouseHotspotY -= (GLint)CGRectGetMinY(*rect); + +	// FIXME: For now we also adapt the mouse position here. In reality we +	// would be better off to also adjust the event position when switching +	// from overlay to game screen or vica versa. +	[self notifyMouseMove]; +} +  - (void)updateMouseCursor {  	if (_mouseCursorTexture == 0) {  		glGenTextures(1, &_mouseCursorTexture); printOpenGLError(); -		setFilterModeForTexture(_mouseCursorTexture, _graphicsMode); +		[self setFilterModeForTexture:_mouseCursorTexture];  	} -	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(); +	[self updateMouseCursorScaling]; + +	_mouseTexCoords[2] = _mouseTexCoords[6] = _videoContext.mouseWidth / (GLfloat)_videoContext.mouseTexture.w; +	_mouseTexCoords[5] = _mouseTexCoords[7] = _videoContext.mouseHeight / (GLfloat)_videoContext.mouseTexture.h; -	free(_mouseCursor); -	_mouseCursor = NULL; +	glBindTexture(GL_TEXTURE_2D, _mouseCursorTexture); printOpenGLError(); +	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _videoContext.mouseTexture.w, _videoContext.mouseTexture.h, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, _videoContext.mouseTexture.pixels); printOpenGLError();  }  - (void)updateMainSurface { @@ -468,7 +384,7 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {  	// 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, _gameScreenTextureWidth, _gameScreenTextureHeight, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, _gameScreenTextureBuffer); printOpenGLError(); +	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _videoContext.screenTexture.w, _videoContext.screenTexture.h, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, _videoContext.screenTexture.pixels); printOpenGLError();  	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); printOpenGLError();  } @@ -477,147 +393,81 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {  	glTexCoordPointer(2, GL_FLOAT, 0, _overlayTexCoords); 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(); +	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _videoContext.overlayTexture.w, _videoContext.overlayTexture.h, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, _videoContext.overlayTexture.pixels); printOpenGLError();  	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); printOpenGLError();  }  - (void)updateMouseSurface { -	int width = _mouseCursorWidth; -	int height = _mouseCursorHeight; - -	int mouseX = _mouseX; -	int mouseY = _mouseY; - -	int hotspotX = _mouseCursorHotspotX; -	int hotspotY = _mouseCursorHotspotY; - -	CGRect *rect; -	int maxWidth, maxHeight; - -	if (!_overlayIsEnabled) { -		rect = &_gameScreenRect; -		maxWidth = _width; -		maxHeight = _height; -	} else { -		rect = &_overlayRect; -		maxWidth = _overlayWidth; -		maxHeight = _overlayHeight; -	} - -	const GLfloat scaleX = CGRectGetWidth(*rect) / (GLfloat)maxWidth; -	const GLfloat scaleY = CGRectGetHeight(*rect) / (GLfloat)maxHeight; - -	mouseX = (int)(mouseX * scaleX); -	mouseY = (int)(mouseY * scaleY); -	hotspotX = (int)(hotspotX * scaleX); -	hotspotY = (int)(hotspotY * scaleY); -	width = (int)(width * scaleX); -	height = (int)(height * scaleY); - -	mouseX -= hotspotX; -	mouseY -= hotspotY; - -	mouseX += (int)CGRectGetMinX(*rect); -	mouseY += (int)CGRectGetMinY(*rect); - -	GLfloat vertices[] = { -		// Top left -		mouseX        , mouseY, -		// Top right -		mouseX + width, mouseY, -		// Bottom left -		mouseX        , mouseY + height, -		// Bottom right -		mouseX + width, mouseY + height -	}; - -	//printf("Cursor: width %u height %u\n", _mouseCursorWidth, _mouseCursorHeight); - -	float texWidth = _mouseCursorWidth / (float)getSizeNextPOT(_mouseCursorWidth); -	float texHeight = _mouseCursorHeight / (float)getSizeNextPOT(_mouseCursorHeight); - -	const GLfloat texCoords[] = { -		// Top left -		0       , 0, -		// Top right -		texWidth, 0, -		// Bottom left -		0       , texHeight, -		// Bottom right -		texWidth, texHeight -	}; - -	glVertexPointer(2, GL_FLOAT, 0, vertices); printOpenGLError(); -	glTexCoordPointer(2, GL_FLOAT, 0, texCoords); printOpenGLError(); +	glVertexPointer(2, GL_FLOAT, 0, _mouseVertCoords); printOpenGLError(); +	glTexCoordPointer(2, GL_FLOAT, 0, _mouseTexCoords); printOpenGLError();  	glBindTexture(GL_TEXTURE_2D, _mouseCursorTexture); printOpenGLError();  	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); printOpenGLError();  } -- (void)initSurface { -	_gameScreenTextureWidth = getSizeNextPOT(_width); -	_gameScreenTextureHeight = getSizeNextPOT(_height); - -	_gameScreenTexCoords[2] = _gameScreenTexCoords[6] = _width / (GLfloat)_gameScreenTextureWidth; -	_gameScreenTexCoords[5] = _gameScreenTexCoords[7] = _height / (GLfloat)_gameScreenTextureHeight; - -	_orientation = [[UIDevice currentDevice] orientation]; - -	switch (_orientation) { -	case UIDeviceOrientationLandscapeLeft: -	case UIDeviceOrientationLandscapeRight: -	case UIDeviceOrientationPortrait: -		break; - -	default: -		_orientation = UIDeviceOrientationPortrait; -	} - -	//printf("Window: (%d, %d), Surface: (%d, %d), Texture(%d, %d)\n", _fullWidth, _fullHeight, _width, _height, _gameScreenTextureWidth, _gameScreenTextureHeight); +- (void)setUpOrientation:(UIDeviceOrientation)orientation width:(int *)width height:(int *)height { +	_orientation = orientation;  	glMatrixMode(GL_PROJECTION);  	glLoadIdentity(); -	int screenWidth, screenHeight; - -	// Set the origin (0,0) depending on the rotation mode. -	if (_orientation ==  UIDeviceOrientationLandscapeRight) { +	// We always force the origin (0,0) to be in the upper left corner. +	switch (_orientation) { +	case UIDeviceOrientationLandscapeRight:  		glRotatef( 90, 0, 0, 1); printOpenGLError();  		glOrthof(0, _renderBufferHeight, _renderBufferWidth, 0, 0, 1); printOpenGLError(); -		screenWidth = _renderBufferHeight; -		screenHeight = _renderBufferWidth; -	} else if (_orientation == UIDeviceOrientationLandscapeLeft) { +		*width = _renderBufferHeight; +		*height = _renderBufferWidth; +		break; + +	case UIDeviceOrientationLandscapeLeft:  		glRotatef(-90, 0, 0, 1); printOpenGLError();  		glOrthof(0, _renderBufferHeight, _renderBufferWidth, 0, 0, 1); printOpenGLError(); -		screenWidth = _renderBufferHeight; -		screenHeight = _renderBufferWidth; -	} else if (_orientation == UIDeviceOrientationPortrait) { +		*width = _renderBufferHeight; +		*height = _renderBufferWidth; +		break; + +	case UIDeviceOrientationPortrait: +	default: +		// We must force the portrait orientation here, since we might not know +		// the real orientation. +		_orientation = UIDeviceOrientationPortrait; +  		glOrthof(0, _renderBufferWidth, _renderBufferHeight, 0, 0, 1); printOpenGLError(); -		screenWidth = _renderBufferWidth; -		screenHeight = _renderBufferHeight; +		*width = _renderBufferWidth; +		*height = _renderBufferHeight; +		break;  	} +} + +- (void)initSurface { +	uint screenTexWidth = getSizeNextPOT(_videoContext.screenWidth); +	uint screenTexHeight = getSizeNextPOT(_videoContext.screenHeight); + +	_gameScreenTexCoords[2] = _gameScreenTexCoords[6] = _videoContext.screenWidth / (GLfloat)screenTexWidth; +	_gameScreenTexCoords[5] = _gameScreenTexCoords[7] = _videoContext.screenHeight / (GLfloat)screenTexHeight; + +	int screenWidth, screenHeight; +	[self setUpOrientation:[[UIDevice currentDevice] orientation] width:&screenWidth height:&screenHeight];  	if (_screenTexture > 0) {  		glDeleteTextures(1, &_screenTexture); printOpenGLError();  	}  	glGenTextures(1, &_screenTexture); printOpenGLError(); -	setFilterModeForTexture(_screenTexture, _graphicsMode); +	[self setFilterModeForTexture:_screenTexture];  	if (_overlayTexture > 0) {  		glDeleteTextures(1, &_overlayTexture); printOpenGLError();  	}  	glGenTextures(1, &_overlayTexture); printOpenGLError(); -	setFilterModeForTexture(_overlayTexture, _graphicsMode); +	[self setFilterModeForTexture:_overlayTexture]; -	free(_gameScreenTextureBuffer); -	int textureSize = _gameScreenTextureWidth * _gameScreenTextureHeight * 2; -	_gameScreenTextureBuffer = (char *)malloc(textureSize); -	memset(_gameScreenTextureBuffer, 0, textureSize); +	_videoContext.screenTexture.create(screenTexWidth, screenTexHeight, Graphics::createPixelFormat<565>());  	glBindRenderbufferOES(GL_RENDERBUFFER_OES, _viewRenderbuffer); printOpenGLError(); @@ -631,7 +481,7 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {  	float overlayPortraitRatio;  	if (_orientation == UIDeviceOrientationLandscapeLeft || _orientation ==  UIDeviceOrientationLandscapeRight) { -		GLfloat gameScreenRatio = (GLfloat)_width / (GLfloat)_height; +		GLfloat gameScreenRatio = (GLfloat)_videoContext.screenWidth / (GLfloat)_videoContext.screenHeight;  		GLfloat screenRatio = (GLfloat)screenWidth / (GLfloat)screenHeight;  		// These are the width/height according to the portrait layout! @@ -660,7 +510,7 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {  		_gameScreenRect = CGRectMake(xOffset, yOffset, rectWidth, rectHeight);  		overlayPortraitRatio = 1.0f;  	} else { -		float ratio = (float)_height / (float)_width; +		float ratio = (float)_videoContext.screenHeight / (float)_videoContext.screenWidth;  		int height = (int)(screenWidth * ratio);  		//printf("Making rect (%u, %u)\n", screenWidth, height);  		_gameScreenRect = CGRectMake(0, 0, screenWidth, height); @@ -674,7 +524,7 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {  		[self addSubview:[_keyboardView inputView]];  		[self addSubview: _keyboardView];  		[[_keyboardView inputView] becomeFirstResponder]; -		overlayPortraitRatio = (_overlayHeight * ratio) / _overlayWidth; +		overlayPortraitRatio = (_videoContext.overlayHeight * ratio) / _videoContext.overlayWidth;  	}  	_overlayRect = CGRectMake(0, 0, screenWidth, screenHeight * overlayPortraitRatio); @@ -688,6 +538,7 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {  	_overlayVertCoords[5] = _overlayVertCoords[7] = CGRectGetMaxY(_overlayRect);  	[self setViewTransformation]; +	[self updateMouseCursorScaling];  }  - (void)setViewTransformation { @@ -698,7 +549,7 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {  	// Scale the shake offset according to the overlay size. We need this to  	// adjust the overlay mouse click coordinates when an offset is set. -	_scaledShakeOffsetY = (int)(_shakeOffsetY / (GLfloat)_height * CGRectGetHeight(_overlayRect)); +	_scaledShakeOffsetY = (int)(_videoContext.shakeOffsetY / (GLfloat)_videoContext.screenHeight * CGRectGetHeight(_overlayRect));  	// Apply the shakeing to the output screen.  	glTranslatef(0, -_scaledShakeOffsetY, 0); @@ -732,6 +583,64 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {  	[_events addObject: event];  } +/** + * Converts portrait mode coordinates into rotated mode coordinates. + */ +- (bool)convertToRotatedCoords:(CGPoint)point result:(CGPoint *)result { +	switch (_orientation) { +	case UIDeviceOrientationLandscapeLeft: +		result->x = point.y; +		result->y = _renderBufferWidth - point.x; +		return true; + +	case UIDeviceOrientationLandscapeRight: +		result->x = _renderBufferHeight - point.y; +		result->y = point.x; +		return true; + +	case UIDeviceOrientationPortrait: +		result->x = point.x; +		result->y = point.y; +		return true; + +	default: +		return false; +	} +} + +- (bool)getMouseCoords:(CGPoint)point eventX:(int *)x eventY:(int *)y { +	if (![self convertToRotatedCoords:point result:&point]) +		return false; + +	CGRect *area; +	int width, height, offsetY; +	if (_videoContext.overlayVisible) { +		area = &_overlayRect; +		width = _videoContext.overlayWidth; +		height = _videoContext.overlayHeight; +		offsetY = _scaledShakeOffsetY; +	} else { +		area = &_gameScreenRect; +		width = _videoContext.screenWidth; +		height = _videoContext.screenHeight; +		offsetY = _videoContext.shakeOffsetY; +	} + +	point.x = (point.x - CGRectGetMinX(*area)) / CGRectGetWidth(*area); +	point.y = (point.y - CGRectGetMinY(*area)) / CGRectGetHeight(*area); + +	*x = (int)(point.x * width); +	// offsetY describes the translation of the screen in the upward direction, +	// thus we need to add it here. +	*y = (int)(point.y * height + offsetY); + +	// Clip coordinates +	if (*x < 0 || *x > width || *y < 0 || *y > height) +		return false; + +	return true; +} +  - (void)deviceOrientationChanged:(UIDeviceOrientation)orientation {  	switch (orientation) {  	case UIDeviceOrientationLandscapeLeft: @@ -762,7 +671,7 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {  	case 1: {  		UITouch *touch = [touches anyObject];  		CGPoint point = [touch locationInView:self]; -		if (!getMouseCoords(_orientation, point, &x, &y)) +		if (![self getMouseCoords:point eventX:&x eventY:&y])  			return;  		_firstTouch = touch; @@ -780,7 +689,7 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {  	case 2: {  		UITouch *touch = [touches anyObject];  		CGPoint point = [touch locationInView:self]; -		if (!getMouseCoords(_orientation, point, &x, &y)) +		if (![self getMouseCoords:point eventX:&x eventY:&y])  			return;  		_secondTouch = touch; @@ -804,7 +713,7 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {  	for (UITouch *touch in touches) {  		if (touch == _firstTouch) {  			CGPoint point = [touch locationInView:self]; -			if (!getMouseCoords(_orientation, point, &x, &y)) +			if (![self getMouseCoords:point eventX:&x eventY:&y])  				return;  			[self addEvent: @@ -817,7 +726,7 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {  			 ];  		} else if (touch == _secondTouch) {  			CGPoint point = [touch locationInView:self]; -			if (!getMouseCoords(_orientation, point, &x, &y)) +			if (![self getMouseCoords:point eventX:&x eventY:&y])  				return;  			[self addEvent: @@ -840,7 +749,7 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {  	case 1: {  		UITouch *touch = [[allTouches allObjects] objectAtIndex:0];  		CGPoint point = [touch locationInView:self]; -		if (!getMouseCoords(_orientation, point, &x, &y)) +		if (![self getMouseCoords:point eventX:&x eventY:&y])  			return;  		[self addEvent: @@ -857,7 +766,7 @@ static void setFilterModeForTexture(GLuint tex, GraphicsModes mode) {  	case 2: {  		UITouch *touch = [[allTouches allObjects] objectAtIndex:1];  		CGPoint point = [touch locationInView:self]; -		if (!getMouseCoords(_orientation, point, &x, &y)) +		if (![self getMouseCoords:point eventX:&x eventY:&y])  			return;  		[self addEvent: diff --git a/backends/platform/iphone/osys_events.cpp b/backends/platform/iphone/osys_events.cpp index c167da35e6..85efbda208 100644 --- a/backends/platform/iphone/osys_events.cpp +++ b/backends/platform/iphone/osys_events.cpp @@ -122,8 +122,8 @@ bool OSystem_IPHONE::handleEvent_mouseDown(Common::Event &event, int x, int y) {  	if (_mouseClickAndDragEnabled) {  		event.type = Common::EVENT_LBUTTONDOWN; -		event.mouse.x = _mouseX; -		event.mouse.y = _mouseY; +		event.mouse.x = _videoContext->mouseX; +		event.mouse.y = _videoContext->mouseY;  		return true;  	} else {  		_lastMouseDown = getMillis(); @@ -140,17 +140,17 @@ bool OSystem_IPHONE::handleEvent_mouseUp(Common::Event &event, int x, int y) {  			return false;  	} else if (_mouseClickAndDragEnabled) {  		event.type = Common::EVENT_LBUTTONUP; -		event.mouse.x = _mouseX; -		event.mouse.y = _mouseY; +		event.mouse.x = _videoContext->mouseX; +		event.mouse.y = _videoContext->mouseY;  	} else {  		if (getMillis() - _lastMouseDown < 250) {  			event.type = Common::EVENT_LBUTTONDOWN; -			event.mouse.x = _mouseX; -			event.mouse.y = _mouseY; +			event.mouse.x = _videoContext->mouseX; +			event.mouse.y = _videoContext->mouseY;  			_queuedInputEvent.type = Common::EVENT_LBUTTONUP; -			_queuedInputEvent.mouse.x = _mouseX; -			_queuedInputEvent.mouse.y = _mouseY; +			_queuedInputEvent.mouse.x = _videoContext->mouseX; +			_queuedInputEvent.mouse.y = _videoContext->mouseY;  			_lastMouseTap = getMillis();  			_queuedEventTime = _lastMouseTap + kQueuedInputEventDelay;  		} else @@ -167,12 +167,12 @@ bool OSystem_IPHONE::handleEvent_secondMouseDown(Common::Event &event, int x, in  	if (_mouseClickAndDragEnabled) {  		event.type = Common::EVENT_LBUTTONUP; -		event.mouse.x = _mouseX; -		event.mouse.y = _mouseY; +		event.mouse.x = _videoContext->mouseX; +		event.mouse.y = _videoContext->mouseY;  		_queuedInputEvent.type = Common::EVENT_RBUTTONDOWN; -		_queuedInputEvent.mouse.x = _mouseX; -		_queuedInputEvent.mouse.y = _mouseY; +		_queuedInputEvent.mouse.x = _videoContext->mouseX; +		_queuedInputEvent.mouse.y = _videoContext->mouseY;  	} else  		return false; @@ -184,7 +184,7 @@ bool OSystem_IPHONE::handleEvent_secondMouseUp(Common::Event &event, int x, int  	if (curTime - _lastSecondaryDown < 400) {  		//printf("Right tap!\n"); -		if (curTime - _lastSecondaryTap < 400 && !_overlayVisible) { +		if (curTime - _lastSecondaryTap < 400 && !_videoContext->overlayVisible) {  			//printf("Right escape!\n");  			event.type = Common::EVENT_KEYDOWN;  			_queuedInputEvent.type = Common::EVENT_KEYUP; @@ -197,11 +197,11 @@ bool OSystem_IPHONE::handleEvent_secondMouseUp(Common::Event &event, int x, int  		} else if (!_mouseClickAndDragEnabled) {  			//printf("Rightclick!\n");  			event.type = Common::EVENT_RBUTTONDOWN; -			event.mouse.x = _mouseX; -			event.mouse.y = _mouseY; +			event.mouse.x = _videoContext->mouseX; +			event.mouse.y = _videoContext->mouseY;  			_queuedInputEvent.type = Common::EVENT_RBUTTONUP; -			_queuedInputEvent.mouse.x = _mouseX; -			_queuedInputEvent.mouse.y = _mouseY; +			_queuedInputEvent.mouse.x = _videoContext->mouseX; +			_queuedInputEvent.mouse.y = _videoContext->mouseY;  			_lastSecondaryTap = curTime;  			_queuedEventTime = curTime + kQueuedInputEventDelay;  		} else { @@ -211,8 +211,8 @@ bool OSystem_IPHONE::handleEvent_secondMouseUp(Common::Event &event, int x, int  	}  	if (_mouseClickAndDragEnabled) {  		event.type = Common::EVENT_RBUTTONUP; -		event.mouse.x = _mouseX; -		event.mouse.y = _mouseY; +		event.mouse.x = _videoContext->mouseX; +		event.mouse.y = _videoContext->mouseY;  	}  	return true; @@ -234,11 +234,11 @@ bool OSystem_IPHONE::handleEvent_mouseDragged(Common::Event &event, int x, int y  		_lastPadX = x;  		_lastPadY = y; -		mouseNewPosX = (int)(_mouseX - deltaX / 0.5f); -		mouseNewPosY = (int)(_mouseY - deltaY / 0.5f); +		mouseNewPosX = (int)(_videoContext->mouseX - deltaX / 0.5f); +		mouseNewPosY = (int)(_videoContext->mouseY - deltaY / 0.5f); -		int widthCap = _overlayVisible ? _overlayWidth : _screenWidth; -		int heightCap = _overlayVisible ? _overlayHeight : _screenHeight; +		int widthCap = _videoContext->overlayVisible ? _videoContext->overlayWidth : _videoContext->screenWidth; +		int heightCap = _videoContext->overlayVisible ? _videoContext->overlayHeight : _videoContext->screenHeight;  		if (mouseNewPosX < 0)  			mouseNewPosX = 0; @@ -350,10 +350,10 @@ void  OSystem_IPHONE::handleEvent_orientationChanged(int orientation) {  	if (_screenOrientation != newOrientation) {  		_screenOrientation = newOrientation; -		iPhone_initSurface(_screenWidth, _screenHeight); +		updateOutputSurface();  		dirtyFullScreen(); -		if (_overlayVisible) +		if (_videoContext->overlayVisible)  			dirtyFullOverlayScreen();  		updateScreen();  	} diff --git a/backends/platform/iphone/osys_main.cpp b/backends/platform/iphone/osys_main.cpp index 2bdc09c9ce..dabf73bf58 100644 --- a/backends/platform/iphone/osys_main.cpp +++ b/backends/platform/iphone/osys_main.cpp @@ -56,17 +56,16 @@ void *OSystem_IPHONE::s_soundParam = NULL;  OSystem_IPHONE::OSystem_IPHONE() :  	_mixer(NULL), _gameScreenRaw(NULL), -	_overlayVisible(false), _gameScreenConverted(NULL), -	_mouseHeight(0), _mouseWidth(0), _mouseBuf(NULL), _lastMouseTap(0), _queuedEventTime(0), +	_mouseBuf(NULL), _lastMouseTap(0), _queuedEventTime(0),  	_mouseNeedTextureUpdate(false), _secondaryTapped(false), _lastSecondaryTap(0),  	_screenOrientation(kScreenOrientationFlippedLandscape), _mouseClickAndDragEnabled(false),  	_gestureStartX(-1), _gestureStartY(-1), _fullScreenIsDirty(false), _fullScreenOverlayIsDirty(false),  	_mouseDirty(false), _timeSuspended(0), _lastDragPosX(-1), _lastDragPosY(-1), _screenChangeCount(0), -	_overlayHeight(0), _overlayWidth(0), _overlayBuffer(0), _mouseCursorPaletteEnabled(false), -	_currentGraphicsMode(kGraphicsModeLinear) { +	_mouseCursorPaletteEnabled(false) {  	_queuedInputEvent.type = Common::EVENT_INVALID;  	_touchpadModeEnabled = !iPhone_isHighResDevice();  	_fsFactory = new POSIXFilesystemFactory(); +	initVideoContext();  }  OSystem_IPHONE::~OSystem_IPHONE() { @@ -74,7 +73,6 @@ OSystem_IPHONE::~OSystem_IPHONE() {  	delete _mixer;  	free(_gameScreenRaw); -	free(_gameScreenConverted);  }  int OSystem_IPHONE::timerHandler(int t) { diff --git a/backends/platform/iphone/osys_main.h b/backends/platform/iphone/osys_main.h index e4b3d358d5..180d3e9d06 100644 --- a/backends/platform/iphone/osys_main.h +++ b/backends/platform/iphone/osys_main.h @@ -59,37 +59,25 @@ protected:  	static SoundProc s_soundCallback;  	static void *s_soundParam; -	int _currentGraphicsMode; -  	Audio::MixerImpl *_mixer; +	VideoContext *_videoContext; +  	Graphics::Surface _framebuffer;  	byte *_gameScreenRaw; -	OverlayColor  *_overlayBuffer; -	uint16 _overlayHeight; -	uint16 _overlayWidth; - -	uint16 *_gameScreenConverted;  	// For use with the game texture  	uint16  _gamePalette[256];  	// For use with the mouse texture  	uint16  _gamePaletteRGBA5551[256]; -	bool _overlayVisible; -	uint16 _screenWidth; -	uint16 _screenHeight;  	struct timeval _startTime;  	uint32 _timeSuspended; -	bool _mouseVisible;  	bool _mouseCursorPaletteEnabled;  	uint16 _mouseCursorPalette[256];  	byte *_mouseBuf;  	byte _mouseKeyColor; -	uint _mouseWidth, _mouseHeight; -	uint _mouseX, _mouseY; -	int _mouseHotspotX, _mouseHotspotY;  	bool _mouseDirty;  	bool _mouseNeedTextureUpdate;  	long _lastMouseDown; @@ -192,13 +180,14 @@ public:  	virtual void logMessage(LogMessageType::Type type, const char *message);  protected: +	void initVideoContext(); +	void updateOutputSurface(); +  	void internUpdateScreen();  	void dirtyFullScreen();  	void dirtyFullOverlayScreen();  	void suspendLoop();  	void drawDirtyRect(const Common::Rect &dirtyRect); -	void drawDirtyOverlayRect(const Common::Rect &dirtyRect); -	void updateHardwareSurfaceForRect(const Common::Rect &updatedRect);  	void updateMouseTexture();  	static void AQBufferCallback(void *in, AudioQueueRef inQ, AudioQueueBufferRef outQB);  	static int timerHandler(int t); diff --git a/backends/platform/iphone/osys_video.cpp b/backends/platform/iphone/osys_video.mm index e26c360c82..31db4c70e7 100644 --- a/backends/platform/iphone/osys_video.cpp +++ b/backends/platform/iphone/osys_video.mm @@ -25,11 +25,16 @@  #include "osys_main.h" +#include "iphone_video.h" + +void OSystem_IPHONE::initVideoContext() { +	_videoContext = [g_iPhoneViewInstance getVideoContext]; +} +  const OSystem::GraphicsMode *OSystem_IPHONE::getSupportedGraphicsModes() const {  	return s_supportedGraphicsModes;  } -  int OSystem_IPHONE::getDefaultGraphicsMode() const {  	return kGraphicsModeLinear;  } @@ -38,8 +43,8 @@ bool OSystem_IPHONE::setGraphicsMode(int mode) {  	switch (mode) {  	case kGraphicsModeNone:  	case kGraphicsModeLinear: -		_currentGraphicsMode = mode; -		iPhone_setGraphicsMode((GraphicsModes)mode); +		_videoContext->graphicsMode = (GraphicsModes)mode; +		[g_iPhoneViewInstance performSelectorOnMainThread:@selector(setGraphicsMode) withObject:nil waitUntilDone: YES];  		return true;  	default: @@ -48,55 +53,44 @@ bool OSystem_IPHONE::setGraphicsMode(int mode) {  }  int OSystem_IPHONE::getGraphicsMode() const { -	return _currentGraphicsMode; +	return _videoContext->graphicsMode;  }  void OSystem_IPHONE::initSize(uint width, uint height, const Graphics::PixelFormat *format) {  	//printf("initSize(%i, %i)\n", width, height); -	_screenWidth = width; -	_screenHeight = height; +	_videoContext->screenWidth = width; +	_videoContext->screenHeight = height; +	_videoContext->shakeOffsetY = 0;  	free(_gameScreenRaw);  	_gameScreenRaw = (byte *)malloc(width * height);  	bzero(_gameScreenRaw, width * height); -	//free(_overlayBuffer); +	updateOutputSurface(); -	int fullSize = _screenWidth * _screenHeight * sizeof(OverlayColor); -	//_overlayBuffer = (OverlayColor *)malloc(fullSize);  	clearOverlay(); -	free(_gameScreenConverted); - -	_gameScreenConverted = (uint16 *)malloc(fullSize); -	bzero(_gameScreenConverted, fullSize); - -	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; +	_videoContext->mouseIsVisible = false;  	_mouseCursorPaletteEnabled = false;  	_screenChangeCount++; +  	updateScreen();  } +void OSystem_IPHONE::updateOutputSurface() { +	[g_iPhoneViewInstance performSelectorOnMainThread:@selector(initSurface) withObject:nil waitUntilDone: YES]; +} +  int16 OSystem_IPHONE::getHeight() { -	return _screenHeight; +	return _videoContext->screenHeight;  }  int16 OSystem_IPHONE::getWidth() { -	return _screenWidth; +	return _videoContext->screenWidth;  }  void OSystem_IPHONE::setPalette(const byte *colors, uint start, uint num) { @@ -137,12 +131,12 @@ void OSystem_IPHONE::copyRectToScreen(const byte *buf, int pitch, int x, int y,  		y = 0;  	} -	if (w > _screenWidth - x) { -		w = _screenWidth - x; +	if (w > (int)_videoContext->screenWidth - x) { +		w = _videoContext->screenWidth - x;  	} -	if (h > _screenHeight - y) { -		h = _screenHeight - y; +	if (h > (int)_videoContext->screenHeight - y) { +		h = _videoContext->screenHeight - y;  	}  	if (w <= 0 || h <= 0) @@ -153,14 +147,14 @@ void OSystem_IPHONE::copyRectToScreen(const byte *buf, int pitch, int x, int y,  	} -	byte *dst = _gameScreenRaw + y * _screenWidth + x; -	if (_screenWidth == pitch && pitch == w) +	byte *dst = _gameScreenRaw + y * _videoContext->screenWidth + x; +	if ((int)_videoContext->screenWidth == pitch && pitch == w)  		memcpy(dst, buf, h * w);  	else {  		do {  			memcpy(dst, buf, w);  			buf += pitch; -			dst += _screenWidth; +			dst += _videoContext->screenWidth;  		} while (--h);  	}  } @@ -176,7 +170,7 @@ void OSystem_IPHONE::updateScreen() {  	_fullScreenIsDirty = false;  	_fullScreenOverlayIsDirty = false; -	iPhone_updateScreen(_mouseX, _mouseY); +	iPhone_updateScreen();  }  void OSystem_IPHONE::internUpdateScreen() { @@ -190,16 +184,19 @@ void OSystem_IPHONE::internUpdateScreen() {  		//printf("Drawing: (%i, %i) -> (%i, %i)\n", dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom);  		drawDirtyRect(dirtyRect); -		updateHardwareSurfaceForRect(dirtyRect); +		// TODO: Implement dirty rect code +		//updateHardwareSurfaceForRect(dirtyRect);  	} -	if (_overlayVisible) { -		while (_dirtyOverlayRects.size()) { +	if (_videoContext->overlayVisible) { +		// TODO: Implement dirty rect code +		_dirtyOverlayRects.clear(); +		/*while (_dirtyOverlayRects.size()) {  			Common::Rect dirtyRect = _dirtyOverlayRects.remove_at(_dirtyOverlayRects.size() - 1);  			//printf("Drawing: (%i, %i) -> (%i, %i)\n", dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom);  			drawDirtyOverlayRect(dirtyRect); -		} +		}*/  	}  } @@ -207,32 +204,25 @@ void OSystem_IPHONE::drawDirtyRect(const Common::Rect &dirtyRect) {  	int h = dirtyRect.bottom - dirtyRect.top;  	int w = dirtyRect.right - dirtyRect.left; -	byte  *src = &_gameScreenRaw[dirtyRect.top * _screenWidth + dirtyRect.left]; -	uint16 *dst = &_gameScreenConverted[dirtyRect.top * _screenWidth + dirtyRect.left]; +	byte *src = &_gameScreenRaw[dirtyRect.top * _videoContext->screenWidth + dirtyRect.left]; +	byte *dstRaw = (byte *)_videoContext->screenTexture.getBasePtr(dirtyRect.left, dirtyRect.top);  	for (int y = h; y > 0; y--) { +		uint16 *dst = (uint16 *)dstRaw;  		for (int x = w; x > 0; x--)  			*dst++ = _gamePalette[*src++]; -		dst += _screenWidth - w; -		src += _screenWidth - w; +		dstRaw += _videoContext->screenTexture.pitch; +		src += _videoContext->screenWidth - w;  	}  } -void OSystem_IPHONE::drawDirtyOverlayRect(const Common::Rect &dirtyRect) { -	iPhone_updateOverlayRect(_overlayBuffer, dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom); -} - -void OSystem_IPHONE::updateHardwareSurfaceForRect(const Common::Rect &updatedRect) { -	iPhone_updateScreenRect(_gameScreenConverted, updatedRect.left, updatedRect.top, updatedRect.right, updatedRect.bottom); -} -  Graphics::Surface *OSystem_IPHONE::lockScreen() {  	//printf("lockScreen()\n");  	_framebuffer.pixels = _gameScreenRaw; -	_framebuffer.w = _screenWidth; -	_framebuffer.h = _screenHeight; -	_framebuffer.pitch = _screenWidth; +	_framebuffer.w = _videoContext->screenWidth; +	_framebuffer.h = _videoContext->screenHeight; +	_framebuffer.pitch = _videoContext->screenWidth;  	_framebuffer.format = Graphics::PixelFormat::createFormatCLUT8();  	return &_framebuffer; @@ -245,41 +235,44 @@ void OSystem_IPHONE::unlockScreen() {  void OSystem_IPHONE::setShakePos(int shakeOffset) {  	//printf("setShakePos(%i)\n", shakeOffset); -	iPhone_setShakeOffset(shakeOffset); +	_videoContext->shakeOffsetY = shakeOffset; +	[g_iPhoneViewInstance performSelectorOnMainThread:@selector(setViewTransformation) withObject:nil waitUntilDone: YES];  	// HACK: We use this to force a redraw.  	_mouseDirty = true;  }  void OSystem_IPHONE::showOverlay() {  	//printf("showOverlay()\n"); -	_overlayVisible = true; +	_videoContext->overlayVisible = true;  	dirtyFullOverlayScreen();  	updateScreen(); -	iPhone_enableOverlay(true); +	[g_iPhoneViewInstance performSelectorOnMainThread:@selector(updateMouseCursorScaling) withObject:nil waitUntilDone: YES]; +	[g_iPhoneViewInstance performSelectorOnMainThread:@selector(clearColorBuffer) withObject:nil waitUntilDone: YES];  }  void OSystem_IPHONE::hideOverlay() {  	//printf("hideOverlay()\n"); -	_overlayVisible = false; +	_videoContext->overlayVisible = false;  	_dirtyOverlayRects.clear();  	dirtyFullScreen(); -	iPhone_enableOverlay(false); +	[g_iPhoneViewInstance performSelectorOnMainThread:@selector(updateMouseCursorScaling) withObject:nil waitUntilDone: YES]; +	[g_iPhoneViewInstance performSelectorOnMainThread:@selector(clearColorBuffer) withObject:nil waitUntilDone: YES];  }  void OSystem_IPHONE::clearOverlay() {  	//printf("clearOverlay()\n"); -	bzero(_overlayBuffer, _overlayWidth * _overlayHeight * sizeof(OverlayColor)); +	bzero(_videoContext->overlayTexture.getBasePtr(0, 0), _videoContext->overlayTexture.h * _videoContext->overlayTexture.pitch);  	dirtyFullOverlayScreen();  }  void OSystem_IPHONE::grabOverlay(OverlayColor *buf, int pitch) {  	//printf("grabOverlay()\n"); -	int h = _overlayHeight; -	OverlayColor *src = _overlayBuffer; +	int h = _videoContext->overlayHeight; +	const byte *src = (const byte *)_videoContext->overlayTexture.getBasePtr(0, 0);  	do { -		memcpy(buf, src, _overlayWidth * sizeof(OverlayColor)); -		src += _overlayWidth; +		memcpy(buf, src, _videoContext->overlayWidth * sizeof(OverlayColor)); +		src += _videoContext->overlayTexture.pitch;  		buf += pitch;  	} while (--h);  } @@ -300,11 +293,11 @@ void OSystem_IPHONE::copyRectToOverlay(const OverlayColor *buf, int pitch, int x  		y = 0;  	} -	if (w > _overlayWidth - x) -		w = _overlayWidth - x; +	if (w > (int)_videoContext->overlayWidth - x) +		w = _videoContext->overlayWidth - x; -	if (h > _overlayHeight - y) -		h = _overlayHeight - y; +	if (h > (int)_videoContext->overlayHeight - y) +		h = _videoContext->overlayHeight - y;  	if (w <= 0 || h <= 0)  		return; @@ -313,30 +306,25 @@ 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 * _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 += _overlayWidth; -		} while (--h); -	} +	byte *dst = (byte *)_videoContext->overlayTexture.getBasePtr(x, y); +	do {  +		memcpy(dst, buf, w * sizeof(OverlayColor)); +		buf += pitch; +		dst += _videoContext->overlayTexture.pitch; +	} while (--h);  }  int16 OSystem_IPHONE::getOverlayHeight() { -	return _overlayHeight; +	return _videoContext->overlayHeight;  }  int16 OSystem_IPHONE::getOverlayWidth() { -	return _overlayWidth; +	return _videoContext->overlayWidth;  }  bool OSystem_IPHONE::showMouse(bool visible) { -	bool last = _mouseVisible; -	_mouseVisible = visible; -	iPhone_showCursor(visible); +	bool last = _videoContext->mouseIsVisible; +	_videoContext->mouseIsVisible = visible;  	_mouseDirty = true;  	return last; @@ -344,16 +332,16 @@ bool OSystem_IPHONE::showMouse(bool visible) {  void OSystem_IPHONE::warpMouse(int x, int y) {  	//printf("warpMouse()\n"); - -	_mouseX = x; -	_mouseY = y; +	_videoContext->mouseX = x; +	_videoContext->mouseY = y; +	[g_iPhoneViewInstance performSelectorOnMainThread:@selector(notifyMouseMove) withObject:nil waitUntilDone: YES];  	_mouseDirty = true;  }  void OSystem_IPHONE::dirtyFullScreen() {  	if (!_fullScreenIsDirty) {  		_dirtyRects.clear(); -		_dirtyRects.push_back(Common::Rect(0, 0, _screenWidth, _screenHeight)); +		_dirtyRects.push_back(Common::Rect(0, 0, _videoContext->screenWidth, _videoContext->screenHeight));  		_fullScreenIsDirty = true;  	}  } @@ -361,7 +349,7 @@ void OSystem_IPHONE::dirtyFullScreen() {  void OSystem_IPHONE::dirtyFullOverlayScreen() {  	if (!_fullScreenOverlayIsDirty) {  		_dirtyOverlayRects.clear(); -		_dirtyOverlayRects.push_back(Common::Rect(0, 0, _overlayWidth, _overlayHeight)); +		_dirtyOverlayRects.push_back(Common::Rect(0, 0, _videoContext->overlayWidth, _videoContext->overlayHeight));  		_fullScreenOverlayIsDirty = true;  	}  } @@ -369,7 +357,7 @@ void OSystem_IPHONE::dirtyFullOverlayScreen() {  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, scale %u)\n", hotspotX, hotspotY, cursorTargetScale); -	if (_mouseBuf != NULL && (_mouseWidth != w || _mouseHeight != h)) { +	if (_mouseBuf != NULL && (_videoContext->mouseWidth != w || _videoContext->mouseHeight != h)) {  		free(_mouseBuf);  		_mouseBuf = NULL;  	} @@ -377,11 +365,11 @@ void OSystem_IPHONE::setMouseCursor(const byte *buf, uint w, uint h, int hotspot  	if (_mouseBuf == NULL)  		_mouseBuf = (byte *)malloc(w * h); -	_mouseWidth = w; -	_mouseHeight = h; +	_videoContext->mouseWidth = w; +	_videoContext->mouseHeight = h; -	_mouseHotspotX = hotspotX; -	_mouseHotspotY = hotspotY; +	_videoContext->mouseHotspotX = hotspotX; +	_videoContext->mouseHotspotY = hotspotY;  	_mouseKeyColor = (byte)keycolor; @@ -406,11 +394,12 @@ void OSystem_IPHONE::setCursorPalette(const byte *colors, uint start, uint num)  }  void OSystem_IPHONE::updateMouseTexture() { -	int texWidth = getSizeNextPOT(_mouseWidth); -	int texHeight = getSizeNextPOT(_mouseHeight); -	int bufferSize = texWidth * texHeight * sizeof(int16); -	uint16 *mouseBuf = (uint16 *)malloc(bufferSize); -	memset(mouseBuf, 0, bufferSize); +	uint texWidth = getSizeNextPOT(_videoContext->mouseWidth); +	uint texHeight = getSizeNextPOT(_videoContext->mouseHeight); + +	Graphics::Surface &mouseTexture = _videoContext->mouseTexture; +	if (mouseTexture.w != texWidth || mouseTexture.h != texHeight) +		mouseTexture.create(texWidth, texHeight, Graphics::createPixelFormat<5551>());  	const uint16 *palette;  	if (_mouseCursorPaletteEnabled) @@ -418,9 +407,10 @@ void OSystem_IPHONE::updateMouseTexture() {  	else  		palette = _gamePaletteRGBA5551; -	for (uint x = 0; x < _mouseWidth; ++x) { -		for (uint y = 0; y < _mouseHeight; ++y) { -			const byte color = _mouseBuf[y * _mouseWidth + x]; +	uint16 *mouseBuf = (uint16 *)mouseTexture.getBasePtr(0, 0); +	for (uint x = 0; x < _videoContext->mouseWidth; ++x) { +		for (uint y = 0; y < _videoContext->mouseHeight; ++y) { +			const byte color = _mouseBuf[y * _videoContext->mouseWidth + x];  			if (color != _mouseKeyColor)  				mouseBuf[y * texWidth + x] = palette[color] | 0x1;  			else @@ -428,5 +418,5 @@ void OSystem_IPHONE::updateMouseTexture() {  		}  	} -	iPhone_setMouseCursor(mouseBuf, _mouseWidth, _mouseHeight, _mouseHotspotX, _mouseHotspotY); +	[g_iPhoneViewInstance performSelectorOnMainThread:@selector(updateMouseCursor) withObject:nil waitUntilDone: YES];  }  | 
