323 lines
8.3 KiB
Text
323 lines
8.3 KiB
Text
#include <MetalKit/MetalKit.h>
|
|
#define VK_USE_PLATFORM_METAL_EXT
|
|
#include <gfx_vulkan.hpp>
|
|
#include <GameController/GameController.h>
|
|
|
|
#import <UIKit/UIKit.h>
|
|
|
|
#include <engine.hpp>
|
|
|
|
#include <@APP_INCLUDE@>
|
|
|
|
@APP_CLASS@* app = nullptr;
|
|
|
|
int maxFPS = 60;
|
|
|
|
std::array<bool, 8> inputKeys;
|
|
|
|
float rightX = 0.0f, rightY = 0.0f;
|
|
float leftX = 0.0f, leftY = 0.0f;
|
|
|
|
@interface GameView : UIView
|
|
@end
|
|
|
|
@implementation GameView
|
|
|
|
+ (Class) layerClass {
|
|
return [CAMetalLayer class];
|
|
}
|
|
|
|
- (void)draw {
|
|
engine->update(1.0f / (float)maxFPS);
|
|
engine->begin_frame(1.0f / (float)maxFPS);
|
|
engine->render(0);
|
|
}
|
|
|
|
- (void) controllerConnected {
|
|
GCController* controller = [GCController controllers][0];
|
|
[[controller extendedGamepad] setValueChangedHandler:^(GCExtendedGamepad * _Nonnull gamepad, GCControllerElement * _Nonnull element) {
|
|
const auto& handle_element = [element](int index, GCControllerElement* e) {
|
|
if(element == e)
|
|
inputKeys[index] = [(GCControllerButtonInput*)e value] == 1.0f;
|
|
};
|
|
|
|
handle_element(0, [[controller extendedGamepad] buttonA]);
|
|
handle_element(1, [[controller extendedGamepad] buttonB]);
|
|
handle_element(2, [[controller extendedGamepad] buttonX]);
|
|
handle_element(3, [[controller extendedGamepad] buttonY]);
|
|
|
|
if(element == [[controller extendedGamepad] dpad]) {
|
|
inputKeys[4] = [[[[controller extendedGamepad] dpad] up] value] == 1.0f;
|
|
inputKeys[5] = [[[[controller extendedGamepad] dpad] down] value] == 1.0f;
|
|
inputKeys[6] = [[[[controller extendedGamepad] dpad] left] value] == 1.0f;
|
|
inputKeys[7] = [[[[controller extendedGamepad] dpad] right] value] == 1.0f;
|
|
}
|
|
|
|
if(element == [[controller extendedGamepad] leftThumbstick]) {
|
|
leftX = [[[[controller extendedGamepad] leftThumbstick] xAxis] value];
|
|
leftY = [[[[controller extendedGamepad] leftThumbstick] yAxis] value];
|
|
}
|
|
|
|
if(element == [[controller extendedGamepad] rightThumbstick]) {
|
|
rightX = [[[[controller extendedGamepad] rightThumbstick] xAxis] value];
|
|
rightY = [[[[controller extendedGamepad] rightThumbstick] yAxis] value];
|
|
}
|
|
}];
|
|
}
|
|
|
|
@end
|
|
|
|
@interface GameViewController : UIViewController
|
|
|
|
@end
|
|
|
|
float mouse_x = 0.0f, mouse_y = 0.0f;
|
|
bool mouse_down = false;
|
|
|
|
@interface GameViewController ()
|
|
{
|
|
GameView* view;
|
|
}
|
|
@end
|
|
|
|
@implementation GameViewController
|
|
|
|
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
|
|
UITouch* touch = [touches anyObject];
|
|
CGPoint touchPoint = [touch locationInView: self.view];
|
|
|
|
mouse_x = touchPoint.x;
|
|
mouse_y = touchPoint.y;
|
|
|
|
mouse_down = true;
|
|
engine->process_mouse_down(0, {static_cast<int32_t>(touchPoint.x), static_cast<int32_t>(touchPoint.y)});
|
|
}
|
|
|
|
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
|
|
UITouch* touch = [touches anyObject];
|
|
CGPoint touchPoint = [touch locationInView: self.view];
|
|
|
|
mouse_x = touchPoint.x;
|
|
mouse_y = touchPoint.y;
|
|
|
|
mouse_down = false;
|
|
}
|
|
|
|
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
|
|
UITouch* touch = [touches anyObject];
|
|
CGPoint touchPoint = [touch locationInView: self.view];
|
|
|
|
mouse_x = touchPoint.x;
|
|
mouse_y = touchPoint.y;
|
|
}
|
|
|
|
int width, height;
|
|
int drawable_width, drawable_height;
|
|
|
|
- (void)viewDidLoad {
|
|
[super viewDidLoad];
|
|
view = (GameView*)self.view;
|
|
view.userInteractionEnabled = true;
|
|
|
|
CADisplayLink* displayLink = [CADisplayLink displayLinkWithTarget:view selector:@selector(draw)];
|
|
[displayLink addToRunLoop:NSRunLoop.mainRunLoop forMode:NSDefaultRunLoopMode];
|
|
|
|
width = [view frame].size.width;
|
|
height = [view frame].size.height;
|
|
|
|
drawable_width = [view frame].size.width * [view contentScaleFactor];
|
|
drawable_height = [view frame].size.height * [view contentScaleFactor];
|
|
|
|
engine = new prism::engine(0, nullptr);
|
|
|
|
app = new @APP_CLASS@();
|
|
engine->set_app(app);
|
|
|
|
GFXCreateInfo createInfo = {};
|
|
createInfo.api_validation_enabled = true;
|
|
|
|
GFXVulkan* gfx = new GFXVulkan();
|
|
gfx->initialize(createInfo);
|
|
engine->set_gfx(gfx);
|
|
|
|
app_main(engine);
|
|
|
|
engine->add_window((void*)CFBridgingRetain([view layer]), 0, {static_cast<uint32_t>(width), static_cast<uint32_t>(height)});
|
|
|
|
app->initialize_render();
|
|
|
|
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
|
|
[nc addObserver:view
|
|
selector:@selector(controllerConnected)
|
|
name:GCControllerDidConnectNotification
|
|
object:nil];
|
|
}
|
|
|
|
- (void)didReceiveMemoryWarning {
|
|
[super didReceiveMemoryWarning];
|
|
// Dispose of any resources that can be recreated.
|
|
}
|
|
|
|
-(bool)prefersStatusBarHidden {
|
|
return YES;
|
|
}
|
|
|
|
@end
|
|
|
|
void platform::capture_mouse(const bool capture) {
|
|
|
|
}
|
|
|
|
// TODO: unimplemented
|
|
PlatformTheme platform::get_theme() {
|
|
return PlatformTheme::Light;
|
|
}
|
|
|
|
void platform::begin_text_input() {
|
|
// TODO: stub
|
|
}
|
|
|
|
void platform::end_text_input() {
|
|
// TODO: stub
|
|
}
|
|
|
|
void* platform::create_native_surface(platform::window_ptr index, void* instance) {
|
|
VkMetalSurfaceCreateInfoEXT surfaceInfo = {};
|
|
surfaceInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
|
|
surfaceInfo.pNext = 0;
|
|
surfaceInfo.flags = 0;
|
|
surfaceInfo.pLayer = (CAMetalLayer*)layer;
|
|
|
|
VkSurfaceKHR surface;
|
|
vkCreateMetalSurfaceEXT((VkInstance)instance, &surfaceInfo, nullptr, &surface);
|
|
|
|
return surface;
|
|
}
|
|
|
|
bool platform::is_main_window(platform::window_ptr index) {
|
|
return true;
|
|
}
|
|
|
|
std::vector<const char*> platform::get_native_surface_extension() {
|
|
return {VK_EXT_METAL_SURFACE_EXTENSION_NAME};
|
|
}
|
|
|
|
void platform::show_window(const platform::window_ptr index) {
|
|
|
|
}
|
|
|
|
bool platform::supports_feature(const PlatformFeature feature) {
|
|
return false;
|
|
}
|
|
|
|
prism::Offset platform::get_cursor_position() {
|
|
return {static_cast<int32_t>(mouse_x), static_cast<int32_t>(mouse_y)};
|
|
}
|
|
|
|
std::tuple<float, float> platform::get_right_stick_position() {
|
|
return {rightX, rightY};
|
|
}
|
|
|
|
std::tuple<float, float> platform::get_left_stick_position() {
|
|
return {leftX, leftY};
|
|
}
|
|
|
|
bool platform::get_key_down(InputButton key) {
|
|
if(key == InputButton::ButtonA)
|
|
return inputKeys[0];
|
|
|
|
if(key == InputButton::ButtonB)
|
|
return inputKeys[1];
|
|
|
|
if(key == InputButton::ButtonX)
|
|
return inputKeys[2];
|
|
|
|
if(key == InputButton::ButtonY)
|
|
return inputKeys[3];
|
|
|
|
if(key == InputButton::DPadUp)
|
|
return inputKeys[4];
|
|
|
|
if(key == InputButton::DPadDown)
|
|
return inputKeys[5];
|
|
|
|
if(key == InputButton::DPadLeft)
|
|
return inputKeys[6];
|
|
|
|
if(key == InputButton::DPadRight)
|
|
return inputKeys[7];
|
|
|
|
return false;
|
|
}
|
|
|
|
platform::window_ptr platform::open_window(const std::string_view title, const prism::Rectangle rect, const WindowFlags flags) {
|
|
return 0;
|
|
}
|
|
|
|
void platform::set_window_title(const platform::window_ptr index, const std::string_view title) {
|
|
|
|
}
|
|
|
|
bool platform::is_window_focused(const platform::window_ptr index) {
|
|
|
|
}
|
|
|
|
void platform::set_window_focused(const platform::window_ptr index) {
|
|
|
|
}
|
|
|
|
prism::Extent platform::get_window_size(const platform::window_ptr index) {
|
|
return {static_cast<uint32_t>(width), static_cast<uint32_t>(height)};
|
|
}
|
|
|
|
prism::Extent platform::get_window_drawable_size(const platform::window_ptr index) {
|
|
return {static_cast<uint32_t>(drawable_width), static_cast<uint32_t>(drawable_height)};
|
|
}
|
|
|
|
prism::Offset platform::get_window_position(const platform::window_ptr index) {
|
|
|
|
}
|
|
|
|
void platform::set_window_size(const platform::window_ptr index, const prism::Extent extent) {
|
|
|
|
}
|
|
|
|
void platform::set_window_position(const platform::window_ptr index, const prism::Offset offset) {
|
|
|
|
}
|
|
|
|
void platform::close_window(const platform::window_ptr index) {
|
|
|
|
}
|
|
|
|
int platform::get_keycode(const InputButton button) {
|
|
|
|
}
|
|
|
|
prism::Rectangle platform::get_monitor_resolution() {
|
|
|
|
}
|
|
|
|
prism::Rectangle platform::get_monitor_work_area() {
|
|
|
|
}
|
|
|
|
prism::Offset platform::get_screen_cursor_position() {
|
|
|
|
}
|
|
|
|
bool platform::get_mouse_button_down(const int index) {
|
|
return mouse_down;
|
|
}
|
|
|
|
float platform::get_monitor_dpi() {
|
|
return 2.0f;
|
|
}
|
|
|
|
std::tuple<float, float> platform::get_wheel_delta() {
|
|
|
|
}
|
|
|
|
const char* platform::get_name() {
|
|
return "iOS";
|
|
}
|