summaryrefslogtreecommitdiff
path: root/src/blu_cat/int
diff options
context:
space:
mode:
Diffstat (limited to 'src/blu_cat/int')
-rw-r--r--src/blu_cat/int/controller.hpp50
-rw-r--r--src/blu_cat/int/core.cpp150
-rw-r--r--src/blu_cat/int/core.hpp12
-rw-r--r--src/blu_cat/int/mode.hpp41
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 */