Explorar el Código

Initial Commit

Vitaliy Polonski hace 1 día
commit
bf121358bb

+ 2 - 0
.gitignore

@@ -0,0 +1,2 @@
+**/build
+**/BUILD

+ 66 - 0
CMakeLists.txt

@@ -0,0 +1,66 @@
+cmake_minimum_required(VERSION 3.22)
+project(kariokaEngine LANGUAGES CXX)
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+find_package(SDL2 REQUIRED)
+find_package(SDL2_image REQUIRED)
+find_package(SDL2_mixer REQUIRED)
+
+# Python
+set(PYBIND11_FINDPYTHON ON)
+add_subdirectory(third_party/pybind11)
+
+# EnTT
+include_directories(third_party/entt/single_include)
+
+# ImGui
+add_library(imgui STATIC
+	third_party/imgui/imgui.cpp
+	third_party/imgui/imgui_draw.cpp
+	third_party/imgui/imgui_tables.cpp
+	third_party/imgui/imgui_widgets.cpp
+	third_party/imgui/backends/imgui_impl_sdl2.cpp
+	third_party/imgui/backends/imgui_impl_sdlrenderer2.cpp
+)
+target_include_directories(imgui PUBLIC
+	third_party/imgui
+	third_party/imgui/backends
+)
+
+target_link_libraries(imgui SDL2::SDL2)
+
+add_executable(kariokaEngine
+	# Core
+	src/main.cpp
+	src/Engine.cpp
+
+	# States
+
+	# Systems
+
+	# Components
+
+	# etc
+)
+
+target_link_libraries(kariokaEngine PRIVATE
+    pybind11::embed
+	SDL2::SDL2
+	SDL2_image::SDL2_image
+	SDL2_mixer::SDL2_mixer
+	imgui
+)
+
+target_compile_definitions(kariokaEngine PRIVATE SDL_MAIN_HANDLED)
+
+if(MINGW)
+	target_link_libraries(kariokaEngine PRIVATE mingw32)
+endif()
+
+add_custom_command(TARGET kariokaEngine POST_BUILD COMMAND
+	${CMAKE_COMMAND} -E copy_directory
+	${CMAKE_SOURCE_DIR}/assets
+	$<TARGET_FILE_DIR:kariokaEngine>/assets
+)

+ 8 - 0
compile.sh

@@ -0,0 +1,8 @@
+#!/bin/bash
+
+cmake -B BUILD \
+	-DCMAKE_BUILD_TYPE=Debug \
+	-DCMAKE_CXX_FLAGS="-fsanitize=address -g -O0" \
+	-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address"
+
+cmake --build build

+ 4 - 0
imgui.ini

