1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
/*
* startSDL.mm, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#import "startSDL.h"
#import "GameChatKeyboardHandler.h"
#include "../Global.h"
#include "CMT.h"
#include "CServerHandler.h"
#include "CFocusableHelper.h"
#include <SDL_main.h>
#include <SDL_events.h>
#include <SDL_render.h>
#include <SDL_system.h>
#import <UIKit/UIKit.h>
@interface SDLViewObserver : NSObject <UIGestureRecognizerDelegate>
@property (nonatomic, strong) GameChatKeyboardHandler * gameChatHandler;
@end
@implementation SDLViewObserver
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
[object removeObserver:self forKeyPath:keyPath];
UIView * view = [object valueForKeyPath:keyPath];
auto longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
longPress.minimumPressDuration = 0.2;
[view addGestureRecognizer:longPress];
auto pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinch:)];
[view addGestureRecognizer:pinch];
}
#pragma mark - Gestures
- (void)handleLongPress:(UIGestureRecognizer *)gesture {
// send RMB click
SDL_EventType mouseButtonType;
switch (gesture.state)
{
case UIGestureRecognizerStateBegan:
mouseButtonType = SDL_MOUSEBUTTONDOWN;
break;
case UIGestureRecognizerStateEnded:
mouseButtonType = SDL_MOUSEBUTTONUP;
break;
default:
return;
}
auto renderer = SDL_GetRenderer(mainWindow);
float scaleX, scaleY;
SDL_Rect viewport;
SDL_RenderGetScale(renderer, &scaleX, &scaleY);
SDL_RenderGetViewport(renderer, &viewport);
auto touchedPoint = [gesture locationInView:gesture.view];
auto screenScale = UIScreen.mainScreen.nativeScale;
Sint32 x = (int)touchedPoint.x * screenScale / scaleX - viewport.x;
Sint32 y = (int)touchedPoint.y * screenScale / scaleY - viewport.y;
SDL_Event rmbEvent;
rmbEvent.button = (SDL_MouseButtonEvent){
.type = mouseButtonType,
.button = SDL_BUTTON_RIGHT,
.clicks = 1,
.x = x,
.y = y,
};
SDL_PushEvent(&rmbEvent);
// small hack to prevent cursor jumping
if (mouseButtonType == SDL_MOUSEBUTTONUP)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.025 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
SDL_Event motionEvent;
motionEvent.motion = (SDL_MouseMotionEvent){
.type = SDL_MOUSEMOTION,
.x = x,
.y = y,
};
SDL_PushEvent(&motionEvent);
});
}
- (void)handlePinch:(UIGestureRecognizer *)gesture {
if(gesture.state != UIGestureRecognizerStateBegan || CSH->state != EClientState::GAMEPLAY)
return;
[self.gameChatHandler triggerInput];
}
#pragma mark - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return [gestureRecognizer isKindOfClass:[UIPinchGestureRecognizer class]];
}
@end
int startSDL(int argc, char * argv[], BOOL startManually)
{
@autoreleasepool {
auto observer = [SDLViewObserver new];
observer.gameChatHandler = [GameChatKeyboardHandler new];
id __block sdlWindowCreationObserver = [NSNotificationCenter.defaultCenter addObserverForName:UIWindowDidBecomeKeyNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
[NSNotificationCenter.defaultCenter removeObserver:sdlWindowCreationObserver];
sdlWindowCreationObserver = nil;
UIWindow * sdlWindow = note.object;
[sdlWindow.rootViewController addObserver:observer forKeyPath:NSStringFromSelector(@selector(view)) options:NSKeyValueObservingOptionNew context:NULL];
}];
id textFieldObserver = [NSNotificationCenter.defaultCenter addObserverForName:UITextFieldTextDidEndEditingNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
removeFocusFromActiveInput();
}];
int result;
if (startManually)
{
// copied from -[SDLUIKitDelegate postFinishLaunch]
SDL_SetMainReady();
SDL_iOSSetEventPump(SDL_TRUE);
result = SDL_main(argc, argv);
SDL_iOSSetEventPump(SDL_FALSE);
}
else
result = SDL_UIKitRunApp(argc, argv, SDL_main);
[NSNotificationCenter.defaultCenter removeObserver:textFieldObserver];
return result;
}
}
|