A lot of more changes
* Custom controls: - Unfinished v2 control - Auto generate default.json, removed internal fallback control - Compatible with Android's dp (might need scaling) - Implemented properties: keycodes, bgColor, strokeColor, strokeWidth, cornerRadius * Other changes - Updated MetalANGLE to 0.0.7 - Updated gl4es 1.1.5 * TODO: - Control converter - Drawer buttons - Multiple keys support (?) - Implement properties: opacity, isSwipeable, isToggle, passThruEnabled, (maybe more?)
This commit is contained in:
1 parent
3ac9a2f85f
commit
c896da08bb
17 files changed
+343
-152
No files matched your search
@@ -21,6 +21,7 @@ add_library(pojavexec SHARED
|
||||
SurfaceViewController.m
|
||||
UpdateHistoryViewController.m
|
||||
customcontrols/ControlButton.m
|
||||
customcontrols/CustomControlsUtils.m
|
||||
egl_bridge.m
|
||||
external/DBNumberedSlider/Classes/DBNumberedSlider.m
|
||||
input_bridge_v3.m
|
||||
|
||||
@@ -6,17 +6,23 @@
|
||||
#include "glfw_keycodes.h"
|
||||
#include "utils.h"
|
||||
|
||||
// CGRectOffset(RECT, notchOffset, 0)
|
||||
#define ADD_BUTTON(NAME, KEY, RECT, VISIBLE) \
|
||||
ControlButton *button_##KEY = [ControlButton initWithName:NAME keycode:KEY rect:CGRectOffset(RECT, notchOffset, 0) transparency:0.0f]; \
|
||||
ControlButton *button_##KEY = [ControlButton initWithName:NAME keycode:KEY rect:CGRectMake(RECT.origin.x * buttonScale, RECT.origin.y * buttonScale, RECT.size.width * buttonScale, RECT.size.height * buttonScale) transparency:0.0f]; \
|
||||
[button_##KEY addGestureRecognizer:[[UITapGestureRecognizer alloc] \
|
||||
initWithTarget:self action:@selector(showControlPopover:)]]; \
|
||||
[self.view addSubview:button_##KEY];
|
||||
|
||||
#define APPLY_SCALE(KEY) \
|
||||
KEY = @([(NSNumber *)KEY floatValue] * savedScale / currentScale);
|
||||
|
||||
int notchOffset;
|
||||
|
||||
@interface CustomControlsViewController () <UIPopoverPresentationControllerDelegate>{
|
||||
}
|
||||
|
||||
@property (nonatomic, strong) NSMutableDictionary* cc_dictionary;
|
||||
|
||||
// - (void)method
|
||||
|
||||
@end
|
||||
@@ -39,80 +45,57 @@ int notchOffset;
|
||||
}
|
||||
|
||||
CGRect screenBounds = [[UIScreen mainScreen] bounds];
|
||||
CGFloat screenScale = [[UIScreen mainScreen] scale];
|
||||
UIEdgeInsets insets = UIApplication.sharedApplication.windows.firstObject.safeAreaInsets;
|
||||
int width = (int) roundf(screenBounds.size.width);
|
||||
int height = (int) roundf(screenBounds.size.height);
|
||||
notchOffset = insets.left;
|
||||
width = width - notchOffset * 2;
|
||||
CGFloat buttonScale = ((NSNumber *) getPreference(@"button_scale")).floatValue / 100.0;
|
||||
CGFloat rectBtnWidth = 80.0 * buttonScale;
|
||||
CGFloat rectBtnHeight = 30.0 * buttonScale;
|
||||
CGFloat squareBtnSize = 50.0 * buttonScale;
|
||||
|
||||
|
||||
UILongPressGestureRecognizer *longpressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(showControlPopover:)];
|
||||
longpressGesture.minimumPressDuration = 0.5;
|
||||
[self.view addGestureRecognizer:longpressGesture];
|
||||
|
||||
|
||||
// Temporary fallback controls
|
||||
BOOL cc_fallback = YES;
|
||||
|
||||
NSString *controlFilePath = [NSString stringWithFormat:@"%s/%@", getenv("POJAV_PATH_CONTROL"), (NSString *)getPreference(@"default_ctrl")];
|
||||
|
||||
NSError *cc_error;
|
||||
NSString *cc_data = [NSString stringWithContentsOfFile:controlFilePath encoding:NSUTF8StringEncoding error:&cc_error];
|
||||
|
||||
if (cc_error != nil) {
|
||||
NSLog(@"Error: could not read \"%@\", falling back to default control, error: %@", controlFilePath, cc_error.localizedDescription);
|
||||
NSLog(@"Error: could not read %@: %@", controlFilePath, cc_error.localizedDescription);
|
||||
showDialog(self, @"Error", [NSString stringWithFormat:@"Could not read %@: %@", controlFilePath, cc_error.localizedDescription]);
|
||||
} else {
|
||||
NSData* cc_objc_data = [cc_data dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSDictionary *cc_dictionary = [NSJSONSerialization JSONObjectWithData:cc_objc_data options:kNilOptions error:&cc_error];
|
||||
self.cc_dictionary = [NSJSONSerialization JSONObjectWithData:cc_objc_data options:NSJSONReadingMutableContainers error:&cc_error];
|
||||
if (cc_error != nil) {
|
||||
showDialog(self, @"Error parsing JSON", cc_error.localizedDescription);
|
||||
} else {
|
||||
NSArray *cc_controlDataList = (NSArray *) [cc_dictionary valueForKey:@"mControlDataList"];
|
||||
NSMutableArray *cc_controlDataList = self.cc_dictionary[@"mControlDataList"];
|
||||
CGFloat currentScale = ((NSNumber *)self.cc_dictionary[@"scaledAt"]).floatValue;
|
||||
CGFloat savedScale = ((NSNumber *)getPreference(@"button_scale")).floatValue;
|
||||
int cc_version = ((NSNumber *)self.cc_dictionary[@"version"]).intValue;
|
||||
for (int i = 0; i < (int) cc_controlDataList.count; i++) {
|
||||
ControlButton *button = [ControlButton initWithProperties:(NSMutableDictionary *)cc_controlDataList[i]];
|
||||
NSMutableDictionary *cc_buttonDict = cc_controlDataList[i];
|
||||
if (cc_version < 2) {
|
||||
showDialog(self, @"Notice", @"Custom controls v1 to v2 was not implemented!");
|
||||
return;
|
||||
//convertV1ToV2(cc_buttonDict);
|
||||
}
|
||||
APPLY_SCALE(cc_buttonDict[@"width"]);
|
||||
APPLY_SCALE(cc_buttonDict[@"height"]);
|
||||
APPLY_SCALE(cc_buttonDict[@"strokeWidth"]);
|
||||
|
||||
ControlButton *button = [ControlButton initWithProperties:cc_buttonDict];
|
||||
[button addGestureRecognizer:[[UITapGestureRecognizer alloc]
|
||||
initWithTarget:self action:@selector(showControlPopover:)]];
|
||||
[self.view addSubview:button];
|
||||
}
|
||||
cc_fallback = NO;
|
||||
self.cc_dictionary[@"scaledAt"] = @(savedScale);
|
||||
}
|
||||
}
|
||||
|
||||
if (cc_fallback == YES) {
|
||||
ADD_BUTTON(@"GUI", SPECIALBTN_TOGGLECTRL, CGRectMake(5, height - 5 - squareBtnSize, squareBtnSize, squareBtnSize), NO);
|
||||
ADD_BUTTON(@"Keyboard", SPECIALBTN_KEYBOARD, CGRectMake(5 * 3 + rectBtnWidth * 2, 5, rectBtnWidth, rectBtnHeight), YES);
|
||||
|
||||
ADD_BUTTON(@"Pri", SPECIALBTN_MOUSEPRI, CGRectMake(5, height - 5 * 3 - squareBtnSize * 3, squareBtnSize, squareBtnSize), YES);
|
||||
ADD_BUTTON(@"Sec", SPECIALBTN_MOUSESEC, CGRectMake(5 * 3 + squareBtnSize * 2, height - 5 * 3 - squareBtnSize * 3, squareBtnSize, squareBtnSize), YES);
|
||||
|
||||
ADD_BUTTON(@"Debug", GLFW_KEY_F3, CGRectMake(5, 5, rectBtnWidth, rectBtnHeight), YES);
|
||||
ADD_BUTTON(@"Chat", GLFW_KEY_T, CGRectMake(5 * 2 + rectBtnWidth, 5, rectBtnWidth, rectBtnHeight), YES);
|
||||
ADD_BUTTON(@"Tab", GLFW_KEY_TAB, CGRectMake(5 * 4 + rectBtnWidth * 3, 5, rectBtnWidth, rectBtnHeight), YES);
|
||||
ADD_BUTTON(@"Opti-Zoom", GLFW_KEY_C, CGRectMake(5 * 5 + rectBtnWidth * 4, 5, rectBtnWidth, rectBtnHeight), YES);
|
||||
ADD_BUTTON(@"Offhand", GLFW_KEY_F, CGRectMake(5 * 6 + rectBtnWidth * 5, 5, rectBtnWidth, rectBtnHeight), YES);
|
||||
ADD_BUTTON(@"3rd", GLFW_KEY_F5, CGRectMake(5, 5 * 2 + rectBtnHeight, rectBtnWidth, rectBtnHeight), YES);
|
||||
|
||||
ADD_BUTTON(@"▲", GLFW_KEY_W, CGRectMake(5 * 2 + squareBtnSize, height - 5 * 3 - squareBtnSize * 3, squareBtnSize, squareBtnSize), YES);
|
||||
ADD_BUTTON(@"◀", GLFW_KEY_A, CGRectMake(5, height - 5 * 2 - squareBtnSize * 2, squareBtnSize, squareBtnSize), YES);
|
||||
ADD_BUTTON(@"▼", GLFW_KEY_S, CGRectMake(5 * 2 + squareBtnSize, height - 5 - squareBtnSize, squareBtnSize, squareBtnSize), YES);
|
||||
ADD_BUTTON(@"▶", GLFW_KEY_D, CGRectMake(5 * 3 + squareBtnSize * 2, height - 5 * 2 - squareBtnSize * 2, squareBtnSize, squareBtnSize), YES);
|
||||
ADD_BUTTON(@"◇", GLFW_KEY_LEFT_SHIFT, CGRectMake(5 * 2 + squareBtnSize, height - 5 * 2 - squareBtnSize * 2, squareBtnSize, squareBtnSize), YES);
|
||||
ADD_BUTTON(@"Inv", GLFW_KEY_E, CGRectMake(5 * 3 + squareBtnSize * 2, height - 5 - squareBtnSize, squareBtnSize, squareBtnSize), YES);
|
||||
|
||||
ADD_BUTTON(@"⬛", GLFW_KEY_SPACE, CGRectMake(width - 5 * 2 - squareBtnSize * 2, height - 5 * 2 - squareBtnSize * 2, squareBtnSize, squareBtnSize), YES);
|
||||
|
||||
ADD_BUTTON(@"Esc", GLFW_KEY_ESCAPE, CGRectMake(width - 5 - rectBtnWidth, height - 5 - rectBtnHeight, rectBtnWidth, rectBtnHeight), YES);
|
||||
|
||||
// ADD_BUTTON(@"Fullscreen", f11, CGRectMake(width - 5 - rectBtnWidth, 5, rectBtnWidth, rectBtnHeight), YES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)showControlPopover:(UIGestureRecognizer *)sender {
|
||||
NSLog(@"Got Gesture = %@", sender);
|
||||
switch (sender.state) {
|
||||
case UIGestureRecognizerStateBegan:
|
||||
if (![sender isKindOfClass:[UILongPressGestureRecognizer class]]) {
|
||||
@@ -181,7 +164,19 @@ int notchOffset;
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
|
||||
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
||||
[button setTitle:@"This is not yet finished. Click here to exit" forState:UIControlStateNormal];
|
||||
button.frame = self.view.frame;
|
||||
[button addTarget:self action:@selector(tempExit) forControlEvents:UIControlEventTouchUpInside];
|
||||
[self.view addSubview:button];
|
||||
}
|
||||
|
||||
- (void)tempExit {
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
[((UINavigationController *)self.presentingViewController) setNavigationBarHidden:NO animated:YES];
|
||||
[((UINavigationController *)self.presentingViewController) popViewControllerAnimated:YES];
|
||||
// [((UINavigationController *)self.presentingViewController).topViewController dismissViewControllerAnimated:YES completion:nil];
|
||||
// NSLog(@"ok=%@", ((UINavigationController *)self.presentingViewController).topViewController);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "utils.h"
|
||||
#include "JavaLauncher.h"
|
||||
|
||||
#import "customcontrols/CustomControlsUtils.h"
|
||||
#import "LauncherPreferences.h"
|
||||
|
||||
// PojavLancher: fixme: are these wrong?
|
||||
@@ -197,6 +198,7 @@ int launchJVM(int argc, char *argv[]) {
|
||||
sprintf(controlPath, "%s/controlmap", homeDir);
|
||||
mkdir(controlPath, S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
setenv("POJAV_PATH_CONTROL", controlPath, 1);
|
||||
generateAndSaveDefaultControl();
|
||||
|
||||
char classpath[10000];
|
||||
|
||||
@@ -263,7 +265,7 @@ int launchJVM(int argc, char *argv[]) {
|
||||
|
||||
if (!started) {
|
||||
// Setup Caciocavallo
|
||||
margv[margc++] = "-Djava.awt.headless=true";
|
||||
margv[margc++] = "-Djava.awt.headless=true"; // TODO: register natives to make this false
|
||||
margv[margc++] = "-Dcacio.font.fontmanager=sun.awt.X11FontManager";
|
||||
margv[margc++] = "-Dcacio.font.fontscaler=sun.font.FreetypeFontScaler";
|
||||
margv[margc++] = "-Dswing.defaultlaf=javax.swing.plaf.metal.MetalLookAndFeel";
|
||||
|
||||
@@ -42,7 +42,7 @@ UITextField* versionTextField;
|
||||
}
|
||||
|
||||
UILabel *btnsizeTextView = [[UILabel alloc] initWithFrame:CGRectMake(4.0, 8.0, 0.0, 30.0)];
|
||||
btnsizeTextView.text = @"Button scale: ";
|
||||
btnsizeTextView.text = @"Button scale (%)";
|
||||
btnsizeTextView.numberOfLines = 0;
|
||||
btnsizeTextView.textAlignment = NSTextAlignmentCenter;
|
||||
[btnsizeTextView sizeToFit];
|
||||
|
||||
@@ -363,21 +363,21 @@ void loginAccountInput(UINavigationController *controller, int type, const char*
|
||||
@interface LoginListViewController () {
|
||||
}
|
||||
|
||||
@property(nonatomic, strong) NSMutableArray *accountList;
|
||||
|
||||
@end
|
||||
|
||||
@implementation LoginListViewController
|
||||
|
||||
NSMutableArray *accountList;
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
[self setTitle:@"Select account"];
|
||||
|
||||
if (accountList == nil) {
|
||||
accountList = [NSMutableArray array];
|
||||
if (self.accountList == nil) {
|
||||
self.accountList = [NSMutableArray array];
|
||||
} else {
|
||||
[accountList removeAllObjects];
|
||||
[self.accountList removeAllObjects];
|
||||
}
|
||||
|
||||
// List accounts
|
||||
@@ -395,7 +395,7 @@ NSMutableArray *accountList;
|
||||
continue;
|
||||
} else if ([@(dir->d_name) hasSuffix:@".json"]) {
|
||||
NSString *trimmedName= [@(dir->d_name) substringToIndex:((int)[@(dir->d_name) length] - 5)];
|
||||
[accountList addObject:trimmedName];
|
||||
[self.accountList addObject:trimmedName];
|
||||
}
|
||||
}
|
||||
closedir(d);
|
||||
@@ -411,7 +411,7 @@ NSMutableArray *accountList;
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return [accountList count];
|
||||
return [self.accountList count];
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
@@ -423,24 +423,24 @@ NSMutableArray *accountList;
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
|
||||
}
|
||||
|
||||
cell.textLabel.text = [accountList objectAtIndex:indexPath.row];
|
||||
cell.textLabel.text = [self.accountList objectAtIndex:indexPath.row];
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
|
||||
NSString *str = [accountList objectAtIndex:indexPath.row];
|
||||
NSString *str = [self.accountList objectAtIndex:indexPath.row];
|
||||
loginAccountInput((UINavigationController *)self.presentingViewController, TYPE_SELECTACC, [str UTF8String]);
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
if (editingStyle == UITableViewCellEditingStyleDelete) {
|
||||
NSString *str = [accountList objectAtIndex:indexPath.row];
|
||||
NSString *str = [self.accountList objectAtIndex:indexPath.row];
|
||||
char accPath[2048];
|
||||
sprintf(accPath, "%s/accounts/%s.json", getenv("POJAV_HOME"), [str UTF8String]);
|
||||
remove(accPath);
|
||||
[accountList removeObjectAtIndex:indexPath.row];
|
||||
[self.accountList removeObjectAtIndex:indexPath.row];
|
||||
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
// #define DEBUG_VISIBLE_TEXT_FIELD
|
||||
|
||||
#define ADD_BUTTON(NAME, KEY, RECT, VISIBLE) \
|
||||
ControlButton *button_##KEY = [ControlButton initWithName:NAME keycode:KEY rect:CGRectOffset(RECT, notchOffset, 0) transparency:0.0f]; \
|
||||
ControlButton *button_##KEY = [ControlButton initWithName:NAME keycode:KEY rect:CGRectMake(RECT.origin.x * buttonScale, RECT.origin.y * buttonScale, RECT.size.width * buttonScale, RECT.size.height * buttonScale) transparency:0.0f]; \
|
||||
[button_##KEY addTarget:self action:@selector(executebtn_down:) forControlEvents:UIControlEventTouchDown]; \
|
||||
[button_##KEY addTarget:self action:@selector(executebtn_up:) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside]; \
|
||||
[self.view addSubview:button_##KEY]; \
|
||||
@@ -26,6 +26,9 @@
|
||||
togglableVisibleButtons[++togglableVisibleButtonIndex] = button_##KEY; \
|
||||
}
|
||||
|
||||
#define APPLY_SCALE(KEY) \
|
||||
KEY = @([(NSNumber *)KEY floatValue] * savedScale / currentScale);
|
||||
|
||||
#define INPUT_SPACE_CHAR @" "
|
||||
#define INPUT_SPACE_LENGTH 20
|
||||
|
||||
@@ -47,7 +50,8 @@ int notchOffset;
|
||||
@interface SurfaceViewController ()<UITextFieldDelegate, UIPointerInteractionDelegate> {
|
||||
}
|
||||
|
||||
@property (strong, nonatomic) MGLContext *context;
|
||||
@property (nonatomic, strong) MGLContext *context;
|
||||
@property (nonatomic, strong) NSMutableDictionary* cc_dictionary;
|
||||
|
||||
- (void)setupGL;
|
||||
|
||||
@@ -77,6 +81,7 @@ int notchOffset;
|
||||
|
||||
notchOffset = insets.left;
|
||||
width = width - notchOffset * 2;
|
||||
CGFloat buttonScale = ((NSNumber *) getPreference(@"button_scale")).floatValue / 100.0;
|
||||
|
||||
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(surfaceOnClick:)];
|
||||
tapGesture.numberOfTapsRequired = 1;
|
||||
@@ -102,16 +107,11 @@ int notchOffset;
|
||||
[touchView addGestureRecognizer:mouseWheelGesture];
|
||||
}
|
||||
|
||||
CGFloat buttonScale = ((NSNumber *) getPreference(@"button_scale")).floatValue / 100.0;
|
||||
CGFloat rectBtnWidth = 80.0 * buttonScale;
|
||||
CGFloat rectBtnHeight = 30.0 * buttonScale;
|
||||
CGFloat squareBtnSize = 50.0 * buttonScale;
|
||||
|
||||
#ifndef DEBUG_VISIBLE_TEXT_FIELD
|
||||
inputView = [[UITextField alloc] initWithFrame:CGRectMake(5 * 3 + rectBtnWidth * 2, 5, rectBtnWidth, rectBtnHeight)];
|
||||
inputView = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
|
||||
inputView.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.0f];
|
||||
#else
|
||||
inputView = [[UITextField alloc] initWithFrame:CGRectMake(5 * 3 + rectBtnWidth * 2, 5 * 2 + rectBtnHeight, 200, rectBtnHeight)];
|
||||
inputView = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
|
||||
inputView.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.5f];
|
||||
|
||||
inputLengthView = [[UILabel alloc] initWithFrame:CGRectMake(5 * 2 + rectBtnWidth, 5 * 2 + rectBtnHeight, rectBtnWidth, rectBtnHeight)];
|
||||
@@ -126,65 +126,52 @@ int notchOffset;
|
||||
// Custom button
|
||||
// ADD_BUTTON(@"F1", f1, CGRectMake(5, 5, width, height));
|
||||
|
||||
// Temporary fallback controls
|
||||
BOOL cc_fallback = YES;
|
||||
|
||||
NSString *controlFilePath = [NSString stringWithFormat:@"%s/%@", getenv("POJAV_PATH_CONTROL"), (NSString *)getPreference(@"default_ctrl")];
|
||||
|
||||
NSError *cc_error;
|
||||
NSString *cc_data = [NSString stringWithContentsOfFile:controlFilePath encoding:NSUTF8StringEncoding error:&cc_error];
|
||||
|
||||
if (cc_error != nil) {
|
||||
NSLog(@"Error: could not read \"%@\", falling back to default control, error: %@", controlFilePath, cc_error.localizedDescription);
|
||||
NSLog(@"Error: could not read %@: %@", controlFilePath, cc_error.localizedDescription);
|
||||
showDialog(self, @"Error", [NSString stringWithFormat:@"Could not read %@: %@", controlFilePath, cc_error.localizedDescription]);
|
||||
} else {
|
||||
NSData* cc_objc_data = [cc_data dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSDictionary *cc_dictionary = [NSJSONSerialization JSONObjectWithData:cc_objc_data options:kNilOptions error:&cc_error];
|
||||
self.cc_dictionary = [NSJSONSerialization JSONObjectWithData:cc_objc_data options:NSJSONReadingMutableContainers error:&cc_error];
|
||||
if (cc_error != nil) {
|
||||
showDialog(self, @"Error parsing JSON", cc_error.localizedDescription);
|
||||
} else {
|
||||
NSArray *cc_controlDataList = (NSArray *) [cc_dictionary valueForKey:@"mControlDataList"];
|
||||
NSMutableArray *cc_controlDataList = self.cc_dictionary[@"mControlDataList"];
|
||||
CGFloat currentScale = ((NSNumber *)self.cc_dictionary[@"scaledAt"]).floatValue;
|
||||
CGFloat savedScale = ((NSNumber *)getPreference(@"button_scale")).floatValue;
|
||||
int cc_version = ((NSNumber *)self.cc_dictionary[@"version"]).intValue;
|
||||
for (int i = 0; i < (int) cc_controlDataList.count; i++) {
|
||||
ControlButton *button = [ControlButton initWithProperties:(NSMutableDictionary *)cc_controlDataList[i]];
|
||||
NSMutableDictionary *cc_buttonDict = cc_controlDataList[i];
|
||||
if (cc_version < 2) {
|
||||
showDialog(self, @"Notice", @"Custom controls v1 to v2 was not implemented!");
|
||||
return;
|
||||
//convertV1ToV2(cc_buttonDict);
|
||||
}
|
||||
APPLY_SCALE(cc_buttonDict[@"width"]);
|
||||
APPLY_SCALE(cc_buttonDict[@"height"]);
|
||||
APPLY_SCALE(cc_buttonDict[@"strokeWidth"]);
|
||||
|
||||
ControlButton *button = [ControlButton initWithProperties:cc_buttonDict];
|
||||
[button addTarget:self action:@selector(executebtn_down:) forControlEvents:UIControlEventTouchDown];
|
||||
[button addTarget:self action:@selector(executebtn_up:) forControlEvents:UIControlEventTouchUpInside];
|
||||
[button addTarget:self action:@selector(executebtn_up:) forControlEvents:UIControlEventTouchUpOutside];
|
||||
[button addTarget:self action:@selector(executebtn_up:) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
|
||||
[self.view addSubview:button];
|
||||
if ([(NSNumber *) [button.properties valueForKey:@"keycode"] intValue] != SPECIALBTN_TOGGLECTRL) {
|
||||
|
||||
int firstKeycode = ((NSNumber *)cc_buttonDict[@"keycodes"][0]).intValue;
|
||||
if (firstKeycode == SPECIALBTN_KEYBOARD) {
|
||||
inputView.frame = button.frame;
|
||||
}
|
||||
if (firstKeycode != SPECIALBTN_TOGGLECTRL) {
|
||||
togglableVisibleButtons[++togglableVisibleButtonIndex] = button;
|
||||
}
|
||||
}
|
||||
cc_fallback = NO;
|
||||
self.cc_dictionary[@"scaledAt"] = @(savedScale);
|
||||
}
|
||||
}
|
||||
|
||||
if (cc_fallback == YES) {
|
||||
ADD_BUTTON(@"GUI", SPECIALBTN_TOGGLECTRL, CGRectMake(5, height - 5 - squareBtnSize, squareBtnSize, squareBtnSize), NO);
|
||||
ADD_BUTTON(@"Keyboard", SPECIALBTN_KEYBOARD, CGRectMake(5 * 3 + rectBtnWidth * 2, 5, rectBtnWidth, rectBtnHeight), YES);
|
||||
|
||||
ADD_BUTTON(@"Pri", SPECIALBTN_MOUSEPRI, CGRectMake(5, height - 5 * 3 - squareBtnSize * 3, squareBtnSize, squareBtnSize), YES);
|
||||
ADD_BUTTON(@"Sec", SPECIALBTN_MOUSESEC, CGRectMake(5 * 3 + squareBtnSize * 2, height - 5 * 3 - squareBtnSize * 3, squareBtnSize, squareBtnSize), YES);
|
||||
|
||||
ADD_BUTTON(@"Debug", GLFW_KEY_F3, CGRectMake(5, 5, rectBtnWidth, rectBtnHeight), YES);
|
||||
ADD_BUTTON(@"Chat", GLFW_KEY_T, CGRectMake(5 * 2 + rectBtnWidth, 5, rectBtnWidth, rectBtnHeight), YES);
|
||||
ADD_BUTTON(@"Tab", GLFW_KEY_TAB, CGRectMake(5 * 4 + rectBtnWidth * 3, 5, rectBtnWidth, rectBtnHeight), YES);
|
||||
ADD_BUTTON(@"Opti-Zoom", GLFW_KEY_C, CGRectMake(5 * 5 + rectBtnWidth * 4, 5, rectBtnWidth, rectBtnHeight), YES);
|
||||
ADD_BUTTON(@"Offhand", GLFW_KEY_F, CGRectMake(5 * 6 + rectBtnWidth * 5, 5, rectBtnWidth, rectBtnHeight), YES);
|
||||
ADD_BUTTON(@"3rd", GLFW_KEY_F5, CGRectMake(5, 5 * 2 + rectBtnHeight, rectBtnWidth, rectBtnHeight), YES);
|
||||
|
||||
ADD_BUTTON(@"▲", GLFW_KEY_W, CGRectMake(5 * 2 + squareBtnSize, height - 5 * 3 - squareBtnSize * 3, squareBtnSize, squareBtnSize), YES);
|
||||
ADD_BUTTON(@"◀", GLFW_KEY_A, CGRectMake(5, height - 5 * 2 - squareBtnSize * 2, squareBtnSize, squareBtnSize), YES);
|
||||
ADD_BUTTON(@"▼", GLFW_KEY_S, CGRectMake(5 * 2 + squareBtnSize, height - 5 - squareBtnSize, squareBtnSize, squareBtnSize), YES);
|
||||
ADD_BUTTON(@"▶", GLFW_KEY_D, CGRectMake(5 * 3 + squareBtnSize * 2, height - 5 * 2 - squareBtnSize * 2, squareBtnSize, squareBtnSize), YES);
|
||||
ADD_BUTTON(@"◇", GLFW_KEY_LEFT_SHIFT, CGRectMake(5 * 2 + squareBtnSize, height - 5 * 2 - squareBtnSize * 2, squareBtnSize, squareBtnSize), YES);
|
||||
ADD_BUTTON(@"Inv", GLFW_KEY_E, CGRectMake(5 * 3 + squareBtnSize * 2, height - 5 - squareBtnSize, squareBtnSize, squareBtnSize), YES);
|
||||
|
||||
ADD_BUTTON(@"⬛", GLFW_KEY_SPACE, CGRectMake(width - 5 * 2 - squareBtnSize * 2, height - 5 * 2 - squareBtnSize * 2, squareBtnSize, squareBtnSize), YES);
|
||||
|
||||
ADD_BUTTON(@"Esc", GLFW_KEY_ESCAPE, CGRectMake(width - 5 - rectBtnWidth, height - 5 - rectBtnHeight, rectBtnWidth, rectBtnHeight), YES);
|
||||
|
||||
// ADD_BUTTON(@"Fullscreen", f11, CGRectMake(width - 5 - rectBtnWidth, 5, rectBtnWidth, rectBtnHeight), YES);
|
||||
}
|
||||
|
||||
[self.view addSubview:inputView];
|
||||
|
||||
[self executebtn_special_togglebtn:0];
|
||||
@@ -557,7 +544,8 @@ int currentVisibility = 1;
|
||||
- (void) executebtn:(UIButton *)sender withAction:(int)action {
|
||||
ControlButton *button = (ControlButton *)sender;
|
||||
int held = action == ACTION_DOWN;
|
||||
int keycode = [(NSNumber *) [button.properties valueForKey:@"keycode"] intValue];
|
||||
// TODO v2: mulitple keys support
|
||||
int keycode = ((NSNumber *)button.properties[@"keycodes"][0]).intValue;
|
||||
if (keycode < 0) {
|
||||
switch (keycode) {
|
||||
case SPECIALBTN_KEYBOARD:
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
/**
|
||||
* Custom controls have same format as Android.
|
||||
* Custom controls have similar format as Android.
|
||||
*
|
||||
* Android - iOS:
|
||||
* ControlButton - same
|
||||
* ControlData - NSArray with JSON components
|
||||
* ControlData - NSDictionary
|
||||
*/
|
||||
|
||||
@interface ControlButton : UIButton {
|
||||
}
|
||||
|
||||
@property (nonatomic, retain) NSMutableDictionary* properties;
|
||||
@property (nonatomic, strong) NSMutableDictionary* properties;
|
||||
|
||||
+ (id)initWithProperties:(NSMutableDictionary *)propArray;
|
||||
+ (id)initWithName:(NSString *)name keycode:(int)keycode rect:(CGRect)rect transparency:(float)transparency;
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
#import "ControlButton.h"
|
||||
#import "CustomControlsUtils.h"
|
||||
#import "../LauncherPreferences.h"
|
||||
|
||||
#define INSERT_VALUE(KEY, VALUE) \
|
||||
string = [string stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"${%@}", @(KEY)] withString:VALUE];
|
||||
|
||||
#define NUM2F(x) [(NSNumber *)x floatValue]
|
||||
|
||||
float getScreenScale() {
|
||||
return (float) (((NSNumber *) getPreference(@"button_scale")).floatValue / 50.0); //[[UIScreen mainScreen] scale];
|
||||
}
|
||||
#define NUM2F(x) (x == nil ? 0 : [(NSNumber *)x floatValue])
|
||||
|
||||
@implementation ControlButton
|
||||
@synthesize properties;
|
||||
@@ -25,11 +22,9 @@ float getScreenScale() {
|
||||
|
||||
+ (id)initWithProperties:(NSMutableDictionary *)propArray {
|
||||
ControlButton *instance = [ControlButton buttonWithType:UIButtonTypeRoundedRect];
|
||||
[instance setTitle:[propArray valueForKey:@"name"]
|
||||
forState:UIControlStateNormal];
|
||||
[instance setTitle:propArray[@"name"] forState:UIControlStateNormal];
|
||||
instance.autoresizingMask = UIViewAutoresizingFlexibleWidth;
|
||||
instance.tintColor = [UIColor whiteColor];
|
||||
|
||||
instance.properties = propArray;
|
||||
[instance update];
|
||||
|
||||
@@ -37,31 +32,29 @@ float getScreenScale() {
|
||||
}
|
||||
|
||||
+ (id)initWithName:(NSString *)name keycode:(int)keycode rect:(CGRect)rect transparency:(float)transparency {
|
||||
float screenScale = getScreenScale();
|
||||
|
||||
NSMutableDictionary *properties = [[NSMutableDictionary alloc] init];
|
||||
[properties setObject:name forKey:@"name"];
|
||||
[properties setObject:@(rect.origin.x * screenScale) forKey:@"x"];
|
||||
[properties setObject:@(rect.origin.y * screenScale) forKey:@"y"];
|
||||
[properties setObject:@(rect.size.width * screenScale) forKey:@"width"];
|
||||
[properties setObject:@(rect.size.height * screenScale) forKey:@"height"];
|
||||
[properties setObject:@(keycode) forKey:@"keycode"];
|
||||
[properties setObject:@(transparency) forKey:@"transparency"];
|
||||
properties[@"name"] = name;
|
||||
properties[@"x"] = @(rect.origin.x);
|
||||
properties[@"y"] = @(rect.origin.y);
|
||||
properties[@"width"] = @(rect.size.width);
|
||||
properties[@"height"] = @(rect.size.height);
|
||||
properties[@"keycode"] = @(keycode);
|
||||
properties[@"transparency"] = @(transparency);
|
||||
properties[@"cornerRadius"] = @(0);
|
||||
|
||||
return [ControlButton initWithProperties:properties];
|
||||
}
|
||||
|
||||
- (float)insertDynamicPos:(NSString*)string {
|
||||
CGRect screenBounds = [[UIScreen mainScreen] bounds];
|
||||
float screenScale = getScreenScale();
|
||||
UIEdgeInsets insets = UIApplication.sharedApplication.windows.firstObject.safeAreaInsets;
|
||||
|
||||
// width: offset the notch parts
|
||||
int screenWidth = (int) roundf((screenBounds.size.width - insets.left - insets.right) * screenScale);
|
||||
int screenHeight = (int) roundf(screenBounds.size.height * screenScale);
|
||||
int screenWidth = (int) roundf(screenBounds.size.width - insets.left - insets.right);
|
||||
int screenHeight = (int) roundf(screenBounds.size.height);
|
||||
|
||||
float width = NUM2F([self.properties valueForKey:@"width"]);
|
||||
float height = NUM2F([self.properties valueForKey:@"height"]);
|
||||
float width = NUM2F(self.properties[@"width"]);
|
||||
float height = NUM2F(self.properties[@"height"]);
|
||||
|
||||
// Insert value to ${variable}
|
||||
INSERT_VALUE("top", @"0");
|
||||
@@ -72,50 +65,73 @@ float getScreenScale() {
|
||||
INSERT_VALUE("height", ([NSString stringWithFormat:@"%f", height]));
|
||||
INSERT_VALUE("screen_width", ([NSString stringWithFormat:@"%d", screenWidth]));
|
||||
INSERT_VALUE("screen_height", ([NSString stringWithFormat:@"%d", screenHeight]));
|
||||
INSERT_VALUE("margin", ([NSString stringWithFormat:@"%f", 2.0 * screenScale])); // FIXME is this correct?
|
||||
INSERT_VALUE("margin", ([NSString stringWithFormat:@"%f", 2.0])); // FIXME is this correct?
|
||||
|
||||
// NSLog(@"Final math: %@", string);
|
||||
|
||||
// Calculate, because the dynamic position contains some math equations
|
||||
// Calculate, since the dynamic position contains some math equations
|
||||
NSExpression *expression = [NSExpression expressionWithFormat:string];
|
||||
return [[expression expressionValueWithObject:nil context:nil] floatValue];
|
||||
}
|
||||
|
||||
- (void)setDefaultValueForKey:(NSString *)key value:(id)value {
|
||||
if (self.properties[key] == nil || self.properties[key] == [NSNull null]) {
|
||||
self.properties[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)update {
|
||||
// net/kdt/pojavlaunch/customcontrols/ControlData.update()
|
||||
|
||||
float screenScale = getScreenScale();
|
||||
UIEdgeInsets insets = UIApplication.sharedApplication.windows.firstObject.safeAreaInsets;
|
||||
|
||||
NSString *propDynamicX = (NSString *) [self.properties valueForKey:@"dynamicX"];
|
||||
NSString *propDynamicY = (NSString *) [self.properties valueForKey:@"dynamicY"];
|
||||
float propX = NUM2F([self.properties valueForKey:@"x"]);
|
||||
float propY = NUM2F([self.properties valueForKey:@"y"]);
|
||||
float propW = NUM2F([self.properties valueForKey:@"width"]);
|
||||
float propH = NUM2F([self.properties valueForKey:@"height"]);
|
||||
NSString *propDynamicX = (NSString *) self.properties[@"dynamicX"];
|
||||
NSString *propDynamicY = (NSString *) self.properties[@"dynamicY"];
|
||||
|
||||
float propX = NUM2F(self.properties[@"x"]);
|
||||
float propY = NUM2F(self.properties[@"y"]);
|
||||
float propW = NUM2F(self.properties[@"width"]);
|
||||
float propH = NUM2F(self.properties[@"height"]);
|
||||
float propCornerRadius = NUM2F(self.properties[@"cornerRadius"]);
|
||||
float propStrokeWidth = NUM2F(self.properties[@"strokeWidth"]);
|
||||
int propBackgroundColor = ((NSNumber *)self.properties[@"bgColor"]).intValue;
|
||||
int propStrokeColor = ((NSNumber *)self.properties[@"strokeColor"]).intValue;
|
||||
|
||||
// isRound is deprecated, only keep for old Android's controls backwards compatibility
|
||||
[self setDefaultValueForKey:@"isRound" value:@(NO)];
|
||||
BOOL propIsRound = self.properties[@"isRound"];
|
||||
[self setDefaultValueForKey:@"cornerRadius" value:@(propIsRound ? 8.0 : 0)];
|
||||
|
||||
// If dynamic position is null, set value to fixed position
|
||||
if (propDynamicX == nil) {
|
||||
propDynamicX = [NSString stringWithFormat:@"%f", propX];
|
||||
[self.properties setObject:propDynamicX forKey:@"dynamicX"];
|
||||
self.properties[@"dynamicX"] = propDynamicX;
|
||||
} if (propDynamicY == nil) {
|
||||
propDynamicY = [NSString stringWithFormat:@"%f", propY];
|
||||
[self.properties setObject:propDynamicY forKey:@"dynamicY"];
|
||||
self.properties[@"dynamicY"] = propDynamicY;
|
||||
}
|
||||
|
||||
// Calculate dynamic position
|
||||
propX = [self insertDynamicPos:propDynamicX];
|
||||
propY = [self insertDynamicPos:propDynamicY];
|
||||
// Set back to fixed position
|
||||
/*
|
||||
[self.properties setObject:@(propX) forKey:@"x"];
|
||||
[self.properties setObject:@(propY) forKey:@"y"];
|
||||
*/
|
||||
|
||||
// Update other properties
|
||||
self.frame = CGRectMake(propX / screenScale + insets.left, propY / screenScale, propW / screenScale, propH / screenScale);
|
||||
self.frame = CGRectMake(propX + insets.left, propY, propW, propH);
|
||||
self.alpha = 1.0f - NUM2F([properties valueForKey:@"transparency"]) / 100.0f;
|
||||
self.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.3f];
|
||||
// self.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.3f];
|
||||
self.backgroundColor = convertARGB2UIColor(propBackgroundColor);
|
||||
|
||||
self.layer.borderColor = [convertARGB2UIColor(propStrokeColor) CGColor];
|
||||
if (propCornerRadius > 0) {
|
||||
self.layer.cornerRadius = self.frame.size.width / 200 * propCornerRadius;
|
||||
}
|
||||
if (propStrokeWidth > 0) {
|
||||
self.layer.borderWidth = self.frame.size.width / propStrokeWidth;
|
||||
}
|
||||
self.clipsToBounds = YES;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,6 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
UIColor* convertARGB2UIColor(int argb);
|
||||
int convertUIColor2ARGB(UIColor* color);
|
||||
void convertV1ToV2(NSMutableDictionary* input);
|
||||
void generateAndSaveDefaultControl();
|
||||
@@ -0,0 +1,171 @@
|
||||
#import "CustomControlsUtils.h"
|
||||
#include "../glfw_keycodes.h"
|
||||
#include "../utils.h"
|
||||
|
||||
NSMutableDictionary* createButton(NSString* name, int* keycodes, NSString* dynamicX, NSString* dynamicY, CGFloat width, CGFloat height) {
|
||||
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
|
||||
dict[@"name"] = name;
|
||||
dict[@"keycodes"] = [[NSMutableArray alloc] init];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
[dict[@"keycodes"] addObject:@(keycodes[i])];
|
||||
}
|
||||
dict[@"dynamicX"] = dynamicX;
|
||||
dict[@"dynamicY"] = dynamicY;
|
||||
dict[@"width"] = @(width);
|
||||
dict[@"height"] = @(height);
|
||||
return dict;
|
||||
}
|
||||
|
||||
UIColor* convertARGB2UIColor(int argb) {
|
||||
return [UIColor
|
||||
colorWithRed:((argb>>16)&0xFF)/255.0
|
||||
green:((argb>>8)&0xFF)/255.0
|
||||
blue:((argb>>0)&0xFF)/255.0
|
||||
alpha:((argb>>24)&0xFF)/255.0];
|
||||
}
|
||||
|
||||
int convertUIColor2ARGB(UIColor* color) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void convertV1ToV2(NSMutableDictionary* input) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void generateAndSaveDefaultControl() {
|
||||
// Generate a V2 control
|
||||
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
|
||||
dict[@"version"] = @(2);
|
||||
dict[@"scaledAt"] = @(100);
|
||||
dict[@"mControlDataList"] = [[NSMutableArray alloc] init];
|
||||
[dict[@"mControlDataList"] addObject:createButton(@"Keyboard",
|
||||
(int[]){SPECIALBTN_KEYBOARD,0,0,0},
|
||||
@"${margin} * 3 + ${width} * 2",
|
||||
@"${margin}",
|
||||
160.0, 60.0
|
||||
)];
|
||||
[dict[@"mControlDataList"] addObject:createButton(@"GUI",
|
||||
(int[]){SPECIALBTN_TOGGLECTRL,0,0,0},
|
||||
@"${margin}",
|
||||
@"${bottom} - ${margin}",
|
||||
100.0, 100.0
|
||||
)];
|
||||
[dict[@"mControlDataList"] addObject:createButton(@"PRI",
|
||||
(int[]){SPECIALBTN_MOUSEPRI,0,0,0},
|
||||
@"${margin}",
|
||||
@"${screen_height} - ${margin} * 3 - ${height} * 3",
|
||||
100.0, 100.0
|
||||
)];
|
||||
[dict[@"mControlDataList"] addObject:createButton(@"SEC",
|
||||
(int[]){SPECIALBTN_MOUSESEC,0,0,0},
|
||||
@"${margin} * 3 + ${width} * 2",
|
||||
@"${screen_height} - ${margin} * 3 - ${height} * 3",
|
||||
100.0, 100.0
|
||||
)];
|
||||
/* // TODO: virtual mouse
|
||||
[dict[@"mControlDataList"] addObject:createButton(@"Mouse",
|
||||
(int[]){SPECIALBTN_VIRTUALMOUSE,0,0,0},
|
||||
@"${right}",
|
||||
@"${margin}",
|
||||
160.0, 60.0
|
||||
)];
|
||||
*/
|
||||
[dict[@"mControlDataList"] addObject:createButton(@"Debug",
|
||||
(int[]){GLFW_KEY_F3,0,0,0},
|
||||
@"${margin}",
|
||||
@"${margin}",
|
||||
160.0, 60.0
|
||||
)];
|
||||
[dict[@"mControlDataList"] addObject:createButton(@"Chat",
|
||||
(int[]){GLFW_KEY_T,0,0,0},
|
||||
@"${margin} * 2 + ${width}",
|
||||
@"${margin}",
|
||||
160.0, 60.0
|
||||
)];
|
||||
[dict[@"mControlDataList"] addObject:createButton(@"Tab",
|
||||
(int[]){GLFW_KEY_TAB,0,0,0},
|
||||
@"${margin} * 4 + ${width} * 3",
|
||||
@"${margin}",
|
||||
160.0, 60.0
|
||||
)];
|
||||
[dict[@"mControlDataList"] addObject:createButton(@"Opti-Zoom",
|
||||
(int[]){GLFW_KEY_C,0,0,0},
|
||||
@"${margin} * 5 + ${width} * 4",
|
||||
@"${margin}",
|
||||
160.0, 60.0
|
||||
)];
|
||||
[dict[@"mControlDataList"] addObject:createButton(@"Offhand",
|
||||
(int[]){GLFW_KEY_F,0,0,0},
|
||||
@"${margin} * 6 + ${width} * 5",
|
||||
@"${margin}",
|
||||
160.0, 60.0
|
||||
)];
|
||||
[dict[@"mControlDataList"] addObject:createButton(@"3rd",
|
||||
(int[]){GLFW_KEY_F5,0,0,0},
|
||||
@"${margin}",
|
||||
@"${margin} * 2 + ${height}",
|
||||
160.0, 60.0
|
||||
)];
|
||||
[dict[@"mControlDataList"] addObject:createButton(@"▲",
|
||||
(int[]){GLFW_KEY_W,0,0,0},
|
||||
@"${margin} * 2 + ${width}",
|
||||
@"${bottom} - ${margin} * 3 - ${height} * 2",
|
||||
100.0, 100.0
|
||||
)];
|
||||
[dict[@"mControlDataList"] addObject:createButton(@"◀",
|
||||
(int[]){GLFW_KEY_A,0,0,0},
|
||||
@"${margin}",
|
||||
@"${bottom} - ${margin} * 2 - ${height}",
|
||||
100.0, 100.0
|
||||
)];
|
||||
[dict[@"mControlDataList"] addObject:createButton(@"▼",
|
||||
(int[]){GLFW_KEY_S,0,0,0},
|
||||
@"${margin} * 2 + ${width}",
|
||||
@"${bottom} - ${margin}",
|
||||
100.0, 100.0
|
||||
)];
|
||||
[dict[@"mControlDataList"] addObject:createButton(@"▶",
|
||||
(int[]){GLFW_KEY_D,0,0,0},
|
||||
@"${margin} * 3 + ${width} * 2",
|
||||
@"${bottom} - ${margin} * 2 - ${height}",
|
||||
100.0, 100.0
|
||||
)];
|
||||
[dict[@"mControlDataList"] addObject:createButton(@"Inv",
|
||||
(int[]){GLFW_KEY_E,0,0,0},
|
||||
@"${margin} * 3 + ${width} * 2",
|
||||
@"${bottom} - ${margin}",
|
||||
100.0, 100.0
|
||||
)];
|
||||
[dict[@"mControlDataList"] addObject:createButton(@"◇",
|
||||
(int[]){GLFW_KEY_LEFT_SHIFT,0,0,0},
|
||||
@"${margin} * 2 + ${width}",
|
||||
@"${screen_height} - ${margin} * 2 - ${height} * 2",
|
||||
100.0, 100.0
|
||||
)];
|
||||
[dict[@"mControlDataList"] addObject:createButton(@"⬛",
|
||||
(int[]){GLFW_KEY_SPACE,0,0,0},
|
||||
@"${right} - ${margin} * 2 - ${width}",
|
||||
@"${bottom} - ${margin} * 2 - ${height}",
|
||||
100.0, 100.0
|
||||
)];
|
||||
[dict[@"mControlDataList"] addObject:createButton(@"Esc",
|
||||
(int[]){GLFW_KEY_ESCAPE,0,0,0},
|
||||
@"${right} - ${margin}",
|
||||
@"${bottom} - ${margin}",
|
||||
160.0, 60.0
|
||||
)];
|
||||
NSOutputStream *os = [[NSOutputStream alloc] initToFileAtPath:
|
||||
[@(getenv("POJAV_PATH_CONTROL")) stringByAppendingString:@"/default.json"] append:NO];
|
||||
[os open];
|
||||
[NSJSONSerialization writeJSONObject:dict toStream:os options:NSJSONWritingPrettyPrinted error:nil];
|
||||
[os close];
|
||||
|
||||
/*
|
||||
[dict[@"mControlDataList"] addObject:createButton(@"NAME",
|
||||
{SPECIALBTN_KEYBOARD,0,0,0},
|
||||
@"DYNAMICX",
|
||||
@"DYNAMICY",
|
||||
WIDTHHEIGHT
|
||||
)];
|
||||
*/
|
||||
}
|
||||
@@ -57,8 +57,8 @@ extern "C" {
|
||||
#define EGL_VERSION_1_0 1
|
||||
typedef unsigned int EGLBoolean;
|
||||
typedef void *EGLDisplay;
|
||||
#include <EGL/eglplatform.h>
|
||||
#include <KHR/khrplatform.h>
|
||||
#include "eglplatform.h"
|
||||
#include "../KHR/khrplatform.h"
|
||||
typedef void *EGLConfig;
|
||||
typedef void *EGLSurface;
|
||||
typedef void *EGLContext;
|
||||
|
||||
@@ -3612,6 +3612,11 @@ GL_APICALL void GL_APIENTRY glEndTilingQCOM (GLbitfield preserveMask);
|
||||
#define GL_SHADER_BINARY_VIV 0x8FC4
|
||||
#endif /* GL_VIV_shader_binary */
|
||||
|
||||
#ifndef GL_MGL_timeline_semaphore
|
||||
#define GL_MGL_timeline_semaphore 1
|
||||
#define GL_TIMELINE_SEMAPHORE_VALUE_MGL 0x9595
|
||||
#endif
|
||||
|
||||
/* ANGLE GLES2 extensions */
|
||||
#include "gl2ext_angle.h"
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
#import "MGLLayer.h"
|
||||
|
||||
#include "EGL/egl.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef enum MGLRenderingAPI : int
|
||||
@@ -27,10 +29,12 @@ typedef enum MGLRenderingAPI : int
|
||||
// contexts.
|
||||
- (id)initWithAPI:(MGLRenderingAPI)api sharegroup:(MGLSharegroup *_Nullable)sharegroup;
|
||||
|
||||
- (MGLRenderingAPI)API;
|
||||
@property(nonatomic, readonly) MGLRenderingAPI API;
|
||||
|
||||
@property(readonly) MGLSharegroup *sharegroup;
|
||||
|
||||
@property(nonatomic, readonly) EGLDisplay eglDisplay;
|
||||
|
||||
// Present the content of layer on screen as soon as possible.
|
||||
- (BOOL)present:(MGLLayer *)layer;
|
||||
|
||||
|
||||
@@ -31,10 +31,13 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@property(nonatomic, readonly) NSInteger framesDisplayed;
|
||||
@property(nonatomic, readonly) NSTimeInterval timeSinceLastUpdate;
|
||||
|
||||
@property(weak, nonatomic, readonly) MGLKView *glView;
|
||||
@property(nonatomic, getter=isPaused) BOOL paused;
|
||||
@property(nonatomic) BOOL pauseOnWillResignActive;
|
||||
@property(nonatomic) BOOL resumeOnDidBecomeActive;
|
||||
|
||||
- (void)pause;
|
||||
- (void)resume;
|
||||
@property(weak, nonatomic, readonly) MGLKView *glView;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in new issue
Block a user