@@ -0,0 +1,4 @@
+[Window][Debug##Default]
+Pos=60,60
+Size=400,400
+

BIN
python310.dll


+ 4 - 0
rebuild.sh

@@ -0,0 +1,4 @@
+#!/bin/bash
+
+rm -rf BUILD
+./compile.sh

+ 160 - 0
src/Engine.cpp

@@ -0,0 +1,160 @@
+#include "Engine.h"
+#include <SDL2/SDL_log.h>
+#include <SDL2/SDL_mixer.h>
+
+Engine::Engine()
+{
+    InitSDL();
+    InitImGui();
+    InitAudio();
+//    InitPython();
+    SDL_Log("Engine::Engine()");
+}
+
+Engine::~Engine()
+{	
+    SDL_Log("Engine::~Engine()");
+    ImGui_ImplSDLRenderer2_Shutdown();
+    ImGui_ImplSDL2_Shutdown();
+    ImGui::DestroyContext();
+
+    Mix_CloseAudio();
+    
+    if (renderer) { SDL_DestroyRenderer(renderer); }
+    if (window)   { SDL_DestroyWindow(window); }
+    
+//    ShutdownPython();
+    
+    SDL_Quit();
+}
+
+void Engine::InitSDL()
+{
+    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
+    {
+        SDL_Log("Engine::InitSDL(): %s", SDL_GetError());
+        exit(1);
+    }
+
+    window = SDL_CreateWindow("kariokaEngine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
+                              EngineConfig::DEFAULT_WINDOW_WIDTH, EngineConfig::DEFAULT_WINDOW_HEIGHT,
+                              SDL_WINDOW_SHOWN);
+    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
+}
+
+void Engine::InitImGui()
+{
+    IMGUI_CHECKVERSION();
+    ImGui::CreateContext();
+    ImGuiIO& io = ImGui::GetIO();
+    (void)io;
+    ImGui::StyleColorsDark();
+    ImGui_ImplSDL2_InitForSDLRenderer(window, renderer);
+    ImGui_ImplSDLRenderer2_Init(renderer);
+}
+
+void Engine::InitAudio()
+{
+    if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0)
+    {
+    }
+    
+    Mix_AllocateChannels(64);
+    Mix_VolumeMusic(EngineConfig::DEFAULT_MUSIC_VOLUME);
+    Mix_Volume(-1, EngineConfig::DEFAULT_SOUND_VOLUME);
+}
+
+void Engine::HandleEvents()
+{
+    SDL_Event e;
+    while (SDL_PollEvent(&e))
+    {
+        ImGui_ImplSDL2_ProcessEvent(&e);
+        if (e.type == SDL_QUIT)
+        {
+            isRunning = false;
+        }
+        
+        // stateManager.HandleEvents(*this, e);
+    }
+}
+
+void Engine::Update(float dt)
+{
+    // stateManager.Update(*this, dt);
+}
+
+void Engine::Render()
+{
+    SDL_RenderClear(renderer);
+    
+    // stateManager.Render(*this);
+    
+    ImGui_ImplSDLRenderer2_NewFrame();
+    ImGui_ImplSDL2_NewFrame();
+    ImGui::NewFrame();
+    // stateManager.RenderImGui(*this);
+    ImGui::Render();
+    ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData(), renderer);
+    
+    SDL_RenderPresent(renderer);
+}
+
+void Engine::Run()
+{
+    Uint64 lastTime = SDL_GetPerformanceCounter();
+    while (isRunning)
+    {
+        Uint64 current = SDL_GetPerformanceCounter();
+        float dt = (current - lastTime) / static_cast<float>(SDL_GetPerformanceFrequency());
+        lastTime = current;
+        
+        HandleEvents();
+        Update(dt);
+        Render();
+        
+        // Safe State Transition
+        // ...
+    }
+}
+
+void Engine::InitPython()
+{
+    if (pythonInterpreter) { return; }
+    
+    try
+    {
+        pythonInterpreter = std::make_unique<py::scoped_interpreter>();
+        
+        py::module_ sys = py::module_::import("sys");
+        auto path = sys.attr("path").cast<py::list>();
+        path.append("assets/scripts");
+        SDL_Log("Python interpreter initialized");
+        RunPythonScript("init.py");
+    }
+    catch (const py::error_already_set& e)
+    {
+        SDL_Log("Python initialization failed: %s", e.what());
+    }
+}
+
+void Engine::ShutdownPython()
+{
+    if (pythonInterpreter)
+    {
+        pythonInterpreter.reset();
+        SDL_Log("Python interpreter shut down");
+    }
+}
+
+void Engine::RunPythonScript(const std::string& filename)
+{
+    try
+    {
+        py::eval_file(filename);
+    }
+    catch (const py::error_already_set& e)
+    {
+        SDL_Log("Python script error in %s:\n%s", filename.c_str(), e.what());
+    }
+}

+ 55 - 0
src/Engine.h

