diff --git a/CMakeLists.txt b/CMakeLists.txt index 5bed6a0..c7160e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,12 @@ cmake_minimum_required(VERSION 3.10) project(Engine) +if (${CMAKE_BUILD_TYPE} STREQUAL "Debug") + set(DEBUG_ENGINE ON) +endif() + +configure_file(engine_build_config.h.in engine_build_config.h) + # VARIABLES set(CMAKE_EXPORT_COMPILE_COMMANDS ON) @@ -12,15 +18,17 @@ if(CMAKE_HOST_WIN32) set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) endif() -set(CMAKE_INSTALL_BINDIR bin) -set(CMAKE_INSTALL_LIBDIR lib) -set(CMAKE_INSTALL_INCLUDEDIR include) set(CMAKE_INSTALL_RPATH "$ORIGIN;$ORIGIN/../lib") # TARGETS -add_library(${PROJECT_NAME} SHARED src/engine.c) +add_library(${PROJECT_NAME} SHARED + src/Game.c + src/Window.c + src/Renderer.c +) target_include_directories(${PROJECT_NAME} PUBLIC + ${CMAKE_CURRENT_BINARY_DIR} include extern/SDL2/SDL/include extern/SDL2/SDL_mixer/include @@ -34,7 +42,12 @@ target_link_libraries(${PROJECT_NAME} PUBLIC SDL2_ttf ) -install(FILES include/engine.h +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/engine_build_config.h + include/constants.h + include/Game.h + include/Window.h + include/Renderer.h CONFIGURATIONS Release DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) diff --git a/engine_build_config.h.in b/engine_build_config.h.in new file mode 100644 index 0000000..3c2da52 --- /dev/null +++ b/engine_build_config.h.in @@ -0,0 +1 @@ +#cmakedefine DEBUG_ENGINE diff --git a/include/Game.h b/include/Game.h new file mode 100644 index 0000000..ebd68b3 --- /dev/null +++ b/include/Game.h @@ -0,0 +1,14 @@ +#ifndef GAME_H +#define GAME_H + +#include + +bool init_game(const char *game_name, int window_width, int window_height, + bool full_screen); +bool game_running(); +void handle_events(); +void update(); +void render(); +void close_game(); + +#endif // !GAME_H diff --git a/include/Renderer.h b/include/Renderer.h new file mode 100644 index 0000000..a1face1 --- /dev/null +++ b/include/Renderer.h @@ -0,0 +1,16 @@ +#ifndef RENDERER_H +#define RENDERER_H + +#include "SDL.h" +#include "SDL_video.h" +#include + +typedef struct renderer Renderer; + +Renderer *create_renderer(); +bool init_renderer(Renderer *renderer, SDL_Window *window); +void render_clear(const Renderer *renderer, SDL_Color color); +void swap_buffers(const Renderer *renderer); +void destroy_renderer(Renderer *renderer); + +#endif // !RENDERER_H diff --git a/include/Window.h b/include/Window.h new file mode 100644 index 0000000..67d1d81 --- /dev/null +++ b/include/Window.h @@ -0,0 +1,22 @@ +#ifndef WINDOW_H +#define WINDOW_H + +#include "Renderer.h" +#include "SDL.h" +#include "SDL_pixels.h" +#include + +typedef struct window { + int width; + int height; + Renderer *renderer; + SDL_Window *SDL_base_window; +} Window; + +bool init_window(Window *wnd, const char *title, int width, int height, + bool full_screen); +void fill_window_with_color(const Window *wnd, SDL_Color color); +void swap_render_buffers(const Window *wnd); +void destroy_window(Window *wnd); + +#endif // !WINDOW_H diff --git a/include/constants.h b/include/constants.h new file mode 100644 index 0000000..e4d0063 --- /dev/null +++ b/include/constants.h @@ -0,0 +1,6 @@ +#ifndef CONSTANTS_H +#define CONSTANTS_H + +#define INTERNAL static + +#endif // !CONSTANTS_H diff --git a/include/engine.h b/include/engine.h deleted file mode 100644 index ed7b5e3..0000000 --- a/include/engine.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef ENGINE_H -#define ENGINE_H - -void init(void); - -#endif // !ENGINE_H diff --git a/src/Game.c b/src/Game.c new file mode 100644 index 0000000..82077c1 --- /dev/null +++ b/src/Game.c @@ -0,0 +1,78 @@ +#include "Game.h" +#include "SDL.h" +#include "SDL_events.h" +#include "SDL_pixels.h" +#include "Window.h" +#include "constants.h" +#include "engine_build_config.h" +#include + +#ifdef DEBUG_ENGINE +#include +#endif /* DEBUG_ENGINE */ + +INTERNAL struct game { + bool running; + Window window; + SDL_Event event; +} Game; + +bool init_game(const char *game_name, int window_width, int window_height, + bool full_screen) { + if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { +#ifdef DEBUG_ENGINE + printf("Failed to initialise game\n"); +#endif /* DEBUG_ENGINE */ + + return false; + } + + if (!init_window(&(Game.window), game_name, window_width, window_height, + full_screen)) { +#ifdef DEBUG_ENGINE + printf("Failed to initialise game\n"); +#endif /* DEBUG_ENGINE */ + + return false; + } + + Game.running = true; + +#ifdef DEBUG_ENGINE + printf("Game initialised successfully\n"); +#endif /* DEBUG_ENGINE */ + + return true; +} + +bool game_running() { return Game.running; } + +void handle_events() { + while (SDL_PollEvent(&(Game.event))) { + switch (Game.event.type) { + case SDL_QUIT: + Game.running = false; + break; + } + } +} + +void update() {} + +void render() { + fill_window_with_color(&(Game.window), (SDL_Color){255, 255, 255, 255}); + + swap_render_buffers(&(Game.window)); +} + +void close_game() { + destroy_window(&(Game.window)); + + Game.running = false; + + SDL_Quit(); + +#ifdef DEBUG_ENGINE + printf("Game closed successfully\n"); +#endif /* DEBUG_ENGINE */ +} diff --git a/src/Renderer.c b/src/Renderer.c new file mode 100644 index 0000000..d85dd9e --- /dev/null +++ b/src/Renderer.c @@ -0,0 +1,58 @@ +#include "Renderer.h" +#include "SDL.h" +#include "SDL_render.h" +#include "engine_build_config.h" +#include +#include + +#ifdef DEBUG_ENGINE +#include +#endif /* DEBUG_ENGINE */ + +typedef struct renderer { + SDL_Renderer *SDL_base_renderer; +} Renderer; + +Renderer *create_renderer() { return (Renderer *)malloc(sizeof(Renderer)); } + +bool init_renderer(Renderer *renderer, SDL_Window *window) { + if (!renderer || !window) { + return false; + } + + renderer->SDL_base_renderer = SDL_CreateRenderer( + window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); + + // Technically speaking, I believe it should be possible to just return + // the pointer. However, to make sure that everything is clear, I am + // performing a test that returns true or false based on whether the + // pointer was initialised or not. + return renderer->SDL_base_renderer ? true : false; +} + +void render_clear(const Renderer *renderer, SDL_Color color) { + SDL_SetRenderDrawColor(renderer->SDL_base_renderer, color.r, color.r, color.b, + color.a); + + SDL_RenderClear(renderer->SDL_base_renderer); +} + +void swap_buffers(const Renderer *renderer) { + SDL_RenderPresent(renderer->SDL_base_renderer); +} + +void destroy_renderer(Renderer *renderer) { + if (renderer) { + if (renderer->SDL_base_renderer) { + SDL_DestroyRenderer(renderer->SDL_base_renderer); + renderer->SDL_base_renderer = NULL; + } + + free(renderer); + renderer = NULL; + +#ifdef DEBUG_ENGINE + printf("Renderer destroyed successfully\n"); +#endif /* DEBUG_ENGINE */ + } +} diff --git a/src/Window.c b/src/Window.c new file mode 100644 index 0000000..85326c7 --- /dev/null +++ b/src/Window.c @@ -0,0 +1,67 @@ +#include "Window.h" +#include "Renderer.h" +#include "engine_build_config.h" +#include + +#ifdef DEBUG_ENGINE +#include +#endif /* DEBUG_ENGINE */ + +bool init_window(Window *wnd, const char *title, int width, int height, + bool full_screen) { + Uint32 window_flags = SDL_WINDOW_ALLOW_HIGHDPI; + + if (full_screen) { + window_flags |= SDL_WINDOW_FULLSCREEN; + } + + wnd->SDL_base_window = + SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + width, height, window_flags); + + if (!wnd->SDL_base_window) { + return false; + } + + SDL_GetWindowSize(wnd->SDL_base_window, &(wnd->width), &(wnd->height)); + + wnd->renderer = create_renderer(); + + if (!wnd->renderer || !init_renderer(wnd->renderer, wnd->SDL_base_window)) { + destroy_window(wnd); + + return false; + } + +#ifdef DEBUG_ENGINE + printf("Renderer initialised successfully\n"); + printf("Window initialised successfully with width %d and height %d\n", + wnd->width, wnd->height); +#endif /* DEBUG_ENGINE */ + + return true; +} + +void fill_window_with_color(const Window *wnd, SDL_Color color) { + render_clear(wnd->renderer, color); +} + +void swap_render_buffers(const Window *wnd) { swap_buffers(wnd->renderer); } + +void destroy_window(Window *wnd) { + if (wnd->SDL_base_window) { + if (wnd->renderer) { + destroy_renderer(wnd->renderer); + } + + SDL_DestroyWindow(wnd->SDL_base_window); + wnd->SDL_base_window = NULL; + + wnd->width = 0; + wnd->height = 0; + +#ifdef DEBUG_ENGINE + printf("Window destroyed successfully\n"); +#endif /* DEBUG_ENGINE */ + } +} diff --git a/src/engine.c b/src/engine.c deleted file mode 100644 index bbc558b..0000000 --- a/src/engine.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "SDL.h" -#include "SDL_image.h" -#include "SDL_mixer.h" -#include "SDL_ttf.h" -#include - -void init(void) { - if (SDL_Init(SDL_INIT_EVERYTHING) == 0) { - printf("SDL initialiased successfully\n"); - - SDL_Quit(); - } -}