aboutsummaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
Diffstat (limited to 'backends')
-rw-r--r--backends/platform/iphone/iphone_common.h52
-rw-r--r--backends/platform/iphone/iphone_main.m96
-rw-r--r--backends/platform/iphone/iphone_video.h61
-rw-r--r--backends/platform/iphone/iphone_video.m318
-rw-r--r--backends/platform/iphone/module.mk12
-rw-r--r--backends/platform/iphone/osys_iphone.cpp621
-rw-r--r--backends/platform/iphone/osys_iphone.h144
7 files changed, 1304 insertions, 0 deletions
diff --git a/backends/platform/iphone/iphone_common.h b/backends/platform/iphone/iphone_common.h
new file mode 100644
index 0000000000..f1731f3dfe
--- /dev/null
+++ b/backends/platform/iphone/iphone_common.h
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+
+enum InputEvent {
+ kInputMouseDown,
+ kInputMouseUp,
+ kInputMouseDragged,
+ kInputMouseSecondToggled
+};
+
+// We need this to be able to call functions from/in Objective-C.
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// On the C++ side
+void iphone_main(int argc, char *argv[]);
+
+// On the ObjC side
+void iPhone_updateScreen();
+unsigned short* iPhone_getSurface();
+void iPhone_lockSurface();
+void iPhone_unlockSurface();
+void iPhone_initSurface(int width, int height);
+bool iPhone_fetchEvent(int *outEvent, float *outX, float *outY);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/backends/platform/iphone/iphone_main.m b/backends/platform/iphone/iphone_main.m
new file mode 100644
index 0000000000..5701b361ff
--- /dev/null
+++ b/backends/platform/iphone/iphone_main.m
@@ -0,0 +1,96 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#import <UIKit/UIKit.h>
+#import <Foundation/NSThread.h>
+#include "iphone_video.h"
+
+void iphone_main(int argc, char *argv[]);
+
+@interface iPhoneMain : UIApplication {
+ UIWindow* _window;
+ iPhoneView* _view;
+}
+
+- (void) mainLoop: (id)param;
+- (iPhoneView*) getView;
+- (UIWindow*) getWindow;
+@end
+
+static int gArgc;
+static char** gArgv;
+
+int main(int argc, char** argv) {
+ gArgc = argc;
+ gArgv = argv;
+
+ [[NSAutoreleasePool alloc] init];
+
+ return UIApplicationMain(argc, argv, [iPhoneMain class]);
+}
+
+@implementation iPhoneMain
+
+-(id) init {
+ [super init];
+ _window = nil;
+ _view = nil;
+ return self;
+}
+
+- (void) mainLoop: (id)param {
+ [[NSAutoreleasePool alloc] init];
+
+ iphone_main(gArgc, gArgv);
+ [UIApp terminate];
+}
+
+- (iPhoneView*) getView {
+ return _view;
+}
+
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
+ // hide the status bar
+ [UIHardware _setStatusBarHeight:0.0f];
+ [self setStatusBarMode:2 orientation:0 duration:0.0f fenceID:0];
+
+ _window = [[UIWindow alloc] initWithContentRect: [UIHardware fullScreenApplicationContentRect]];
+ [_window retain];
+
+ _view = [[iPhoneView alloc] initWithFrame: [UIHardware fullScreenApplicationContentRect]];
+ [_window setContentView: _view];
+
+ [_window orderFront: self];
+ [_window makeKey: self];
+
+ [NSThread detachNewThreadSelector:@selector(mainLoop:) toTarget:self withObject:nil];
+}
+
+- (UIWindow*) getWindow {
+ return _window;
+}
+
+@end
+
diff --git a/backends/platform/iphone/iphone_video.h b/backends/platform/iphone/iphone_video.h
new file mode 100644
index 0000000000..dfd45eb89a
--- /dev/null
+++ b/backends/platform/iphone/iphone_video.h
@@ -0,0 +1,61 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _IPHONE_VIDEO__H
+#define _IPHONE_VIDEO__H
+
+#import <UIKit/UIKit.h>
+#import <UIKit/UIView-Geometry.h>
+#import <GraphicsServices/GraphicsServices.h>
+#import <Foundation/Foundation.h>
+#import <CoreSurface/CoreSurface.h>
+#import <LayerKit/LKLayer.h>
+
+
+@interface iPhoneView : UIView
+{
+ CoreSurfaceBufferRef _screenSurface;
+ NSMutableArray* _events;
+ NSLock* _lock;
+ int _fullWidth;
+ int _fullHeight;
+ int _widthOffset;
+ int _heightOffset;
+}
+
+- (id)initWithFrame:(struct CGRect)frame;
+
+- (void)drawRect:(CGRect)frame;
+
+- (CoreSurfaceBufferRef)getSurface;
+
+- (void)initSurface;
+
+- (void)updateScreen;
+
+- (id)getEvent;
+@end
+
+#endif /* _IPHONE_VIDEO__H */
diff --git a/backends/platform/iphone/iphone_video.m b/backends/platform/iphone/iphone_video.m
new file mode 100644
index 0000000000..becd30b7d7
--- /dev/null
+++ b/backends/platform/iphone/iphone_video.m
@@ -0,0 +1,318 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "iphone_video.h"
+#include "iphone_common.h"
+
+#import <UIKit/UIKit.h>
+#import <UIKit/UIView-Geometry.h>
+#import <GraphicsServices/GraphicsServices.h>
+#import <Foundation/Foundation.h>
+#import <CoreSurface/CoreSurface.h>
+#import <LayerKit/LKLayer.h>
+
+static iPhoneView *sharedInstance = nil;
+static int _width = 0;
+static int _height = 0;
+
+// static long lastTick = 0;
+// static int frames = 0;
+
+unsigned short* iPhone_getSurface() {
+ return CoreSurfaceBufferGetBaseAddress([sharedInstance getSurface]);
+}
+
+void iPhone_updateScreen() {
+ [sharedInstance performSelectorOnMainThread:@selector(updateScreen) withObject:nil waitUntilDone: NO];
+}
+
+void iPhone_lockSurface() {
+ CoreSurfaceBufferLock([sharedInstance getSurface], 3);
+}
+
+void iPhone_unlockSurface() {
+ CoreSurfaceBufferUnlock([sharedInstance getSurface]);
+}
+
+void iPhone_initSurface(int width, int height) {
+ _width = width;
+ _height = height;
+
+ [sharedInstance performSelectorOnMainThread:@selector(initSurface) withObject:nil waitUntilDone: YES];
+}
+
+bool iPhone_fetchEvent(int *outEvent, float *outX, float *outY)
+{
+ id event = [sharedInstance getEvent];
+ if (event == nil) {
+ return false;
+ }
+
+ id type = [event objectForKey:@"type"];
+
+ if (type == nil) {
+ printf("fetchEvent says: No type!\n");
+ return false;
+ }
+
+ *outEvent = [type intValue];
+ *outX = [[event objectForKey:@"x"] floatValue];
+ *outY = [[event objectForKey:@"y"] floatValue];
+ return true;
+}
+
+@implementation iPhoneView
+
+- (id)initWithFrame:(struct CGRect)frame {
+ [super initWithFrame: frame];
+
+ _fullWidth = frame.size.width;
+ _fullHeight = frame.size.height;
+
+ sharedInstance = self;
+
+ return self;
+}
+
+-(void) dealloc {
+ [super dealloc];
+}
+
+- (CoreSurfaceBufferRef)getSurface {
+ return _screenSurface;
+}
+
+- (void)drawRect:(CGRect)frame {
+ // if (lastTick == 0) {
+ // lastTick = time(0);
+ // }
+ //
+ // frames++;
+ // if (time(0) > lastTick) {
+ // lastTick = time(0);
+ // printf("FPS: %i\n", frames);
+ // frames = 0;
+ // }
+}
+
+- (void)updateScreen {
+ [sharedInstance setNeedsDisplay];
+}
+
+- (void)initSurface {
+ //printf("Window: (%d, %d), Surface: (%d, %d)\n", _fullWidth, _fullHeight, _width, _height);
+
+ int pitch = _width * 2;
+ int allocSize = 2 * _width * _height;
+ char *pixelFormat = "565L";
+
+ NSDictionary* dict = [[NSDictionary alloc] initWithObjectsAndKeys:
+ kCFBooleanTrue, kCoreSurfaceBufferGlobal,
+ @"PurpleGFXMem", kCoreSurfaceBufferMemoryRegion,
+ [NSNumber numberWithInt: pitch], kCoreSurfaceBufferPitch,
+ [NSNumber numberWithInt: _width], kCoreSurfaceBufferWidth,
+ [NSNumber numberWithInt: _height], kCoreSurfaceBufferHeight,
+ [NSNumber numberWithInt: *(int*)pixelFormat], kCoreSurfaceBufferPixelFormat,
+ [NSNumber numberWithInt: allocSize], kCoreSurfaceBufferAllocSize,
+ nil
+ ];
+
+ //("Allocating surface: %d\n", allocSize);
+ _screenSurface = CoreSurfaceBufferCreate((CFDictionaryRef)dict);
+ //printf("Surface created.\n");
+ CoreSurfaceBufferLock(_screenSurface, 3);
+
+ LKLayer* screenLayer = [[LKLayer layer] retain];
+
+ float ratioDifference = ((float)_width / (float)_height) / ((float)_fullWidth / (float)_fullHeight);
+ int rectWidth, rectHeight;
+ if (ratioDifference < 1.0f) {
+ rectWidth = _fullWidth * ratioDifference;
+ rectHeight = _fullHeight;
+ _widthOffset = (_fullWidth - rectWidth)/2;
+ _heightOffset = 0;
+ } else {
+ rectWidth = _fullWidth;
+ rectHeight = _fullHeight / ratioDifference;
+ _heightOffset = (_fullHeight - rectHeight)/2;
+ _widthOffset = 0;
+ }
+
+ //printf("Rect: %i, %i, %i, %i\n", _widthOffset, _heightOffset, rectWidth + _widthOffset, rectHeight + _heightOffset);
+ [screenLayer setFrame: CGRectMake(_widthOffset, _heightOffset, rectWidth + _widthOffset, rectHeight + _heightOffset)];
+
+ [screenLayer setContents: _screenSurface];
+ [screenLayer setOpaque: YES];
+ [[sharedInstance _layer] addSublayer: screenLayer];
+
+ CoreSurfaceBufferUnlock(_screenSurface);
+ [dict release];
+}
+
+
+- (void)lock
+{
+ [_lock lock];
+}
+
+- (void)unlock
+{
+ [_lock unlock];
+}
+
+- (id)getEvent
+{
+ if (_events == nil || [_events count] == 0) {
+ return nil;
+ }
+
+ [self lock];
+
+ id event = [_events objectAtIndex: 0];
+ if (event == nil) {
+ return nil;
+ }
+
+ [_events removeObjectAtIndex: 0];
+ [self unlock];
+
+ return event;
+}
+
+- (void)addEvent:(NSDictionary*)event
+{
+ [self lock];
+
+ if(_events == nil)
+ _events = [[NSMutableArray alloc] init];
+
+ [_events addObject: event];
+
+ [self unlock];
+}
+
+- (void)mouseDown:(GSEvent*)event
+{
+ struct CGPoint point = GSEventGetLocationInWindow(event);
+
+ [self addEvent:
+ [[NSDictionary alloc] initWithObjectsAndKeys:
+ [NSNumber numberWithInt:kInputMouseDown], @"type",
+ [NSNumber numberWithFloat:(point.x/_fullWidth)], @"x",
+ [NSNumber numberWithFloat:(point.y/_fullHeight)], @"y",
+ nil
+ ]
+ ];
+}
+
+- (void)mouseUp:(GSEvent*)event
+{
+ struct CGPoint point = GSEventGetLocationInWindow(event);
+ [self addEvent:
+ [[NSDictionary alloc] initWithObjectsAndKeys:
+ [NSNumber numberWithInt:kInputMouseUp], @"type",
+ [NSNumber numberWithFloat:(point.x/_fullWidth)], @"x",
+ [NSNumber numberWithFloat:(point.y/_fullHeight)], @"y",
+ nil
+ ]
+ ];
+}
+
+- (void)mouseDragged:(GSEvent*)event
+{
+ struct CGPoint point = GSEventGetLocationInWindow(event);
+ [self addEvent:
+ [[NSDictionary alloc] initWithObjectsAndKeys:
+ [NSNumber numberWithInt:kInputMouseDragged], @"type",
+ [NSNumber numberWithFloat:(point.x/_fullWidth)], @"x",
+ [NSNumber numberWithFloat:(point.y/_fullHeight)], @"y",
+ nil
+ ]
+ ];
+}
+
+- (void)mouseEntered:(GSEvent*)event
+{
+ //printf("mouseEntered()\n");
+ // struct CGPoint point = GSEventGetLocationInWindow(event);
+ // [self addEvent:
+ // [[NSDictionary alloc] initWithObjectsAndKeys:
+ // [NSNumber numberWithInt:kInputMouseSecondStartDrag], @"type",
+ // [NSNumber numberWithFloat:(point.x/_fullWidth)], @"x",
+ // [NSNumber numberWithFloat:(point.y/_fullHeight)], @"y",
+ // nil
+ // ]
+ // ];
+}
+
+- (void)mouseExited:(GSEvent*)event
+{
+ //printf("mouseExited().\n");
+ // [self addEvent:
+ // [[NSDictionary alloc] initWithObjectsAndKeys:
+ // @"mouseExited", @"type",
+ // nil
+ // ]
+ // ];
+}
+
+- (void)mouseMoved:(GSEvent*)event
+{
+ //printf("mouseMoved()\n");
+ struct CGPoint point = GSEventGetLocationInWindow(event);
+ [self addEvent:
+ [[NSDictionary alloc] initWithObjectsAndKeys:
+ [NSNumber numberWithInt:kInputMouseSecondToggled], @"type",
+ [NSNumber numberWithFloat:(point.x/_fullWidth)], @"x",
+ [NSNumber numberWithFloat:(point.y/_fullHeight)], @"y",
+ nil
+ ]
+ ];
+}
+
+- (void)keyDown:(GSEvent*)event
+{
+ printf("keyDown()\n");
+ [self addEvent:
+ [[NSDictionary alloc] initWithObjectsAndKeys:
+ @"keyDown", @"type",
+ nil
+ ]
+ ];
+}
+
+- (void)keyUp:(GSEvent*)event
+{
+ printf("keyUp()\n");
+ [self addEvent:
+ [[NSDictionary alloc] initWithObjectsAndKeys:
+ @"keyUp", @"type",
+ nil
+ ]
+ ];
+}
+
+@end
+
diff --git a/backends/platform/iphone/module.mk b/backends/platform/iphone/module.mk
new file mode 100644
index 0000000000..2d26c26e59
--- /dev/null
+++ b/backends/platform/iphone/module.mk
@@ -0,0 +1,12 @@
+MODULE := backends/platform/iphone
+
+MODULE_OBJS := \
+ osys_iphone.o \
+ iphone_main.o \
+ iphone_video.o
+
+MODULE_DIRS += \
+ backends/platform/iphone/
+
+# We don't use the rules.mk here on purpose
+OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS)
diff --git a/backends/platform/iphone/osys_iphone.cpp b/backends/platform/iphone/osys_iphone.cpp
new file mode 100644
index 0000000000..7cf4ecffb0
--- /dev/null
+++ b/backends/platform/iphone/osys_iphone.cpp
@@ -0,0 +1,621 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#if defined(IPHONE_BACKEND)
+
+#include <CoreGraphics/CGDirectDisplay.h>
+#include <CoreSurface/CoreSurface.h>
+#include <unistd.h>
+#include <pthread.h>
+
+#include "common/system.h"
+#include "common/scummsys.h"
+#include "common/util.h"
+#include "common/rect.h"
+#include "common/events.h"
+
+#include "base/main.h"
+
+#include "backends/saves/default/default-saves.h"
+#include "backends/timer/default/default-timer.h"
+#include "backends/intern.h"
+#include "sound/mixer.h"
+
+#include "osys_iphone.h"
+#include "iphone_common.h"
+
+const OSystem::GraphicsMode OSystem_IPHONE::s_supportedGraphicsModes[] = {
+ {0, 0, 0}
+};
+
+OSystem_IPHONE::OSystem_IPHONE() :
+ _savefile(NULL), _mixer(NULL), _timer(NULL), _offscreen(NULL),
+ _overlayVisible(false), _overlayBuffer(NULL), _fullscreen(NULL),
+ _mouseHeight(0), _mouseWidth(0), _mouseBuf(NULL), _lastMouseTap(0),
+ _secondaryTapped(false), _lastSecondaryTap(0)
+{
+ _queuedInputEvent.type = (Common::EventType)0;
+}
+
+OSystem_IPHONE::~OSystem_IPHONE() {
+ delete _savefile;
+ delete _mixer;
+ delete _timer;
+ delete _offscreen;
+ delete _fullscreen;
+}
+
+void OSystem_IPHONE::initBackend() {
+ _savefile = new DefaultSaveFileManager();
+ _mixer = new Audio::Mixer();
+ _timer = new DefaultTimerManager();
+
+ setSoundCallback(Audio::Mixer::mixCallback, _mixer);
+
+ gettimeofday(&_startTime, NULL);
+
+ OSystem::initBackend();
+}
+
+bool OSystem_IPHONE::hasFeature(Feature f) {
+ return false;
+}
+
+void OSystem_IPHONE::setFeatureState(Feature f, bool enable) {
+}
+
+bool OSystem_IPHONE::getFeatureState(Feature f) {
+ return false;
+}
+
+const OSystem::GraphicsMode* OSystem_IPHONE::getSupportedGraphicsModes() const {
+ return s_supportedGraphicsModes;
+}
+
+
+int OSystem_IPHONE::getDefaultGraphicsMode() const {
+ return -1;
+}
+
+bool OSystem_IPHONE::setGraphicsMode(const char *mode) {
+ return true;
+}
+
+bool OSystem_IPHONE::setGraphicsMode(int mode) {
+ return true;
+}
+
+int OSystem_IPHONE::getGraphicsMode() const {
+ return -1;
+}
+
+void OSystem_IPHONE::initSize(uint width, uint height) {
+ //printf("initSize(%i, %i)\n", width, height);
+
+ _screenWidth = width;
+ _screenHeight = height;
+
+ if (_offscreen)
+ free(_offscreen);
+
+ _offscreen = (byte *)malloc(width * height);
+ bzero(_offscreen, width * height);
+
+ if (_overlayBuffer)
+ free(_overlayBuffer);
+
+ int fullSize = _screenWidth * _screenHeight * sizeof(OverlayColor);
+ _overlayBuffer = (OverlayColor *)malloc(fullSize);
+ clearOverlay();
+
+ if (_fullscreen) {
+ free(_fullscreen);
+ }
+ _fullscreen = (uint16 *)malloc(fullSize);
+ bzero(_fullscreen, fullSize);
+
+ iPhone_initSurface(height, width);
+
+ _mouseVisible = false;
+}
+
+int16 OSystem_IPHONE::getHeight() {
+ return _screenHeight;
+}
+
+int16 OSystem_IPHONE::getWidth() {
+ return _screenWidth;
+}
+
+void OSystem_IPHONE::setPalette(const byte *colors, uint start, uint num) {
+ //printf("setPalette()\n");
+ const byte *b = colors;
+
+ for (uint i = start; i < num; ++i) {
+ _palette[i] = RGBToColor(b[0], b[1], b[2]);
+ b += 4;
+ }
+}
+
+void OSystem_IPHONE::grabPalette(byte *colors, uint start, uint num) {
+ //printf("grabPalette()\n");
+}
+
+void OSystem_IPHONE::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) {
+ //printf("copyRectToScreen()\n");
+ //Clip the coordinates
+ if (x < 0) {
+ w += x;
+ buf -= x;
+ x = 0;
+ }
+
+ if (y < 0) {
+ h += y;
+ buf -= y * pitch;
+ y = 0;
+ }
+
+ if (w > _screenWidth - x) {
+ w = _screenWidth - x;
+ }
+
+ if (h > _screenHeight - y) {
+ h = _screenHeight - y;
+ }
+
+ if (w <= 0 || h <= 0)
+ return;
+
+
+ byte *dst = _offscreen + y * _screenWidth + x;
+ if (_screenWidth == pitch && pitch == w) {
+ memcpy(dst, buf, h * w);
+ } else {
+ do {
+ memcpy(dst, buf, w);
+ buf += pitch;
+ dst += _screenWidth;
+ } while (--h);
+ }
+}
+
+void OSystem_IPHONE::updateScreen() {
+ //printf("updateScreen()\n");
+
+ //uint16* screen = iPhone_getSurface();
+
+ int row;
+ if (_overlayVisible) {
+ for (int x = _screenWidth; x >= 1; x--) {
+ row = (_screenWidth - x) * _screenHeight;
+ for (int y = 0; y < _screenHeight; y++) {
+ _fullscreen[row + y] = _overlayBuffer[y * _screenWidth + x];
+ }
+ }
+ } else {
+ for (int x = _screenWidth; x >= 1; x--) {
+ row = (_screenWidth - x) * _screenHeight;
+ for (int y = 0; y < _screenHeight; y++) {
+ _fullscreen[row + y] = _palette[_offscreen[y * _screenWidth + x]];
+ }
+ }
+ }
+
+ //draw mouse on top
+ if (_mouseVisible) {
+ for (uint x = _mouseWidth; x >= 1; x--) {
+ int mx = _mouseX + x; // + _mouseHotspotX;
+ row = (_screenWidth - mx) * _screenHeight;
+ if (mx >= 0 && mx < _screenWidth) {
+ for (uint y = 0; y < _mouseHeight; ++y) {
+ if (_mouseBuf[y * _mouseWidth + x] != _mouseKeyColour) {
+ int my = _mouseY + y; // + _mouseHotspotY;
+
+ if ( my >= 0 && my < _screenHeight)
+ _fullscreen[row + my] = _palette[_mouseBuf[y * _mouseWidth + x]];
+ }
+ }
+ }
+ }
+ }
+
+ memcpy(iPhone_getSurface(), _fullscreen, (_screenWidth * _screenHeight) * 2);
+ iPhone_updateScreen();
+}
+
+Graphics::Surface *OSystem_IPHONE::lockScreen() {
+ //printf("lockScreen()\n");
+
+ _framebuffer.pixels = _offscreen;
+ _framebuffer.w = _screenWidth;
+ _framebuffer.h = _screenHeight;
+ _framebuffer.pitch = _screenWidth;
+ _framebuffer.bytesPerPixel = 1;
+
+ return &_framebuffer;
+}
+
+void OSystem_IPHONE::unlockScreen() {
+ //printf("unlockScreen()\n");
+ updateScreen();
+}
+
+void OSystem_IPHONE::setShakePos(int shakeOffset) {
+}
+
+void OSystem_IPHONE::showOverlay() {
+ //printf("showOverlay()\n");
+ _overlayVisible = true;
+}
+
+void OSystem_IPHONE::hideOverlay() {
+ //printf("hideOverlay()\n");
+ _overlayVisible = false;
+}
+
+void OSystem_IPHONE::clearOverlay() {
+ //printf("clearOverlay()\n");
+ bzero(_overlayBuffer, _screenWidth * _screenHeight * sizeof(OverlayColor));
+}
+
+void OSystem_IPHONE::grabOverlay(OverlayColor *buf, int pitch) {
+ //printf("grabOverlay()\n");
+ int h = _screenHeight;
+ OverlayColor *src = _overlayBuffer;
+
+ do {
+ memcpy(buf, src, _screenWidth * sizeof(OverlayColor));
+ src += _screenWidth;
+ buf += pitch;
+ } while (--h);
+}
+
+void OSystem_IPHONE::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) {
+ //printf("copyRectToOverlay(buf, pitch=%i, x=%i, y=%i, w=%i, h=%i)\n", pitch, x, y, w, h);
+
+ //Clip the coordinates
+ if (x < 0) {
+ w += x;
+ buf -= x;
+ x = 0;
+ }
+
+ if (y < 0) {
+ h += y;
+ buf -= y * pitch;
+ y = 0;
+ }
+
+ if (w > _screenWidth - x) {
+ w = _screenWidth - x;
+ }
+
+ if (h > _screenHeight - y) {
+ h = _screenHeight - y;
+ }
+
+ if (w <= 0 || h <= 0)
+ return;
+
+
+ OverlayColor *dst = _overlayBuffer + (y * _screenWidth + x);
+ if (_screenWidth == pitch && pitch == w) {
+ memcpy(dst, buf, h * w * sizeof(OverlayColor));
+ } else {
+ do {
+ memcpy(dst, buf, w * sizeof(OverlayColor));
+ buf += pitch;
+ dst += _screenWidth;
+ } while (--h);
+ }
+}
+
+int16 OSystem_IPHONE::getOverlayHeight() {
+ return _screenHeight;
+}
+
+int16 OSystem_IPHONE::getOverlayWidth() {
+ return _screenWidth;
+}
+
+OverlayColor OSystem_IPHONE::RGBToColor(uint8 r, uint8 g, uint8 b)
+{
+ return (r & 0xF8) << 8 | (g & 0xFC) << 3 | (b >> 3);
+}
+
+void OSystem_IPHONE::colorToRGB(OverlayColor color, uint8 &r, uint8 &g, uint8 &b)
+{
+ r = ((color & 0xF800) >> 11) << 3;
+ g = ((color & 0x07e0) >> 5) << 2;
+ b = (color & 0x001F) << 3;
+}
+
+bool OSystem_IPHONE::showMouse(bool visible) {
+ bool last = _mouseVisible;
+ _mouseVisible = visible;
+ return last;
+}
+
+void OSystem_IPHONE::warpMouse(int x, int y) {
+ //printf("warpMouse()\n");
+ _mouseX = x;
+ _mouseY = y;
+}
+
+void OSystem_IPHONE::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor, int cursorTargetScale) {
+ //printf("setMouseCursor()\n");
+
+ if (_mouseBuf != NULL && (_mouseWidth != w || _mouseHeight != h)) {
+ free(_mouseBuf);
+ _mouseBuf = NULL;
+ }
+
+ if (_mouseBuf == NULL) {
+ _mouseBuf = (byte *)malloc(w * h);
+ }
+
+ _mouseWidth = w;
+ _mouseHeight = h;
+
+ _mouseHotspotX = hotspotX;
+ _mouseHotspotY = hotspotY;
+
+ _mouseKeyColour = keycolor;
+
+ memcpy(_mouseBuf, buf, w * h);
+}
+
+bool OSystem_IPHONE::pollEvent(Common::Event &event) {
+ //printf("pollEvent()\n");
+
+ if (_queuedInputEvent.type != (Common::EventType)0) {
+ event = _queuedInputEvent;
+ _queuedInputEvent.type = (Common::EventType)0;
+ return true;
+ }
+
+ int eventType;
+ float xUnit, yUnit;
+
+ if (iPhone_fetchEvent(&eventType, &xUnit, &yUnit)) {
+ int x = (int)((1.0 - yUnit) * _screenWidth);
+ int y = (int)(xUnit * _screenHeight);
+
+ long curTime = getMillis();
+
+ switch ((InputEvent)eventType) {
+ case kInputMouseDown:
+ //printf("Mouse down at (%u, %u)\n", x, y);
+ _lastMouseDown = curTime;
+ _mouseX = x;
+ _mouseY = y;
+ return false;
+
+ break;
+ case kInputMouseUp:
+ //printf("Mouse up at (%u, %u)\n", x, y);
+
+ if (curTime - _lastMouseDown < 250) {
+ event.type = Common::EVENT_LBUTTONDOWN;
+ event.mouse.x = _mouseX;
+ event.mouse.y = _mouseY;
+
+ _queuedInputEvent.type = Common::EVENT_LBUTTONUP;
+ _queuedInputEvent.mouse.x = _mouseX;
+ _queuedInputEvent.mouse.y = _mouseY;
+ _lastMouseTap = curTime;
+
+ // if (curTime - _lastMouseTap < 250 && !_overlayVisible) {
+ // event.type = Common::EVENT_KEYDOWN;
+ // _queuedInputEvent.type = Common::EVENT_KEYUP;
+ //
+ // event.kbd.flags = _queuedInputEvent.kbd.flags = 0;
+ // event.kbd.keycode = _queuedInputEvent.kbd.keycode = Common::KEYCODE_ESCAPE;
+ // event.kbd.ascii = _queuedInputEvent.kbd.ascii = 27;
+ //
+ // _lastMouseTap = 0;
+ // } else {
+ //
+ // }
+ } else {
+ return false;
+ }
+
+ break;
+ case kInputMouseDragged:
+ //printf("Mouse dragged at (%u, %u)\n", x, y);
+ if (_secondaryTapped) {
+ int vecX = (x - _gestureStartX);
+ int vecY = (y - _gestureStartY);
+ int lengthSq = vecX * vecX + vecY * vecY;
+ //printf("Lengthsq: %u\n", lengthSq);
+
+ if (lengthSq > 5000) { // Long enough gesture to react upon.
+ _gestureStartX = x;
+ _gestureStartY = y;
+
+ float vecLength = sqrt(lengthSq);
+ float vecXNorm = vecX / vecLength;
+ float vecYNorm = vecY / vecLength;
+
+ //printf("Swipe vector: (%.2f, %.2f)\n", vecXNorm, vecYNorm);
+
+ if (vecXNorm > -0.50 && vecXNorm < 0.50 && vecYNorm > 0.75) {
+ // Swipe down
+ event.type = Common::EVENT_KEYDOWN;
+ _queuedInputEvent.type = Common::EVENT_KEYUP;
+
+ event.kbd.flags = _queuedInputEvent.kbd.flags = 0;
+ event.kbd.keycode = _queuedInputEvent.kbd.keycode = Common::KEYCODE_F5;
+ event.kbd.ascii = _queuedInputEvent.kbd.ascii = 27;
+ } else if (vecXNorm > -0.50 && vecXNorm < 0.50 && vecYNorm < -0.75) {
+ // Swipe up
+ event.type = Common::EVENT_KEYDOWN;
+ _queuedInputEvent.type = Common::EVENT_KEYUP;
+
+ event.kbd.flags = _queuedInputEvent.kbd.flags = 0;
+ event.kbd.keycode = _queuedInputEvent.kbd.keycode = Common::KEYCODE_1;
+ event.kbd.ascii = _queuedInputEvent.kbd.ascii = 27;
+ } else if (vecXNorm > 0.75 && vecYNorm > -0.5 && vecYNorm < 0.5) {
+ // Swipe right
+ return false;
+ } else if (vecXNorm < -0.75 && vecYNorm > -0.5 && vecYNorm < 0.5) {
+ // Swipe left
+ return false;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ } else {
+ event.type = Common::EVENT_MOUSEMOVE;
+ event.mouse.x = x;
+ event.mouse.y = y;
+ _mouseX = x;
+ _mouseY = y;
+ }
+ break;
+ case kInputMouseSecondToggled:
+ _secondaryTapped = !_secondaryTapped;
+ //printf("Mouse second at (%u, %u). State now %s.\n", x, y, _secondaryTapped ? "on" : "off");
+ if (_secondaryTapped) {
+ _lastSecondaryDown = curTime;
+ _gestureStartX = x;
+ _gestureStartY = y;
+ return false;
+ } else if (curTime - _lastSecondaryDown < 250 ) {
+ if (curTime - _lastSecondaryTap < 250 && !_overlayVisible) {
+ event.type = Common::EVENT_KEYDOWN;
+ _queuedInputEvent.type = Common::EVENT_KEYUP;
+
+ event.kbd.flags = _queuedInputEvent.kbd.flags = 0;
+ event.kbd.keycode = _queuedInputEvent.kbd.keycode = Common::KEYCODE_ESCAPE;
+ event.kbd.ascii = _queuedInputEvent.kbd.ascii = 27;
+
+ _lastSecondaryTap = 0;
+ } else {
+ event.type = Common::EVENT_RBUTTONDOWN;
+ event.mouse.x = _mouseX;
+ event.mouse.y = _mouseY;
+ _queuedInputEvent.type = Common::EVENT_RBUTTONUP;
+ _queuedInputEvent.mouse.x = _mouseX;
+ _queuedInputEvent.mouse.y = _mouseY;
+ _lastSecondaryTap = curTime;
+ }
+ } else {
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return true;
+ }
+ return false;
+}
+
+uint32 OSystem_IPHONE::getMillis() {
+ //printf("getMillis()\n");
+
+ struct timeval currentTime;
+ gettimeofday(&currentTime, NULL);
+ return (uint32)(((currentTime.tv_sec - _startTime.tv_sec) * 1000) +
+ ((currentTime.tv_usec - _startTime.tv_usec) / 1000));
+}
+
+void OSystem_IPHONE::delayMillis(uint msecs) {
+ //printf("delayMillis(%d)\n", msecs);
+ usleep(msecs * 1000);
+}
+
+OSystem::MutexRef OSystem_IPHONE::createMutex(void) {
+ pthread_mutex_t *mutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
+ pthread_mutex_init(mutex, NULL);
+ return (MutexRef)mutex;
+}
+
+void OSystem_IPHONE::lockMutex(MutexRef mutex) {
+ pthread_mutex_lock((pthread_mutex_t *) mutex);
+}
+
+void OSystem_IPHONE::unlockMutex(MutexRef mutex) {
+ pthread_mutex_unlock((pthread_mutex_t *) mutex);
+}
+
+void OSystem_IPHONE::deleteMutex(MutexRef mutex) {
+ pthread_mutex_destroy((pthread_mutex_t *) mutex);
+ free(mutex);
+}
+
+bool OSystem_IPHONE::setSoundCallback(SoundProc proc, void *param) {
+ return true;
+}
+
+void OSystem_IPHONE::clearSoundCallback() {
+}
+
+int OSystem_IPHONE::getOutputSampleRate() const {
+ return 22050;
+}
+
+void OSystem_IPHONE::quit() {
+ //exit(0);
+}
+
+void OSystem_IPHONE::setWindowCaption(const char *caption) {
+}
+
+Common::SaveFileManager *OSystem_IPHONE::getSavefileManager() {
+ assert(_savefile);
+ return _savefile;
+}
+
+Audio::Mixer *OSystem_IPHONE::getMixer() {
+ assert(_mixer);
+ return _mixer;
+}
+
+Common::TimerManager *OSystem_IPHONE::getTimerManager() {
+ assert(_timer);
+ return _timer;
+}
+
+OSystem *OSystem_IPHONE_create() {
+ return new OSystem_IPHONE();
+}
+
+void iphone_main(int argc, char *argv[]) {
+ g_system = OSystem_IPHONE_create();
+ assert(g_system);
+
+ // Invoke the actual ScummVM main entry point:
+ scummvm_main(argc, argv);
+ g_system->quit(); // TODO: Consider removing / replacing this!
+}
+
+#endif
diff --git a/backends/platform/iphone/osys_iphone.h b/backends/platform/iphone/osys_iphone.h
new file mode 100644
index 0000000000..43d7897b6c
--- /dev/null
+++ b/backends/platform/iphone/osys_iphone.h
@@ -0,0 +1,144 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifdef IPHONE_BACKEND
+
+#include "graphics/surface.h"
+
+// #include <AudioToolbox/AudioQueue.h>
+//
+// /* Audio Resources */
+// #define AUDIO_BUFFERS 3
+// #define AUDIO_PRECACHE 4
+// #define WAVE_BUFFER_SIZE 735
+// #define WAVE_BUFFER_BANKS 25
+//
+// typedef struct AQCallbackStruct {
+// AudioQueueRef queue;
+// UInt32 frameCount;
+// AudioQueueBufferRef mBuffers[AUDIO_BUFFERS];
+// AudioStreamBasicDescription mDataFormat;
+// } AQCallbackStruct;
+
+class OSystem_IPHONE : public OSystem {
+protected:
+ static const OSystem::GraphicsMode s_supportedGraphicsModes[];
+
+ Common::SaveFileManager *_savefile;
+ Audio::Mixer *_mixer;
+ Common::TimerManager *_timer;
+
+ Graphics::Surface _framebuffer;
+ byte *_offscreen;
+ OverlayColor *_overlayBuffer;
+ uint16 *_fullscreen;
+
+ uint16 _palette[256];
+ bool _overlayVisible;
+ uint16 _screenWidth;
+ uint16 _screenHeight;
+
+ struct timeval _startTime;
+
+ bool _mouseVisible;
+ byte *_mouseBuf;
+ byte _mouseKeyColour;
+ uint _mouseWidth, _mouseHeight;
+ int _mouseX, _mouseY;
+ int _mouseHotspotX, _mouseHotspotY;
+ long _lastMouseDown;
+ long _lastMouseTap;
+ Common::Event _queuedInputEvent;
+ bool _secondaryTapped;
+ long _lastSecondaryDown;
+ long _lastSecondaryTap;
+ int _gestureStartX, _gestureStartY;
+
+public:
+
+ OSystem_IPHONE();
+ virtual ~OSystem_IPHONE();
+
+ virtual void initBackend();
+
+ virtual bool hasFeature(Feature f);
+ virtual void setFeatureState(Feature f, bool enable);
+ virtual bool getFeatureState(Feature f);
+ virtual const GraphicsMode *getSupportedGraphicsModes() const;
+ virtual int getDefaultGraphicsMode() const;
+ bool setGraphicsMode(const char *name);
+ virtual bool setGraphicsMode(int mode);
+ virtual int getGraphicsMode() const;
+ virtual void initSize(uint width, uint height);
+ virtual int16 getHeight();
+ virtual int16 getWidth();
+ virtual void setPalette(const byte *colors, uint start, uint num);
+ virtual void grabPalette(byte *colors, uint start, uint num);
+ virtual void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h);
+ virtual void updateScreen();
+ virtual Graphics::Surface *lockScreen();
+ virtual void unlockScreen();
+ virtual void setShakePos(int shakeOffset);
+
+ virtual void showOverlay();
+ virtual void hideOverlay();
+ virtual void clearOverlay();
+ virtual void grabOverlay(OverlayColor *buf, int pitch);
+ virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
+ virtual int16 getOverlayHeight();
+ virtual int16 getOverlayWidth();
+
+ virtual OverlayColor RGBToColor(uint8 r, uint8 g, uint8 b);
+ virtual void colorToRGB(OverlayColor color, uint8 &r, uint8 &g, uint8 &b);
+
+ virtual bool showMouse(bool visible);
+
+ virtual void warpMouse(int x, int y);
+ virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int cursorTargetScale = 1);
+
+ virtual bool pollEvent(Common::Event &event);
+ virtual uint32 getMillis();
+ virtual void delayMillis(uint msecs);
+
+ virtual MutexRef createMutex(void);
+ virtual void lockMutex(MutexRef mutex);
+ virtual void unlockMutex(MutexRef mutex);
+ virtual void deleteMutex(MutexRef mutex);
+
+ typedef void (*SoundProc)(void *param, byte *buf, int len);
+ virtual bool setSoundCallback(SoundProc proc, void *param);
+ virtual void clearSoundCallback();
+ virtual int getOutputSampleRate() const;
+
+ virtual void quit();
+
+ virtual void setWindowCaption(const char *caption);
+
+ virtual Common::SaveFileManager *getSavefileManager();
+ virtual Audio::Mixer *getMixer();
+ virtual Common::TimerManager *getTimerManager();
+};
+
+#endif