@@ -0,0 +1,55 @@
+#ifndef __ENGINE_H__
+#define __ENGINE_H__
+
+#include <SDL2/SDL.h>
+#include <imgui.h>
+#include <imgui_impl_sdl2.h>
+#include <imgui_impl_sdlrenderer2.h>
+#include <entt/entt.hpp>
+#include <sol/sol.hpp>
+
+#include "EngineConfig.h"
+
+#include <pybind11/embed.h>
+namespace py = pybind11;
+
+class Engine
+{
+public:
+    Engine();
+    ~Engine();
+    void Run();
+    
+    // Getters / Setters
+    SDL_Renderer* GetRenderer() const { return renderer; }
+    SDL_Window*   GetWindow()   const { return window; }
+    bool          IsRunning()   const { return isRunning; }
+    void          StopRunning()       { isRunning = false; }
+    
+    // Safe State transition
+    
+private:
+    SDL_Window*   window    = nullptr;
+    SDL_Renderer* renderer  = nullptr;
+    bool          isRunning = true;
+
+    SDL_Rect camera = { 0, 0, EngineConfig::DEFAULT_WINDOW_WIDTH, EngineConfig::DEFAULT_WINDOW_HEIGHT };
+    
+    // General functions
+    void InitSDL();
+    void InitImGui();
+    void InitAudio();
+    void HandleEvents();
+    void Update(float dt);
+    void Render();
+
+    // Python support
+    void InitPython();
+    void ShutdownPython();
+    void RunPythonScript(const std::string& filename);
+    std::unique_ptr<py::scoped_interpreter> pythonInterpreter;
+
+
+};
+
+#endif

+ 18 - 0
src/EngineConfig.h

@@ -0,0 +1,18 @@
+#ifndef __ENGINE_CONFIG_H__
+#define __ENGINE_CONFIG_H__
+
+namespace EngineConfig
+{
+    // Window settings
+    constexpr int DEFAULT_WINDOW_WIDTH = 1280;
+    constexpr int DEFAULT_WINDOW_HEIGHT = 720;
+    
+    // Performance
+    constexpr int DEFAULT_MAX_ENTITIES = 10240;
+    
+    // Audio
+    constexpr int DEFAULT_SOUND_VOLUME = 100;
+    constexpr int DEFAULT_MUSIC_VOLUME = 80;
+};
+
+#endif

+ 15 - 0
src/components/ScriptComponents.cpp

@@ -0,0 +1,15 @@
+#include "ScriptComponent.h"
+#include <SDL2/SDL_log.h>
+
+void ScriptComponent::update(float dt)
+{
+    if (!initialized || !instance) { return; }
+    
+    try
+    {
+    }
+    catch (const py::error_already_set& e)
+    {
+        SDL_Log("Script error in %s.%s::update(): %s", scriptModule, scriptClass, e.what());
+    }
+}

+ 23 - 0
src/components/ScriptComponents.h

@@ -0,0 +1,23 @@
+#ifndef __COMPONENTS__SCRIPT_COMPONENT_H__
+#define __COMPONENTS__SCRIPT_COMPONENT_H__
+
+#include <pybind11/pybind11.h>
+#include <string>
+#include <memory>
+
+namespace py = pybind11;
+
+struct ScriptComponent
+{
+    std::string scriptModule; // e.g. "enemy_ai" (without .py)
+    std::string scriptClass;  // e.g. "EnemyAI"
+    
+    py::object instance       // Holds the live Python object
+    bool initialized = false;
+    
+    ScriptComponent() = default;
+    ScriptComponent(const std::string& moduleName, const std::string& className)
+        : scriptModule(moduleName), scriptClass(className) {}
+};
+
+#endif

+ 11 - 0
src/main.cpp

@@ -0,0 +1,11 @@
+#include "Engine.h"
+#include <stdio.h>
+
+int main(int argc, char* argv[])
+{
+    fprintf(stderr, "Starting main()\n");
+    Engine engine;
+    fprintf(stderr, "Calling engine.Run()\n");
+    engine.Run();
+    return 0;
+}

+ 1 - 0
third_party/entt

@@ -0,0 +1 @@
+Subproject commit 9c5281c79a241ec810f999ad9675fa32f51f934f

+ 1 - 0
third_party/imgui

@@ -0,0 +1 @@
+Subproject commit 6c754ed2cb483488cf728a0d80f0152cbcb5eeb8

+ 1 - 0
third_party/pybind11

@@ -0,0 +1 @@
+Subproject commit 3b62426106e475a98346645727750e07ad0cdb6e

+ 1 - 0
third_party/sol2

@@ -0,0 +1 @@
+Subproject commit c1f95a773c6f8f4fde8ca3efe872e7286afe4444