diff options
Diffstat (limited to 'src/blu_cat/int')
| -rw-r--r-- | src/blu_cat/int/controller.hpp | 50 | ||||
| -rw-r--r-- | src/blu_cat/int/core.cpp | 150 | ||||
| -rw-r--r-- | src/blu_cat/int/core.hpp | 12 | ||||
| -rw-r--r-- | src/blu_cat/int/mode.hpp | 41 |
4 files changed, 194 insertions, 59 deletions
diff --git a/src/blu_cat/int/controller.hpp b/src/blu_cat/int/controller.hpp new file mode 100644 index 0000000..deedde3 --- /dev/null +++ b/src/blu_cat/int/controller.hpp @@ -0,0 +1,50 @@ +/* + * Copyright 2022-2025 Frederico de Oliveira Linhares + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BLU_CAT_INT_CONTROLLER_H +#define BLU_CAT_INT_CONTROLLER_H 1 + +#include <SDL3/SDL.h> + +namespace BluCat::INT +{ + +struct Controller +{ + virtual void + key_down(SDL_Keycode keycode){}; + virtual void + key_up(SDL_Keycode keycode){}; + + virtual void + mouse_button_down(SDL_MouseButtonEvent& e){}; + virtual void + mouse_button_up(SDL_MouseButtonEvent& e){}; + virtual void + mouse_motion(int x, int y, int xrel, int yrel){}; + + virtual void + tick(){}; + virtual void + render(){}; + + virtual + ~Controller(){}; +}; + +} + +#endif /* BLU_CAT_INT_CONTROLLER_H */ diff --git a/src/blu_cat/int/core.cpp b/src/blu_cat/int/core.cpp index d631d17..6f67b98 100644 --- a/src/blu_cat/int/core.cpp +++ b/src/blu_cat/int/core.cpp @@ -56,14 +56,14 @@ vk_debug_callback( void load_sdl(void *obj) { - if(SDL_Init(SDL_INIT_EVERYTHING) < 0) + if(!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) { std::string error{"SDL could not initialize! SDL Error → "}; error += SDL_GetError(); - throw error; + throw CommandError{error}; } - if(SDL_Vulkan_LoadLibrary(nullptr) != 0) + if(!SDL_Vulkan_LoadLibrary(nullptr)) { SDL_Quit(); std::string error{"SDL could not initialize Vulkan! SDL_Error → "}; @@ -80,51 +80,13 @@ unload_sdl(void *obj) } void -load_sdl_mixer(void *obj) -{ - int flags = MIX_INIT_OGG|MIX_INIT_MOD; - int initted = Mix_Init(flags); - if(initted&flags != flags) - { - std::string error{"Could not initialize SDL mixer → "}; - error += Mix_GetError(); - throw CommandError{error}; - } -} - -void -unload_sdl_mixer(void *obj) -{ - while(Mix_Init(0)) Mix_Quit(); -} - -void -load_sdl_open_audio(void *obj) -{ - if(Mix_OpenAudio(22050, MIX_DEFAULT_FORMAT, 2, 1024) == -1) - { - std::string error{"Could not open SDL mixer audio → "}; - error += Mix_GetError(); - throw CommandError{error}; - } -} - -void -unload_sdl_open_audio(void *obj) -{ - Mix_CloseAudio(); -} - -void load_window(void *obj) { - BluCat::INT::core.window = nullptr; BluCat::INT::core.window = SDL_CreateWindow( BluCat::INT::core.game_name.c_str(), - SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, BluCat::INT::core.display_width, BluCat::INT::core.display_height, SDL_WINDOW_VULKAN); - if(BluCat::INT::core.window == nullptr) + if(BluCat::INT::core.window == NULL) { std::string error{"Window could not be created! SDL_Error → "}; error += SDL_GetError(); @@ -160,8 +122,10 @@ load_vk_instance(void *obj) uint32_t vk_sdl_extension_count; std::vector<const char*> vk_sdl_extensions; - if(!SDL_Vulkan_GetInstanceExtensions( - BluCat::INT::core.window, &vk_sdl_extension_count, nullptr)) + const char * const *instance_extensions = + SDL_Vulkan_GetInstanceExtensions(&vk_sdl_extension_count); + + if(instance_extensions == NULL) { std::string error{ "Vulkan extensions could not be loaded by SDL! SDL_Error: "}; @@ -169,10 +133,8 @@ load_vk_instance(void *obj) throw CommandError{error}; } - vk_sdl_extensions.resize(vk_sdl_extension_count); - SDL_Vulkan_GetInstanceExtensions( - BluCat::INT::core.window, &vk_sdl_extension_count, - vk_sdl_extensions.data()); + for(auto i{0}; i < vk_sdl_extension_count; i++) + vk_sdl_extensions.push_back(instance_extensions[i]); // Combine all extensions. vk_extensions_count = vk_sdl_extension_count + @@ -290,7 +252,7 @@ load_window_surface(void *obj) { if(!SDL_Vulkan_CreateSurface( BluCat::INT::core.window, BluCat::INT::core.vk_instance, - &BluCat::INT::core.window_surface)) + nullptr, &BluCat::INT::core.window_surface)) { std::string error{"Failed to create a window surface → "}; error += SDL_GetError(); @@ -692,13 +654,13 @@ load_renderer(void *obj) { try { + auto width{static_cast<float>(BluCat::INT::core.display_width)}; + auto height{static_cast<float>(BluCat::INT::core.display_height)}; glm::vec4 region( - 0.f, 0.f, - static_cast<float>(BluCat::INT::core.display_width), - static_cast<float>(BluCat::INT::core.display_height)); + 0.f, 0.f, width, height); BluCat::INT::core.vk_renderer = new BluCat::GRA::Renderer( - {}, - {std::make_shared<BluCat::GRA::View3D>(region, region.z, region.w)}); + {std::make_shared<BluCat::GRA::View>(region, region.z, region.w)}, + width, height); } catch(const CommandError &e) { @@ -722,8 +684,6 @@ std::mt19937 random_number_generator; const CommandChain Core::loader{ {&load_sdl, &unload_sdl}, - {&load_sdl_mixer, &unload_sdl_mixer}, - {&load_sdl_open_audio, &unload_sdl_open_audio}, {&load_window, &unload_window}, {&load_vk_instance, &unload_vk_instance}, {&load_window_surface, &unload_window_surface}, @@ -758,4 +718,82 @@ const CommandChain Core::loader{ Core core; +void +run_game(std::unique_ptr<BluCat::INT::Mode> _mode) +{ + using namespace std::chrono; + using namespace std::this_thread; + + std::unique_ptr<BluCat::INT::Mode> mode{std::move(_mode)}; + std::unique_ptr<BluCat::INT::Controller> controller{ + mode->default_controller()}; + + bool quit{false}; + int x, y, xrel, yrel; + SDL_Event event; + auto frame_start = steady_clock::now(); + + while(!quit) + { + if(core.next_game_mode) + { + mode = std::move(core.next_game_mode); + controller = mode->default_controller(); + } + else if(core.next_game_controller) + controller = std::move(core.next_game_controller); + + while(SDL_PollEvent(&event)) + { + switch(event.type) + { + case SDL_EVENT_KEY_DOWN: + if(event.key.repeat != 0) continue; + controller->key_down(event.key.key); + break; + case SDL_EVENT_KEY_UP: + if(event.key.repeat != 0) continue; + controller->key_up(event.key.key); + break; + case SDL_EVENT_MOUSE_BUTTON_DOWN: + controller->mouse_button_down(event.button); + break; + case SDL_EVENT_MOUSE_BUTTON_UP: + controller->mouse_button_up(event.button); + break; + case SDL_EVENT_MOUSE_MOTION: + x = event.motion.x; + y = event.motion.y; + + xrel = event.motion.xrel; + yrel = event.motion.yrel; + + controller->mouse_motion(x, y, xrel, yrel); + break; + case SDL_EVENT_QUIT: + quit = true; + } + } + + controller->tick(); + mode->render(); + controller->render(); + BluCat::INT::core.vk_renderer->draw(); + + { // Timer + auto frame_stop = steady_clock::now(); + auto frame_duration = frame_stop - frame_start; + + // If frame take less time than maximum allowed. + if(core.max_frame_duration > frame_duration) + sleep_for(core.max_frame_duration - frame_duration); + + frame_start = frame_stop; + } + } + + controller = nullptr; + mode = nullptr; +} + } diff --git a/src/blu_cat/int/core.hpp b/src/blu_cat/int/core.hpp index a334dfa..4737123 100644 --- a/src/blu_cat/int/core.hpp +++ b/src/blu_cat/int/core.hpp @@ -32,9 +32,8 @@ #include <Windows.h> #endif -#include <SDL2/SDL.h> -#include <SDL2/SDL_vulkan.h> -#include <SDL2/SDL_mixer.h> +#include <SDL3/SDL.h> +#include <SDL3/SDL_vulkan.h> #include <ft2build.h> #include FT_FREETYPE_H @@ -59,6 +58,7 @@ #include "../gra/renderer.hpp" #include "../gra/swapchain.hpp" #include "../gra/vulkan.hpp" +#include "mode.hpp" namespace BluCat::INT { @@ -132,10 +132,16 @@ struct Core vk_graphics_pipeline_2d_wired; BluCat::GRA::Renderer *vk_renderer; + + std::unique_ptr<BluCat::INT::Mode> next_game_mode{nullptr}; + std::unique_ptr<BluCat::INT::Controller> next_game_controller{nullptr}; }; extern Core core; +void +run_game(std::unique_ptr<Mode> initial_mode); + } #endif /* BLU_CAT_INT_CORE_H */ diff --git a/src/blu_cat/int/mode.hpp b/src/blu_cat/int/mode.hpp new file mode 100644 index 0000000..8197f75 --- /dev/null +++ b/src/blu_cat/int/mode.hpp @@ -0,0 +1,41 @@ +/* + * Copyright 2022-2025 Frederico de Oliveira Linhares + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BLU_CAT_INT_MODE_H +#define BLU_CAT_INT_MODE_H 1 + +#include <memory> + +#include "controller.hpp" + +namespace BluCat::INT +{ + +struct Mode +{ + virtual std::unique_ptr<Controller> + default_controller() = 0; + + virtual void + render() = 0; + + virtual + ~Mode(){}; +}; + +} + +#endif /* BLU_CAT_INT_MODE_H */ |
