#include <@APP_INCLUDE@> #include #include "gfx_vulkan.hpp" #include "platform.hpp" #include #include #include @APP_CLASS@* app = nullptr; GFX* gfx_interface = nullptr; struct Window { int identifier = 0; SDL_Window* window = nullptr; bool operator==(const Window& b) { return identifier == b.identifier && window == b.window; } }; std::vector windows; Window* get_window(const int index) { for(auto& window : windows) { if(window.identifier == index) return &window; } return nullptr; } Window* get_window_by_sdl_id(const Uint32 id) { for(auto& window : windows) { if(SDL_GetWindowID(window.window) == id) return &window; } return nullptr; } static std::map inputToKeyCode = { { {InputButton::A, 38}, {InputButton::W, 25}, {InputButton::S, 39}, {InputButton::D, 40}, {InputButton::Q, 24} }}; /* * Platform functions" */ const char* platform::get_name() { return "Linux (SDL)"; } bool platform::supports_feature(const PlatformFeature feature) { if(feature == PlatformFeature::Windowing) return true; return false; } int platform::open_window(const std::string_view title, const prism::Rectangle rect, const WindowFlags flags) { auto& win = windows.emplace_back(); win.identifier = windows.size() - 1; int sdl_flags = SDL_WINDOW_VULKAN; if(flags == WindowFlags::Borderless) sdl_flags |= SDL_WINDOW_BORDERLESS; if(flags == WindowFlags::Resizable) sdl_flags |= SDL_WINDOW_RESIZABLE; win.window = SDL_CreateWindow(title.data(), rect.offset.x, rect.offset.y, rect.extent.width, rect.extent.height, sdl_flags); engine->add_window((void*)&win, win.identifier, rect.extent); app->initialize_render(); return win.identifier; } void platform::close_window(const int index) { auto window = get_window(index); engine->remove_window(window->identifier); SDL_DestroyWindow(window->window); utility::erase(windows, *window); } void platform::force_quit() { } float platform::get_window_dpi(const int index) { return 1.0; } float platform::get_monitor_dpi() { return 1.0; } prism::Rectangle platform::get_monitor_resolution() { SDL_DisplayMode DM; SDL_GetCurrentDisplayMode(0, &DM); return {0, 0, (uint32_t)DM.w, (uint32_t)DM.h}; } prism::Rectangle platform::get_monitor_work_area() { return platform::get_monitor_resolution(); } prism::Offset platform::get_window_position(const int index) { auto window = get_window(index); int x, y; SDL_GetWindowPosition(window->window, &x, &y); return {(int32_t)x, (int32_t)y}; } prism::Extent platform::get_window_size(const int index) { auto window = get_window(index); int width, height; SDL_GetWindowSize(window->window, &width, &height); return {(uint32_t)width, (uint32_t)height}; } prism::Extent platform::get_window_drawable_size(const int index) { auto window = get_window(index); int width, height; SDL_GetWindowSize(window->window, &width, &height); return {(uint32_t)width, (uint32_t)height}; } bool platform::is_window_focused(const int index) { return false; } void platform::set_window_focused(const int index) { auto window = get_window(index); SDL_SetWindowInputFocus(window->window); } void platform::set_window_position(const int index, const prism::Offset offset) { auto window = get_window(index); SDL_SetWindowPosition(window->window, offset.x, offset.y); } void platform::set_window_size(const int index, const prism::Extent extent) { auto window = get_window(index); SDL_SetWindowSize(window->window, extent.width, extent.height); } void platform::set_window_title(const int index, const std::string_view title) { auto window = get_window(index); SDL_SetWindowTitle(window->window, title.data()); } bool platform::get_key_down(const InputButton key) { return false; } int platform::get_keycode(const InputButton key) { return inputToKeyCode[key]; } prism::Offset platform::get_cursor_position() { int x, y; SDL_GetMouseState(&x, &y); return {(int32_t)x, (int32_t)y}; } prism::Offset platform::get_screen_cursor_position() { int x, y; SDL_GetGlobalMouseState(&x, &y); return {(int32_t)x, (int32_t)y}; } bool platform::get_mouse_button_down(const int button) { return SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_LEFT + button); } std::tuple platform::get_wheel_delta() { return {0.0f, 0.0f}; } std::tuple platform::get_right_stick_position() { return {0.0f, 0.0f}; } std::tuple platform::get_left_stick_position() { return {0.0f, 0.0f}; } void platform::capture_mouse(const bool capture) { } void platform::open_dialog(const bool existing, std::function returnFunction, bool openDirectory) { } void platform::save_dialog(std::function returnFunction) { } char* platform::translate_keycode(const unsigned int keycode) { return ""; } int stdout_copy; int stderr_copy; void platform::mute_output() { } void platform::unmute_output() { } int main(int argc, char* argv[]) { SDL_Init(SDL_INIT_VIDEO); engine = new prism::engine(argc, argv); app = new @APP_CLASS@(); engine->set_app(app); GFXCreateInfo info = {}; gfx_interface = new GFXVulkan(); if(gfx_interface->initialize(info)) { engine->set_gfx(gfx_interface); } else { return -1; } app_main(engine); while(!engine->is_quitting()) { SDL_Event event = {}; while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_QUIT: engine->quit(); break; case SDL_WINDOWEVENT: if (event.window.event == SDL_WINDOWEVENT_RESIZED) { auto window = get_window_by_sdl_id(event.window.windowID); if(window != nullptr) engine->resize(window->identifier, {static_cast(event.window.data1), static_cast(event.window.data2)}); } break; } } if(engine->is_quitting()) break; engine->update(1.0 / 60.0); engine->begin_frame(1.0 / 60.0); for(auto window : windows) engine->render(window.identifier); engine->end_frame(); } return 0; } PlatformTheme platform::get_theme() { return PlatformTheme::Light; } void* platform::create_native_surface(int index, void* instance) { auto window = get_window(index); VkSurfaceKHR surface; SDL_Vulkan_CreateSurface(window->window, (VkInstance)instance, &surface); return surface; } std::vector platform::get_native_surface_extension() { // dummy window auto dummy = SDL_CreateWindow("", 0, 0, 1, 1, SDL_WINDOW_VULKAN); unsigned int count = 0; SDL_Vulkan_GetInstanceExtensions(dummy, &count, nullptr); std::vector extensions(count); SDL_Vulkan_GetInstanceExtensions(dummy, &count, extensions.data()); SDL_DestroyWindow(dummy); return extensions; }