diff --git a/src/blah_app.cpp b/src/blah_app.cpp index 1458315..f886a91 100644 --- a/src/blah_app.cpp +++ b/src/blah_app.cpp @@ -12,14 +12,6 @@ using namespace Blah; -#define BLAH_ASSERT_RUNNING() BLAH_ASSERT(app_is_running, "The App is not running (call App::run)") - -// Internal Platform Pointer -Platform* Internal::platform = nullptr; - -// Internal Renderer Pointer -Renderer* Internal::renderer = nullptr; - // Internal Audio bool bool Internal::audio_is_init = false; @@ -33,15 +25,16 @@ namespace u64 app_time_accumulator = 0; u32 app_flags = 0; TargetRef app_backbuffer; + Renderer* app_renderer_api; void get_drawable_size(int* w, int* h) { // Some renderer implementations might return their own size - if (Internal::renderer->get_draw_size(w, h)) + if (app_renderer_api->get_draw_size(w, h)) return; // otherwise fallback to the platform size - Internal::platform->get_draw_size(w, h); + Platform::get_draw_size(w, h); } // A dummy Target that represents the Back Buffer. @@ -57,8 +50,8 @@ namespace void clear(Color color, float depth, u8 stencil, ClearMask mask) override { BLAH_ASSERT_RENDERER(); - if (Internal::renderer) - Internal::renderer->clear_backbuffer(color, depth, stencil, mask); + if (app_renderer_api) + app_renderer_api->clear_backbuffer(color, depth, stencil, mask); } }; } @@ -99,15 +92,7 @@ bool App::run(const Config* c) // initialize the system { - Internal::platform = Platform::try_make_platform(app_config); - if (!Internal::platform) - { - Log::error("Failed to create Platform module"); - Internal::app_shutdown(); - return false; - } - - if (!Internal::platform->init(app_config)) + if (!Platform::init(app_config)) { Log::error("Failed to initialize Platform module"); Internal::app_shutdown(); @@ -117,26 +102,26 @@ bool App::run(const Config* c) // initialize audio { - if (!Blah::Internal::audio_is_init) { + if (!Internal::audio_is_init) { int more_on_emscripten = 1; - #ifdef __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ more_on_emscripten = 4; - #endif - Blah::Internal::audio_is_init = Blah::Internal::audio_init(c->audio_frequency_in_Hz, 1024 * more_on_emscripten); +#endif + Internal::audio_is_init = Internal::audio_init(c->audio_frequency_in_Hz, 1024 * more_on_emscripten); } } // initialize graphics { - Internal::renderer = Renderer::try_make_renderer(app_config.renderer_type); - if (Internal::renderer == nullptr) + app_renderer_api = Renderer::try_make_renderer(app_config.renderer_type); + if (app_renderer_api == nullptr) { Log::error("Renderer module was not found"); Internal::app_shutdown(); return false; } - if (!Internal::renderer->init()) + if (!app_renderer_api->init()) { Log::error("Failed to initialize Renderer module"); Internal::app_shutdown(); @@ -145,22 +130,22 @@ bool App::run(const Config* c) } // apply default flags - Internal::platform->set_app_flags(app_flags); - Internal::renderer->set_app_flags(app_flags); + Platform::set_app_flags(app_flags); + app_renderer_api->set_app_flags(app_flags); // input + poll the platform once Internal::input_init(); Internal::input_step_state(); - Internal::platform->update(Input::state); + Platform::update(Input::state); // startup if (app_config.on_startup != nullptr) app_config.on_startup(); - app_time_last = Internal::platform->ticks(); + app_time_last = Platform::ticks(); app_time_accumulator = 0; // display window - Internal::platform->ready(); + Platform::ready(); // Begin main loop #ifdef __EMSCRIPTEN__ @@ -187,9 +172,9 @@ void Internal::app_step() static const auto step = []() { Internal::input_step_state(); - platform->update(Input::state); + Platform::update(Input::state); Internal::input_step_bindings(); - renderer->update(); + app_renderer_api->update(); if (app_config.on_update != nullptr) app_config.on_update(); }; @@ -200,7 +185,7 @@ void Internal::app_step() if (is_fixed_timestep) { u64 time_target = (u64)((1.0 / app_config.target_framerate) * Time::ticks_per_second); - u64 ticks_curr = Internal::platform->ticks(); + u64 ticks_curr = Platform::ticks(); u64 ticks_diff = ticks_curr - app_time_last; app_time_last = ticks_curr; app_time_accumulator += ticks_diff; @@ -209,9 +194,9 @@ void Internal::app_step() while (app_time_accumulator < time_target) { int milliseconds = (int)(time_target - app_time_accumulator) / (Time::ticks_per_second / 1000); - Internal::platform->sleep(milliseconds); + Platform::sleep(milliseconds); - ticks_curr = Internal::platform->ticks(); + ticks_curr = Platform::ticks(); ticks_diff = ticks_curr - app_time_last; app_time_last = ticks_curr; app_time_accumulator += ticks_diff; @@ -250,7 +235,7 @@ void Internal::app_step() // Update with Variable Timestep else { - u64 ticks_curr = Internal::platform->ticks(); + u64 ticks_curr = Platform::ticks(); u64 ticks_diff = ticks_curr - app_time_last; app_time_last = ticks_curr; app_time_accumulator += ticks_diff; @@ -274,37 +259,36 @@ void Internal::app_step() // Draw Frame { - renderer->before_render(); + app_renderer_api->before_render(); if (app_config.on_render != nullptr) app_config.on_render(); - renderer->after_render(); - platform->present(); + app_renderer_api->after_render(); + Platform::present(); } // Update audio - Blah::Internal::audio_update(); + if (Internal::audio_is_init) + Blah::Internal::audio_update(); } void Internal::app_shutdown() { Internal::input_shutdown(); - if (renderer) - renderer->shutdown(); + if (app_renderer_api) + { + app_renderer_api->shutdown(); + delete app_renderer_api; + } + app_renderer_api = nullptr; - if (platform) - platform->shutdown(); + if (Internal::audio_is_init) + { + Internal::audio_shutdown(); + Internal::audio_is_init = false; + } - if (renderer) - delete renderer; - renderer = nullptr; - - if (platform) - delete platform; - platform = nullptr; - - Blah::Internal::audio_shutdown(); - Blah::Internal::audio_is_init = false; + Platform::shutdown(); // clear static App state app_config = Config(); @@ -322,6 +306,12 @@ void Internal::app_shutdown() Time::delta = 0; } +Renderer* Internal::app_renderer() +{ + BLAH_ASSERT_RUNNING(); + return app_renderer_api; +} + void App::exit() { BLAH_ASSERT_RUNNING(); @@ -338,59 +328,59 @@ const Config& App::config() const char* App::path() { BLAH_ASSERT_RUNNING(); - return Internal::platform->app_path(); + return Platform::app_path(); } const char* App::user_path() { BLAH_ASSERT_RUNNING(); - return Internal::platform->user_path(); + return Platform::user_path(); } const char* App::get_title() { BLAH_ASSERT_RUNNING(); - return Internal::platform->get_title(); + return Platform::get_title(); } void App::set_title(const char* title) { BLAH_ASSERT_RUNNING(); - Internal::platform->set_title(title); + Platform::set_title(title); } Point App::get_position() { BLAH_ASSERT_RUNNING(); Point result; - Internal::platform->get_position(&result.x, &result.y); + Platform::get_position(&result.x, &result.y); return result; } void App::set_position(Point point) { BLAH_ASSERT_RUNNING(); - Internal::platform->set_position(point.x, point.y); + Platform::set_position(point.x, point.y); } Point App::get_size() { BLAH_ASSERT_RUNNING(); Point result; - Internal::platform->get_size(&result.x, &result.y); + Platform::get_size(&result.x, &result.y); return result; } void App::set_size(Point point) { BLAH_ASSERT_RUNNING(); - Internal::platform->set_size(point.x, point.y); + Platform::set_size(point.x, point.y); } Point App::get_backbuffer_size() { BLAH_ASSERT_RUNNING(); - if (Internal::renderer) + if (app_renderer_api) return Point(app_backbuffer->width(), app_backbuffer->height()); return Point(0, 0); } @@ -398,13 +388,13 @@ Point App::get_backbuffer_size() float App::content_scale() { BLAH_ASSERT_RUNNING(); - return Internal::platform->get_content_scale(); + return Platform::get_content_scale(); } bool App::focused() { BLAH_ASSERT_RUNNING(); - return Internal::platform->get_focused(); + return Platform::get_focused(); } void App::set_flag(u32 flag, bool enabled) @@ -420,10 +410,9 @@ void App::set_flag(u32 flag, bool enabled) if (was != app_flags) { - if (Internal::platform) - Internal::platform->set_app_flags(app_flags); - if (Internal::renderer) - Internal::renderer->set_app_flags(app_flags); + Platform::set_app_flags(app_flags); + if (app_renderer_api) + app_renderer_api->set_app_flags(app_flags); } } @@ -437,7 +426,7 @@ const RendererInfo& App::renderer() { BLAH_ASSERT_RUNNING(); BLAH_ASSERT_RENDERER(); - return Internal::renderer->info; + return app_renderer_api->info; } const TargetRef& App::backbuffer() @@ -449,5 +438,5 @@ const TargetRef& App::backbuffer() void System::open_url(const char* url) { BLAH_ASSERT_RUNNING(); - Internal::platform->open_url(url); + Platform::open_url(url); } \ No newline at end of file diff --git a/src/blah_audio.cpp b/src/blah_audio.cpp index c028b34..4306c99 100644 --- a/src/blah_audio.cpp +++ b/src/blah_audio.cpp @@ -18,7 +18,7 @@ namespace Blah { bool audio_init(unsigned play_frequency_in_Hz, int buffered_samples) { - cs_error_t err = cs_init(Internal::platform->d3d11_get_hwnd(), play_frequency_in_Hz, buffered_samples, NULL); + cs_error_t err = cs_init(Platform::d3d11_get_hwnd(), play_frequency_in_Hz, buffered_samples, NULL); if (err != CUTE_SOUND_ERROR_NONE) { Log::error(cs_error_as_string(err)); return false; diff --git a/src/blah_batch.cpp b/src/blah_batch.cpp index 0462fff..995e32f 100644 --- a/src/blah_batch.cpp +++ b/src/blah_batch.cpp @@ -282,7 +282,8 @@ void Batch::render(const TargetRef& target, const Mat4x4f& matrix) if (!m_default_material) { BLAH_ASSERT_RENDERER(); - m_default_material = Material::create(Internal::renderer->default_batcher_shader); + if (auto renderer = Internal::app_renderer()) + m_default_material = Material::create(renderer->default_batcher_shader); } } diff --git a/src/blah_filesystem.cpp b/src/blah_filesystem.cpp index e07dc27..1678ed5 100644 --- a/src/blah_filesystem.cpp +++ b/src/blah_filesystem.cpp @@ -5,11 +5,11 @@ using namespace Blah; FileRef File::open(const FilePath& path, FileMode mode) { - BLAH_ASSERT_PLATFORM(); + BLAH_ASSERT_RUNNING(); FileRef ref; - if (Internal::platform) - ref = Internal::platform->file_open(path.cstr(), mode); + if (App::is_running()) + ref = Platform::file_open(path.cstr(), mode); if (ref) ref->m_mode = mode; return ref; @@ -17,17 +17,17 @@ FileRef File::open(const FilePath& path, FileMode mode) bool File::exists(const FilePath& path) { - BLAH_ASSERT_PLATFORM(); - if (Internal::platform) - return Internal::platform->file_exists(path.cstr()); + BLAH_ASSERT_RUNNING(); + if (App::is_running()) + return Platform::file_exists(path.cstr()); return false; } bool File::destroy(const FilePath& path) { - BLAH_ASSERT_PLATFORM(); - if (Internal::platform) - return Internal::platform->file_delete(path.cstr()); + BLAH_ASSERT_RUNNING(); + if (App::is_running()) + return Platform::file_delete(path.cstr()); return false; } @@ -38,37 +38,37 @@ FileMode File::mode() const bool Directory::create(const FilePath& path) { - BLAH_ASSERT_PLATFORM(); - if (Internal::platform) - return Internal::platform->dir_create(path.cstr()); + BLAH_ASSERT_RUNNING(); + if (App::is_running()) + return Platform::dir_create(path.cstr()); return false; } bool Directory::exists(const FilePath& path) { - BLAH_ASSERT_PLATFORM(); - if (Internal::platform) - return Internal::platform->dir_exists(path.cstr()); + BLAH_ASSERT_RUNNING(); + if (App::is_running()) + return Platform::dir_exists(path.cstr()); return false; } bool Directory::destroy(const FilePath& path) { - BLAH_ASSERT_PLATFORM(); - if (Internal::platform) - return Internal::platform->dir_delete(path.cstr()); + BLAH_ASSERT_RUNNING(); + if (App::is_running()) + return Platform::dir_delete(path.cstr()); return false; } Vector Directory::enumerate(const FilePath& path, bool recursive) { - BLAH_ASSERT_PLATFORM(); + BLAH_ASSERT_RUNNING(); Vector list; - if (Internal::platform) + if (App::is_running()) { - Internal::platform->dir_enumerate(list, path.cstr(), recursive); + Platform::dir_enumerate(list, path.cstr(), recursive); for (auto& it : list) { for (int n = 0; n < it.length(); n ++) @@ -81,9 +81,9 @@ Vector Directory::enumerate(const FilePath& path, bool recursive) void Directory::explore(const FilePath& path) { - BLAH_ASSERT_PLATFORM(); - if (Internal::platform) - Internal::platform->dir_explore(path); + BLAH_ASSERT_RUNNING(); + if (App::is_running()) + Platform::dir_explore(path); } FilePath Path::get_file_name(const FilePath& path) diff --git a/src/blah_graphics.cpp b/src/blah_graphics.cpp index 83f0bbc..c1f021a 100644 --- a/src/blah_graphics.cpp +++ b/src/blah_graphics.cpp @@ -88,8 +88,8 @@ ShaderRef Shader::create(const ShaderData& data) ShaderRef shader; - if (Internal::renderer) - shader = Internal::renderer->create_shader(&data); + if (auto renderer = Internal::app_renderer()) + shader = renderer->create_shader(&data); // validate the shader if (shader) @@ -130,9 +130,9 @@ TextureRef Texture::create(int width, int height, TextureFormat format, unsigned BLAH_ASSERT(width > 0 && height > 0, "Texture width and height must be larger than 0"); BLAH_ASSERT((int)format > (int)TextureFormat::None && (int)format < (int)TextureFormat::Count, "Invalid texture format"); - if (Internal::renderer) + if (auto renderer = Internal::app_renderer()) { - auto tex = Internal::renderer->create_texture(width, height, format); + auto tex = renderer->create_texture(width, height, format); if (tex && data != nullptr) tex->set_data(data); @@ -194,8 +194,8 @@ TargetRef Target::create(int width, int height, const AttachmentFormats& texture BLAH_ASSERT(depth_count <= 1, "Target can only have 1 Depth/Stencil Texture"); BLAH_ASSERT(color_count <= Attachments::capacity - 1, "Exceeded maximum Color texture count"); - if (Internal::renderer) - return Internal::renderer->create_target(width, height, textures.data(), textures.size()); + if (auto renderer = Internal::app_renderer()) + return renderer->create_target(width, height, textures.data(), textures.size()); return TargetRef(); } @@ -224,8 +224,8 @@ MeshRef Mesh::create() { BLAH_ASSERT_RENDERER(); - if (Internal::renderer) - return Internal::renderer->create_mesh(); + if (auto renderer = Internal::app_renderer()) + return renderer->create_mesh(); return MeshRef(); } @@ -623,7 +623,7 @@ void DrawCall::perform() BLAH_ASSERT(material->shader(), "Trying to draw with an invalid Shader"); BLAH_ASSERT(mesh, "Trying to draw with an invalid Mesh"); - if (!Internal::renderer) + if (!Internal::app_renderer()) return; // copy call @@ -685,5 +685,5 @@ void DrawCall::perform() pass.scissor = pass.scissor.overlap_rect(Rectf(0, 0, draw_size.x, draw_size.y)); // perform render - Internal::renderer->render(pass); + Internal::app_renderer()->render(pass); } diff --git a/src/blah_input.cpp b/src/blah_input.cpp index 3cf2a7f..2abd689 100644 --- a/src/blah_input.cpp +++ b/src/blah_input.cpp @@ -78,8 +78,7 @@ void Internal::input_step_state() } // get clipboard - if (Internal::platform) - g_clipboard = Internal::platform->get_clipboard(); + g_clipboard = Platform::get_clipboard(); } void Internal::input_step_bindings() @@ -397,9 +396,9 @@ const String& Input::get_clipboard() void Input::set_clipboard(const String& text) { + BLAH_ASSERT_RUNNING(); g_clipboard = text; - if (Internal::platform) - Internal::platform->set_clipboard(text); + Platform::set_clipboard(text); } ButtonBindingRef Input::register_binding(const ButtonBinding& binding_data) diff --git a/src/blah_time.cpp b/src/blah_time.cpp index dd8123b..ce21e22 100644 --- a/src/blah_time.cpp +++ b/src/blah_time.cpp @@ -12,8 +12,8 @@ float Time::pause_timer = 0; u64 Time::get_ticks() { - if (Internal::platform) - return Internal::platform->ticks(); + if (App::is_running()) + return Platform::ticks(); return 0; } diff --git a/src/internal/blah_internal.h b/src/internal/blah_internal.h index 2a0bf70..e9a4072 100644 --- a/src/internal/blah_internal.h +++ b/src/internal/blah_internal.h @@ -2,19 +2,18 @@ #include "blah_renderer.h" #include "blah_platform.h" -#define BLAH_ASSERT_RENDERER() BLAH_ASSERT(Blah::Internal::renderer, "Renderer has not been created") -#define BLAH_ASSERT_PLATFORM() BLAH_ASSERT(Blah::Internal::platform, "Platform has not been created") +#define BLAH_ASSERT_RENDERER() BLAH_ASSERT(Blah::Internal::app_renderer(), "Renderer has not been created") +#define BLAH_ASSERT_RUNNING() BLAH_ASSERT(Blah::App::is_running(), "The App is not running (call App::run)") namespace Blah { namespace Internal { - extern Platform* platform; - extern Renderer* renderer; extern bool audio_is_init; void app_step(); void app_shutdown(); + Renderer* app_renderer(); void input_init(); void input_step_state(); diff --git a/src/internal/blah_platform.h b/src/internal/blah_platform.h index 845fefc..b636c37 100644 --- a/src/internal/blah_platform.h +++ b/src/internal/blah_platform.h @@ -8,112 +8,105 @@ namespace Blah { struct Config; - class Platform + namespace Platform { - public: - - virtual ~Platform() = default; - // Initialize the Graphics - virtual bool init(const Config& config) = 0; + bool init(const Config& config); // Called after the on_startup callback, but before the update loop begins - virtual void ready() = 0; + void ready(); // Called during shutdown - virtual void shutdown() = 0; + void shutdown(); // The time, in ticks (microseconds) since the Application was started - virtual u64 ticks() = 0; + u64 ticks(); // Called every frame - virtual void update(InputState& state) = 0; + void update(InputState& state); // Sleeps the current thread - virtual void sleep(int milliseconds) = 0; + void sleep(int milliseconds); // Called to present the window contents - virtual void present() = 0; + void present(); // Called when the App sets flags - virtual void set_app_flags(u32 flags) = 0; + void set_app_flags(u32 flags); // Gets the Application Window Title in UTF-8 - virtual const char* get_title() = 0; + const char* get_title(); // Sets the Application Window Title in UTF-8 - virtual void set_title(const char* title) = 0; + void set_title(const char* title); // Gets the Application Window Position, in Screen Coordinates - virtual void get_position(int* x, int* y) = 0; + void get_position(int* x, int* y); // Sets the Application Window Position, in Screen Coordinates - virtual void set_position(int x, int y) = 0; + void set_position(int x, int y); // Gets whether the Window has focus - virtual bool get_focused() = 0; + bool get_focused(); // Gets the Application Window Size, in Screen Coordinates - virtual void get_size(int* width, int* height) = 0; + void get_size(int* width, int* height); // Sets the Application Window Size, in Screen Coordinates - virtual void set_size(int width, int height) = 0; + void set_size(int width, int height); // Gets the Application Window Drawing Size, in Pixels. This may differ from the Window Size on hi-dpi displays. - virtual void get_draw_size(int* width, int* height) = 0; + void get_draw_size(int* width, int* height); // Gets the Desktop Content Scale. Gui should be scaled by this value - virtual float get_content_scale() = 0; + float get_content_scale(); // Returns the absolute path to the directory that the application was started from - virtual const char* app_path() = 0; + const char* app_path(); // Returns the absolute path to the user directory where save data and settings should be stored - virtual const char* user_path() = 0; + const char* user_path(); // Opens a file and sets the handle, or returns an empty handle if it fails - virtual FileRef file_open(const char* path, FileMode mode) = 0; + FileRef file_open(const char* path, FileMode mode); // Returns true if a file with the given path exists - virtual bool file_exists(const char* path) = 0; + bool file_exists(const char* path); // Returns true if a file with the given path was deleted - virtual bool file_delete(const char* path) = 0; + bool file_delete(const char* path); // Returns true if a directory with the given path was successfully created - virtual bool dir_create(const char* path) = 0; + bool dir_create(const char* path); // Returns true if a directory with the given path exists - virtual bool dir_exists(const char* path) = 0; + bool dir_exists(const char* path); // Returns true if a directory with the given path was deleted - virtual bool dir_delete(const char* path) = 0; + bool dir_delete(const char* path); // enumerates a directory and appends each file to the given list - virtual void dir_enumerate(Vector& list, const char* path, bool recursive) = 0; + void dir_enumerate(Vector& list, const char* path, bool recursive); // opens a directory in the OS file explorer / finder - virtual void dir_explore(const char* path) = 0; + void dir_explore(const char* path); // sets the contents of the clipboard - virtual void set_clipboard(const char* text) = 0; + void set_clipboard(const char* text); // gets the contents of the clipboard into the given string - virtual const char* get_clipboard() = 0; + const char* get_clipboard(); // Tries to open a URL in a web browser - virtual void open_url(const char* url) = 0; + void open_url(const char* url); // OpenGL Methods - virtual void* gl_get_func(const char* name) = 0; - virtual void* gl_context_create() = 0; - virtual void gl_context_make_current(void* context) = 0; - virtual void gl_context_destroy(void* context) = 0; + void* gl_get_func(const char* name); + void* gl_context_create(); + void gl_context_make_current(void* context); + void gl_context_destroy(void* context); // D3D11 Methods - virtual void* d3d11_get_hwnd() = 0; - - // Instantiates the Platform object - static Platform* try_make_platform(const Config& config); + void* d3d11_get_hwnd(); }; } \ No newline at end of file diff --git a/src/internal/blah_platform_sdl2.cpp b/src/internal/blah_platform_sdl2.cpp index 5ef7b9f..1160e91 100644 --- a/src/internal/blah_platform_sdl2.cpp +++ b/src/internal/blah_platform_sdl2.cpp @@ -71,67 +71,18 @@ namespace Blah size_t write(const void* buffer, size_t length) override { return SDL_RWwrite(handle, buffer, sizeof(char), length); } }; - struct SDL2_Platform : public Platform - { - SDL_Window* window = nullptr; - SDL_Joystick* joysticks[Input::max_controllers]; - SDL_GameController* gamepads[Input::max_controllers]; - char* base_path_value = nullptr; - char* user_path_value = nullptr; - char* clipboard_text = nullptr; - bool displayed = false; - - SDL2_Platform(); - bool init(const Config& config) override; - void ready() override; - void shutdown() override; - u64 ticks() override; - void update(InputState& state) override; - void sleep(int milliseconds) override; - void present() override; - void set_app_flags(u32 flags) override; - const char* get_title() override; - void set_title(const char* title) override; - void get_position(int* x, int* y) override; - void set_position(int x, int y) override; - bool get_focused() override; - void get_size(int* width, int* height) override; - void set_size(int width, int height) override; - void get_draw_size(int* width, int* height) override; - float get_content_scale() override; - const char* app_path() override; - const char* user_path() override; - FileRef file_open(const char* path, FileMode mode) override; - bool file_exists(const char* path) override; - bool file_delete(const char* path) override; - bool dir_create(const char* path) override; - bool dir_exists(const char* path) override; - bool dir_delete(const char* path) override; - void dir_enumerate(Vector& list, const char* path, bool recursive) override; - void dir_explore(const char* path) override; - void set_clipboard(const char* text) override; - const char* get_clipboard() override; - void open_url(const char* url) override; - void* gl_get_func(const char* name) override; - void* gl_context_create() override; - void gl_context_make_current(void* context) override; - void gl_context_destroy(void* context) override; - void* d3d11_get_hwnd() override; - }; + SDL_Window* sdl2_window = nullptr; + SDL_Joystick* sdl2_joysticks[Input::max_controllers]; + SDL_GameController* sdl2_gamepads[Input::max_controllers]; + char* sdl2_base_path_value = nullptr; + char* sdl2_user_path_value = nullptr; + char* sdl2_clipboard_text = nullptr; + bool sdl2_displayed = false; } using namespace Blah; -SDL2_Platform::SDL2_Platform() -{ - for (int i = 0; i < Input::max_controllers; i++) - { - joysticks[i] = nullptr; - gamepads[i] = nullptr; - } -} - -bool SDL2_Platform::init(const Config& config) +bool Platform::init(const Config& config) { // TODO: // control this via some kind of config flag @@ -185,54 +136,60 @@ bool SDL2_Platform::init(const Config& config) } // create the window - window = SDL_CreateWindow(config.name, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, config.width, config.height, flags); - if (window == nullptr) + sdl2_window = SDL_CreateWindow(config.name, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, config.width, config.height, flags); + if (sdl2_window == nullptr) { Log::error("Failed to create a Window"); return false; } + for (int i = 0; i < Input::max_controllers; i++) + { + sdl2_joysticks[i] = nullptr; + sdl2_gamepads[i] = nullptr; + } + return true; } -void SDL2_Platform::ready() +void Platform::ready() { } -void SDL2_Platform::shutdown() +void Platform::shutdown() { - if (window != nullptr) - SDL_DestroyWindow(window); - window = nullptr; - displayed = false; + if (sdl2_window != nullptr) + SDL_DestroyWindow(sdl2_window); + sdl2_window = nullptr; + sdl2_displayed = false; - if (base_path_value != nullptr) - SDL_free(base_path_value); + if (sdl2_base_path_value != nullptr) + SDL_free(sdl2_base_path_value); - if (user_path_value != nullptr) - SDL_free(user_path_value); + if (sdl2_user_path_value != nullptr) + SDL_free(sdl2_user_path_value); - if (clipboard_text != nullptr) - SDL_free(clipboard_text); + if (sdl2_clipboard_text != nullptr) + SDL_free(sdl2_clipboard_text); SDL_Quit(); } -u64 SDL2_Platform::ticks() +u64 Platform::ticks() { auto counter = SDL_GetPerformanceCounter(); auto per_second = (double)SDL_GetPerformanceFrequency(); return (u64)(counter * (Time::ticks_per_second / per_second)); } -void SDL2_Platform::update(InputState& state) +void Platform::update(InputState& state) { // update the mouse every frame { int win_x, win_y, x, y; - SDL_GetWindowPosition(window, &win_x, &win_y); + SDL_GetWindowPosition(sdl2_window, &win_x, &win_y); SDL_GetGlobalMouseState(&x, &y); state.mouse.on_move( @@ -301,7 +258,7 @@ void SDL2_Platform::update(InputState& state) if (SDL_IsGameController(index) == SDL_FALSE && index >= 0 && index < Input::max_controllers) { - auto ptr = joysticks[index] = SDL_JoystickOpen(index); + auto ptr = sdl2_joysticks[index] = SDL_JoystickOpen(index); auto name = SDL_JoystickName(ptr); auto button_count = SDL_JoystickNumButtons(ptr); auto axis_count = SDL_JoystickNumAxes(ptr); @@ -314,19 +271,19 @@ void SDL2_Platform::update(InputState& state) } else if (event.type == SDL_JOYDEVICEREMOVED) { - auto index = blah_sdl_find_joystick_index(joysticks, event.jdevice.which); + auto index = blah_sdl_find_joystick_index(sdl2_joysticks, event.jdevice.which); if (index >= 0) { if (SDL_IsGameController(index) == SDL_FALSE) { state.controllers[index].on_disconnect(); - SDL_JoystickClose(joysticks[index]); + SDL_JoystickClose(sdl2_joysticks[index]); } } } else if (event.type == SDL_JOYBUTTONDOWN) { - auto index = blah_sdl_find_joystick_index(joysticks, event.jdevice.which); + auto index = blah_sdl_find_joystick_index(sdl2_joysticks, event.jdevice.which); if (index >= 0) { if (SDL_IsGameController(index) == SDL_FALSE) @@ -335,7 +292,7 @@ void SDL2_Platform::update(InputState& state) } else if (event.type == SDL_JOYBUTTONUP) { - auto index = blah_sdl_find_joystick_index(joysticks, event.jdevice.which); + auto index = blah_sdl_find_joystick_index(sdl2_joysticks, event.jdevice.which); if (index >= 0) { if (SDL_IsGameController(index) == SDL_FALSE) @@ -344,7 +301,7 @@ void SDL2_Platform::update(InputState& state) } else if (event.type == SDL_JOYAXISMOTION) { - auto index = blah_sdl_find_joystick_index(joysticks, event.jdevice.which); + auto index = blah_sdl_find_joystick_index(sdl2_joysticks, event.jdevice.which); if (index >= 0) { if (SDL_IsGameController(index) == SDL_FALSE) @@ -364,7 +321,7 @@ void SDL2_Platform::update(InputState& state) auto index = event.cdevice.which; if (index >= 0 && index < Input::max_controllers) { - auto ptr = gamepads[index] = SDL_GameControllerOpen(index); + auto ptr = sdl2_gamepads[index] = SDL_GameControllerOpen(index); auto name = SDL_GameControllerName(ptr); auto vendor = SDL_GameControllerGetVendor(ptr); auto product = SDL_GameControllerGetProduct(ptr); @@ -375,16 +332,16 @@ void SDL2_Platform::update(InputState& state) } else if (event.type == SDL_CONTROLLERDEVICEREMOVED) { - auto index = blah_sdl_find_gamepad_index(gamepads, event.cdevice.which); + auto index = blah_sdl_find_gamepad_index(sdl2_gamepads, event.cdevice.which); if (index >= 0) { state.controllers[index].on_disconnect(); - SDL_GameControllerClose(gamepads[index]); + SDL_GameControllerClose(sdl2_gamepads[index]); } } else if (event.type == SDL_CONTROLLERBUTTONDOWN) { - auto index = blah_sdl_find_gamepad_index(gamepads, event.cdevice.which); + auto index = blah_sdl_find_gamepad_index(sdl2_gamepads, event.cdevice.which); if (index >= 0) { Button button = Button::None; @@ -396,7 +353,7 @@ void SDL2_Platform::update(InputState& state) } else if (event.type == SDL_CONTROLLERBUTTONUP) { - auto index = blah_sdl_find_gamepad_index(gamepads, event.cdevice.which); + auto index = blah_sdl_find_gamepad_index(sdl2_gamepads, event.cdevice.which); if (index >= 0) { Button button = Button::None; @@ -408,7 +365,7 @@ void SDL2_Platform::update(InputState& state) } else if (event.type == SDL_CONTROLLERAXISMOTION) { - auto index = blah_sdl_find_gamepad_index(gamepads, event.cdevice.which); + auto index = blah_sdl_find_gamepad_index(sdl2_gamepads, event.cdevice.which); if (index >= 0) { Axis axis = Axis::None; @@ -427,33 +384,33 @@ void SDL2_Platform::update(InputState& state) } } -void SDL2_Platform::sleep(int milliseconds) +void Platform::sleep(int milliseconds) { if (milliseconds >= 0) SDL_Delay((u32)milliseconds); } -void SDL2_Platform::present() +void Platform::present() { if (App::renderer().type == RendererType::OpenGL) - SDL_GL_SwapWindow(window); + SDL_GL_SwapWindow(sdl2_window); // display the window // this avoids a short black screen on macOS - if (!displayed) + if (!sdl2_displayed) { - SDL_ShowWindow(window); - displayed = true; + SDL_ShowWindow(sdl2_window); + sdl2_displayed = true; } } -void SDL2_Platform::set_app_flags(u32 flags) +void Platform::set_app_flags(u32 flags) { // Toggle Fullscreen - SDL_SetWindowFullscreen(window, ((flags & Flags::Fullscreen) != 0) ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); + SDL_SetWindowFullscreen(sdl2_window, ((flags & Flags::Fullscreen) != 0) ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); // Toggle Resizable - SDL_SetWindowResizable(window, ((flags & Flags::Resizable) != 0) ? SDL_TRUE : SDL_FALSE); + SDL_SetWindowResizable(sdl2_window, ((flags & Flags::Resizable) != 0) ? SDL_TRUE : SDL_FALSE); // Toggle V-Sync for OpenGL #ifndef __EMSCRIPTEN__ @@ -462,57 +419,57 @@ void SDL2_Platform::set_app_flags(u32 flags) #endif } -const char* SDL2_Platform::get_title() +const char* Platform::get_title() { - return SDL_GetWindowTitle(window); + return SDL_GetWindowTitle(sdl2_window); } -void SDL2_Platform::set_title(const char* title) +void Platform::set_title(const char* title) { - SDL_SetWindowTitle(window, title); + SDL_SetWindowTitle(sdl2_window, title); } -void SDL2_Platform::get_position(int* x, int* y) +void Platform::get_position(int* x, int* y) { - SDL_GetWindowPosition(window, x, y); + SDL_GetWindowPosition(sdl2_window, x, y); } -void SDL2_Platform::set_position(int x, int y) +void Platform::set_position(int x, int y) { - SDL_SetWindowPosition(window, x, y); + SDL_SetWindowPosition(sdl2_window, x, y); } -bool SDL2_Platform::get_focused() +bool Platform::get_focused() { - auto flags = SDL_GetWindowFlags(window); + auto flags = SDL_GetWindowFlags(sdl2_window); return (flags & SDL_WINDOW_INPUT_FOCUS) != 0 && (flags & SDL_WINDOW_MINIMIZED) == 0; } -void SDL2_Platform::get_size(int* width, int* height) +void Platform::get_size(int* width, int* height) { - SDL_GetWindowSize(window, width, height); + SDL_GetWindowSize(sdl2_window, width, height); } -void SDL2_Platform::set_size(int width, int height) +void Platform::set_size(int width, int height) { - SDL_SetWindowSize(window, width, height); + SDL_SetWindowSize(sdl2_window, width, height); } -void SDL2_Platform::get_draw_size(int* width, int* height) +void Platform::get_draw_size(int* width, int* height) { switch (App::renderer().type) { case RendererType::OpenGL: - SDL_GL_GetDrawableSize(window, width, height); + SDL_GL_GetDrawableSize(sdl2_window, width, height); break; case RendererType::None: case RendererType::D3D11: - SDL_GetWindowSize(window, width, height); + SDL_GetWindowSize(sdl2_window, width, height); break; } } -float SDL2_Platform::get_content_scale() +float Platform::get_content_scale() { // TODO: // This is incorrect! but for some reason the scale @@ -525,7 +482,7 @@ float SDL2_Platform::get_content_scale() // is there a way to get this value properly? My Windows & Linux PC's both seem to thing 96 is correct const float hidpi_res = 96; - int index = SDL_GetWindowDisplayIndex(window); + int index = SDL_GetWindowDisplayIndex(sdl2_window); if (index < 0) { Log::error(SDL_GetError()); @@ -542,25 +499,25 @@ float SDL2_Platform::get_content_scale() return (ddpi / hidpi_res); } -const char* SDL2_Platform::app_path() +const char* Platform::app_path() { - if (base_path_value == nullptr) - base_path_value = SDL_GetBasePath(); - return base_path_value; + if (sdl2_base_path_value == nullptr) + sdl2_base_path_value = SDL_GetBasePath(); + return sdl2_base_path_value; } -const char* SDL2_Platform::user_path() +const char* Platform::user_path() { - if (user_path_value == nullptr) + if (sdl2_user_path_value == nullptr) { auto& config = App::config(); - user_path_value = SDL_GetPrefPath(nullptr, config.name); + sdl2_user_path_value = SDL_GetPrefPath(nullptr, config.name); } - return user_path_value; + return sdl2_user_path_value; } -FileRef SDL2_Platform::file_open(const char* path, FileMode mode) +FileRef Platform::file_open(const char* path, FileMode mode) { const char* sdl_mode = ""; @@ -587,32 +544,32 @@ FileRef SDL2_Platform::file_open(const char* path, FileMode mode) return FileRef(new SDL2_File(ptr)); } -bool SDL2_Platform::file_exists(const char* path) +bool Platform::file_exists(const char* path) { return std::filesystem::is_regular_file(path); } -bool SDL2_Platform::file_delete(const char* path) +bool Platform::file_delete(const char* path) { return std::filesystem::remove(path); } -bool SDL2_Platform::dir_create(const char* path) +bool Platform::dir_create(const char* path) { return std::filesystem::create_directories(path); } -bool SDL2_Platform::dir_exists(const char* path) +bool Platform::dir_exists(const char* path) { return std::filesystem::is_directory(path); } -bool SDL2_Platform::dir_delete(const char* path) +bool Platform::dir_delete(const char* path) { return std::filesystem::remove_all(path) > 0; } -void SDL2_Platform::dir_enumerate(Vector& list, const char* path, bool recursive) +void Platform::dir_enumerate(Vector& list, const char* path, bool recursive) { if (std::filesystem::is_directory(path)) { @@ -629,7 +586,7 @@ void SDL2_Platform::dir_enumerate(Vector& list, const char* path, bool } } -void SDL2_Platform::dir_explore(const char* path) +void Platform::dir_explore(const char* path) { #if _WIN32 @@ -646,64 +603,59 @@ void SDL2_Platform::dir_explore(const char* path) #endif } -void SDL2_Platform::set_clipboard(const char* text) +void Platform::set_clipboard(const char* text) { SDL_SetClipboardText(text); } -const char* SDL2_Platform::get_clipboard() +const char* Platform::get_clipboard() { // free previous clipboard text - if (clipboard_text != nullptr) - SDL_free(clipboard_text); + if (sdl2_clipboard_text != nullptr) + SDL_free(sdl2_clipboard_text); - clipboard_text = SDL_GetClipboardText(); - return clipboard_text; + sdl2_clipboard_text = SDL_GetClipboardText(); + return sdl2_clipboard_text; } -void* SDL2_Platform::gl_get_func(const char* name) +void* Platform::gl_get_func(const char* name) { return SDL_GL_GetProcAddress(name); } -void* SDL2_Platform::gl_context_create() +void* Platform::gl_context_create() { - void* pointer = SDL_GL_CreateContext(window); + void* pointer = SDL_GL_CreateContext(sdl2_window); if (pointer == nullptr) Log::error("SDL_GL_CreateContext failed: %s", SDL_GetError()); return pointer; } -void SDL2_Platform::gl_context_make_current(void* context) +void Platform::gl_context_make_current(void* context) { - SDL_GL_MakeCurrent(window, context); + SDL_GL_MakeCurrent(sdl2_window, context); } -void SDL2_Platform::gl_context_destroy(void* context) +void Platform::gl_context_destroy(void* context) { SDL_GL_DeleteContext(context); } -void* SDL2_Platform::d3d11_get_hwnd() +void* Platform::d3d11_get_hwnd() { #if _WIN32 SDL_SysWMinfo info; SDL_VERSION(&info.version); - SDL_GetWindowWMInfo(window, &info); + SDL_GetWindowWMInfo(sdl2_window, &info); return info.info.win.window; #else return nullptr; #endif } -void SDL2_Platform::open_url(const char* url) +void Platform::open_url(const char* url) { SDL_OpenURL(url); } -Platform* Platform::try_make_platform(const Config& config) -{ - return new SDL2_Platform(); -} - #endif // BLAH_PLATFORM_SDL2 diff --git a/src/internal/blah_platform_win32.cpp b/src/internal/blah_platform_win32.cpp index e73e457..75ad55f 100644 --- a/src/internal/blah_platform_win32.cpp +++ b/src/internal/blah_platform_win32.cpp @@ -48,89 +48,50 @@ namespace Blah size_t write(const void* buffer, size_t length) override; }; - struct Win32_Platform : public Platform + // Main State + HWND win32_hwnd; + FilePath win32_working_directory; + FilePath win32_user_directory; + Duration win32_start_time; + RECT win32_windowed_position; + bool win32_fullscreen = false; + InputState* win32_input_state = nullptr; + String win32_clipboard; + + // XInput + struct { - // Main State - HWND hwnd; - FilePath working_directory; - FilePath user_directory; - Duration start_time; - RECT windowed_position; - bool fullscreen = false; - InputState* input_state = nullptr; - String clipboard; + HMODULE dll; + XInputGetCapabilities_fn get_capabilities; + XInputGetState_fn get_state; + } win32_xinput; - // XInput - struct - { - HMODULE dll; - XInputGetCapabilities_fn get_capabilities; - XInputGetState_fn get_state; - } xinput; + struct Joystick + { + bool connected = false; + bool accounted = false; + GUID dinstance = GUID_NULL; + DWORD xindex = 0; + } win32_joysticks[Input::max_controllers]; - struct Joystick - { - bool connected = false; - bool accounted = false; - GUID dinstance = GUID_NULL; - DWORD xindex = 0; - } joysticks[Input::max_controllers]; - - // OpenGL Methods - // These are only loaded if built using the OpenGL Backend - struct - { - HMODULE dll; - wglGetProcAddress_fn get_proc_address; - wglCreateContext_fn create_context; - wglDeleteContext_fn delete_context; - wglMakeCurrent_fn make_current; - } gl; - - bool init(const Config& config) override; - void ready() override; - void shutdown() override; - u64 ticks() override; - void update(InputState& state) override; - void sleep(int milliseconds) override; - void present() override; - const char* get_title() override; - void set_title(const char* title) override; - void get_position(int* x, int* y) override; - void set_position(int x, int y) override; - bool get_focused() override; - void set_app_flags(u32 flags) override; - void get_size(int* width, int* height) override; - void set_size(int width, int height) override; - void get_draw_size(int* width, int* height) override; - float get_content_scale() override; - const char* app_path() override; - const char* user_path() override; - FileRef file_open(const char* path, FileMode mode) override; - bool file_exists(const char* path) override; - bool file_delete(const char* path) override; - bool dir_create(const char* path) override; - bool dir_exists(const char* path) override; - bool dir_delete(const char* path) override; - void dir_enumerate(Vector& list, const char* path, bool recursive) override; - void dir_explore(const char* path) override; - void set_clipboard(const char* text) override; - const char* get_clipboard() override; - void open_url(const char* url) override; - void* gl_get_func(const char* name) override; - void* gl_context_create() override; - void gl_context_make_current(void* context) override; - void gl_context_destroy(void* context) override; - void* d3d11_get_hwnd() override; - - void detect_joysticks(); - }; + // OpenGL Methods + // These are only loaded if built using the OpenGL Backend + struct + { + HMODULE dll; + wglGetProcAddress_fn get_proc_address; + wglCreateContext_fn create_context; + wglDeleteContext_fn delete_context; + wglMakeCurrent_fn make_current; + } win32_gl; // Main Windows Procedure callback - LRESULT CALLBACK win32_window_procedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + LRESULT CALLBACK win32_window_procedure(HWND win32_hwnd, UINT msg, WPARAM wParam, LPARAM lParam); // Converts Windows scancode to Blah key Key win32_scancode_to_key(WPARAM wParam, LPARAM lParam); + + void win32_detect_joysticks(); } using namespace Blah; @@ -194,7 +155,7 @@ size_t Win32File::read(void* buffer, size_t length) to_read = (DWORD)(length - read); DWORD moved = 0; - if (ReadFile(m_handle, (char *)buffer + read, to_read, &moved, NULL)) + if (ReadFile(m_handle, (char*)buffer + read, to_read, &moved, NULL)) read += moved; if (moved < to_read) @@ -217,7 +178,7 @@ size_t Win32File::write(const void* buffer, size_t length) to_write = (DWORD)(length - written); DWORD moved = 0; - if (WriteFile(m_handle, (char *)buffer + written, to_write, &moved, NULL)) + if (WriteFile(m_handle, (char*)buffer + written, to_write, &moved, NULL)) written += moved; if (moved < to_write) @@ -227,7 +188,7 @@ size_t Win32File::write(const void* buffer, size_t length) return written; } -bool Win32_Platform::init(const Config& config) +bool Platform::init(const Config& config) { // Required to call this for Windows SetProcessDPIAware(); @@ -252,10 +213,10 @@ bool Win32_Platform::init(const Config& config) RegisterClass(&wc); // Create the Window Instance - hwnd = CreateWindow("BLAH WINDOW", config.name, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 640, 480, NULL, NULL, hInstance, NULL); + win32_hwnd = CreateWindow("BLAH WINDOW", config.name, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 640, 480, NULL, NULL, hInstance, NULL); // Failed to create the Window - if (hwnd == NULL) + if (win32_hwnd == NULL) { Log::error("Window Creation Failed"); return false; @@ -273,18 +234,18 @@ bool Win32_Platform::init(const Config& config) if (config.renderer_type == RendererType::OpenGL) { // Load the DLL - gl.dll = LoadLibraryA("opengl32.dll"); - if (gl.dll == NULL) + win32_gl.dll = LoadLibraryA("opengl32.dll"); + if (win32_gl.dll == NULL) { Log::error("OpenGL Instantiation Failed - unable to fine opengl32.dll"); return false; } // Get the Windows GL functions we need - gl.get_proc_address = (wglGetProcAddress_fn)GetProcAddress(gl.dll, "wglGetProcAddress"); - gl.create_context = (wglCreateContext_fn)GetProcAddress(gl.dll, "wglCreateContext"); - gl.delete_context = (wglDeleteContext_fn)GetProcAddress(gl.dll, "wglDeleteContext"); - gl.make_current = (wglMakeCurrent_fn)GetProcAddress(gl.dll, "wglMakeCurrent"); + win32_gl.get_proc_address = (wglGetProcAddress_fn)GetProcAddress(win32_gl.dll, "wglGetProcAddress"); + win32_gl.create_context = (wglCreateContext_fn)GetProcAddress(win32_gl.dll, "wglCreateContext"); + win32_gl.delete_context = (wglDeleteContext_fn)GetProcAddress(win32_gl.dll, "wglDeleteContext"); + win32_gl.make_current = (wglMakeCurrent_fn)GetProcAddress(win32_gl.dll, "wglMakeCurrent"); // TODO: // Allow the user to apply (some of) these values before instantiation. @@ -312,7 +273,7 @@ bool Win32_Platform::init(const Config& config) 0, 0, 0 // layer masks ignored }; - HDC hdc = GetDC(hwnd); + HDC hdc = GetDC(win32_hwnd); // get the best available match of pixel format for the device context int pixel_format = ChoosePixelFormat(hdc, &pfd); @@ -327,17 +288,17 @@ bool Win32_Platform::init(const Config& config) for (int i = 0; dlls[i]; i++) { - xinput.dll = LoadLibraryA(dlls[i]); + win32_xinput.dll = LoadLibraryA(dlls[i]); - if (xinput.dll) + if (win32_xinput.dll) { - xinput.get_capabilities = (XInputGetCapabilities_fn)GetProcAddress(xinput.dll, "XInputGetCapabilities"); - xinput.get_state = (XInputGetState_fn)GetProcAddress(xinput.dll, "XInputGetState"); + win32_xinput.get_capabilities = (XInputGetCapabilities_fn)GetProcAddress(win32_xinput.dll, "XInputGetCapabilities"); + win32_xinput.get_state = (XInputGetState_fn)GetProcAddress(win32_xinput.dll, "XInputGetState"); break; } } - if (!xinput.dll) + if (!win32_xinput.dll) Log::warn("Failed to find XInput dll; No Controller Support"); } @@ -349,10 +310,10 @@ bool Win32_Platform::init(const Config& config) auto normalized = Path::normalize(buffer); auto end = normalized.last_index_of('/');; if (end >= 0) - working_directory = FilePath(normalized.begin(), normalized.begin() + end); + win32_working_directory = FilePath(normalized.begin(), normalized.begin() + end); else - working_directory = normalized; - working_directory.append("/"); + win32_working_directory = normalized; + win32_working_directory.append("/"); } // Get Application User Directory @@ -366,56 +327,56 @@ bool Win32_Platform::init(const Config& config) FilePath result; result.append((u16*)path, (u16*)end); - user_directory = Path::join(Path::normalize(result), config.name) + "/"; + win32_user_directory = Path::join(Path::normalize(result), config.name) + "/"; } CoTaskMemFree(path); } // Reset our game timer - start_time = std::chrono::system_clock::now().time_since_epoch(); + win32_start_time = std::chrono::system_clock::now().time_since_epoch(); - // Not currently fullscreen - fullscreen = false; + // Not currently win32_fullscreen + win32_fullscreen = false; // Finished Platform Setup return true; } -void Win32_Platform::ready() +void Platform::ready() { // Display the game window - ShowWindow(hwnd, SW_SHOW); + ShowWindow(win32_hwnd, SW_SHOW); } -void Win32_Platform::shutdown() +void Platform::shutdown() { - if (xinput.dll) - FreeLibrary(xinput.dll); + if (win32_xinput.dll) + FreeLibrary(win32_xinput.dll); - if (gl.dll) - FreeLibrary(gl.dll); + if (win32_gl.dll) + FreeLibrary(win32_gl.dll); - DestroyWindow(hwnd); + DestroyWindow(win32_hwnd); } -u64 Win32_Platform::ticks() +u64 Platform::ticks() { // Todo: // This should account for whatever Time::ticks_per_second is set to auto now = std::chrono::system_clock::now().time_since_epoch(); - return std::chrono::duration_cast(now - start_time).count(); + return std::chrono::duration_cast(now - win32_start_time).count(); } -void Win32_Platform::update(InputState& state) +void Platform::update(InputState& state) { // store reference to input state - bool first_update = input_state == nullptr; - input_state = &state; + bool first_update = win32_input_state == nullptr; + win32_input_state = &state; // if this is the first update, poll joysticks that are already connected if (first_update) - detect_joysticks(); + win32_detect_joysticks(); // Catch & Dispatch Window Messages MSG msg; @@ -426,82 +387,82 @@ void Win32_Platform::update(InputState& state) } } -void Win32_Platform::sleep(int milliseconds) +void Platform::sleep(int milliseconds) { if (milliseconds > 0) Sleep(milliseconds); } -void Win32_Platform::present() +void Platform::present() { if (App::renderer().type == RendererType::OpenGL) { - HDC hdc = GetDC(hwnd); + HDC hdc = GetDC(win32_hwnd); SwapBuffers(hdc); } } -const char* Win32_Platform::get_title() +const char* Platform::get_title() { return nullptr; } -void Win32_Platform::set_title(const char* title) +void Platform::set_title(const char* title) { - SetWindowText(hwnd, title); + SetWindowText(win32_hwnd, title); } -void Win32_Platform::get_position(int* x, int* y) +void Platform::get_position(int* x, int* y) { RECT rect; - if (GetWindowRect(hwnd, &rect)) + if (GetWindowRect(win32_hwnd, &rect)) { *x = rect.left; *y = rect.top; } } -void Win32_Platform::set_position(int x, int y) +void Platform::set_position(int x, int y) { int w, h; get_size(&w, &h); - SetWindowPos(hwnd, NULL, x, y, w, h, 0); + SetWindowPos(win32_hwnd, NULL, x, y, w, h, 0); } -bool Win32_Platform::get_focused() +bool Platform::get_focused() { Log::warn("App::focused not implemented for Win32 yet"); return true; } -void Win32_Platform::set_app_flags(u32 flags) +void Platform::set_app_flags(u32 flags) { - // toggle fullscreen + // toggle win32_fullscreen { bool enabled = (flags & Flags::Fullscreen) != 0; - if (fullscreen == enabled) + if (win32_fullscreen == enabled) return; - fullscreen = enabled; + win32_fullscreen = enabled; - if (fullscreen) + if (win32_fullscreen) { - GetWindowRect(hwnd, &windowed_position); + GetWindowRect(win32_hwnd, &win32_windowed_position); int w = GetSystemMetrics(SM_CXSCREEN); int h = GetSystemMetrics(SM_CYSCREEN); - SetWindowLongPtr(hwnd, GWL_STYLE, WS_VISIBLE | WS_POPUP); - SetWindowPos(hwnd, HWND_TOP, 0, 0, w, h, 0); - ShowWindow(hwnd, SW_SHOW); + SetWindowLongPtr(win32_hwnd, GWL_STYLE, WS_VISIBLE | WS_POPUP); + SetWindowPos(win32_hwnd, HWND_TOP, 0, 0, w, h, 0); + ShowWindow(win32_hwnd, SW_SHOW); } else { - SetWindowLongPtr(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW); - SetWindowPos(hwnd, HWND_TOP, - windowed_position.left, - windowed_position.top, - windowed_position.right - windowed_position.left, - windowed_position.bottom - windowed_position.top, 0); - ShowWindow(hwnd, SW_SHOW); + SetWindowLongPtr(win32_hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW); + SetWindowPos(win32_hwnd, HWND_TOP, + win32_windowed_position.left, + win32_windowed_position.top, + win32_windowed_position.right - win32_windowed_position.left, + win32_windowed_position.bottom - win32_windowed_position.top, 0); + ShowWindow(win32_hwnd, SW_SHOW); } } @@ -509,88 +470,88 @@ void Win32_Platform::set_app_flags(u32 flags) // TODO: ... } -void Win32_Platform::get_size(int* width, int* height) +void Platform::get_size(int* width, int* height) { RECT rect; - if (GetClientRect(hwnd, &rect)) + if (GetClientRect(win32_hwnd, &rect)) { *width = rect.right - rect.left; *height = rect.bottom - rect.top; } } -void Win32_Platform::set_size(int width, int height) +void Platform::set_size(int width, int height) { RECT client_rect; RECT border_rect; - GetClientRect(hwnd, &client_rect); - GetWindowRect(hwnd, &border_rect); + GetClientRect(win32_hwnd, &client_rect); + GetWindowRect(win32_hwnd, &border_rect); int border_width = (border_rect.right - border_rect.left) - (client_rect.right - client_rect.left); int border_height = (border_rect.bottom - border_rect.top) - (client_rect.bottom - client_rect.top); - SetWindowPos(hwnd, NULL, border_rect.left, border_rect.top, width + border_width, height + border_height, 0); + SetWindowPos(win32_hwnd, NULL, border_rect.left, border_rect.top, width + border_width, height + border_height, 0); } -void Win32_Platform::get_draw_size(int* width, int* height) +void Platform::get_draw_size(int* width, int* height) { RECT rect; - if (GetClientRect(hwnd, &rect)) + if (GetClientRect(win32_hwnd, &rect)) { *width = rect.right - rect.left; *height = rect.bottom - rect.top; } } -float Win32_Platform::get_content_scale() +float Platform::get_content_scale() { // base value of Windows DPI // as seen here: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdpiforwindow constexpr float base_raw_value = 96.0f; - UINT raw_value = GetDpiForWindow(hwnd); + UINT raw_value = GetDpiForWindow(win32_hwnd); return (raw_value / base_raw_value); } -const char* Win32_Platform::app_path() +const char* Platform::app_path() { - return working_directory.cstr(); + return win32_working_directory.cstr(); } -const char* Win32_Platform::user_path() +const char* Platform::user_path() { - return user_directory.cstr(); + return win32_user_directory.cstr(); } -bool Win32_Platform::file_exists(const char* path) +bool Platform::file_exists(const char* path) { return std::filesystem::is_regular_file(path); } -bool Win32_Platform::file_delete(const char* path) +bool Platform::file_delete(const char* path) { return std::filesystem::remove(path); } -bool Win32_Platform::dir_create(const char* path) +bool Platform::dir_create(const char* path) { std::error_code error; return std::filesystem::create_directories(path, error); } -bool Win32_Platform::dir_exists(const char* path) +bool Platform::dir_exists(const char* path) { return std::filesystem::is_directory(path); } -bool Win32_Platform::dir_delete(const char* path) +bool Platform::dir_delete(const char* path) { return std::filesystem::remove_all(path) > 0; } -void Win32_Platform::dir_enumerate(Vector& list, const char* path, bool recursive) +void Platform::dir_enumerate(Vector& list, const char* path, bool recursive) { if (std::filesystem::is_directory(path)) { @@ -607,12 +568,12 @@ void Win32_Platform::dir_enumerate(Vector& list, const char* path, boo } } -void Win32_Platform::dir_explore(const char* path) +void Platform::dir_explore(const char* path) { ShellExecute(NULL, "open", path, NULL, NULL, SW_SHOWDEFAULT); } -FileRef Win32_Platform::file_open(const char* path, FileMode mode) +FileRef Platform::file_open(const char* path, FileMode mode) { int access = 0; int creation = 0; @@ -645,52 +606,52 @@ FileRef Win32_Platform::file_open(const char* path, FileMode mode) return FileRef(new Win32File(result)); } -void* Win32_Platform::gl_get_func(const char* name) +void* Platform::gl_get_func(const char* name) { // this check is taken from https://www.khronos.org/opengl/wiki/Load_OpenGL_Functions // wglGetProcAddress doesn't always return valid pointers for some specific methods? - void* p = (void*)gl.get_proc_address(name); + void* p = (void*)win32_gl.get_proc_address(name); if ((p == 0) || (p == (void*)0x1) || (p == (void*)0x2) || (p == (void*)0x3) || (p == (void*)-1)) { - p = (void*)GetProcAddress(gl.dll, name); + p = (void*)GetProcAddress(win32_gl.dll, name); } return p; } -void* Win32_Platform::gl_context_create() +void* Platform::gl_context_create() { - HDC hdc = GetDC(hwnd); - return gl.create_context(hdc); + HDC hdc = GetDC(win32_hwnd); + return win32_gl.create_context(hdc); } -void Win32_Platform::gl_context_make_current(void* context) +void Platform::gl_context_make_current(void* context) { if (context != nullptr) { - HDC hdc = GetDC(hwnd); - gl.make_current(hdc, (HGLRC)context); + HDC hdc = GetDC(win32_hwnd); + win32_gl.make_current(hdc, (HGLRC)context); } else - gl.make_current(NULL, NULL); + win32_gl.make_current(NULL, NULL); } -void Win32_Platform::gl_context_destroy(void* context) +void Platform::gl_context_destroy(void* context) { - gl.delete_context((HGLRC)context); + win32_gl.delete_context((HGLRC)context); } -void* Win32_Platform::d3d11_get_hwnd() +void* Platform::d3d11_get_hwnd() { - return hwnd; + return win32_hwnd; } -void Win32_Platform::set_clipboard(const char* text) +void Platform::set_clipboard(const char* text) { auto len = strlen(text); if (auto glob = GlobalAlloc(GMEM_MOVEABLE, len)) @@ -711,7 +672,7 @@ void Win32_Platform::set_clipboard(const char* text) } } -const char* Win32_Platform::get_clipboard() +const char* Platform::get_clipboard() { if (OpenClipboard(nullptr)) { @@ -720,44 +681,42 @@ const char* Win32_Platform::get_clipboard() { auto text = static_cast(GlobalLock(data)); if (text) - clipboard = text; + win32_clipboard = text; GlobalUnlock(data); } CloseClipboard(); } - return clipboard.cstr(); + return win32_clipboard.cstr(); } -void Win32_Platform::open_url(const char* url) +void Platform::open_url(const char* url) { auto cmd = String("start ") + url; system(cmd.cstr()); } -void Win32_Platform::detect_joysticks() +void win32_detect_joysticks() { - auto platform = ((Win32_Platform*)Internal::platform); - // mark all joysticks as unnacounted for for (int i = 0; i < Input::max_controllers; i++) - platform->joysticks[i].accounted = false; + win32_joysticks[i].accounted = false; // check for xinput controllers - if (platform->xinput.dll) + if (win32_xinput.dll) { for (DWORD index = 0; index < XUSER_MAX_COUNT; index++) { // can't get capabilities; not connected XINPUT_CAPABILITIES xic; - if (platform->xinput.get_capabilities(index, 0, &xic) != ERROR_SUCCESS) + if (win32_xinput.get_capabilities(index, 0, &xic) != ERROR_SUCCESS) continue; // already connected bool already_connected = false; for (int i = 0; i < Input::max_controllers; i++) { - auto& it = platform->joysticks[i]; + auto& it = win32_joysticks[i]; if (it.connected && it.dinstance == GUID_NULL && it.xindex == index) { it.accounted = true; @@ -772,7 +731,7 @@ void Win32_Platform::detect_joysticks() // find an empty slot and mark connected for (int i = 0; i < Input::max_controllers; i++) { - auto& it = platform->joysticks[i]; + auto& it = win32_joysticks[i]; if (!it.connected) { it.connected = it.accounted = true; @@ -783,7 +742,7 @@ void Win32_Platform::detect_joysticks() // TODO: // Get Product Info & Proper Name - platform->input_state->controllers[i].on_connect("Xbox Controller", true, 15, 6, 0, 0, 0); + win32_input_state->controllers[i].on_connect("Xbox Controller", true, 15, 6, 0, 0, 0); break; } @@ -794,21 +753,18 @@ void Win32_Platform::detect_joysticks() // call disconnect on joysticks that aren't accounted for for (int i = 0; i < Input::max_controllers; i++) { - auto& it = platform->joysticks[i]; + auto& it = win32_joysticks[i]; if (it.connected && !it.accounted) { Log::info("Disconnected [%i]", i); - platform->input_state->controllers[i].on_disconnect(); - it = Win32_Platform::Joystick(); + win32_input_state->controllers[i].on_disconnect(); + it = Joystick(); } } } -LRESULT CALLBACK Blah::win32_window_procedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +LRESULT CALLBACK Blah::win32_window_procedure(HWND win32_hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { - auto platform = ((Win32_Platform*)Internal::platform); - auto input_state = platform->input_state; - switch (msg) { case WM_CLOSE: @@ -829,41 +785,41 @@ LRESULT CALLBACK Blah::win32_window_procedure(HWND hwnd, UINT msg, WPARAM wParam // DBT_DEVNODES_CHANGED = 0x0007 // https://docs.microsoft.com/en-us/windows/win32/devio/wm-devicechange if (wParam == 0x0007) - platform->detect_joysticks(); + win32_detect_joysticks(); return 0; } // Mouse Input case WM_LBUTTONDOWN: - input_state->mouse.on_press(MouseButton::Left); + win32_input_state->mouse.on_press(MouseButton::Left); return 0; case WM_LBUTTONUP: - input_state->mouse.on_release(MouseButton::Left); + win32_input_state->mouse.on_release(MouseButton::Left); return 0; case WM_RBUTTONDOWN: - input_state->mouse.on_press(MouseButton::Right); + win32_input_state->mouse.on_press(MouseButton::Right); return 0; case WM_RBUTTONUP: - input_state->mouse.on_release(MouseButton::Right); + win32_input_state->mouse.on_release(MouseButton::Right); return 0; case WM_MBUTTONDOWN: - input_state->mouse.on_press(MouseButton::Middle); + win32_input_state->mouse.on_press(MouseButton::Middle); return 0; case WM_MBUTTONUP: - input_state->mouse.on_release(MouseButton::Middle); + win32_input_state->mouse.on_release(MouseButton::Middle); return 0; case WM_MOUSEMOVE: - input_state->mouse.on_move(Vec2f((float)((u16)lParam), (float)(lParam >> 16)), Vec2f::zero); + win32_input_state->mouse.on_move(Vec2f((float)((u16)lParam), (float)(lParam >> 16)), Vec2f::zero); return 0; case WM_MOUSEWHEEL: - input_state->mouse.wheel = Point(0, GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA); + win32_input_state->mouse.wheel = Point(0, GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA); return 0; // Text Input @@ -875,7 +831,7 @@ LRESULT CALLBACK Blah::win32_window_procedure(HWND hwnd, UINT msg, WPARAM wParam String result; result.append((u32)wParam); if (result.length() > 0) - input_state->keyboard.text += result.cstr(); + win32_input_state->keyboard.text += result.cstr(); return 0; } @@ -888,7 +844,7 @@ LRESULT CALLBACK Blah::win32_window_procedure(HWND hwnd, UINT msg, WPARAM wParam { auto key = Blah::win32_scancode_to_key(wParam, lParam); if (key != Key::Unknown) - input_state->keyboard.on_press(key); + win32_input_state->keyboard.on_press(key); } return 0; } @@ -898,12 +854,12 @@ LRESULT CALLBACK Blah::win32_window_procedure(HWND hwnd, UINT msg, WPARAM wParam { auto key = Blah::win32_scancode_to_key(wParam, lParam); if (key != Key::Unknown) - input_state->keyboard.on_release(key); + win32_input_state->keyboard.on_release(key); return 0; } } - return DefWindowProc(hwnd, msg, wParam, lParam); + return DefWindowProc(win32_hwnd, msg, wParam, lParam); } Blah::Key Blah::win32_scancode_to_key(WPARAM wParam, LPARAM lParam) @@ -1086,9 +1042,4 @@ Blah::Key Blah::win32_scancode_to_key(WPARAM wParam, LPARAM lParam) return Key::Unknown; } -Platform* Platform::try_make_platform(const Config& config) -{ - return new Win32_Platform(); -} - #endif // BLAH_PLATFORM_WIN32 diff --git a/src/internal/blah_renderer.h b/src/internal/blah_renderer.h index edc0b8b..a969a73 100644 --- a/src/internal/blah_renderer.h +++ b/src/internal/blah_renderer.h @@ -9,10 +9,10 @@ namespace Blah { public: - // Renderer Info + // Renderer Info, should be assigned during init RendererInfo info; - // Default Shader for the Batcher + // Default Shader for the Batcher, should be created in init ShaderRef default_batcher_shader; virtual ~Renderer() = default; diff --git a/src/internal/blah_renderer_d3d11.cpp b/src/internal/blah_renderer_d3d11.cpp index 15e3ebc..160d7b9 100644 --- a/src/internal/blah_renderer_d3d11.cpp +++ b/src/internal/blah_renderer_d3d11.cpp @@ -17,7 +17,7 @@ #include // shorthand to our internal state -#define RENDERER ((Renderer_D3D11*)Internal::renderer) +#define RENDERER ((Renderer_D3D11*)Internal::app_renderer()) namespace Blah { @@ -776,7 +776,7 @@ namespace Blah desc.SampleDesc.Quality = 0; desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; desc.BufferCount = 1; - desc.OutputWindow = (HWND)Internal::platform->d3d11_get_hwnd(); + desc.OutputWindow = (HWND)Platform::d3d11_get_hwnd(); desc.Windowed = true; // Creation Flags diff --git a/src/internal/blah_renderer_opengl.cpp b/src/internal/blah_renderer_opengl.cpp index 6d807bc..73c4886 100644 --- a/src/internal/blah_renderer_opengl.cpp +++ b/src/internal/blah_renderer_opengl.cpp @@ -340,7 +340,7 @@ typedef void (APIENTRY* DEBUGPROC)(GLenum source, const void* userParam); // shorthand to our internal state -#define RENDERER ((Renderer_OpenGL*)Internal::renderer) +#define RENDERER ((Renderer_OpenGL*)Internal::app_renderer()) namespace Blah { @@ -1176,16 +1176,16 @@ namespace Blah bool Renderer_OpenGL::init() { // create gl context - context = Internal::platform->gl_context_create(); + context = Platform::gl_context_create(); if (context == nullptr) { Log::error("Failed to create OpenGL Context"); return false; } - Internal::platform->gl_context_make_current(context); + Platform::gl_context_make_current(context); // bind opengl functions - #define GL_FUNC(name, ...) gl.name = (Renderer_OpenGL::Bindings::name ## Func)(Internal::platform->gl_get_func("gl" #name)); + #define GL_FUNC(name, ...) gl.name = (Renderer_OpenGL::Bindings::name ## Func)(Platform::gl_get_func("gl" #name)); GL_FUNCTIONS #undef GL_FUNC @@ -1229,7 +1229,7 @@ namespace Blah void Renderer_OpenGL::shutdown() { - Internal::platform->gl_context_destroy(context); + Platform::gl_context_destroy(context); context = nullptr; } @@ -1546,33 +1546,33 @@ namespace Blah void Renderer_OpenGL::clear_backbuffer(Color color, float depth, u8 stencil, ClearMask mask) { - RENDERER->gl.BindFramebuffer(GL_FRAMEBUFFER, 0); - RENDERER->gl.Disable(GL_SCISSOR_TEST); + RENDERER->gl.BindFramebuffer(GL_FRAMEBUFFER, 0); + RENDERER->gl.Disable(GL_SCISSOR_TEST); - int clear = 0; + int clear = 0; - if (((int)mask & (int)ClearMask::Color) == (int)ClearMask::Color) - { - clear |= GL_COLOR_BUFFER_BIT; - RENDERER->gl.ColorMask(true, true, true, true); - RENDERER->gl.ClearColor(color.r / 255.0f, color.g / 255.0f, color.b / 255.0f, color.a / 255.0f); - } + if (((int)mask & (int)ClearMask::Color) == (int)ClearMask::Color) + { + clear |= GL_COLOR_BUFFER_BIT; + RENDERER->gl.ColorMask(true, true, true, true); + RENDERER->gl.ClearColor(color.r / 255.0f, color.g / 255.0f, color.b / 255.0f, color.a / 255.0f); + } - if (((int)mask & (int)ClearMask::Depth) == (int)ClearMask::Depth) - { - clear |= GL_DEPTH_BUFFER_BIT; - if (RENDERER->gl.ClearDepth) - RENDERER->gl.ClearDepth(depth); - } + if (((int)mask & (int)ClearMask::Depth) == (int)ClearMask::Depth) + { + clear |= GL_DEPTH_BUFFER_BIT; + if (RENDERER->gl.ClearDepth) + RENDERER->gl.ClearDepth(depth); + } - if (((int)mask & (int)ClearMask::Stencil) == (int)ClearMask::Stencil) - { - clear |= GL_STENCIL_BUFFER_BIT; - if (RENDERER->gl.ClearStencil) - RENDERER->gl.ClearStencil(stencil); - } + if (((int)mask & (int)ClearMask::Stencil) == (int)ClearMask::Stencil) + { + clear |= GL_STENCIL_BUFFER_BIT; + if (RENDERER->gl.ClearStencil) + RENDERER->gl.ClearStencil(stencil); + } - RENDERER->gl.Clear(clear); + RENDERER->gl.Clear(clear); } }