Initial commit of the iPhone/iPod Touch backend

svn-id: r29488
This commit is contained in:
Oystein Eftevaag 2007-11-13 08:06:15 +00:00
parent c908a8a73f
commit 05b5a493f8
16 changed files with 1381 additions and 6 deletions

View file

@ -103,6 +103,15 @@ bundle: scummvm-static
$(srcdir)/tools/credits.pl --rtf > $(bundle_name)/Contents/Resources/Credits.rtf
strip $(bundle_name)/Contents/MacOS/scummvm
iphonebundle:
mkdir -p $(bundle_name)
cp $(srcdir)/dists/iphone/Info.plist $(bundle_name)/
cp $(srcdir)/gui/themes/modern.ini $(bundle_name)/
cp $(srcdir)/gui/themes/modern.zip $(bundle_name)/
cp scummvm $(bundle_name)/ScummVM
cp $(srcdir)/dists/iphone/icon.png $(bundle_name)/icon.png
cp $(srcdir)/dists/iphone/Default.png $(bundle_name)/Default.png
# location of additional libs for OS X usually /sw/ for fink or
# /opt/local/ for darwinports
OSXOPT=/sw

View file

@ -109,6 +109,9 @@ else
.cpp.o:
$(MKDIR) $(*D)/$(DEPDIR)
$(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o
.m.o:
$(MKDIR) $(*D)/$(DEPDIR)
$(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP $(OBJCFLAGS) -c $(<) -o $*.o
endif
ifdef HAVE_NASM

View file

@ -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

View file

@ -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

View file

@ -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 */

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -214,7 +214,7 @@ void registerDefaults() {
// Register default savepath
#ifdef DEFAULT_SAVE_PATH
char savePath[MAXPATHLEN];
#ifdef UNIX
#if defined(UNIX) && !defined(IPHONE)
const char *home = getenv("HOME");
if (home && *home && strlen(home) < MAXPATHLEN) {
snprintf(savePath, MAXPATHLEN, "%s/%s", home, DEFAULT_SAVE_PATH);
@ -224,6 +224,10 @@ void registerDefaults() {
strcpy(savePath, Symbian::GetExecutablePath());
strcat(savePath, DEFAULT_SAVE_PATH);
ConfMan.registerDefault("savepath", savePath);
#elif defined (IPHONE) // The iphone has / set as home dir when launching from the Springboard.
strcpy(savePath, "/var/root/");
strcat(savePath, DEFAULT_SAVE_PATH);
ConfMan.registerDefault("savepath", savePath);
#endif
#endif // #ifdef DEFAULT_SAVE_PATH
@ -527,6 +531,11 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, char **ar
DO_LONG_OPTION("record-time-file-name")
END_OPTION
#ifdef IPHONE
// This is automatically set when launched from the Springboard.
DO_LONG_OPTION_OPT("launchedFromSB", 0)
END_OPTION
#endif
unknownOption:
// If we get till here, the option is unhandled and hence unknown.

View file

@ -82,7 +82,9 @@ ConfigManager::ConfigManager()
void ConfigManager::loadDefaultConfigFile() {
char configFile[MAXPATHLEN];
#if defined(UNIX) && !defined(GP2X) // GP2X is Linux based but Home dir can be read only so do not use it and put the config in the executable dir.
// GP2X is Linux based but Home dir can be read only so do not use it and put the config in the executable dir.
// On the iPhone, the home dir of the user when you launch the app from the Springboard, is /. Which we don't want.
#if defined(UNIX) && !defined(GP2X) && !defined(IPHONE)
const char *home = getenv("HOME");
if (home != NULL && strlen(home) < MAXPATHLEN)
snprintf(configFile, MAXPATHLEN, "%s/%s", home, DEFAULT_CONFIG_FILE);
@ -135,6 +137,8 @@ void ConfigManager::loadDefaultConfigFile() {
#elif defined(PALMOS_MODE)
strcpy(configFile,"/PALM/Programs/ScummVM/" DEFAULT_CONFIG_FILE);
#elif defined(IPHONE)
strcpy(configFile,"/var/root/" DEFAULT_CONFIG_FILE);
#elif defined(__PLAYSTATION2__)
((OSystem_PS2*)g_system)->makeConfigPath(configFile);
#elif defined(__PSP__)

View file

@ -30,7 +30,7 @@
#include "common/hash-str.h"
#include <errno.h>
#ifdef MACOSX
#if defined(MACOSX) || defined(IPHONE)
#include "CoreFoundation/CoreFoundation.h"
#endif
@ -329,7 +329,7 @@ bool File::open(const String &filename, AccessMode mode) {
_handle = fopenNoCase(filename, "", modeStr);
// Last last (really) resort: try looking inside the application bundle on Mac OS X for the lowercase file.
#ifdef MACOSX
#if defined(MACOSX) || defined(IPHONE)
if (!_handle) {
CFStringRef cfFileName = CFStringCreateWithBytes(NULL, (const UInt8 *)filename.c_str(), filename.size(), kCFStringEncodingASCII, false);
CFURLRef fileUrl = CFBundleCopyResourceURL(CFBundleGetMainBundle(), cfFileName, NULL, NULL);

26
configure vendored
View file

@ -207,7 +207,7 @@ EOF
if test -n "$_host"; then
# In cross-compiling mode, we cannot run the result
eval "$1 -o tmp_cxx_compiler$EXEEXT tmp_cxx_compiler.cpp" 2> /dev/null && rm -f tmp_cxx_compiler$EXEEXT tmp_cxx_compiler.cpp
eval "$1 $CXXFLAGS -o tmp_cxx_compiler$EXEEXT tmp_cxx_compiler.cpp" 2> /dev/null && rm -f tmp_cxx_compiler$EXEEXT tmp_cxx_compiler.cpp
else
eval "$1 $CXXFLAGS -o tmp_cxx_compiler$EXEEXT tmp_cxx_compiler.cpp" 2> /dev/null && eval "./tmp_cxx_compiler 2> /dev/null" && rm -f tmp_cxx_compiler$EXEEXT tmp_cxx_compiler.cpp
fi
@ -732,6 +732,10 @@ i586-mingw32msvc)
_host_os=mingw32msvc
_host_cpu=i586
;;
iphone)
_host_os=iphone
_host_cpu=arm
;;
*)
if test -z "$_host"; then
guessed_host=`$_srcdir/config.guess`
@ -977,6 +981,12 @@ case $_host_os in
mint*)
DEFINES="$DEFINES -DUNIX -DSYSTEM_NOT_SUPPORTING_D_TYPE"
;;
iphone*)
DEFINES="$DEFINES -DUNIX -DIPHONE"
LIBS="$LIBS -lobjc -framework UIKit -framework CoreGraphics -framework CoreSurface \
-framework LayerKit -framework GraphicsServices -framework CoreFoundation \
-framework Foundation -framework AudioToolbox -framework CoreAudio"
;;
amigaos*)
# TODO: anything to be added here?
;;
@ -1064,7 +1074,15 @@ if test -n "$_host"; then
_ranlib=i586-mingw32msvc-ranlib
LIBS="$LIBS -lmingw32 -lwinmm"
OBJS="$OBJS scummvmico.o"
;;
;;
arm-iphone)
echo "Cross-compiling to $_host, forcing endianness, alignment and type sizes"
_endian=little
_need_memalign=yes
type_1_byte='char'
type_2_byte='short'
type_4_byte='int'
;;
*)
echo "Continuing with auto-detected values ... if you have problems, please add your target to configure."
;;
@ -1546,6 +1564,10 @@ case $_backend in
DEFINES="$DEFINES -DX11_BACKEND"
MODULES="$MODULES backends/platform/x11"
;;
iphone)
DEFINES="$DEFINES -DIPHONE_BACKEND"
MODULES="$MODULES backends/platform/iphone"
;;
*)
echo "support for $_backend backend not implemented in configure script yet"
exit 1

BIN
dists/iphone/Default.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

24
dists/iphone/Info.plist Normal file
View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>ScummVM</string>
<key>CFBundleIdentifier</key>
<string>com.scummvm.scummvm</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>ScummVM</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>svn</string>
</dict>
</plist>

BIN
dists/iphone/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB