diff options
Diffstat (limited to 'src/candy_gear')
37 files changed, 3329 insertions, 0 deletions
diff --git a/src/candy_gear/candy_gear.cpp b/src/candy_gear/candy_gear.cpp new file mode 100644 index 0000000..b1758a4 --- /dev/null +++ b/src/candy_gear/candy_gear.cpp @@ -0,0 +1,146 @@ +/* + * Copyright 2022-2024 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. + */ + +#include "candy_gear.hpp" + +#include <mruby/array.h> +#include <mruby/hash.h> +#include <mruby/string.h> + +#include "core.hpp" +#include "view_2d.hpp" +#include "view_3d.hpp" + +static mrb_value +cg_mCandyGear_set_game_name(mrb_state *mrb, mrb_value self) +{ + mrb_value name; + + mrb_get_args(mrb, "S", &name); + BluCat::INT::core.game_name = RSTRING_PTR(name); + + return self; +} + +static mrb_value +cg_mCandyGear_set_views(mrb_state *mrb, mrb_value self) +{ + struct RClass *cg_m, *cg_cView2D, *cg_cView3D; + mrb_value *array; + mrb_int array_len; + + std::vector<std::shared_ptr<BluCat::GRA::View2D>> views_2d; + std::vector<std::shared_ptr<BluCat::GRA::View3D>> views_3d; + + cg_m = mrb_module_get(mrb, "CandyGear"); + cg_cView2D = mrb_class_get_under(mrb, cg_m, "View2D"); + cg_cView3D = mrb_class_get_under(mrb, cg_m, "View3D"); + + mrb_get_args(mrb, "a", &array, &array_len); + for(mrb_int i{0}; i < array_len; i++) + { + if(mrb_obj_is_kind_of(mrb, array[i], cg_cView2D)) + { + auto v = (std::shared_ptr<BluCat::GRA::View2D>*)DATA_PTR(array[i]); + views_2d.push_back(*v); + } + else if(mrb_obj_is_kind_of(mrb, array[i], cg_cView3D)) + { + auto v = (std::shared_ptr<BluCat::GRA::View3D>*)DATA_PTR(array[i]); + views_3d.push_back(*v); + } + } + + // A Renderer need at least one view to work. + if(views_2d.size() > 0 || views_3d.size() > 0) + { + delete BluCat::INT::core.vk_renderer; + BluCat::INT::core.vk_renderer = new BluCat::GRA::Renderer({views_2d, views_3d}); + } + + return self; +} + +static mrb_value +cg_mCandyGear_log(mrb_state *mrb, mrb_value self) +{ + const char *message; + mrb_sym sym_log_level; + Log::Level log_lvl; + + mrb_get_args(mrb, "nz", &sym_log_level, &message); + + if(sym_log_level == cg_core.sym_trace) + log_lvl = Log::Level::Trace; + else if(sym_log_level == cg_core.sym_debug) + log_lvl = Log::Level::Debug; + else if(sym_log_level == cg_core.sym_information) + log_lvl = Log::Level::Information; + else if(sym_log_level == cg_core.sym_warning) + log_lvl = Log::Level::Warning; + else if(sym_log_level == cg_core.sym_error) + log_lvl = Log::Level::Error; + else + log_lvl = Log::Level::Fatal; + + BluCat::INT::core.log.message(log_lvl, message); + + return self; +} + +static mrb_value +cg_mCandyGear_quit(mrb_state *mrb, mrb_value self) +{ + cg_core.quit_game = true; + + return self; +} + +void +cg_candy_gear_init_config(mrb_state *mrb) +{ + struct RClass *cg_m; + + cg_m = mrb_module_get(mrb, "CandyGear"); + + mrb_define_class_method( + mrb, cg_m, "game_name=", cg_mCandyGear_set_game_name, MRB_ARGS_REQ(1)); +} + +void +cg_candy_gear_finish_config(mrb_state *mrb) +{ + struct RClass *cg_m; + + cg_m = mrb_module_get(mrb, "CandyGear"); + + mrb_undef_class_method(mrb, cg_m, "game_name="); +} + +void +cg_candy_gear_init(mrb_state *mrb) +{ + struct RClass *cg_m; + + cg_m = mrb_module_get(mrb, "CandyGear"); + + mrb_define_class_method( + mrb, cg_m, "views=", cg_mCandyGear_set_views, MRB_ARGS_REQ(1)); + mrb_define_class_method( + mrb, cg_m, "log", cg_mCandyGear_log, MRB_ARGS_REQ(2)); + mrb_define_class_method( + mrb, cg_m, "quit", cg_mCandyGear_quit, MRB_ARGS_NONE()); +} diff --git a/src/candy_gear/candy_gear.hpp b/src/candy_gear/candy_gear.hpp new file mode 100644 index 0000000..3ec92b3 --- /dev/null +++ b/src/candy_gear/candy_gear.hpp @@ -0,0 +1,32 @@ +/* + * Copyright 2022 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 CANDY_GEAR_CANDY_GEAR_H +#define CANDY_GEAR_CANDY_GEAR_H 1 + +#include "core.hpp" + +// Provides the basic interface the game needs to configure the engine's +// initialization. +void +cg_candy_gear_init_config(mrb_state *mrb); +void +cg_candy_gear_finish_config(mrb_state *mrb); + +void +cg_candy_gear_init(mrb_state *mrb); + +#endif /* CANDY_GEAR_CANDY_GEAR_H */ diff --git a/src/candy_gear/core.cpp b/src/candy_gear/core.cpp new file mode 100644 index 0000000..28f5a15 --- /dev/null +++ b/src/candy_gear/core.cpp @@ -0,0 +1,398 @@ +/* + * Copyright 2022-2024 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. + */ + +#include "core.hpp" + +#include "candy_gear.hpp" +#include "font.hpp" +#include "graphic.hpp" +#include "key.hpp" +#include "orientation_3d.hpp" +#include "skeletal_model.hpp" +#include "skeletal_mesh.hpp" +#include "static_model.hpp" +#include "static_mesh.hpp" +#include "sound.hpp" +#include "sprite.hpp" +#include "sprite_3d.hpp" +#include "texture.hpp" +#include "vector_3d.hpp" +#include "vector_4d.hpp" +#include "view_2d.hpp" +#include "view_3d.hpp" + +#ifdef DEBUG +#include <sstream> +#endif + +namespace +{ + +void +load_mruby_symbols(void *obj) +{ + cg_core.sym_config = mrb_intern_cstr(cg_core.mrb, "config"); + cg_core.sym_debug = mrb_intern_cstr(cg_core.mrb, "debug"); + cg_core.sym_error = mrb_intern_cstr(cg_core.mrb, "error"); + cg_core.sym_fatal = mrb_intern_cstr(cg_core.mrb, "fatal"); + cg_core.sym_information = mrb_intern_cstr(cg_core.mrb, "information"); + cg_core.sym_init = mrb_intern_cstr(cg_core.mrb, "init"); + cg_core.sym_key_down = mrb_intern_cstr(cg_core.mrb, "key_down"); + cg_core.sym_key_up = mrb_intern_cstr(cg_core.mrb, "key_up"); + cg_core.sym_quit = mrb_intern_cstr(cg_core.mrb, "quit"); + cg_core.sym_tick = mrb_intern_cstr(cg_core.mrb, "tick"); + cg_core.sym_trace = mrb_intern_cstr(cg_core.mrb, "trace"); + cg_core.sym_warning = mrb_intern_cstr(cg_core.mrb, "warning"); +} + +void +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); + + fp = fopen(cg_core.game_file.c_str(), "rb"); + mrb_load_irep_file(cg_core.mrb, fp); + fclose(fp); + if (cg_core.mrb->exc) + { + mrb_print_error(cg_core.mrb); + throw CommandError{"Error loading game."}; + } + + mrb_funcall_id(cg_core.mrb, main_obj, cg_core.sym_config, 0); + if (cg_core.mrb->exc) + { + mrb_print_error(cg_core.mrb); + throw CommandError{"Error configuring game."}; + } + + cg_candy_gear_finish_config(cg_core.mrb); + cg_graphic_finish_config(cg_core.mrb); +} + +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); +} + +void +unload_blucat(void *obj) +{ + BluCat::INT::core.loader.revert(nullptr); +} + +void +load_mruby_interface(void *obj) +{ + cg_candy_gear_init(cg_core.mrb); + cg_font_init(cg_core.mrb); + cg_key_init(cg_core.mrb); + cg_orientation_3d_init(cg_core.mrb); + cg_skeletal_model_init(cg_core.mrb); + cg_skeletal_mesh_init(cg_core.mrb); + cg_static_model_init(cg_core.mrb); + cg_static_mesh_init(cg_core.mrb); + cg_sound_init(cg_core.mrb); + cg_sprite_init(cg_core.mrb); + cg_sprite_3d_init(cg_core.mrb); + cg_texture_init(cg_core.mrb); + cg_vector_3d_init(cg_core.mrb); + cg_vector_4d_init(cg_core.mrb); + cg_view_2d_init(cg_core.mrb); + cg_view_3d_init(cg_core.mrb); +} + +} + +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 new file mode 100644 index 0000000..60d8339 --- /dev/null +++ b/src/candy_gear/core.hpp @@ -0,0 +1,66 @@ +/* + * Copyright 2022-2024 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 CANDY_GEAR_CORE_H +#define CANDY_GEAR_CORE_H 1 + +#include <mruby.h> +#include <mruby/class.h> +#include <mruby/compile.h> +#include <mruby/data.h> +#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" + +/** + * The Core class stores all global states that the engine needs to work. + * Global variables are not evil if you use them carefully. + */ +struct cg_sCore +{ + static const CommandChain loader; + + mrb_state *mrb; + + std::string game_file; + + /// mruby symbols + mrb_sym sym_config, sym_debug, sym_error, sym_fatal, sym_information, + sym_init, sym_key_down, sym_key_up, sym_quit, sym_tick, sym_trace, + sym_warning; + + bool quit_game; + + SDL_Window *window; +}; + +extern cg_sCore cg_core; + +#endif /* CANDY_GEAR_CORE_H */ diff --git a/src/candy_gear/font.cpp b/src/candy_gear/font.cpp new file mode 100644 index 0000000..f9cbf44 --- /dev/null +++ b/src/candy_gear/font.cpp @@ -0,0 +1,68 @@ +/* + * Copyright 2022-2024 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. + */ + +#include "font.hpp" + +#include "../blu_cat/gra/font.hpp" + +void +cg_free_font(mrb_state *mrb, void *obj) +{ + auto ptr = static_cast<BluCat::GRA::Font*>(obj); + + ptr->~Font(); + mrb_free(mrb, ptr); +} + +const struct mrb_data_type +cg_font_type = {"CG_Font", cg_free_font}; + +static mrb_value +cg_cFont_initialize(mrb_state *mrb, mrb_value self) +{ + BluCat::GRA::Font *ptr; + const char *font_path; + mrb_int font_size; + + mrb_get_args(mrb, "zi", &font_path, &font_size); + ptr = (BluCat::GRA::Font*)DATA_PTR(self); + if(ptr) mrb_free(mrb, ptr); + ptr = (BluCat::GRA::Font*)mrb_malloc(mrb, sizeof(BluCat::GRA::Font)); + + try + { + new(ptr)BluCat::GRA::Font(font_path, font_size); + } + catch(const std::invalid_argument &e) + { + mrb_raise(mrb, E_RUNTIME_ERROR, e.what()); + } + + mrb_data_init(self, ptr, &cg_font_type); + return self; +} + +void +cg_font_init(mrb_state *mrb) +{ + struct RClass *cg_m, *cg_cFont; + + cg_m = mrb_module_get(mrb, "CandyGear"); + cg_cFont = mrb_define_class_under(mrb, cg_m, "Font", mrb->object_class); + MRB_SET_INSTANCE_TT(cg_cFont, MRB_TT_DATA); + mrb_define_method( + mrb, cg_cFont, "initialize", cg_cFont_initialize, MRB_ARGS_REQ(2)); +} diff --git a/src/candy_gear/font.hpp b/src/candy_gear/font.hpp new file mode 100644 index 0000000..0128ea0 --- /dev/null +++ b/src/candy_gear/font.hpp @@ -0,0 +1,28 @@ +/* + * Copyright 2022-2023 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 CANDY_GEAR_FONT_H +#define CANDY_GEAR_FONT_H 1 + +#include "core.hpp" + +extern const struct mrb_data_type +cg_font_type; + +void +cg_font_init(mrb_state *mrb); + +#endif /* CANDY_GEAR_FONT_H */ diff --git a/src/candy_gear/graphic.cpp b/src/candy_gear/graphic.cpp new file mode 100644 index 0000000..ad701d1 --- /dev/null +++ b/src/candy_gear/graphic.cpp @@ -0,0 +1,83 @@ +/* + * Copyright 2022 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. + */ + +#include "graphic.hpp" + +#include "core.hpp" + +static mrb_value +cg_mCandyGear_set_display_width(mrb_state *mrb, mrb_value self) +{ + mrb_int width; + + mrb_get_args(mrb, "i", &width); + BluCat::INT::core.display_width = width; + + return self; +} + +static mrb_value +cg_mCandyGear_set_display_height(mrb_state *mrb, mrb_value self) +{ + mrb_int height; + + mrb_get_args(mrb, "i", &height); + BluCat::INT::core.display_height = height; + + return self; +} + +static mrb_value +cg_mCandyGear_set_fps(mrb_state *mrb, mrb_value self) +{ + mrb_int fps; + + mrb_get_args(mrb, "i", &fps); + BluCat::INT::core.fps = fps; + + return self; +} + +void +cg_graphic_init_config(mrb_state *mrb) +{ + struct RClass *cg_m, *cg_mGraphic; + + cg_m = mrb_module_get(mrb, "CandyGear"); + cg_mGraphic = mrb_define_module_under(mrb, cg_m, "Graphic"); + + mrb_define_class_method( + mrb, cg_mGraphic, "display_width=", cg_mCandyGear_set_display_width, + MRB_ARGS_REQ(1)); + mrb_define_class_method( + mrb, cg_mGraphic, "display_height=", cg_mCandyGear_set_display_height, + MRB_ARGS_REQ(1)); + mrb_define_class_method( + mrb, cg_mGraphic, "fps=", cg_mCandyGear_set_fps, MRB_ARGS_REQ(1)); +} + +void +cg_graphic_finish_config(mrb_state *mrb) +{ + struct RClass *cg_m, *cg_mGraphic; + + cg_m = mrb_module_get(mrb, "CandyGear"); + cg_mGraphic = mrb_module_get_under(mrb, cg_m, "Graphic"); + + mrb_undef_class_method(mrb, cg_mGraphic, "display_width="); + mrb_undef_class_method(mrb, cg_mGraphic, "display_height="); + mrb_undef_class_method(mrb, cg_mGraphic, "fps="); +} diff --git a/src/candy_gear/graphic.hpp b/src/candy_gear/graphic.hpp new file mode 100644 index 0000000..fbd9df8 --- /dev/null +++ b/src/candy_gear/graphic.hpp @@ -0,0 +1,29 @@ +/* + * Copyright 2022 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 CANDY_GEAR_GRAPHIC_H +#define CANDY_GEAR_GRAPHIC_H 1 + +#include "core.hpp" + +// Provides the basic interface the game needs to configure the engine's +// initialization. +void +cg_graphic_init_config(mrb_state *mrb); +void +cg_graphic_finish_config(mrb_state *mrb); + +#endif /* CANDY_GEAR_GRAPHIC_H */ diff --git a/src/candy_gear/key.cpp b/src/candy_gear/key.cpp new file mode 100644 index 0000000..615119c --- /dev/null +++ b/src/candy_gear/key.cpp @@ -0,0 +1,71 @@ +/* + * Copyright 2022 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. + */ + +#include "key.hpp" + +void +cg_key_init(mrb_state *mrb) +{ + struct RClass *cg_m, *cg_mKey; + + cg_m = mrb_module_get(mrb, "CandyGear"); + cg_mKey = mrb_define_module_under(mrb, cg_m, "Key"); + + mrb_define_const(mrb, cg_mKey, "A", mrb_int_value(mrb, SDLK_a)); + mrb_define_const(mrb, cg_mKey, "B", mrb_int_value(mrb, SDLK_b)); + mrb_define_const(mrb, cg_mKey, "C", mrb_int_value(mrb, SDLK_c)); + mrb_define_const(mrb, cg_mKey, "D", mrb_int_value(mrb, SDLK_d)); + mrb_define_const(mrb, cg_mKey, "E", mrb_int_value(mrb, SDLK_e)); + mrb_define_const(mrb, cg_mKey, "F", mrb_int_value(mrb, SDLK_f)); + mrb_define_const(mrb, cg_mKey, "G", mrb_int_value(mrb, SDLK_g)); + mrb_define_const(mrb, cg_mKey, "H", mrb_int_value(mrb, SDLK_h)); + mrb_define_const(mrb, cg_mKey, "I", mrb_int_value(mrb, SDLK_i)); + mrb_define_const(mrb, cg_mKey, "J", mrb_int_value(mrb, SDLK_j)); + mrb_define_const(mrb, cg_mKey, "K", mrb_int_value(mrb, SDLK_k)); + mrb_define_const(mrb, cg_mKey, "L", mrb_int_value(mrb, SDLK_l)); + mrb_define_const(mrb, cg_mKey, "M", mrb_int_value(mrb, SDLK_m)); + mrb_define_const(mrb, cg_mKey, "N", mrb_int_value(mrb, SDLK_n)); + mrb_define_const(mrb, cg_mKey, "O", mrb_int_value(mrb, SDLK_o)); + mrb_define_const(mrb, cg_mKey, "P", mrb_int_value(mrb, SDLK_p)); + mrb_define_const(mrb, cg_mKey, "Q", mrb_int_value(mrb, SDLK_q)); + mrb_define_const(mrb, cg_mKey, "R", mrb_int_value(mrb, SDLK_r)); + mrb_define_const(mrb, cg_mKey, "S", mrb_int_value(mrb, SDLK_s)); + mrb_define_const(mrb, cg_mKey, "T", mrb_int_value(mrb, SDLK_t)); + mrb_define_const(mrb, cg_mKey, "U", mrb_int_value(mrb, SDLK_u)); + mrb_define_const(mrb, cg_mKey, "V", mrb_int_value(mrb, SDLK_v)); + mrb_define_const(mrb, cg_mKey, "W", mrb_int_value(mrb, SDLK_w)); + mrb_define_const(mrb, cg_mKey, "X", mrb_int_value(mrb, SDLK_x)); + mrb_define_const(mrb, cg_mKey, "Y", mrb_int_value(mrb, SDLK_y)); + mrb_define_const(mrb, cg_mKey, "Z", mrb_int_value(mrb, SDLK_z)); + + mrb_define_const(mrb, cg_mKey, "UP", mrb_int_value(mrb, SDLK_UP)); + mrb_define_const(mrb, cg_mKey, "DOWN", mrb_int_value(mrb, SDLK_DOWN)); + mrb_define_const(mrb, cg_mKey, "LEFT", mrb_int_value(mrb, SDLK_LEFT)); + mrb_define_const(mrb, cg_mKey, "RIGHT", mrb_int_value(mrb, SDLK_RIGHT)); + + mrb_define_const( + mrb, cg_mKey, "BACKSPACE", mrb_int_value(mrb, SDLK_BACKSPACE)); + mrb_define_const(mrb, cg_mKey, "TAB", mrb_int_value(mrb, SDLK_TAB)); + mrb_define_const( + mrb, cg_mKey, "LEFT_SHIFT", mrb_int_value(mrb, SDLK_LSHIFT)); + mrb_define_const( + mrb, cg_mKey, "RIGHT_SHIFT", mrb_int_value(mrb, SDLK_RSHIFT)); + mrb_define_const(mrb, cg_mKey, "SPACE", mrb_int_value(mrb, SDLK_SPACE)); + mrb_define_const(mrb, cg_mKey, "LEFT_ALT", mrb_int_value(mrb, SDLK_LALT)); + mrb_define_const(mrb, cg_mKey, "RIGHT_ALT", mrb_int_value(mrb, SDLK_RALT)); + mrb_define_const(mrb, cg_mKey, "LEFT_CTRL", mrb_int_value(mrb, SDLK_LCTRL)); + mrb_define_const(mrb, cg_mKey, "RIGHT_CTRL", mrb_int_value(mrb, SDLK_RCTRL)); +} diff --git a/src/candy_gear/key.hpp b/src/candy_gear/key.hpp new file mode 100644 index 0000000..d3f4f5f --- /dev/null +++ b/src/candy_gear/key.hpp @@ -0,0 +1,25 @@ +/* + * Copyright 2022 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 CANDY_GEAR_KEY_H +#define CANDY_GEAR_KEY_H 1 + +#include "core.hpp" + +void +cg_key_init(mrb_state *mrb); + +#endif /* CANDY_GEAR_KEY_H */ diff --git a/src/candy_gear/main.cpp b/src/candy_gear/main.cpp new file mode 100644 index 0000000..353b6bf --- /dev/null +++ b/src/candy_gear/main.cpp @@ -0,0 +1,115 @@ +/* + * Copyright 2022-2024 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. + */ + +#include <chrono> +#include <thread> + +#include "core.hpp" + +cg_sCore cg_core; + +int main(int argc, char *argv[]) +{ + using namespace std::chrono; + using namespace std::this_thread; + + SDL_Event event; + + // Random numbers + BluCat::INT::random_number_generator.seed(BluCat::INT::random_seed()); + + cg_core.game_file = argv[1]; + cg_core.mrb = mrb_open(); + if (!cg_core.mrb) throw CommandError{"Failed to initialize mruby."}; + try{ cg_sCore::loader.execute(nullptr); } + catch(const CommandError &error) + { + BluCat::INT::core.log.message(Log::Level::Fatal, error.what()); + mrb_close(cg_core.mrb); + return 1; + } + + mrb_value main_obj{mrb_top_self(cg_core.mrb)}; + + mrb_funcall_id(cg_core.mrb, main_obj, cg_core.sym_init, 0); + if (cg_core.mrb->exc) + { + mrb_print_error(cg_core.mrb); + mrb_close(cg_core.mrb); + cg_sCore::loader.revert(nullptr); + return 1; + } + + auto frame_start = steady_clock::now(); + + // Game main loop. + while(!cg_core.quit_game) + { + // Get input. + while(SDL_PollEvent(&event) != 0) + { + switch(event.type) + { + case SDL_KEYDOWN: + mrb_funcall_id( + cg_core.mrb, main_obj, cg_core.sym_key_down, 1, + mrb_int_value(cg_core.mrb, event.key.keysym.sym)); + break; + case SDL_KEYUP: + mrb_funcall_id( + cg_core.mrb, main_obj, cg_core.sym_key_up, 1, + mrb_int_value(cg_core.mrb, event.key.keysym.sym)); + break; + case SDL_MOUSEMOTION: + break; + case SDL_MOUSEBUTTONDOWN: + break; + case SDL_MOUSEBUTTONUP: + break; + case SDL_QUIT: + mrb_funcall_id(cg_core.mrb, main_obj, cg_core.sym_quit, 0); + break; + } + } + + mrb_funcall_id(cg_core.mrb, main_obj, cg_core.sym_tick, 0); + if (cg_core.mrb->exc) + { + mrb_print_error(cg_core.mrb); + cg_core.quit_game = true; + } + else + { + 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(BluCat::INT::core.max_frame_duration > frame_duration) + sleep_for(BluCat::INT::core.max_frame_duration - frame_duration); + + frame_start = frame_stop; + } + } + } + + mrb_close(cg_core.mrb); + cg_sCore::loader.revert(nullptr); + + return 0; +} diff --git a/src/candy_gear/orientation_3d.cpp b/src/candy_gear/orientation_3d.cpp new file mode 100644 index 0000000..cb42984 --- /dev/null +++ b/src/candy_gear/orientation_3d.cpp @@ -0,0 +1,135 @@ +/* + * Copyright 2022-2024 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. + */ + +#define _USE_MATH_DEFINES + +#include "orientation_3d.hpp" + +#include "vector_3d.hpp" + +void +cg_free_orientation_3d(mrb_state *mrb, void* obj) +{ + auto ptr = static_cast<std::shared_ptr<glm::quat>*>(obj); + + ptr->~shared_ptr(); + mrb_free(mrb, ptr); +} + +const struct mrb_data_type cg_orientation_3d_type = { + "CG_Orientation3D", cg_free_orientation_3d}; + +static mrb_value +cg_cOrientation3D_initialize(mrb_state *mrb, mrb_value self) +{ + mrb_float x, y, z; + std::shared_ptr<glm::quat> *ptr; + + mrb_get_args(mrb, "fff", &x, &y, &z); + ptr = (std::shared_ptr<glm::quat>*)DATA_PTR(self); + if(ptr) mrb_free(mrb, ptr); + ptr = (std::shared_ptr<glm::quat>*)mrb_malloc( + mrb, sizeof(std::shared_ptr<glm::quat>)); + + glm::vec3 angles(x, y, z); + new(ptr)std::shared_ptr<glm::quat>( + std::make_shared<glm::quat>(angles)); + (**ptr) = glm::normalize(**ptr); + + mrb_data_init(self, ptr, &cg_orientation_3d_type); + return self; +} + +static mrb_value +cg_cOrientation3D_get_w(mrb_state *mrb, mrb_value self) +{ + std::shared_ptr<glm::quat> *ptr = + (std::shared_ptr<glm::quat>*)DATA_PTR(self); + + return mrb_float_value(mrb, (*ptr)->w); +} + +static mrb_value +cg_cOrientation3D_get_x(mrb_state *mrb, mrb_value self) +{ + std::shared_ptr<glm::quat> *ptr = + (std::shared_ptr<glm::quat>*)DATA_PTR(self); + + return mrb_float_value(mrb, (*ptr)->x); +} + +static mrb_value +cg_cOrientation3D_get_y(mrb_state *mrb, mrb_value self) +{ + std::shared_ptr<glm::quat> *ptr = + (std::shared_ptr<glm::quat>*)DATA_PTR(self); + + return mrb_float_value(mrb, (*ptr)->y); +} + +static mrb_value +cg_cOrientation3D_get_z(mrb_state *mrb, mrb_value self) +{ + std::shared_ptr<glm::quat> *ptr = + (std::shared_ptr<glm::quat>*)DATA_PTR(self); + + return mrb_float_value(mrb, (*ptr)->z); +} + +static mrb_value +cg_cOrientation3D_rotate(mrb_state *mrb, mrb_value self) +{ + mrb_float x, y, z; + auto *ptr = (std::shared_ptr<glm::quat>*)DATA_PTR(self); + + mrb_get_args(mrb, "fff", &x, &y, &z); + + glm::vec3 angles(x, y, z); + glm::quat rot(angles); + (**ptr) *= rot; + + // TODO: calling normalize for every rotation is expensive. + (**ptr) = glm::normalize(**ptr); + + return self; +} + +void +cg_orientation_3d_init(mrb_state *mrb) +{ + struct RClass *cg_m, *cg_cOrientation3D; + + cg_m = mrb_module_get(mrb, "CandyGear"); + cg_cOrientation3D = mrb_define_class_under( + mrb, cg_m, "Orientation3D", mrb->object_class); + MRB_SET_INSTANCE_TT(cg_cOrientation3D, MRB_TT_DATA); + mrb_define_method( + mrb, cg_cOrientation3D, "initialize", cg_cOrientation3D_initialize, + MRB_ARGS_REQ(3)); + + mrb_define_method( + mrb, cg_cOrientation3D, "w", cg_cOrientation3D_get_w, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cOrientation3D, "x", cg_cOrientation3D_get_x, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cOrientation3D, "y", cg_cOrientation3D_get_y, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cOrientation3D, "z", cg_cOrientation3D_get_z, MRB_ARGS_NONE()); + + mrb_define_method( + mrb, cg_cOrientation3D, "rotate", cg_cOrientation3D_rotate, + MRB_ARGS_REQ(3)); +} diff --git a/src/candy_gear/orientation_3d.hpp b/src/candy_gear/orientation_3d.hpp new file mode 100644 index 0000000..45a8ab2 --- /dev/null +++ b/src/candy_gear/orientation_3d.hpp @@ -0,0 +1,27 @@ +/* + * Copyright 2022-2024 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 CANDY_GEAR_ORIENTATION_3D_H +#define CANDY_GEAR_ORIENTATION_3D_H 1 + +#include "core.hpp" + +extern const struct mrb_data_type cg_orientation_3d_type; + +void +cg_orientation_3d_init(mrb_state *mrb); + +#endif /* CANDY_GEAR_ORIENTATION_3D_H */ diff --git a/src/candy_gear/skeletal_mesh.cpp b/src/candy_gear/skeletal_mesh.cpp new file mode 100644 index 0000000..4af4419 --- /dev/null +++ b/src/candy_gear/skeletal_mesh.cpp @@ -0,0 +1,67 @@ +/* + * Copyright 2022-2024 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. + */ + +#include "skeletal_mesh.hpp" + +#include "orientation_3d.hpp" +#include "vector_3d.hpp" +#include "../blu_cat/gra/skeletal_mesh.hpp" + +void +cg_free_skeletal_mesh(mrb_state *mrb, void* obj) +{ + auto ptr = static_cast<std::shared_ptr<BluCat::GRA::SkeletalMesh>*>(obj); + + ptr->~shared_ptr(); + mrb_free(mrb, ptr); +} + +const struct mrb_data_type cg_skeletal_mesh_type = { + "CG_SkeletalMesh", cg_free_skeletal_mesh }; + +static mrb_value +cg_cSkeletalMesh_initialize(mrb_state *mrb, mrb_value self) +{ + const char *file_path; + + std::shared_ptr<BluCat::GRA::SkeletalMesh> *ptr; + + mrb_get_args(mrb, "z", &file_path); + ptr = (std::shared_ptr<BluCat::GRA::SkeletalMesh>*)DATA_PTR(self); + if(ptr) mrb_free(mrb, ptr); + ptr = (std::shared_ptr<BluCat::GRA::SkeletalMesh>*)mrb_malloc( + mrb, sizeof(std::shared_ptr<BluCat::GRA::SkeletalMesh>)); + + new(ptr)std::shared_ptr<BluCat::GRA::SkeletalMesh>( + std::make_shared<BluCat::GRA::SkeletalMesh>(file_path)); + + mrb_data_init(self, ptr, &cg_skeletal_mesh_type); + return self; +} + +void +cg_skeletal_mesh_init(mrb_state *mrb) +{ + struct RClass *cg_m, *cg_cSkeletalMesh; + + cg_m = mrb_module_get(mrb, "CandyGear"); + cg_cSkeletalMesh = mrb_define_class_under( + mrb, cg_m, "SkeletalMesh", mrb->object_class); + MRB_SET_INSTANCE_TT(cg_cSkeletalMesh, MRB_TT_DATA); + mrb_define_method( + mrb, cg_cSkeletalMesh, "initialize", cg_cSkeletalMesh_initialize, + MRB_ARGS_REQ(1)); +} diff --git a/src/candy_gear/skeletal_mesh.hpp b/src/candy_gear/skeletal_mesh.hpp new file mode 100644 index 0000000..476aa9b --- /dev/null +++ b/src/candy_gear/skeletal_mesh.hpp @@ -0,0 +1,27 @@ +/* + * Copyright 2022-2023 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 CANDY_GEAR_SKELETAL_MESH_H +#define CANDY_GEAR_SKELETAL_MESH_H 1 + +#include "core.hpp" + +extern const struct mrb_data_type cg_skeletal_mesh_type; + +void +cg_skeletal_mesh_init(mrb_state *mrb); + +#endif /* CANDY_GEAR_SKELETAL_MESH_H */ diff --git a/src/candy_gear/skeletal_model.cpp b/src/candy_gear/skeletal_model.cpp new file mode 100644 index 0000000..41d0c9a --- /dev/null +++ b/src/candy_gear/skeletal_model.cpp @@ -0,0 +1,134 @@ +/* + * Copyright 2022-2024 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. + */ + +#include "skeletal_model.hpp" + +#include "orientation_3d.hpp" +#include "vector_3d.hpp" +#include "skeletal_mesh.hpp" +#include "texture.hpp" +#include "../blu_cat/gra/skeletal_model.hpp" + +void +cg_free_skeletal_model(mrb_state *mrb, void *obj) +{ + auto ptr = static_cast<std::shared_ptr<BluCat::GRA::SkeletalModel>*>(obj); + + ptr->~shared_ptr(); + mrb_free(mrb, ptr); +} + +const struct mrb_data_type cg_skeletal_model_type = { + "CG_SkeletalModel", cg_free_skeletal_model }; + +static mrb_value +cg_cSkeletalModel_initialize(mrb_state *mrb, mrb_value self) +{ + std::shared_ptr<BluCat::GRA::SkeletalMesh> *skeletal_mesh; + std::shared_ptr<BluCat::GRA::Texture> *texture; + std::shared_ptr<glm::vec3> *position; + std::shared_ptr<glm::quat> *orientation; + std::shared_ptr<BluCat::GRA::SkeletalModel> *ptr; + + mrb_get_args( + mrb, "dddd", &skeletal_mesh, &cg_skeletal_mesh_type, &texture, + &cg_texture_type, &position, &cg_vector_3d_type, &orientation, + &cg_orientation_3d_type); + ptr = (std::shared_ptr<BluCat::GRA::SkeletalModel>*)DATA_PTR(self); + if(ptr) mrb_free(mrb, ptr); + ptr = (std::shared_ptr<BluCat::GRA::SkeletalModel>*)mrb_malloc( + mrb, sizeof(std::shared_ptr<BluCat::GRA::SkeletalModel>)); + + new(ptr)std::shared_ptr<BluCat::GRA::SkeletalModel>( + std::make_shared<BluCat::GRA::SkeletalModel>( + *skeletal_mesh, *texture, *position, *orientation)); + + mrb_data_init(self, ptr, &cg_skeletal_model_type); + return self; +} + +static mrb_value +cg_cSkeletalModel_set_orientation(mrb_state *mrb, mrb_value self) +{ + auto ptr = (std::shared_ptr<BluCat::GRA::SkeletalModel>*)DATA_PTR(self); + std::shared_ptr<glm::quat> *orientation; + + mrb_get_args(mrb, "d", &orientation, &cg_orientation_3d_type); + (*ptr)->orientation = *orientation; + + return self; +} + +static mrb_value +cg_cSkeletalModel_set_position(mrb_state *mrb, mrb_value self) +{ + auto ptr = (std::shared_ptr<BluCat::GRA::SkeletalModel>*)DATA_PTR(self); + std::shared_ptr<glm::vec3> *position; + + mrb_get_args(mrb, "d", &position, &cg_vector_3d_type); + (*ptr)->position = *position; + + return self; +} + +static mrb_value +cg_cSkeletalModel_set_animation(mrb_state *mrb, mrb_value self) +{ + auto ptr = (std::shared_ptr<BluCat::GRA::SkeletalModel>*)DATA_PTR(self); + mrb_int animation_index; + + mrb_get_args(mrb, "i", &animation_index); + (*ptr)->animation_index = animation_index; + + return self; +} + +static mrb_value +cg_cSkeletalModel_draw(mrb_state *mrb, mrb_value self) +{ + auto ptr = (std::shared_ptr<BluCat::GRA::SkeletalModel>*)DATA_PTR(self); + + auto &instances = BluCat::INT::core.vk_renderer->skeletal_models_to_draw[ + BluCat::INT::core.vk_swapchain->current_frame][(*ptr)->skeletal_mesh]; + instances.push_back(*ptr); + + return self; +} + +void +cg_skeletal_model_init(mrb_state *mrb) +{ + struct RClass *cg_m, *cg_cSkeletalModel; + + cg_m = mrb_module_get(mrb, "CandyGear"); + cg_cSkeletalModel = mrb_define_class_under( + mrb, cg_m, "SkeletalModel", mrb->object_class); + MRB_SET_INSTANCE_TT(cg_cSkeletalModel, MRB_TT_DATA); + mrb_define_method( + mrb, cg_cSkeletalModel, "initialize", cg_cSkeletalModel_initialize, + MRB_ARGS_REQ(4)); + mrb_define_method( + mrb, cg_cSkeletalModel, "position=", cg_cSkeletalModel_set_position, + MRB_ARGS_REQ(1)); + mrb_define_method( + mrb, cg_cSkeletalModel, "orientation=", cg_cSkeletalModel_set_orientation, + MRB_ARGS_REQ(1)); + mrb_define_method( + mrb, cg_cSkeletalModel, "animation=", cg_cSkeletalModel_set_animation, + MRB_ARGS_REQ(1)); + mrb_define_method( + mrb, cg_cSkeletalModel, "draw", cg_cSkeletalModel_draw, MRB_ARGS_NONE()); +} diff --git a/src/candy_gear/skeletal_model.hpp b/src/candy_gear/skeletal_model.hpp new file mode 100644 index 0000000..05f9c2e --- /dev/null +++ b/src/candy_gear/skeletal_model.hpp @@ -0,0 +1,25 @@ +/* + * Copyright 2022-2023 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 CANDY_GEAR_SKELETAL_MODEL_H +#define CANDY_GEAR_SKELETAL_MODEL_H 1 + +#include "core.hpp" + +void +cg_skeletal_model_init(mrb_state *mrb); + +#endif /* CANDY_GEAR_SKELETAL_MODEL_H */ diff --git a/src/candy_gear/sound.cpp b/src/candy_gear/sound.cpp new file mode 100644 index 0000000..0b3518f --- /dev/null +++ b/src/candy_gear/sound.cpp @@ -0,0 +1,73 @@ +/* + * Copyright 2022 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. + */ + +#include "sound.hpp" + +void +cg_free_sound(mrb_state *mrb, void* obj) +{ + struct cg_sound *ptr = static_cast<cg_sound*>(obj); + + Mix_FreeChunk(ptr->chunk); + mrb_free(mrb, ptr); +} + +const struct mrb_data_type cg_sound_type = { + "CG_Sound", cg_free_sound }; + +static mrb_value +cg_cSound_initialize(mrb_state *mrb, mrb_value self) +{ + const char *file_path; + + struct cg_sound *ptr; + + mrb_get_args(mrb, "z", &file_path); + ptr = (struct cg_sound *)DATA_PTR(self); + if(ptr) mrb_free(mrb, ptr); + ptr = (struct cg_sound *)mrb_malloc(mrb, sizeof(struct cg_sound)); + + ptr->chunk = Mix_LoadWAV(file_path); + if(ptr->chunk == NULL) mrb_raise(mrb, E_RUNTIME_ERROR, Mix_GetError()); + + mrb_data_init(self, ptr, &cg_sound_type); + return self; +} + +static mrb_value +cg_cSound_play(mrb_state *mrb, mrb_value self) +{ + struct cg_sound *ptr; + + ptr = (struct cg_sound *)DATA_PTR(self); + + Mix_PlayChannel(-1, ptr->chunk, 0); + + return self; +} + +void +cg_sound_init(mrb_state *mrb) +{ + struct RClass *cg_m, *cg_cSound; + + cg_m = mrb_module_get(mrb, "CandyGear"); + cg_cSound = mrb_define_class_under(mrb, cg_m, "Sound", mrb->object_class); + MRB_SET_INSTANCE_TT(cg_cSound, MRB_TT_DATA); + mrb_define_method( + mrb, cg_cSound, "initialize", cg_cSound_initialize, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, cg_cSound, "play", cg_cSound_play, MRB_ARGS_NONE()); +} diff --git a/src/candy_gear/sound.hpp b/src/candy_gear/sound.hpp new file mode 100644 index 0000000..2f483e3 --- /dev/null +++ b/src/candy_gear/sound.hpp @@ -0,0 +1,32 @@ +/* + * Copyright 2022 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 CANDY_GEAR_SOUND_H +#define CANDY_GEAR_SOUND_H 1 + +#include "core.hpp" + +struct cg_sound +{ + Mix_Chunk *chunk; +}; + +extern const struct mrb_data_type cg_sound_type; + +void +cg_sound_init(mrb_state *mrb); + +#endif /* CANDY_GEAR_SOUND_H */ diff --git a/src/candy_gear/sprite.cpp b/src/candy_gear/sprite.cpp new file mode 100644 index 0000000..daf96a8 --- /dev/null +++ b/src/candy_gear/sprite.cpp @@ -0,0 +1,93 @@ +/* + * Copyright 2022-2024 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. + */ + +#include "sprite.hpp" + +#include "texture.hpp" +#include "vector_4d.hpp" +#include "view_2d.hpp" +#include "../blu_cat/gra/sprite.hpp" + +void +cg_free_sprite(mrb_state *mrb, void* obj) +{ + auto ptr = static_cast<std::shared_ptr<BluCat::GRA::Sprite>*>(obj); + + ptr->~shared_ptr(); + mrb_free(mrb, ptr); +} + +const struct mrb_data_type cg_sprite_type = { "CG_Sprite", cg_free_sprite }; + +static mrb_value +cg_cSprite_initialize(mrb_state *mrb, mrb_value self) +{ + mrb_float x, y, w, h; + glm::vec4 vector_4d; + std::shared_ptr<BluCat::GRA::Texture> *texture; + std::shared_ptr<BluCat::GRA::Sprite> *ptr; + + mrb_get_args( + mrb, "dffff", &texture, &cg_texture_type, &x, &y, &w, &h); + ptr = (std::shared_ptr<BluCat::GRA::Sprite>*)DATA_PTR(self); + if(ptr) mrb_free(mrb, ptr); + ptr = (std::shared_ptr<BluCat::GRA::Sprite>*)mrb_malloc( + mrb, sizeof(std::shared_ptr<BluCat::GRA::Sprite>)); + + vector_4d.x = x; + vector_4d.y = y; + vector_4d.z = w; + vector_4d.w = h; + new(ptr)std::shared_ptr<BluCat::GRA::Sprite>( + std::make_shared<BluCat::GRA::Sprite>(*texture, vector_4d)); + + mrb_data_init(self, ptr, &cg_sprite_type); + return self; +} + +static mrb_value +cg_cSprite_draw(mrb_state *mrb, mrb_value self) +{ + mrb_value view_value; + BluCat::GRA::View2D *view_2d; + mrb_float x, y, w, h, z_index{0.0}; + auto ptr = (std::shared_ptr<BluCat::GRA::Sprite>*)DATA_PTR(self); + + mrb_get_args(mrb, "offff|f", &view_value, &x, &y, &w, &h, &z_index); + + view_2d = cg_cView_to_view_2d(mrb, view_value); + + glm::vec4 rect(x, y, x + w, y + h); + auto &sprites_to_draw = view_2d->sprites_to_draw[ + BluCat::INT::core.vk_swapchain->current_frame]; + sprites_to_draw.emplace_back(*ptr, rect, z_index); + + return self; +} + +void +cg_sprite_init(mrb_state *mrb) +{ + struct RClass *cg_m, *cg_cSprite; + + cg_m = mrb_module_get(mrb, "CandyGear"); + cg_cSprite = mrb_define_class_under(mrb, cg_m, "Sprite", mrb->object_class); + MRB_SET_INSTANCE_TT(cg_cSprite, MRB_TT_DATA); + mrb_define_method( + mrb, cg_cSprite, "initialize", cg_cSprite_initialize, MRB_ARGS_REQ(5)); + mrb_define_method(mrb, cg_cSprite, "draw", cg_cSprite_draw, MRB_ARGS_REQ(5)| + MRB_ARGS_OPT(1)); +} diff --git a/src/candy_gear/sprite.hpp b/src/candy_gear/sprite.hpp new file mode 100644 index 0000000..528f2f7 --- /dev/null +++ b/src/candy_gear/sprite.hpp @@ -0,0 +1,27 @@ +/* + * Copyright 2022 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 CANDY_GEAR_SPRITE_H +#define CANDY_GEAR_SPRITE_H 1 + +#include "core.hpp" + +extern const struct mrb_data_type cg_sprite_type; + +void +cg_sprite_init(mrb_state *mrb); + +#endif /* CANDY_GEAR_SPRITE_H */ diff --git a/src/candy_gear/sprite_3d.cpp b/src/candy_gear/sprite_3d.cpp new file mode 100644 index 0000000..d03b585 --- /dev/null +++ b/src/candy_gear/sprite_3d.cpp @@ -0,0 +1,82 @@ +/* + * Copyright 2022-2024 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. + */ + +#include "sprite_3d.hpp" + +#include "sprite.hpp" +#include "vector_3d.hpp" + +void +cg_free_sprite_3d(mrb_state *mrb, void *obj) +{ + auto ptr = static_cast<std::shared_ptr<BluCat::GRA::Sprite3D>*>(obj); + + ptr->~shared_ptr(); + mrb_free(mrb, ptr); +} + +const struct mrb_data_type cg_sprite_3d_type = { + "CG_Sprite3D", cg_free_sprite_3d }; + +static mrb_value +cg_cSprite3D_initialize(mrb_state *mrb, mrb_value self) +{ + std::shared_ptr<BluCat::GRA::Sprite> *sprite; + std::shared_ptr<glm::vec3> *position; + mrb_float w, h; + std::shared_ptr<BluCat::GRA::Sprite3D> *ptr; + + mrb_get_args(mrb, "ddff", &sprite, &cg_sprite_type, + &position, &cg_vector_3d_type, &w, &h); + ptr = (std::shared_ptr<BluCat::GRA::Sprite3D>*)DATA_PTR(self); + if(ptr) mrb_free(mrb, ptr); + ptr = (std::shared_ptr<BluCat::GRA::Sprite3D>*)mrb_malloc( + mrb, sizeof(std::shared_ptr<BluCat::GRA::Sprite3D>)); + + glm::vec3 size{w, h, 0.0}; + new(ptr)std::shared_ptr<BluCat::GRA::Sprite3D>( + std::make_shared<BluCat::GRA::Sprite3D>(*sprite, *position, size)); + + mrb_data_init(self, ptr, &cg_sprite_3d_type); + return self; +} + +static mrb_value +cg_cSprite3D_draw(mrb_state *mrb, mrb_value self) +{ + auto ptr = (std::shared_ptr<BluCat::GRA::Sprite3D>*)DATA_PTR(self); + + auto &sprites_3d_to_draw = BluCat::INT::core.vk_renderer->sprites_3d_to_draw[ + BluCat::INT::core.vk_swapchain->current_frame]; + sprites_3d_to_draw.emplace_back(*ptr); + + return self; +} + +void +cg_sprite_3d_init(mrb_state *mrb) +{ + struct RClass *cg_m, *cg_cSprite3D; + + cg_m = mrb_module_get(mrb, "CandyGear"); + cg_cSprite3D = mrb_define_class_under( + mrb, cg_m, "Sprite3D", mrb->object_class); + MRB_SET_INSTANCE_TT(cg_cSprite3D, MRB_TT_DATA); + mrb_define_method( + mrb, cg_cSprite3D, "initialize", cg_cSprite3D_initialize, MRB_ARGS_REQ(3)); + mrb_define_method( + mrb, cg_cSprite3D, "draw", cg_cSprite3D_draw, MRB_ARGS_NONE()); +} diff --git a/src/candy_gear/sprite_3d.hpp b/src/candy_gear/sprite_3d.hpp new file mode 100644 index 0000000..526c23a --- /dev/null +++ b/src/candy_gear/sprite_3d.hpp @@ -0,0 +1,25 @@ +/* + * Copyright 2022-2023 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 CANDY_GEAR_SPRITE_3D_H +#define CANDY_GEAR_SPRITE_3D_H 1 + +#include "core.hpp" + +void +cg_sprite_3d_init(mrb_state *mrb); + +#endif /* CANDY_GEAR_SPRITE_3D_H */ diff --git a/src/candy_gear/static_mesh.cpp b/src/candy_gear/static_mesh.cpp new file mode 100644 index 0000000..9cb79ef --- /dev/null +++ b/src/candy_gear/static_mesh.cpp @@ -0,0 +1,67 @@ +/* + * Copyright 2022-2024 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. + */ + +#include "static_mesh.hpp" + +#include "orientation_3d.hpp" +#include "vector_3d.hpp" +#include "../blu_cat/gra/static_mesh.hpp" + +void +cg_free_static_mesh(mrb_state *mrb, void* obj) +{ + auto ptr = static_cast<std::shared_ptr<BluCat::GRA::StaticMesh>*>(obj); + + ptr->~shared_ptr(); + mrb_free(mrb, ptr); +} + +const struct mrb_data_type cg_static_mesh_type = { + "CG_StaticMesh", cg_free_static_mesh }; + +static mrb_value +cg_cStaticMesh_initialize(mrb_state *mrb, mrb_value self) +{ + const char *file_path; + + std::shared_ptr<BluCat::GRA::StaticMesh> *ptr; + + mrb_get_args(mrb, "z", &file_path); + ptr = (std::shared_ptr<BluCat::GRA::StaticMesh>*)DATA_PTR(self); + if(ptr) mrb_free(mrb, ptr); + ptr = (std::shared_ptr<BluCat::GRA::StaticMesh>*)mrb_malloc( + mrb, sizeof(std::shared_ptr<BluCat::GRA::StaticMesh>)); + + new(ptr)std::shared_ptr<BluCat::GRA::StaticMesh>( + std::make_shared<BluCat::GRA::StaticMesh>(file_path)); + + mrb_data_init(self, ptr, &cg_static_mesh_type); + return self; +} + +void +cg_static_mesh_init(mrb_state *mrb) +{ + struct RClass *cg_m, *cg_cStaticMesh; + + cg_m = mrb_module_get(mrb, "CandyGear"); + cg_cStaticMesh = mrb_define_class_under( + mrb, cg_m, "StaticMesh", mrb->object_class); + MRB_SET_INSTANCE_TT(cg_cStaticMesh, MRB_TT_DATA); + mrb_define_method( + mrb, cg_cStaticMesh, "initialize", cg_cStaticMesh_initialize, + MRB_ARGS_REQ(1)); +} diff --git a/src/candy_gear/static_mesh.hpp b/src/candy_gear/static_mesh.hpp new file mode 100644 index 0000000..8f3b2d6 --- /dev/null +++ b/src/candy_gear/static_mesh.hpp @@ -0,0 +1,27 @@ +/* + * Copyright 2022-2023 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 CANDY_GEAR_STATIC_MESH_H +#define CANDY_GEAR_STATIC_MESH_H 1 + +#include "core.hpp" + +extern const struct mrb_data_type cg_static_mesh_type; + +void +cg_static_mesh_init(mrb_state *mrb); + +#endif /* CANDY_GEAR_STATIC_MESH_H */ diff --git a/src/candy_gear/static_model.cpp b/src/candy_gear/static_model.cpp new file mode 100644 index 0000000..1a6eabe --- /dev/null +++ b/src/candy_gear/static_model.cpp @@ -0,0 +1,134 @@ +/* + * Copyright 2022-2024 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. + */ + +#include "static_model.hpp" + +#include "orientation_3d.hpp" +#include "static_mesh.hpp" +#include "texture.hpp" +#include "vector_3d.hpp" +#include "../blu_cat/gra/static_model.hpp" + +void +cg_free_static_model(mrb_state *mrb, void *obj) +{ + auto ptr = static_cast<std::shared_ptr<BluCat::GRA::StaticModel>*>(obj); + + ptr->~shared_ptr(); + mrb_free(mrb, ptr); +} + +const struct mrb_data_type cg_static_model_type = { + "CG_StaticModel", cg_free_static_model }; + +static mrb_value +cg_cStaticModel_initialize(mrb_state *mrb, mrb_value self) +{ + std::shared_ptr<BluCat::GRA::StaticMesh> *static_mesh; + std::shared_ptr<BluCat::GRA::Texture> *texture; + std::shared_ptr<glm::vec3> *position; + std::shared_ptr<glm::quat> *orientation; + std::shared_ptr<BluCat::GRA::StaticModel> *ptr; + + mrb_get_args( + mrb, "dddd", &static_mesh, &cg_static_mesh_type, &texture, + &cg_texture_type, &position, &cg_vector_3d_type, &orientation, + &cg_orientation_3d_type); + ptr = (std::shared_ptr<BluCat::GRA::StaticModel>*)DATA_PTR(self); + if(ptr) mrb_free(mrb, ptr); + ptr = (std::shared_ptr<BluCat::GRA::StaticModel>*)mrb_malloc( + mrb, sizeof(std::shared_ptr<BluCat::GRA::StaticModel>)); + + new(ptr)std::shared_ptr<BluCat::GRA::StaticModel>( + std::make_shared<BluCat::GRA::StaticModel>( + *static_mesh, *texture, *position, *orientation)); + + mrb_data_init(self, ptr, &cg_static_model_type); + return self; +} + +static mrb_value +cg_cStaticModel_set_orientation(mrb_state *mrb, mrb_value self) +{ + auto ptr = (std::shared_ptr<BluCat::GRA::StaticModel>*)DATA_PTR(self); + std::shared_ptr<glm::quat> *orientation; + + mrb_get_args(mrb, "d", &orientation, &cg_orientation_3d_type); + (*ptr)->orientation = *orientation; + + return self; +} + +static mrb_value +cg_cStaticModel_set_position(mrb_state *mrb, mrb_value self) +{ + auto ptr = (std::shared_ptr<BluCat::GRA::StaticModel>*)DATA_PTR(self); + std::shared_ptr<glm::vec3> *position; + + mrb_get_args(mrb, "d", &position, &cg_vector_3d_type); + (*ptr)->position = *position; + + return self; +} + +static mrb_value +cg_cStaticModel_set_texture(mrb_state *mrb, mrb_value self) +{ + auto ptr = (std::shared_ptr<BluCat::GRA::StaticModel>*)DATA_PTR(self); + std::shared_ptr<BluCat::GRA::Texture> *texture; + + mrb_get_args(mrb, "d", &texture, &cg_texture_type); + (*ptr)->texture = *texture; + + return self; +} + +static mrb_value +cg_cStaticModel_draw(mrb_state *mrb, mrb_value self) +{ + auto ptr = (std::shared_ptr<BluCat::GRA::StaticModel>*)DATA_PTR(self); + + auto &instances = BluCat::INT::core.vk_renderer->static_models_to_draw[ + BluCat::INT::core.vk_swapchain->current_frame][(*ptr)->static_mesh]; + instances.push_back(*ptr); + + return self; +} + +void +cg_static_model_init(mrb_state *mrb) +{ + struct RClass *cg_m, *cg_cStaticModel; + + cg_m = mrb_module_get(mrb, "CandyGear"); + cg_cStaticModel = mrb_define_class_under( + mrb, cg_m, "StaticModel", mrb->object_class); + MRB_SET_INSTANCE_TT(cg_cStaticModel, MRB_TT_DATA); + mrb_define_method( + mrb, cg_cStaticModel, "initialize", cg_cStaticModel_initialize, + MRB_ARGS_REQ(4)); + mrb_define_method( + mrb, cg_cStaticModel, "position=", cg_cStaticModel_set_position, + MRB_ARGS_REQ(1)); + mrb_define_method( + mrb, cg_cStaticModel, "orientation=", cg_cStaticModel_set_orientation, + MRB_ARGS_REQ(1)); + mrb_define_method( + mrb, cg_cStaticModel, "texture=", cg_cStaticModel_set_texture, + MRB_ARGS_REQ(1)); + mrb_define_method( + mrb, cg_cStaticModel, "draw", cg_cStaticModel_draw, MRB_ARGS_NONE()); +} diff --git a/src/candy_gear/static_model.hpp b/src/candy_gear/static_model.hpp new file mode 100644 index 0000000..dfb7054 --- /dev/null +++ b/src/candy_gear/static_model.hpp @@ -0,0 +1,25 @@ +/* + * Copyright 2022-2023 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 CANDY_GEAR_STATIC_MODEL_H +#define CANDY_GEAR_STATIC_MODEL_H 1 + +#include "core.hpp" + +void +cg_static_model_init(mrb_state *mrb); + +#endif /* CANDY_GEAR_STATIC_MODEL_H */ diff --git a/src/candy_gear/texture.cpp b/src/candy_gear/texture.cpp new file mode 100644 index 0000000..355a622 --- /dev/null +++ b/src/candy_gear/texture.cpp @@ -0,0 +1,121 @@ +/* + * Copyright 2022-2024 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. + */ + +#include "texture.hpp" + +#include "core.hpp" +#include "font.hpp" +#include "../blu_cat/gra/texture.hpp" + +void +cg_free_texture(mrb_state *mrb, void* obj) +{ + auto *ptr = static_cast<std::shared_ptr<BluCat::GRA::Texture>*>(obj); + + ptr->~shared_ptr(); + mrb_free(mrb, ptr); +} + +const struct mrb_data_type cg_texture_type = { "CG_Texture", cg_free_texture }; + +static mrb_value +texture_alloc(mrb_state *mrb, mrb_value klass) +{ + struct RClass *cg_cTexture = mrb_class_ptr(klass); + enum mrb_vtype ttype = MRB_INSTANCE_TT(cg_cTexture); + + // I do not know if I need this. If things break, try uncomment this line. + // if (ttype == 0) ttype = MRB_TT_OBJECT; + return mrb_obj_value( + (struct RObject*)mrb_obj_alloc(mrb, ttype, cg_cTexture)); +} + +static mrb_value +cg_cTexture_from_image(mrb_state *mrb, mrb_value self) +{ + struct mrb_value texture = texture_alloc(mrb, self); + const char *file_path; + std::shared_ptr<BluCat::GRA::Texture> *ptr; + + mrb_get_args(mrb, "z", &file_path); + ptr = (std::shared_ptr<BluCat::GRA::Texture>*)DATA_PTR(texture); + if(ptr) mrb_free(mrb, ptr); + ptr = (std::shared_ptr<BluCat::GRA::Texture>*)mrb_malloc( + mrb, sizeof(std::shared_ptr<BluCat::GRA::Texture>)); + new(ptr)std::shared_ptr<BluCat::GRA::Texture>( + std::make_shared<BluCat::GRA::Texture>(file_path)); + + mrb_data_init(texture, ptr, &cg_texture_type); + return texture; +} + +mrb_value +cg_cTexture_from_text(mrb_state *mrb, mrb_value self) +{ + const char *text; + unsigned int width, height; + struct mrb_value texture = texture_alloc(mrb, self); + BluCat::GRA::Font *font_ptr; + std::shared_ptr<BluCat::GRA::Texture> *ptr; + + mrb_get_args(mrb, "dz", &font_ptr, &cg_font_type, &text); + + ptr = (std::shared_ptr<BluCat::GRA::Texture>*)DATA_PTR(texture); + if(ptr) mrb_free(mrb, ptr); + ptr = (std::shared_ptr<BluCat::GRA::Texture>*)mrb_malloc( + mrb, sizeof(std::shared_ptr<BluCat::GRA::Texture>)); + new(ptr)std::shared_ptr<BluCat::GRA::Texture>( + std::make_shared<BluCat::GRA::Texture>(font_ptr, text)); + + mrb_data_init(texture, ptr, &cg_texture_type); + return texture; +} + +static mrb_value +cg_cTexture_width(mrb_state *mrb, mrb_value self) +{ + auto ptr = (std::shared_ptr<BluCat::GRA::Texture>*)DATA_PTR(self); + return mrb_int_value(mrb, (*ptr)->width); +} + +static mrb_value +cg_cTexture_height(mrb_state *mrb, mrb_value self) +{ + auto ptr = (std::shared_ptr<BluCat::GRA::Texture>*)DATA_PTR(self); + return mrb_int_value(mrb, (*ptr)->height); +} + +void +cg_texture_init(mrb_state *mrb) +{ + struct RClass *cg_m, *cg_cTexture; + + cg_m = mrb_module_get(mrb, "CandyGear"); + cg_cTexture = mrb_define_class_under( + mrb, cg_m, "Texture", mrb->object_class); + MRB_SET_INSTANCE_TT(cg_cTexture, MRB_TT_DATA); + + mrb_undef_class_method(mrb, cg_cTexture, "new"); + mrb_define_class_method( + mrb, cg_cTexture, "from_image", cg_cTexture_from_image, + MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1)); + mrb_define_class_method( + mrb, cg_cTexture, "from_text", cg_cTexture_from_text, MRB_ARGS_REQ(2)); + mrb_define_method( + mrb, cg_cTexture, "width", cg_cTexture_width, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cTexture, "height", cg_cTexture_height, MRB_ARGS_NONE()); +} diff --git a/src/candy_gear/texture.hpp b/src/candy_gear/texture.hpp new file mode 100644 index 0000000..cd96026 --- /dev/null +++ b/src/candy_gear/texture.hpp @@ -0,0 +1,28 @@ +/* + * Copyright 2022 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 CANDY_GEAR_TEXTURE_H +#define CANDY_GEAR_TEXTURE_H 1 + +#include "core.hpp" +#include "../blu_cat/com/command.hpp" + +extern const struct mrb_data_type cg_texture_type; + +void +cg_texture_init(mrb_state *mrb); + +#endif /* CANDY_GEAR_TEXTURE_H */ diff --git a/src/candy_gear/vector_3d.cpp b/src/candy_gear/vector_3d.cpp new file mode 100644 index 0000000..fc5d186 --- /dev/null +++ b/src/candy_gear/vector_3d.cpp @@ -0,0 +1,302 @@ +/* + * Copyright 2022-2024 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. + */ + +#include "vector_3d.hpp" + +#include <memory> + +#include <glm/vec3.hpp> + +#include <mruby/array.h> + +#include "orientation_3d.hpp" + +void +cg_free_vector_3d(mrb_state *mrb, void* obj) +{ + auto ptr = static_cast<std::shared_ptr<glm::vec3>*>(obj); + + ptr->~shared_ptr(); + mrb_free(mrb, ptr); +} + +const struct mrb_data_type cg_vector_3d_type = { + "CG_Vector3D", cg_free_vector_3d}; + +static mrb_value +cg_cVector3D_initialize(mrb_state *mrb, mrb_value self) +{ + mrb_float x = 0.0f; + mrb_float y = 0.0f; + mrb_float z = 0.0f; + std::shared_ptr<glm::vec3> *ptr; + + mrb_get_args(mrb, "|fff", &x, &y, &z); + ptr = (std::shared_ptr<glm::vec3>*)DATA_PTR(self); + if(ptr) mrb_free(mrb, ptr); + ptr = (std::shared_ptr<glm::vec3>*)mrb_malloc( + mrb, sizeof(std::shared_ptr<glm::vec3>)); + + new(ptr)std::shared_ptr<glm::vec3>(std::make_shared<glm::vec3>(x, y, z)); + + mrb_data_init(self, ptr, &cg_vector_3d_type); + return self; +} + +mrb_value +cg_cVector3D_get_x(mrb_state *mrb, mrb_value self) +{ + std::shared_ptr<glm::vec3> *ptr = + (std::shared_ptr<glm::vec3>*)DATA_PTR(self); + + return mrb_float_value(mrb, (*ptr)->x); +} + +mrb_value +cg_cVector3D_get_y(mrb_state *mrb, mrb_value self) +{ + std::shared_ptr<glm::vec3> *ptr = + (std::shared_ptr<glm::vec3>*)DATA_PTR(self); + + return mrb_float_value(mrb, (*ptr)->y); +} + +mrb_value +cg_cVector3D_get_z(mrb_state *mrb, mrb_value self) +{ + std::shared_ptr<glm::vec3> *ptr = + (std::shared_ptr<glm::vec3>*)DATA_PTR(self); + + return mrb_float_value(mrb, (*ptr)->z); +} + +mrb_value +cg_cVector3D_get_xy(mrb_state *mrb, mrb_value self) +{ + std::shared_ptr<glm::vec3> *ptr = + (std::shared_ptr<glm::vec3>*)DATA_PTR(self); + + mrb_value array = mrb_ary_new_capa(mrb, 2); + mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->x)); + mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->y)); + + return array; +} + +mrb_value +cg_cVector3D_get_xz(mrb_state *mrb, mrb_value self) +{ + std::shared_ptr<glm::vec3> *ptr = + (std::shared_ptr<glm::vec3>*)DATA_PTR(self); + + mrb_value array = mrb_ary_new_capa(mrb, 2); + mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->x)); + mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->z)); + + return array; +} + +mrb_value +cg_cVector3D_get_yz(mrb_state *mrb, mrb_value self) +{ + std::shared_ptr<glm::vec3> *ptr = + (std::shared_ptr<glm::vec3>*)DATA_PTR(self); + + mrb_value array = mrb_ary_new_capa(mrb, 2); + mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->y)); + mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->z)); + + return array; +} + +mrb_value +cg_cVector3D_get_xyz(mrb_state *mrb, mrb_value self) +{ + std::shared_ptr<glm::vec3> *ptr = + (std::shared_ptr<glm::vec3>*)DATA_PTR(self); + + mrb_value array = mrb_ary_new_capa(mrb, 3); + mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->x)); + mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->y)); + mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->z)); + + return array; +} + +static mrb_value +cg_cVector3D_set_x(mrb_state *mrb, mrb_value self) +{ + mrb_float x; + std::shared_ptr<glm::vec3> *ptr = + (std::shared_ptr<glm::vec3>*)DATA_PTR(self); + + mrb_get_args(mrb, "f", &x); + (*ptr)->x = x; + + return self; +} + +static mrb_value +cg_cVector3D_set_y(mrb_state *mrb, mrb_value self) +{ + mrb_float y; + std::shared_ptr<glm::vec3> *ptr = + (std::shared_ptr<glm::vec3>*)DATA_PTR(self); + + mrb_get_args(mrb, "f", &y); + (*ptr)->y = y; + + return self; +} + +static mrb_value +cg_cVector3D_set_z(mrb_state *mrb, mrb_value self) +{ + mrb_float z; + std::shared_ptr<glm::vec3> *ptr = + (std::shared_ptr<glm::vec3>*)DATA_PTR(self); + + mrb_get_args(mrb, "f", &z); + (*ptr)->z = z; + + return self; +} + +static mrb_value +cg_cVector3D_set_xy(mrb_state *mrb, mrb_value self) +{ + mrb_float x, y; + std::shared_ptr<glm::vec3> *ptr = + (std::shared_ptr<glm::vec3>*)DATA_PTR(self); + + mrb_get_args(mrb, "ff", &x, &y); + (*ptr)->x = x; + (*ptr)->y = y; + + return self; +} + +static mrb_value +cg_cVector3D_set_xz(mrb_state *mrb, mrb_value self) +{ + mrb_float x, z; + std::shared_ptr<glm::vec3> *ptr = + (std::shared_ptr<glm::vec3>*)DATA_PTR(self); + + mrb_get_args(mrb, "ff", &x, &z); + (*ptr)->x = x; + (*ptr)->z = z; + + return self; +} + +static mrb_value +cg_cVector3D_set_yz(mrb_state *mrb, mrb_value self) +{ + mrb_float y, z; + std::shared_ptr<glm::vec3> *ptr = + (std::shared_ptr<glm::vec3>*)DATA_PTR(self); + + mrb_get_args(mrb, "ff", &y, &z); + (*ptr)->y = y; + (*ptr)->z = z; + + return self; +} + +static mrb_value +cg_cVector3D_set_xyz(mrb_state *mrb, mrb_value self) +{ + mrb_float x, y, z; + std::shared_ptr<glm::vec3> *ptr = + (std::shared_ptr<glm::vec3>*)DATA_PTR(self); + + mrb_get_args(mrb, "fff", &x, &y, &z); + (*ptr)->x = x; + (*ptr)->y = y; + (*ptr)->z = z; + + return self; +} + +static mrb_value +cg_cVector3D_translate(mrb_state *mrb, mrb_value self) +{ + auto *ptr = (std::shared_ptr<glm::vec3>*)DATA_PTR(self); + std::shared_ptr<glm::vec3> *direction; + std::shared_ptr<glm::quat> *orientation; + + mrb_get_args( + mrb, "dd", &direction, &cg_vector_3d_type, + &orientation, &cg_orientation_3d_type); + + auto rotated_direction = **orientation * **direction; + + **ptr += rotated_direction; + + return self; +} + +void +cg_vector_3d_init(mrb_state *mrb) +{ + struct RClass *cg_m, *cg_cVector3D; + + cg_m = mrb_module_get(mrb, "CandyGear"); + cg_cVector3D = mrb_define_class_under( + mrb, cg_m, "Vector3D", mrb->object_class); + MRB_SET_INSTANCE_TT(cg_cVector3D, MRB_TT_DATA); + mrb_define_method( + mrb, cg_cVector3D, "initialize", cg_cVector3D_initialize, + MRB_ARGS_NONE()|MRB_ARGS_OPT(3)); + + mrb_define_method( + mrb, cg_cVector3D, "x", cg_cVector3D_get_x, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cVector3D, "y", cg_cVector3D_get_y, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cVector3D, "z", cg_cVector3D_get_z, MRB_ARGS_NONE()); + + mrb_define_method( + mrb, cg_cVector3D, "xy", cg_cVector3D_get_xy, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cVector3D, "xz", cg_cVector3D_get_xz, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cVector3D, "yz", cg_cVector3D_get_yz, MRB_ARGS_NONE()); + + mrb_define_method( + mrb, cg_cVector3D, "xyz", cg_cVector3D_get_xyz, MRB_ARGS_NONE()); + + mrb_define_method( + mrb, cg_cVector3D, "x=", cg_cVector3D_set_x, MRB_ARGS_REQ(1)); + mrb_define_method( + mrb, cg_cVector3D, "y=", cg_cVector3D_set_y, MRB_ARGS_REQ(1)); + mrb_define_method( + mrb, cg_cVector3D, "z=", cg_cVector3D_set_z, MRB_ARGS_REQ(1)); + + mrb_define_method( + mrb, cg_cVector3D, "set_xy", cg_cVector3D_set_xy, MRB_ARGS_REQ(2)); + mrb_define_method( + mrb, cg_cVector3D, "set_xz", cg_cVector3D_set_xz, MRB_ARGS_REQ(2)); + mrb_define_method( + mrb, cg_cVector3D, "set_yz", cg_cVector3D_set_yz, MRB_ARGS_REQ(2)); + + mrb_define_method( + mrb, cg_cVector3D, "set_xyz", cg_cVector3D_set_xyz, MRB_ARGS_REQ(3)); + + mrb_define_method( + mrb, cg_cVector3D, "translate", cg_cVector3D_translate, MRB_ARGS_REQ(2)); +} diff --git a/src/candy_gear/vector_3d.hpp b/src/candy_gear/vector_3d.hpp new file mode 100644 index 0000000..2827813 --- /dev/null +++ b/src/candy_gear/vector_3d.hpp @@ -0,0 +1,34 @@ +/* + * Copyright 2022 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 CANDY_GEAR_VECTOR_3D_H +#define CANDY_GEAR_VECTOR_3D_H 1 + +#include "core.hpp" + +extern const struct mrb_data_type cg_vector_3d_type; + +mrb_value +cg_cVector3D_get_x(mrb_state *mrb, mrb_value self); +mrb_value +cg_cVector3D_get_y(mrb_state *mrb, mrb_value self); +mrb_value +cg_cVector3D_get_z(mrb_state *mrb, mrb_value self); + +void +cg_vector_3d_init(mrb_state *mrb); + +#endif /* CANDY_GEAR_VECTOR_3D_H */ diff --git a/src/candy_gear/vector_4d.cpp b/src/candy_gear/vector_4d.cpp new file mode 100644 index 0000000..b44b612 --- /dev/null +++ b/src/candy_gear/vector_4d.cpp @@ -0,0 +1,479 @@ +/* + * Copyright 2022-2024 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. + */ + +#include "vector_4d.hpp" + +#include <memory> + +#include <glm/vec4.hpp> +#include <mruby/array.h> + +#include "vector_3d.hpp" +#include "view_2d.hpp" + +namespace +{ + +constexpr bool +align_vertically(const float a_x, const float a_width, + const float b_x, const float b_width) +{ + return a_x <= b_x + b_width && a_x + a_width >= b_x; +} + +constexpr bool +align_horizontally(const float a_y, const float a_height, + const float b_y, const float b_height) +{ + return a_y <= b_y + b_height && a_y + a_height >= b_y; +} + +} + +void +cg_free_vector_4d(mrb_state *mrb, void* obj) +{ + auto ptr = static_cast<std::shared_ptr<glm::vec4>*>(obj); + + ptr->~shared_ptr(); + mrb_free(mrb, ptr); +} + +const struct mrb_data_type cg_vector_4d_type = { + "CG_Vector4D", cg_free_vector_4d}; + +static mrb_value +cg_cVector4D_initialize(mrb_state *mrb, mrb_value self) +{ + mrb_float x = 0.0f; + mrb_float y = 0.0f; + mrb_float w = 0.0f; + mrb_float h = 0.0f; + std::shared_ptr<glm::vec4> *ptr; + + mrb_get_args(mrb, "|ffff", &x, &y, &w, &h); + ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + if(ptr) mrb_free(mrb, ptr); + ptr = (std::shared_ptr<glm::vec4>*)mrb_malloc( + mrb, sizeof(std::shared_ptr<glm::vec4>)); + + new(ptr)std::shared_ptr<glm::vec4>(std::make_shared<glm::vec4>(x, y, w, h)); + + mrb_data_init(self, ptr, &cg_vector_4d_type); + return self; +} + +mrb_value +cg_cVector4D_get_x(mrb_state *mrb, mrb_value self) +{ + std::shared_ptr<glm::vec4> *ptr = + (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + + return mrb_float_value(mrb, (*ptr)->x); +} + +mrb_value +cg_cVector4D_get_y(mrb_state *mrb, mrb_value self) +{ + auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + + return mrb_float_value(mrb, (*ptr)->y); +} + +mrb_value +cg_cVector4D_get_w(mrb_state *mrb, mrb_value self) +{ + auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + + return mrb_float_value(mrb, (*ptr)->z); +} + +mrb_value +cg_cVector4D_get_h(mrb_state *mrb, mrb_value self) +{ + auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + + return mrb_float_value(mrb, (*ptr)->w); +} + +mrb_value +cg_cVector4D_get_xy(mrb_state *mrb, mrb_value self) +{ + auto *ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + + mrb_value array = mrb_ary_new_capa(mrb, 2); + mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->x)); + mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->y)); + + return array; +} + +mrb_value +cg_cVector4D_get_xw(mrb_state *mrb, mrb_value self) +{ + auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + + mrb_value array = mrb_ary_new_capa(mrb, 2); + mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->x)); + mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->z)); + + return array; +} + +mrb_value +cg_cVector4D_get_xh(mrb_state *mrb, mrb_value self) +{ + auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + + mrb_value array = mrb_ary_new_capa(mrb, 2); + mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->x)); + mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->w)); + + return array; +} + +mrb_value +cg_cVector4D_get_yw(mrb_state *mrb, mrb_value self) +{ + auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + + mrb_value array = mrb_ary_new_capa(mrb, 2); + mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->y)); + mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->z)); + + return array; +} + +mrb_value +cg_cVector4D_get_yh(mrb_state *mrb, mrb_value self) +{ + auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + + mrb_value array = mrb_ary_new_capa(mrb, 2); + mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->y)); + mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->w)); + + return array; +} + +mrb_value +cg_cVector4D_get_wh(mrb_state *mrb, mrb_value self) +{ + auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + + mrb_value array = mrb_ary_new_capa(mrb, 2); + mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->z)); + mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->w)); + + return array; +} + +static mrb_value +cg_cVector4D_set_x(mrb_state *mrb, mrb_value self) +{ + mrb_float x; + auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + + mrb_get_args(mrb, "f", &x); + (*ptr)->x = x; + + return self; +} + +static mrb_value +cg_cVector4D_set_y(mrb_state *mrb, mrb_value self) +{ + mrb_float y; + auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + + mrb_get_args(mrb, "f", &y); + (*ptr)->y = y; + + return self; +} + +static mrb_value +cg_cVector4D_set_w(mrb_state *mrb, mrb_value self) +{ + mrb_float w; + auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + + mrb_get_args(mrb, "f", &w); + (*ptr)->z = w; + + return self; +} + +static mrb_value +cg_cVector4D_set_h(mrb_state *mrb, mrb_value self) +{ + mrb_float h; + auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + + mrb_get_args(mrb, "f", &h); + (*ptr)->w = h; + + return self; +} + +static mrb_value +cg_cVector4D_set_xy(mrb_state *mrb, mrb_value self) +{ + mrb_float x, y; + auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + + mrb_get_args(mrb, "ff", &x, &y); + (*ptr)->x = x; + (*ptr)->y = y; + + return self; +} + +static mrb_value +cg_cVector4D_set_xw(mrb_state *mrb, mrb_value self) +{ + mrb_float x, w; + auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + + mrb_get_args(mrb, "ff", &x, &w); + (*ptr)->x = x; + (*ptr)->z = w; + + return self; +} + +static mrb_value +cg_cVector4D_set_xh(mrb_state *mrb, mrb_value self) +{ + mrb_float x, h; + auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + + mrb_get_args(mrb, "ff", &x, &h); + (*ptr)->x = x; + (*ptr)->w = h; + + return self; +} + +static mrb_value +cg_cVector4D_set_yw(mrb_state *mrb, mrb_value self) +{ + mrb_float y, w; + auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + + mrb_get_args(mrb, "ff", &y, &w); + (*ptr)->y = y; + (*ptr)->z = w; + + return self; +} + +static mrb_value +cg_cVector4D_set_yh(mrb_state *mrb, mrb_value self) +{ + mrb_float y, h; + auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + + mrb_get_args(mrb, "ff", &y, &h); + (*ptr)->x = y; + (*ptr)->w = h; + + return self; +} + +static mrb_value +cg_cVector4D_set_wh(mrb_state *mrb, mrb_value self) +{ + mrb_float w, h; + auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + + mrb_get_args(mrb, "ff", &w, &h); + (*ptr)->z = w; + (*ptr)->w = h; + + return self; +} + +static mrb_value +cg_cVector4D_align_vertically(mrb_state *mrb, mrb_value self) +{ + std::shared_ptr<glm::vec4> *ptr, *that; + + mrb_get_args(mrb, "d", &that, &cg_vector_4d_type); + ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + + return mrb_bool_value( + align_vertically((*ptr)->x, (*ptr)->z, (*that)->x, (*that)->z)); +} + +static mrb_value +cg_cVector4D_align_horizontally(mrb_state *mrb, mrb_value self) +{ + std::shared_ptr<glm::vec4> *ptr, *that; + + mrb_get_args(mrb, "d", &that, &cg_vector_4d_type); + ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + + return mrb_bool_value( + align_horizontally((*ptr)->y, (*ptr)->w, (*that)->y, (*that)->w)); +} + +static mrb_value +cg_cVector4D_collide(mrb_state *mrb, mrb_value self) +{ + std::shared_ptr<glm::vec4> *ptr, *that; + + mrb_get_args(mrb, "d", &that, &cg_vector_4d_type); + ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + + return mrb_bool_value( + align_vertically((*ptr)->x, (*ptr)->z, (*that)->x, (*that)->z) && + align_horizontally((*ptr)->y, (*ptr)->w, (*that)->y, (*that)->w)); +} + +static mrb_value +cg_cVector4D_draw_rectangle(mrb_state *mrb, mrb_value self) +{ + mrb_value view_value; + BluCat::GRA::View2D *view_2d; + std::shared_ptr<glm::vec3> *color; + auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self); + + mrb_get_args(mrb, "od", &view_value, &color, &cg_vector_3d_type); + + view_2d = cg_cView_to_view_2d(mrb, view_value); + + glm::vec4 position( + (*ptr)->x, (*ptr)->y, (*ptr)->x + (*ptr)->z, (*ptr)->y + (*ptr)->w); + BluCat::GRA::Rectangle rect{position, (**color)}; + auto &rectangles = view_2d->rectangles_to_draw[ + BluCat::INT::core.vk_swapchain->current_frame]; + rectangles.push_back(rect); + + return self; +} + +void +cg_vector_4d_init(mrb_state *mrb) +{ + struct RClass *cg_m, *cg_cVector4D; + + cg_m = mrb_module_get(mrb, "CandyGear"); + cg_cVector4D = mrb_define_class_under( + mrb, cg_m, "Vector4D", mrb->object_class); + MRB_SET_INSTANCE_TT(cg_cVector4D, MRB_TT_DATA); + mrb_define_method( + mrb, cg_cVector4D, "initialize", cg_cVector4D_initialize, + MRB_ARGS_NONE()|MRB_ARGS_OPT(4)); + + mrb_define_method( + mrb, cg_cVector4D, "x", cg_cVector4D_get_x, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cVector4D, "y", cg_cVector4D_get_y, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cVector4D, "w", cg_cVector4D_get_w, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cVector4D, "h", cg_cVector4D_get_h, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cVector4D, "r", cg_cVector4D_get_x, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cVector4D, "g", cg_cVector4D_get_y, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cVector4D, "b", cg_cVector4D_get_w, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cVector4D, "a", cg_cVector4D_get_h, MRB_ARGS_NONE()); + + mrb_define_method( + mrb, cg_cVector4D, "xy", cg_cVector4D_get_xy, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cVector4D, "xw", cg_cVector4D_get_xw, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cVector4D, "xh", cg_cVector4D_get_xh, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cVector4D, "yw", cg_cVector4D_get_yw, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cVector4D, "yh", cg_cVector4D_get_yh, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cVector4D, "wh", cg_cVector4D_get_wh, MRB_ARGS_NONE()); + + mrb_define_method( + mrb, cg_cVector4D, "rg", cg_cVector4D_get_xy, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cVector4D, "rb", cg_cVector4D_get_xw, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cVector4D, "ra", cg_cVector4D_get_xh, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cVector4D, "gb", cg_cVector4D_get_yw, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cVector4D, "ga", cg_cVector4D_get_yh, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cVector4D, "ba", cg_cVector4D_get_wh, MRB_ARGS_NONE()); + + mrb_define_method( + mrb, cg_cVector4D, "x=", cg_cVector4D_set_x, MRB_ARGS_REQ(1)); + mrb_define_method( + mrb, cg_cVector4D, "y=", cg_cVector4D_set_y, MRB_ARGS_REQ(1)); + mrb_define_method( + mrb, cg_cVector4D, "w=", cg_cVector4D_set_w, MRB_ARGS_REQ(1)); + mrb_define_method( + mrb, cg_cVector4D, "h=", cg_cVector4D_set_h, MRB_ARGS_REQ(1)); + mrb_define_method( + mrb, cg_cVector4D, "r=", cg_cVector4D_set_x, MRB_ARGS_REQ(1)); + mrb_define_method( + mrb, cg_cVector4D, "g=", cg_cVector4D_set_y, MRB_ARGS_REQ(1)); + mrb_define_method( + mrb, cg_cVector4D, "b=", cg_cVector4D_set_w, MRB_ARGS_REQ(1)); + mrb_define_method( + mrb, cg_cVector4D, "a=", cg_cVector4D_set_h, MRB_ARGS_REQ(1)); + + mrb_define_method( + mrb, cg_cVector4D, "set_xy", cg_cVector4D_set_xy, MRB_ARGS_REQ(2)); + mrb_define_method( + mrb, cg_cVector4D, "set_xw", cg_cVector4D_set_xw, MRB_ARGS_REQ(2)); + mrb_define_method( + mrb, cg_cVector4D, "set_xh", cg_cVector4D_set_xh, MRB_ARGS_REQ(2)); + mrb_define_method( + mrb, cg_cVector4D, "set_yw", cg_cVector4D_set_yw, MRB_ARGS_REQ(2)); + mrb_define_method( + mrb, cg_cVector4D, "set_yh", cg_cVector4D_set_yh, MRB_ARGS_REQ(2)); + mrb_define_method( + mrb, cg_cVector4D, "set_wh", cg_cVector4D_set_wh, MRB_ARGS_REQ(2)); + + mrb_define_method( + mrb, cg_cVector4D, "set_rg", cg_cVector4D_set_xy, MRB_ARGS_REQ(2)); + mrb_define_method( + mrb, cg_cVector4D, "set_rb", cg_cVector4D_set_xw, MRB_ARGS_REQ(2)); + mrb_define_method( + mrb, cg_cVector4D, "set_ra", cg_cVector4D_set_xh, MRB_ARGS_REQ(2)); + mrb_define_method( + mrb, cg_cVector4D, "set_gb", cg_cVector4D_set_yw, MRB_ARGS_REQ(2)); + mrb_define_method( + mrb, cg_cVector4D, "set_ga", cg_cVector4D_set_yh, MRB_ARGS_REQ(2)); + mrb_define_method( + mrb, cg_cVector4D, "set_ba", cg_cVector4D_set_wh, MRB_ARGS_REQ(2)); + + mrb_define_method( + mrb, cg_cVector4D, "align_vertically?", cg_cVector4D_align_vertically, + MRB_ARGS_REQ(1)); + mrb_define_method( + mrb, cg_cVector4D, "align_horizontally?", + cg_cVector4D_align_horizontally, MRB_ARGS_REQ(1)); + mrb_define_method( + mrb, cg_cVector4D, "collide?", cg_cVector4D_collide, MRB_ARGS_REQ(1)); + mrb_define_method( + mrb, cg_cVector4D, "draw_rectangle", cg_cVector4D_draw_rectangle, + MRB_ARGS_REQ(2)); +} diff --git a/src/candy_gear/vector_4d.hpp b/src/candy_gear/vector_4d.hpp new file mode 100644 index 0000000..2797d53 --- /dev/null +++ b/src/candy_gear/vector_4d.hpp @@ -0,0 +1,27 @@ +/* + * Copyright 2022 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 CANDY_GEAR_VECTOR_4D_H +#define CANDY_GEAR_VECTOR_4D_H 1 + +#include "core.hpp" + +extern const struct mrb_data_type cg_vector_4d_type; + +void +cg_vector_4d_init(mrb_state *mrb); + +#endif /* CANDY_GEAR_VECTOR_4D_H */ diff --git a/src/candy_gear/view_2d.cpp b/src/candy_gear/view_2d.cpp new file mode 100644 index 0000000..e0dc8a1 --- /dev/null +++ b/src/candy_gear/view_2d.cpp @@ -0,0 +1,90 @@ +/* + * Copyright 2022-2024 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. + */ + +#include "view_2d.hpp" + +#include "sprite.hpp" +#include "vector_4d.hpp" +#include "view_3d.hpp" +#include "../blu_cat/gra/sprite.hpp" +#include "../blu_cat/gra/view_2d.hpp" + +void +cg_free_view_2d(mrb_state *mrb, void* obj) +{ + auto ptr = static_cast<std::shared_ptr<BluCat::GRA::View2D>*>(obj); + + ptr->~shared_ptr(); + mrb_free(mrb, ptr); +} + +const struct mrb_data_type cg_view_2d_type = { "CG_View2D", cg_free_view_2d }; + +static mrb_value +cg_cView2D_initialize(mrb_state *mrb, mrb_value self) +{ + std::shared_ptr<glm::vec4> *region; + mrb_float projection_width, projection_height; + std::shared_ptr<BluCat::GRA::View2D> *ptr; + + mrb_get_args(mrb, "dff", ®ion, &cg_vector_4d_type, + &projection_width, &projection_height); + ptr = (std::shared_ptr<BluCat::GRA::View2D>*)DATA_PTR(self); + if(ptr) mrb_free(mrb, ptr); + ptr = (std::shared_ptr<BluCat::GRA::View2D>*)mrb_malloc( + mrb, sizeof(std::shared_ptr<BluCat::GRA::View2D>)); + + new(ptr)std::shared_ptr<BluCat::GRA::View2D>( + std::make_shared<BluCat::GRA::View2D>( + *region->get(), projection_width, projection_height)); + + mrb_data_init(self, ptr, &cg_view_2d_type); + return self; +} + +BluCat::GRA::View2D* +cg_cView_to_view_2d(mrb_state *mrb, mrb_value view_value) +{ + BluCat::GRA::View2D* view_2d; + const mrb_data_type *type = DATA_TYPE(view_value); + + if(type == &cg_view_2d_type) + view_2d = static_cast<std::shared_ptr<BluCat::GRA::View2D>*>( + DATA_PTR(view_value))->get(); + else if (type == &cg_view_3d_type) + view_2d = static_cast<BluCat::GRA::View2D*>( + static_cast<std::shared_ptr<BluCat::GRA::View3D>*>( + DATA_PTR(view_value))->get()); + else + mrb_raisef( + mrb, E_TYPE_ERROR, "wrong argument type %s (expected %s or %s)", + type->struct_name, cg_view_2d_type.struct_name, + cg_view_3d_type.struct_name); + + return view_2d; +} + +void +cg_view_2d_init(mrb_state *mrb) +{ + struct RClass *cg_m, *cg_cView2D; + + cg_m = mrb_module_get(mrb, "CandyGear"); + cg_cView2D = mrb_define_class_under(mrb, cg_m, "View2D", mrb->object_class); + MRB_SET_INSTANCE_TT(cg_cView2D, MRB_TT_DATA); + mrb_define_method( + mrb, cg_cView2D, "initialize", cg_cView2D_initialize, MRB_ARGS_REQ(3)); +} diff --git a/src/candy_gear/view_2d.hpp b/src/candy_gear/view_2d.hpp new file mode 100644 index 0000000..9b742a0 --- /dev/null +++ b/src/candy_gear/view_2d.hpp @@ -0,0 +1,33 @@ +/* + * Copyright 2022-2024 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 CANDY_GEAR_VIEW_2D_H +#define CANDY_GEAR_VIEW_2D_H 1 + +#include "core.hpp" + +extern const struct mrb_data_type cg_view_2d_type; + +// Receives a mrb_value that points to a View2D or a View3D and returns a +// pointer to View2D. If the mrb_value points to a View3D, the view will be +// cast to a BluCat::GRA::View2D. +BluCat::GRA::View2D* +cg_cView_to_view_2d(mrb_state *mrb, mrb_value view_value); + +void +cg_view_2d_init(mrb_state *mrb); + +#endif /* CANDY_GEAR_VIEW_2D_H */ diff --git a/src/candy_gear/view_3d.cpp b/src/candy_gear/view_3d.cpp new file mode 100644 index 0000000..b829cca --- /dev/null +++ b/src/candy_gear/view_3d.cpp @@ -0,0 +1,127 @@ +/* + * Copyright 2022-2024 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. + */ + +#include "view_3d.hpp" + +#include "sprite.hpp" +#include "orientation_3d.hpp" +#include "vector_3d.hpp" +#include "vector_4d.hpp" +#include "../blu_cat/gra/sprite.hpp" +#include "../blu_cat/gra/view_3d.hpp" + +void +cg_free_view_3d(mrb_state *mrb, void* obj) +{ + auto ptr = static_cast<std::shared_ptr<BluCat::GRA::View3D>*>(obj); + + ptr->~shared_ptr(); + mrb_free(mrb, ptr); +} + +const struct mrb_data_type cg_view_3d_type = { "CG_View3D", cg_free_view_3d }; + +static mrb_value +cg_cView3D_initialize(mrb_state *mrb, mrb_value self) +{ + std::shared_ptr<glm::vec4> *region; + mrb_float projection_width, projection_height; + std::shared_ptr<BluCat::GRA::View3D> *ptr; + + mrb_get_args(mrb, "dff", ®ion, &cg_vector_4d_type, + &projection_width, &projection_height); + ptr = (std::shared_ptr<BluCat::GRA::View3D>*)DATA_PTR(self); + if(ptr) mrb_free(mrb, ptr); + ptr = (std::shared_ptr<BluCat::GRA::View3D>*)mrb_malloc( + mrb, sizeof(std::shared_ptr<BluCat::GRA::View3D>)); + + new(ptr)std::shared_ptr<BluCat::GRA::View3D>( + std::make_shared<BluCat::GRA::View3D>( + *region->get(), projection_width, projection_height)); + + mrb_data_init(self, ptr, &cg_view_3d_type); + return self; +} + +static mrb_value +cg_cView3D_set_camera_position(mrb_state *mrb, mrb_value self) +{ + std::shared_ptr<glm::vec3> *camera_position; + auto ptr = (std::shared_ptr<BluCat::GRA::View3D>*)DATA_PTR(self); + + mrb_get_args(mrb, "d", &camera_position, &cg_vector_3d_type); + (*ptr)->camera_position = (*camera_position); + + return self; +} + +static mrb_value +cg_cView3D_set_camera_orientation(mrb_state *mrb, mrb_value self) +{ + std::shared_ptr<glm::quat> *camera_orientation; + auto ptr = (std::shared_ptr<BluCat::GRA::View3D>*)DATA_PTR(self); + + mrb_get_args(mrb, "d", &camera_orientation, &cg_orientation_3d_type); + (*ptr)->camera_orientation = (*camera_orientation); + + return self; +} + +static mrb_value +cg_cView3D_get_field_of_view(mrb_state *mrb, mrb_value self) +{ + auto ptr = (std::shared_ptr<BluCat::GRA::View3D>*)DATA_PTR(self); + + return mrb_float_value(mrb, (*ptr)->field_of_view); + + return self; +} + +static mrb_value +cg_cView3D_set_field_of_view(mrb_state *mrb, mrb_value self) +{ + mrb_float fov; + auto ptr = (std::shared_ptr<BluCat::GRA::View3D>*)DATA_PTR(self); + + mrb_get_args(mrb, "f", &fov); + (*ptr)->field_of_view = fov; + + return self; +} + +void +cg_view_3d_init(mrb_state *mrb) +{ + struct RClass *cg_m, *cg_cView3D; + + cg_m = mrb_module_get(mrb, "CandyGear"); + cg_cView3D = mrb_define_class_under(mrb, cg_m, "View3D", mrb->object_class); + MRB_SET_INSTANCE_TT(cg_cView3D, MRB_TT_DATA); + mrb_define_method( + mrb, cg_cView3D, "initialize", cg_cView3D_initialize, MRB_ARGS_REQ(3)); + mrb_define_method( + mrb, cg_cView3D, "camera_position=", cg_cView3D_set_camera_position, + MRB_ARGS_REQ(1)); + mrb_define_method( + mrb, cg_cView3D, "camera_orientation=", cg_cView3D_set_camera_orientation, + MRB_ARGS_REQ(1)); + mrb_define_method( + mrb, cg_cView3D, "field_of_view", cg_cView3D_get_field_of_view, + MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cView3D, "field_of_view=", cg_cView3D_set_field_of_view, + MRB_ARGS_REQ(1)); +} diff --git a/src/candy_gear/view_3d.hpp b/src/candy_gear/view_3d.hpp new file mode 100644 index 0000000..22aa084 --- /dev/null +++ b/src/candy_gear/view_3d.hpp @@ -0,0 +1,27 @@ +/* + * Copyright 2022 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 CANDY_GEAR_VIEW_3D_H +#define CANDY_GEAR_VIEW_3D_H 1 + +#include "core.hpp" + +extern const struct mrb_data_type cg_view_3d_type; + +void +cg_view_3d_init(mrb_state *mrb); + +#endif /* CANDY_GEAR_VIEW_3D_H */ |