mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-16 22:58:09 +00:00
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
This commit is contained in:
parent
6471eb84f2
commit
6a4ce78789
@ -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.
|
||||
|
51
backends/platform/iphone/iphone_keyboard.h
Normal file
51
backends/platform/iphone/iphone_keyboard.h
Normal file
@ -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
|
88
backends/platform/iphone/iphone_keyboard.m
Normal file
88
backends/platform/iphone/iphone_keyboard.m
Normal file
@ -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
|
@ -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 */
|
||||
|
@ -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
|
||||
]
|
||||
];
|
||||
|
@ -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/
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user