summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFrederico Linhares <fred@linhares.blue>2025-03-12 20:40:25 -0300
committerFrederico Linhares <fred@linhares.blue>2025-03-12 20:40:25 -0300
commit96228c92004fefae3cb3392c20d90ec4ede753cd (patch)
tree3fa37641dbc915ddf1096efd6e21ddcb3884fe78 /src
parentdaa767aa5ea95fa2386c5ecaff31bd5598c43700 (diff)
refa Move initialization code to BluCat
Diffstat (limited to 'src')
-rw-r--r--src/blu_cat/int/core.cpp260
-rw-r--r--src/blu_cat/int/core.hpp28
-rw-r--r--src/candy_gear/core.cpp269
-rw-r--r--src/candy_gear/core.hpp17
4 files changed, 284 insertions, 290 deletions
diff --git a/src/blu_cat/int/core.cpp b/src/blu_cat/int/core.cpp
index eafdab7..d631d17 100644
--- a/src/blu_cat/int/core.cpp
+++ b/src/blu_cat/int/core.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 Frederico de Oliveira Linhares
+ * 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.
@@ -54,6 +54,258 @@ vk_debug_callback(
#endif
void
+load_sdl(void *obj)
+{
+ if(SDL_Init(SDL_INIT_EVERYTHING) < 0)
+ {
+ std::string error{"SDL could not initialize! SDL Error → "};
+ error += SDL_GetError();
+ throw error;
+ }
+
+ if(SDL_Vulkan_LoadLibrary(nullptr) != 0)
+ {
+ SDL_Quit();
+ std::string error{"SDL could not initialize Vulkan! SDL_Error → "};
+ error += SDL_GetError();
+ throw CommandError{error};
+ }
+}
+
+void
+unload_sdl(void *obj)
+{
+ SDL_Vulkan_UnloadLibrary();
+ SDL_Quit();
+}
+
+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)
+ {
+ std::string error{"Window could not be created! SDL_Error → "};
+ error += SDL_GetError();
+ throw CommandError{error};
+ }
+}
+
+void
+unload_window(void *obj)
+{
+ SDL_DestroyWindow(BluCat::INT::core.window);
+}
+
+void
+load_vk_instance(void *obj)
+{
+ std::vector<const char*> vk_extensions;
+ std::vector<const char*> vk_required_layers_names;
+
+ // Get extensions.
+ {
+ uint32_t vk_extensions_count;
+ std::vector<const char*> vk_required_extensions;
+
+ // Load debuging layers.
+#ifdef DEBUG
+ vk_required_extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
+ vk_required_layers_names.push_back("VK_LAYER_KHRONOS_validation");
+#endif
+
+ // Get extensions for SDL.
+ {
+ 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))
+ {
+ std::string error{
+ "Vulkan extensions could not be loaded by SDL! SDL_Error: "};
+ error += SDL_GetError();
+ 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());
+
+ // Combine all extensions.
+ vk_extensions_count = vk_sdl_extension_count +
+ vk_required_extensions.size();
+ vk_extensions.resize(vk_extensions_count);
+ for(auto i{0}; i < vk_sdl_extension_count; i++)
+ vk_extensions[i] = vk_sdl_extensions[i];
+ for(auto i{0}; i < vk_required_extensions.size(); i++)
+ vk_extensions[i + vk_sdl_extension_count] = vk_required_extensions[i];
+ }
+
+#ifdef DEBUG
+ BluCat::INT::core.log.message(Log::Level::Trace, "Enabled VK extensions.");
+ for(auto vk_extension: vk_extensions)
+ {
+ std::string message{"Extension name: "};
+ message += vk_extension;
+ BluCat::INT::core.log.message(Log::Level::Trace, message);
+ }
+#endif
+ }
+
+ // Get available instance layers.
+ {
+ uint32_t vk_available_layers_count;
+ std::vector<VkLayerProperties> vk_available_layers;
+ std::vector<const char*> vk_available_layers_names;
+
+ vkEnumerateInstanceLayerProperties(&vk_available_layers_count, nullptr);
+ vk_available_layers.resize(vk_available_layers_count);
+ vkEnumerateInstanceLayerProperties(&vk_available_layers_count,
+ vk_available_layers.data());
+ vk_available_layers_names.resize(vk_available_layers_count);
+#ifdef DEBUG
+ BluCat::INT::core.log.message(
+ Log::Level::Trace, "Available VK instance layers.");
+#endif
+ for(uint32_t i = 0; i < vk_available_layers_count; i++)
+ {
+#ifdef DEBUG
+ std::stringstream message{};
+ message << "\nname: " << vk_available_layers[i].layerName << std::endl;
+ message << "Description: " << vk_available_layers[i].description <<
+ std::endl;
+ message << "Spec version: " << vk_available_layers[i].specVersion <<
+ std::endl;
+ message << "Implementation version: " <<
+ vk_available_layers[i].implementationVersion << std::endl;
+ BluCat::INT::core.log.message(Log::Level::Trace, message.str());
+#endif
+
+ vk_available_layers_names[i] = vk_available_layers[i].layerName;
+ }
+
+ // If required layers are not all available.
+ if(!std::includes(
+ vk_available_layers_names.begin(), vk_available_layers_names.end(),
+ vk_required_layers_names.begin(), vk_required_layers_names.begin()))
+ throw CommandError{"Some required Vulkan layers are not available."};
+ }
+
+ {
+ VkApplicationInfo app_info;
+ app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
+ app_info.pNext = nullptr;
+ app_info.pApplicationName = BluCat::INT::core.game_name.c_str();
+ app_info.applicationVersion = VK_MAKE_VERSION(
+ BluCat::INT::core.game_version_major,
+ BluCat::INT::core.game_version_minor,
+ BluCat::INT::core.game_version_patch);
+ app_info.pEngineName = "BluCat::GRA";
+ app_info.engineVersion = VK_MAKE_VERSION(
+ BLU_CAT_VERSION_MAJOR,
+ BLU_CAT_VERSION_MINOR,
+ BLU_CAT_VERSION_PATCH);
+ app_info.apiVersion = VK_API_VERSION_1_0;
+
+ VkInstanceCreateInfo create_info;
+ create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
+ create_info.pNext = nullptr;
+ create_info.flags = 0;
+ create_info.pApplicationInfo = &app_info;
+ create_info.enabledExtensionCount = vk_extensions.size();
+ create_info.ppEnabledExtensionNames = vk_extensions.data();
+ create_info.enabledLayerCount = vk_required_layers_names.size();
+ create_info.ppEnabledLayerNames = vk_required_layers_names.data();
+
+ VkResult result =
+ vkCreateInstance(&create_info, nullptr, &BluCat::INT::core.vk_instance);
+ if(result != VK_SUCCESS)
+ {
+ std::string error{""};
+ switch(result)
+ {
+ case VK_ERROR_LAYER_NOT_PRESENT:
+ error = " Layer not present.";
+ break;
+ case VK_ERROR_EXTENSION_NOT_PRESENT:
+ error = " Extension not present.";
+ }
+ error = "Failed to create Vulkan instance." + error;
+ throw CommandError{error};
+ }
+ }
+}
+
+void
+unload_vk_instance(void *obj)
+{
+ vkDestroyInstance(BluCat::INT::core.vk_instance, nullptr);
+}
+
+void
+load_window_surface(void *obj)
+{
+ if(!SDL_Vulkan_CreateSurface(
+ BluCat::INT::core.window, BluCat::INT::core.vk_instance,
+ &BluCat::INT::core.window_surface))
+ {
+ std::string error{"Failed to create a window surface → "};
+ error += SDL_GetError();
+ throw CommandError{error};
+ }
+}
+
+void
+unload_window_surface(void *obj)
+{
+ vkDestroySurfaceKHR(
+ BluCat::INT::core.vk_instance, BluCat::INT::core.window_surface, nullptr);
+}
+
+void
load_threads(void *obj)
{
auto num_threads{std::thread::hardware_concurrency() - 1};
@@ -469,6 +721,12 @@ std::random_device random_seed;
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},
{&load_threads, &unload_threads},
{&load_fps, nullptr},
{&load_font_library, &unload_font_library},
diff --git a/src/blu_cat/int/core.hpp b/src/blu_cat/int/core.hpp
index 0900b81..a334dfa 100644
--- a/src/blu_cat/int/core.hpp
+++ b/src/blu_cat/int/core.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 Frederico de Oliveira Linhares
+ * 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.
@@ -26,6 +26,19 @@
#include <memory>
#include <random>
+#define SDL_MAIN_HANDLED
+
+#ifdef _WIN64
+#include <Windows.h>
+#endif
+
+#include <SDL2/SDL.h>
+#include <SDL2/SDL_vulkan.h>
+#include <SDL2/SDL_mixer.h>
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
#include "../com/command.hpp"
#include "../com/job_queue.hpp"
#include "../com/worker.hpp"
@@ -64,22 +77,27 @@ struct Core
std::vector<std::thread> threads;
/// Text displayed in the game window.
- std::string game_name;
+ std::string game_name{"BluCat Game"};
/**
* @{
* This is the ammount of pixel that the games uses when rendering to the
* screen.
*/
- uint32_t display_width, display_height;
+ uint32_t display_width{800};
+ uint32_t display_height{600};
/// @}
- int game_version_major, game_version_minor, game_version_patch;
+ int game_version_major{0};
+ int game_version_minor{1};
+ int game_version_patch{0};
- uint32_t fps;
+ uint32_t fps{30};
std::chrono::duration<long long, std::milli> max_frame_duration;
float delta_time;
+ SDL_Window *window;
+
FT_Library font_library;
VkSurfaceKHR window_surface;
diff --git a/src/candy_gear/core.cpp b/src/candy_gear/core.cpp
index 28f5a15..6897921 100644
--- a/src/candy_gear/core.cpp
+++ b/src/candy_gear/core.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 Frederico de Oliveira Linhares
+ * 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.
@@ -64,17 +64,6 @@ load_game(void *obj)
FILE *fp;
mrb_value main_obj{mrb_top_self(cg_core.mrb)};
- BluCat::INT::core.game_name = "CandyGear Game";
-
- BluCat::INT::core.display_width = 800;
- BluCat::INT::core.display_height = 600;
-
- BluCat::INT::core.game_version_major = 0;
- BluCat::INT::core.game_version_minor = 1;
- BluCat::INT::core.game_version_patch = 0;
-
- BluCat::INT::core.fps = 30;
-
mrb_define_module(cg_core.mrb, "CandyGear");
cg_candy_gear_init_config(cg_core.mrb);
cg_graphic_init_config(cg_core.mrb);
@@ -100,256 +89,6 @@ load_game(void *obj)
}
void
-load_sdl(void *obj)
-{
- if(SDL_Init(SDL_INIT_EVERYTHING) < 0)
- {
- std::string error{"SDL could not initialize! SDL Error → "};
- error += SDL_GetError();
- throw error;
- }
-
- if(SDL_Vulkan_LoadLibrary(nullptr) != 0)
- {
- SDL_Quit();
- std::string error{"SDL could not initialize Vulkan! SDL_Error → "};
- error += SDL_GetError();
- throw CommandError{error};
- }
-}
-
-void
-unload_sdl(void *obj)
-{
- SDL_Vulkan_UnloadLibrary();
- SDL_Quit();
-}
-
-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)
-{
- cg_core.window = NULL;
- cg_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(cg_core.window == NULL)
- {
- std::string error{"Window could not be created! SDL_Error → "};
- error += SDL_GetError();
- throw CommandError{error};
- }
-}
-
-void
-unload_window(void *obj)
-{
- SDL_DestroyWindow(cg_core.window);
-}
-
-void
-load_vk_instance(void *obj)
-{
- std::vector<const char*> vk_extensions;
- std::vector<const char*> vk_required_layers_names;
-
- // Get extensions.
- {
- uint32_t vk_extensions_count;
- std::vector<const char*> vk_required_extensions;
-
- // Load debuging layers.
-#ifdef DEBUG
- vk_required_extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
- vk_required_layers_names.push_back("VK_LAYER_KHRONOS_validation");
-#endif
-
- // Get extensions for SDL.
- {
- uint32_t vk_sdl_extension_count;
- std::vector<const char*> vk_sdl_extensions;
-
- if(!SDL_Vulkan_GetInstanceExtensions(
- cg_core.window, &vk_sdl_extension_count, nullptr))
- {
- std::string error{
- "Vulkan extensions could not be loaded by SDL! SDL_Error: "};
- error += SDL_GetError();
- throw CommandError{error};
- }
-
- vk_sdl_extensions.resize(vk_sdl_extension_count);
- SDL_Vulkan_GetInstanceExtensions(
- cg_core.window, &vk_sdl_extension_count, vk_sdl_extensions.data());
-
- // Combine all extensions.
- vk_extensions_count = vk_sdl_extension_count +
- vk_required_extensions.size();
- vk_extensions.resize(vk_extensions_count);
- for(auto i{0}; i < vk_sdl_extension_count; i++)
- vk_extensions[i] = vk_sdl_extensions[i];
- for(auto i{0}; i < vk_required_extensions.size(); i++)
- vk_extensions[i + vk_sdl_extension_count] = vk_required_extensions[i];
- }
-
-#ifdef DEBUG
- BluCat::INT::core.log.message(Log::Level::Trace, "Enabled VK extensions.");
- for(auto vk_extension: vk_extensions)
- {
- std::string message{"Extension name: "};
- message += vk_extension;
- BluCat::INT::core.log.message(Log::Level::Trace, message);
- }
-#endif
- }
-
- // Get available instance layers.
- {
- uint32_t vk_available_layers_count;
- std::vector<VkLayerProperties> vk_available_layers;
- std::vector<const char*> vk_available_layers_names;
-
- vkEnumerateInstanceLayerProperties(&vk_available_layers_count, nullptr);
- vk_available_layers.resize(vk_available_layers_count);
- vkEnumerateInstanceLayerProperties(&vk_available_layers_count,
- vk_available_layers.data());
- vk_available_layers_names.resize(vk_available_layers_count);
-#ifdef DEBUG
- BluCat::INT::core.log.message(
- Log::Level::Trace, "Available VK instance layers.");
-#endif
- for(uint32_t i = 0; i < vk_available_layers_count; i++)
- {
-#ifdef DEBUG
- std::stringstream message{};
- message << "\nname: " << vk_available_layers[i].layerName << std::endl;
- message << "Description: " << vk_available_layers[i].description <<
- std::endl;
- message << "Spec version: " << vk_available_layers[i].specVersion <<
- std::endl;
- message << "Implementation version: " <<
- vk_available_layers[i].implementationVersion << std::endl;
- BluCat::INT::core.log.message(Log::Level::Trace, message.str());
-#endif
-
- vk_available_layers_names[i] = vk_available_layers[i].layerName;
- }
-
- // If required layers are not all available.
- if(!std::includes(
- vk_available_layers_names.begin(), vk_available_layers_names.end(),
- vk_required_layers_names.begin(), vk_required_layers_names.begin()))
- throw CommandError{"Some required Vulkan layers are not available."};
- }
-
- {
- VkApplicationInfo app_info;
- app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
- app_info.pNext = nullptr;
- app_info.pApplicationName = BluCat::INT::core.game_name.c_str();
- app_info.applicationVersion = VK_MAKE_VERSION(
- BluCat::INT::core.game_version_major,
- BluCat::INT::core.game_version_minor,
- BluCat::INT::core.game_version_patch);
- app_info.pEngineName = "BluCat::GRA";
- app_info.engineVersion = VK_MAKE_VERSION(
- BLU_CAT_VERSION_MAJOR,
- BLU_CAT_VERSION_MINOR,
- BLU_CAT_VERSION_PATCH);
- app_info.apiVersion = VK_API_VERSION_1_0;
-
- VkInstanceCreateInfo create_info;
- create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
- create_info.pNext = nullptr;
- create_info.flags = 0;
- create_info.pApplicationInfo = &app_info;
- create_info.enabledExtensionCount = vk_extensions.size();
- create_info.ppEnabledExtensionNames = vk_extensions.data();
- create_info.enabledLayerCount = vk_required_layers_names.size();
- create_info.ppEnabledLayerNames = vk_required_layers_names.data();
-
- VkResult result =
- vkCreateInstance(&create_info, nullptr, &BluCat::INT::core.vk_instance);
- if(result != VK_SUCCESS)
- {
- std::string error{""};
- switch(result)
- {
- case VK_ERROR_LAYER_NOT_PRESENT:
- error = " Layer not present.";
- break;
- case VK_ERROR_EXTENSION_NOT_PRESENT:
- error = " Extension not present.";
- }
- error = "Failed to create Vulkan instance." + error;
- throw CommandError{error};
- }
- }
-}
-
-void
-unload_vk_instance(void *obj)
-{
- vkDestroyInstance(BluCat::INT::core.vk_instance, nullptr);
-}
-
-void
-load_window_surface(void *obj)
-{
- if(!SDL_Vulkan_CreateSurface(
- cg_core.window, BluCat::INT::core.vk_instance, &BluCat::INT::core.window_surface))
- {
- std::string error{"Failed to create a window surface → "};
- error += SDL_GetError();
- throw CommandError{error};
- }
-}
-
-void
-unload_window_surface(void *obj)
-{
- vkDestroySurfaceKHR(
- BluCat::INT::core.vk_instance, BluCat::INT::core.window_surface, nullptr);
-}
-
-void
load_blucat(void *obj)
{
BluCat::INT::core.loader.execute(nullptr);
@@ -387,12 +126,6 @@ load_mruby_interface(void *obj)
const CommandChain cg_sCore::loader{
{&load_mruby_symbols, nullptr},
{&load_game, nullptr},
- {&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},
{&load_blucat, &unload_blucat},
{&load_mruby_interface, nullptr}
};
diff --git a/src/candy_gear/core.hpp b/src/candy_gear/core.hpp
index 60d8339..e3288b4 100644
--- a/src/candy_gear/core.hpp
+++ b/src/candy_gear/core.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 Frederico de Oliveira Linhares
+ * 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.
@@ -24,19 +24,6 @@
#include <mruby/dump.h>
#include <mruby/variable.h>
-#define SDL_MAIN_HANDLED
-
-#ifdef _WIN64
-#include <Windows.h>
-#endif
-
-#include <SDL2/SDL.h>
-#include <SDL2/SDL_vulkan.h>
-#include <SDL2/SDL_mixer.h>
-
-#include <ft2build.h>
-#include FT_FREETYPE_H
-
#include "../blu_cat/int/core.hpp"
/**
@@ -57,8 +44,6 @@ struct cg_sCore
sym_warning;
bool quit_game;
-
- SDL_Window *window;
};
extern cg_sCore cg_core;