aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOystein Eftevaag2007-11-18 17:58:53 +0000
committerOystein Eftevaag2007-11-18 17:58:53 +0000
commit6a4ce78789a4297a46e3528eaaf48601c1461549 (patch)
treefc45564e71f217f80e96eacce1840791087233cc
parent6471eb84f25d156a98bcf0447862e4839f8cc24d (diff)
downloadscummvm-rg350-6a4ce78789a4297a46e3528eaaf48601c1461549.tar.gz
scummvm-rg350-6a4ce78789a4297a46e3528eaaf48601c1461549.tar.bz2
scummvm-rg350-6a4ce78789a4297a46e3528eaaf48601c1461549.zip
Implemented soft keyboard support, and added a workarond for engines that can't handle mouse-down and mouse-up events coming in two subsequent calls to pollEvent()
svn-id: r29557
-rw-r--r--backends/platform/iphone/iphone_common.h3
-rw-r--r--backends/platform/iphone/iphone_keyboard.h51
-rw-r--r--backends/platform/iphone/iphone_keyboard.m88
-rw-r--r--backends/platform/iphone/iphone_video.h5
-rw-r--r--backends/platform/iphone/iphone_video.m65
-rw-r--r--backends/platform/iphone/module.mk3
-rw-r--r--backends/platform/iphone/osys_iphone.cpp84
-rw-r--r--backends/platform/iphone/osys_iphone.h3
8 files changed, 266 insertions, 36 deletions
diff --git a/backends/platform/iphone/iphone_common.h b/backends/platform/iphone/iphone_common.h
index 287f797472..567f54800e 100644
--- a/backends/platform/iphone/iphone_common.h
+++ b/backends/platform/iphone/iphone_common.h
@@ -29,7 +29,8 @@ enum InputEvent {
kInputMouseUp,
kInputMouseDragged,
kInputMouseSecondToggled,
- kInputOrientationChanged
+ kInputOrientationChanged,
+ kInputKeyPressed
};
// We need this to be able to call functions from/in Objective-C.
diff --git a/backends/platform/iphone/iphone_keyboard.h b/backends/platform/iphone/iphone_keyboard.h
new file mode 100644
index 0000000000..17a3836efd
--- /dev/null
+++ b/backends/platform/iphone/iphone_keyboard.h
@@ -0,0 +1,51 @@
+/* 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 <UIKit/UITextView.h>
+
+@protocol KeyboardInputProtocol
+- (void)handleKeyPress:(unichar)c;
+@end
+
+@interface SoftKeyboard : UIKeyboard<KeyboardInputProtocol> {
+ id inputDelegate;
+ UITextView* inputView;
+}
+
+- (id)initWithFrame:(CGRect)frame;
+- (UITextView*)inputView;
+- (void)setInputDelegate:(id)delegate;
+- (void)handleKeyPress:(unichar)c;
+
+@end
+
+@interface TextInputHandler : UITextView {
+ SoftKeyboard* softKeyboard;
+}
+
+- (id)initWithKeyboard:(SoftKeyboard*)keyboard;
+
+@end
diff --git a/backends/platform/iphone/iphone_keyboard.m b/backends/platform/iphone/iphone_keyboard.m
new file mode 100644
index 0000000000..923b7be46d
--- /dev/null
+++ b/backends/platform/iphone/iphone_keyboard.m
@@ -0,0 +1,88 @@
+/* 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 "iphone_keyboard.h"
+
+// Override settings of the default keyboard implementation
+@implementation UIKeyboardImpl (DisableFeatures)
+
+- (BOOL)autoCapitalizationPreference {
+ return false;
+}
+
+- (BOOL)autoCorrectionPreference {
+ return false;
+}
+
+@end
+
+@implementation TextInputHandler
+
+- (id)initWithKeyboard:(SoftKeyboard*)keyboard; {
+ self = [super initWithFrame:CGRectMake(0.0f, 0.0f, 0.0f, 0.0f)];
+ softKeyboard = keyboard;
+ return self;
+}
+
+- (BOOL)webView:(id)fp8 shouldDeleteDOMRange:(id)fp12 {
+ [softKeyboard handleKeyPress:0x08];
+}
+
+- (BOOL)webView:(id)fp8 shouldInsertText:(id)character
+ replacingDOMRange:(id)fp16
+ givenAction:(int)fp20 {
+
+ if ([character length] != 1) {
+ [NSException raise:@"Unsupported" format:@"Unhandled multi-char insert!"];
+ return false;
+ }
+ [softKeyboard handleKeyPress:[character characterAtIndex:0]];
+}
+
+@end
+
+
+@implementation SoftKeyboard
+
+- (id)initWithFrame:(CGRect)frame {
+ self = [super initWithFrame:frame];
+ inputDelegate = nil;
+ inputView = [[TextInputHandler alloc] initWithKeyboard:self];
+ return self;
+}
+
+- (UITextView*)inputView {
+ return inputView;
+}
+
+- (void)setInputDelegate:(id)delegate {
+ inputDelegate = delegate;
+}
+
+- (void)handleKeyPress:(unichar)c {
+ [inputDelegate handleKeyPress:c];
+}
+
+@end \ No newline at end of file
diff --git a/backends/platform/iphone/iphone_video.h b/backends/platform/iphone/iphone_video.h
index 167b74705b..9a0492bad3 100644
--- a/backends/platform/iphone/iphone_video.h
+++ b/backends/platform/iphone/iphone_video.h
@@ -33,13 +33,14 @@
#import <CoreSurface/CoreSurface.h>
#import <LayerKit/LKLayer.h>
+#import "iphone_keyboard.h"
@interface iPhoneView : UIView
{
CoreSurfaceBufferRef _screenSurface;
NSMutableArray* _events;
NSLock* _lock;
- UIKeyboardImpl* _keyboard;
+ SoftKeyboard* _keyboardView;
LKLayer* _screenLayer;
int _fullWidth;
@@ -64,4 +65,6 @@
@end
+
+
#endif /* _IPHONE_VIDEO__H */
diff --git a/backends/platform/iphone/iphone_video.m b/backends/platform/iphone/iphone_video.m
index d3989e3838..df15f61a6b 100644
--- a/backends/platform/iphone/iphone_video.m
+++ b/backends/platform/iphone/iphone_video.m
@@ -32,6 +32,7 @@
#import <Foundation/Foundation.h>
#import <CoreSurface/CoreSurface.h>
#import <LayerKit/LKLayer.h>
+#import <UIKit/UIKeyboardLayoutQWERTY.h>
static iPhoneView *sharedInstance = nil;
static int _width = 0;
@@ -108,15 +109,17 @@ bool getLocalMouseCoords(CGPoint *point) {
_screenLayer = nil;
sharedInstance = self;
-
- _keyboard = [UIKeyboardImpl sharedInstance];
- //[self addSubview:_keyboard];
+ _keyboardView = nil;
return self;
}
-(void) dealloc {
[super dealloc];
+
+ if (_keyboardView != nil) {
+ [_keyboardView dealloc];
+ }
}
- (CoreSurfaceBufferRef)getSurface {
@@ -169,6 +172,11 @@ bool getLocalMouseCoords(CGPoint *point) {
LKLayer* screenLayer = [[LKLayer layer] retain];
+ if (_keyboardView != nil) {
+ [_keyboardView removeFromSuperview];
+ [[_keyboardView inputView] removeFromSuperview];
+ }
+
if (_landscape) {
float ratioDifference = ((float)_width / (float)_height) / ((float)_fullWidth / (float)_fullHeight);
int rectWidth, rectHeight;
@@ -187,10 +195,20 @@ bool getLocalMouseCoords(CGPoint *point) {
//printf("Rect: %i, %i, %i, %i\n", _widthOffset, _heightOffset, rectWidth + _widthOffset, rectHeight + _heightOffset);
_screenRect = CGRectMake(_widthOffset, _heightOffset, rectWidth + _widthOffset, rectHeight + _heightOffset);
[screenLayer setFrame: _screenRect];
- } else {
+ } else {
float ratio = (float)_height / (float)_width;
_screenRect = CGRectMake(0, 0, _fullWidth, _fullWidth * ratio);
- [screenLayer setFrame: _screenRect];
+ [screenLayer setFrame: _screenRect];
+
+ CGRect keyFrame = CGRectMake(0.0f, _screenRect.size.height, _fullWidth, _fullHeight);
+ if (_keyboardView == nil) {
+ _keyboardView = [[SoftKeyboard alloc] initWithFrame:keyFrame];
+ [_keyboardView setInputDelegate:self];
+ }
+
+ [self addSubview:[_keyboardView inputView]];
+ [self addSubview: _keyboardView];
+ [[_keyboardView inputView] becomeFirstResponder];
}
[screenLayer setContents: _screenSurface];
@@ -306,20 +324,24 @@ bool getLocalMouseCoords(CGPoint *point) {
}
- (void)mouseEntered:(GSEvent*)event {
- //printf("mouseEntered()\n");
+ printf("mouseEntered()\n");
// struct CGPoint point = GSEventGetLocationInWindow(event);
+ //
+ // if (!getLocalMouseCoords(&point))
+ // return;
+ //
// [self addEvent:
// [[NSDictionary alloc] initWithObjectsAndKeys:
- // [NSNumber numberWithInt:kInputMouseSecondStartDrag], @"type",
- // [NSNumber numberWithFloat:(point.x/_fullWidth)], @"x",
- // [NSNumber numberWithFloat:(point.y/_fullHeight)], @"y",
+ // [NSNumber numberWithInt:kInputMouseSecondToggled], @"type",
+ // [NSNumber numberWithFloat:point.x], @"x",
+ // [NSNumber numberWithFloat:point.y], @"y",
// nil
// ]
// ];
}
- (void)mouseExited:(GSEvent*)event {
- //printf("mouseExited().\n");
+ printf("mouseExited().\n");
// [self addEvent:
// [[NSDictionary alloc] initWithObjectsAndKeys:
// @"mouseExited", @"type",
@@ -330,12 +352,12 @@ bool getLocalMouseCoords(CGPoint *point) {
- (void)mouseMoved:(GSEvent*)event
{
- //printf("mouseMoved()\n");
+ printf("mouseMoved()\n");
struct CGPoint point = GSEventGetLocationInWindow(event);
if (!getLocalMouseCoords(&point))
return;
-
+
[self addEvent:
[[NSDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithInt:kInputMouseSecondToggled], @"type",
@@ -346,23 +368,12 @@ bool getLocalMouseCoords(CGPoint *point) {
];
}
-- (void)keyDown:(GSEvent*)event
-{
- printf("keyDown()\n");
+- (void)handleKeyPress:(unichar)c {
[self addEvent:
[[NSDictionary alloc] initWithObjectsAndKeys:
- @"keyDown", @"type",
- nil
- ]
- ];
-}
-
-- (void)keyUp:(GSEvent*)event
-{
- printf("keyUp()\n");
- [self addEvent:
- [[NSDictionary alloc] initWithObjectsAndKeys:
- @"keyUp", @"type",
+ [NSNumber numberWithInt:kInputKeyPressed], @"type",
+ [NSNumber numberWithFloat:(float)c], @"x",
+ [NSNumber numberWithFloat:0], @"y",
nil
]
];
diff --git a/backends/platform/iphone/module.mk b/backends/platform/iphone/module.mk
index 2d26c26e59..47461ad2b2 100644
--- a/backends/platform/iphone/module.mk
+++ b/backends/platform/iphone/module.mk
@@ -3,7 +3,8 @@ MODULE := backends/platform/iphone
MODULE_OBJS := \
osys_iphone.o \
iphone_main.o \
- iphone_video.o
+ iphone_video.o \
+ iphone_keyboard.o
MODULE_DIRS += \
backends/platform/iphone/
diff --git a/backends/platform/iphone/osys_iphone.cpp b/backends/platform/iphone/osys_iphone.cpp
index 6f1d82fb2c..8c029d10b5 100644
--- a/backends/platform/iphone/osys_iphone.cpp
+++ b/backends/platform/iphone/osys_iphone.cpp
@@ -59,7 +59,8 @@ 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), _landscapeMode(true)
+ _secondaryTapped(false), _lastSecondaryTap(0), _landscapeMode(true),
+ _needEventRestPeriod(false)
{
_queuedInputEvent.type = (Common::EventType)0;
}
@@ -495,6 +496,13 @@ bool OSystem_IPHONE::pollEvent(Common::Event &event) {
_timerCallbackNext = curTime + _timerCallbackTimer;
}
+ if (_needEventRestPeriod) {
+ // Workaround: Some engines can't handle mouse-down and mouse-up events
+ // appearing right after each other, without a call returning no input in between.
+ _needEventRestPeriod = false;
+ return false;
+ }
+
if (_queuedInputEvent.type != (Common::EventType)0) {
event = _queuedInputEvent;
_queuedInputEvent.type = (Common::EventType)0;
@@ -535,7 +543,8 @@ bool OSystem_IPHONE::pollEvent(Common::Event &event) {
_queuedInputEvent.mouse.x = _mouseX;
_queuedInputEvent.mouse.y = _mouseY;
_lastMouseTap = curTime;
-
+ _needEventRestPeriod = true;
+
// if (curTime - _lastMouseTap < 250 && !_overlayVisible) {
// event.type = Common::EVENT_KEYDOWN;
// _queuedInputEvent.type = Common::EVENT_KEYUP;
@@ -578,7 +587,8 @@ bool OSystem_IPHONE::pollEvent(Common::Event &event) {
event.kbd.flags = _queuedInputEvent.kbd.flags = 0;
event.kbd.keycode = _queuedInputEvent.kbd.keycode = Common::KEYCODE_F5;
- event.kbd.ascii = _queuedInputEvent.kbd.ascii = 27;
+ event.kbd.ascii = _queuedInputEvent.kbd.ascii = Common::ASCII_F5;
+ _needEventRestPeriod = true;
} else if (vecXNorm > -0.50 && vecXNorm < 0.50 && vecYNorm < -0.75) {
// Swipe up
event.type = Common::EVENT_KEYDOWN;
@@ -587,6 +597,7 @@ bool OSystem_IPHONE::pollEvent(Common::Event &event) {
event.kbd.flags = _queuedInputEvent.kbd.flags = 0;
event.kbd.keycode = _queuedInputEvent.kbd.keycode = Common::KEYCODE_1;
event.kbd.ascii = _queuedInputEvent.kbd.ascii = '1';
+ _needEventRestPeriod = true;
} else if (vecXNorm > 0.75 && vecYNorm > -0.5 && vecYNorm < 0.5) {
// Swipe right
return false;
@@ -620,8 +631,8 @@ bool OSystem_IPHONE::pollEvent(Common::Event &event) {
event.kbd.flags = _queuedInputEvent.kbd.flags = 0;
event.kbd.keycode = _queuedInputEvent.kbd.keycode = Common::KEYCODE_ESCAPE;
- event.kbd.ascii = _queuedInputEvent.kbd.ascii = 27;
-
+ event.kbd.ascii = _queuedInputEvent.kbd.ascii = Common::ASCII_ESCAPE;
+ _needEventRestPeriod = true;
_lastSecondaryTap = 0;
} else {
event.type = Common::EVENT_RBUTTONDOWN;
@@ -631,6 +642,7 @@ bool OSystem_IPHONE::pollEvent(Common::Event &event) {
_queuedInputEvent.mouse.x = _mouseX;
_queuedInputEvent.mouse.y = _mouseY;
_lastSecondaryTap = curTime;
+ _needEventRestPeriod = true;
}
} else {
return false;
@@ -649,6 +661,68 @@ bool OSystem_IPHONE::pollEvent(Common::Event &event) {
_dirtyRects.push_back(Common::Rect(0, 0, _screenWidth, _screenHeight));
}
break;
+ case kInputKeyPressed:
+ int keyPressed = (int)xUnit;
+ int ascii = keyPressed;
+ //printf("key: %i\n", keyPressed);
+
+ // We remap some of the iPhone keyboard keys.
+ // The first ten here are the row of symbols below the numeric keys.
+ switch (keyPressed) {
+ case 45:
+ keyPressed = Common::KEYCODE_F1;
+ ascii = Common::ASCII_F1;
+ break;
+ case 47:
+ keyPressed = Common::KEYCODE_F2;
+ ascii = Common::ASCII_F2;
+ break;
+ case 58:
+ keyPressed = Common::KEYCODE_F3;
+ ascii = Common::ASCII_F3;
+ break;
+ case 59:
+ keyPressed = Common::KEYCODE_F4;
+ ascii = Common::ASCII_F4;
+ break;
+ case 40:
+ keyPressed = Common::KEYCODE_F5;
+ ascii = Common::ASCII_F5;
+ break;
+ case 41:
+ keyPressed = Common::KEYCODE_F6;
+ ascii = Common::ASCII_F6;
+ break;
+ case 36:
+ keyPressed = Common::KEYCODE_F7;
+ ascii = Common::ASCII_F7;
+ break;
+ case 38:
+ keyPressed = Common::KEYCODE_F8;
+ ascii = Common::ASCII_F8;
+ break;
+ case 64:
+ keyPressed = Common::KEYCODE_F9;
+ ascii = Common::ASCII_F9;
+ break;
+ case 34:
+ keyPressed = Common::KEYCODE_F10;
+ ascii = Common::ASCII_F10;
+ break;
+ case 10:
+ keyPressed = Common::KEYCODE_RETURN;
+ ascii = Common::ASCII_RETURN;
+ break;
+ }
+ 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)keyPressed;
+ event.kbd.ascii = _queuedInputEvent.kbd.ascii = ascii;
+ _needEventRestPeriod = true;
+ break;
+
default:
break;
}
diff --git a/backends/platform/iphone/osys_iphone.h b/backends/platform/iphone/osys_iphone.h
index 9abd8657e7..65d4b9744e 100644
--- a/backends/platform/iphone/osys_iphone.h
+++ b/backends/platform/iphone/osys_iphone.h
@@ -28,7 +28,7 @@
#include "graphics/surface.h"
#define AUDIO_BUFFERS 3
-#define WAVE_BUFFER_SIZE 2048
+#define WAVE_BUFFER_SIZE 4096
#define AUDIO_SAMPLE_RATE 44100
typedef void (*SoundProc)(void *param, byte *buf, int len);
@@ -74,6 +74,7 @@ protected:
long _lastMouseDown;
long _lastMouseTap;
Common::Event _queuedInputEvent;
+ bool _needEventRestPeriod;
bool _secondaryTapped;
long _lastSecondaryDown;
long _lastSecondaryTap;