From 7b0bd2f70eb174bfa5371c5c45817cdb95e6f29a Mon Sep 17 00:00:00 2001 From: TheoryOfNekomata Date: Sat, 4 Dec 2021 09:00:12 +0800 Subject: [PATCH] Retrieve config code Get config code from old repo. --- CMakeLists.txt | 2 +- src/packages/game/IZ_app.c | 91 +++++++++++ src/packages/game/IZ_app.h | 31 ++++ .../game/adapter/framework/IZ_keyboard.c | 1 + .../game/adapter/framework/IZ_keyboard.h | 45 ++++++ src/packages/game/config/IZ_config.c | 151 ++++++++++++++++++ src/packages/game/config/IZ_config.h | 12 ++ src/packages/game/logging/IZ_log.c | 92 +++++++++++ src/packages/game/logging/IZ_log.h | 53 ++++++ src/packages/game/main.c | 140 ++++++++-------- src/packages/game/timer/IZ_timer.c | 69 ++++++++ src/packages/game/timer/IZ_timer.h | 42 +++++ 12 files changed, 664 insertions(+), 65 deletions(-) create mode 100644 src/packages/game/IZ_app.c create mode 100644 src/packages/game/IZ_app.h create mode 100644 src/packages/game/adapter/framework/IZ_keyboard.c create mode 100644 src/packages/game/adapter/framework/IZ_keyboard.h create mode 100644 src/packages/game/logging/IZ_log.c create mode 100644 src/packages/game/logging/IZ_log.h create mode 100644 src/packages/game/timer/IZ_timer.c create mode 100644 src/packages/game/timer/IZ_timer.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d44740..f316d5f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ set(SDL2PATH "${PROJECT_SOURCE_DIR}/dependencies/SDL2-2.0.16/x86_64-w64-mingw32" find_package(SDL2 REQUIRED) include_directories(${SDL2_INCLUDE_DIR}) -add_executable(izanami src/packages/game/main.c src/packages/game/math/IZ_vector.c src/packages/game/math/IZ_vector.h src/packages/game/math/IZ_math.c src/packages/game/math/IZ_math.h src/packages/game/core/IZ_placeable.c src/packages/game/core/IZ_placeable.h src/packages/game/core/IZ_movable.c src/packages/game/core/IZ_movable.h src/packages/game/core/IZ_spatial.c src/packages/game/core/IZ_spatial.h src/packages/game/input/IZ_action.c src/packages/game/input/IZ_action.h src/packages/game/config/IZ_config.c src/packages/game/config/IZ_config.h src/packages/game/config/IZ_config_window.c src/packages/game/config/IZ_config_window.h src/packages/game/config/IZ_config_mapping.c src/packages/game/config/IZ_config_mapping.h src/packages/game/config/IZ_config_pool.c src/packages/game/config/IZ_config_pool.h src/packages/game/core/IZ_constants.h) +add_executable(izanami src/packages/game/main.c src/packages/game/math/IZ_vector.c src/packages/game/math/IZ_vector.h src/packages/game/math/IZ_math.c src/packages/game/math/IZ_math.h src/packages/game/core/IZ_placeable.c src/packages/game/core/IZ_placeable.h src/packages/game/core/IZ_movable.c src/packages/game/core/IZ_movable.h src/packages/game/core/IZ_spatial.c src/packages/game/core/IZ_spatial.h src/packages/game/input/IZ_action.c src/packages/game/input/IZ_action.h src/packages/game/config/IZ_config.c src/packages/game/config/IZ_config.h src/packages/game/config/IZ_config_window.c src/packages/game/config/IZ_config_window.h src/packages/game/config/IZ_config_mapping.c src/packages/game/config/IZ_config_mapping.h src/packages/game/config/IZ_config_pool.c src/packages/game/config/IZ_config_pool.h src/packages/game/core/IZ_constants.h src/packages/game/IZ_app.c src/packages/game/IZ_app.h src/packages/game/logging/IZ_log.c src/packages/game/logging/IZ_log.h src/packages/game/timer/IZ_timer.c src/packages/game/timer/IZ_timer.h src/packages/game/adapter/framework/IZ_keyboard.c src/packages/game/adapter/framework/IZ_keyboard.h) target_link_libraries(izanami ${SDL2_LIBRARY}) diff --git a/src/packages/game/IZ_app.c b/src/packages/game/IZ_app.c new file mode 100644 index 0000000..2a91ece --- /dev/null +++ b/src/packages/game/IZ_app.c @@ -0,0 +1,91 @@ +#include "IZ_app.h" + +/** + * Logs the application command-line arguments. + * @param argc The argument count. + * @param argv The argument values. + */ +void IZ_LogArguments(int argc, char** argv) { + unsigned int i; + for (i = 0; i < argc; i += 1) { + IZ_Log("Argument(%d)=%s", i, argv[i]); + } +} + +typedef enum { + IZ_INITIALIZE_FRAMEWORK_RESULT_OK, + IZ_INITIALIZE_FRAMEWORK_RESULT_ERROR, +} IZ_InitializeFrameworkResult; + +IZ_InitializeFrameworkResult IZ_InitializeFramework() { + IZ_LogInfo(IZ_LOG_CATEGORY_GENERIC, "Initializing framework..."); + if (SDL_Init( + SDL_INIT_VIDEO + | SDL_INIT_GAMECONTROLLER + | SDL_INIT_AUDIO + | SDL_INIT_EVENTS + | SDL_INIT_TIMER + ) < 0) { + IZ_LogError("ERROR! %s", SDL_GetError()); + return IZ_INITIALIZE_FRAMEWORK_RESULT_ERROR; + } + + IZ_LogInfo(IZ_LOG_CATEGORY_GENERIC, "OK!"); + return IZ_INITIALIZE_FRAMEWORK_RESULT_OK; +} + +typedef enum { + IZ_INITIALIZE_CONFIG_RESULT_OK, + IZ_INITIALIZE_CONFIG_RESULT_ERROR, +} IZ_InitializeConfigResult; + +IZ_InitializeConfigResult IZ_InitializeConfig(IZ_App* app) { + IZ_LogInfo(IZ_LOG_CATEGORY_GENERIC, "Initializing config..."); + if (IZ_ConfigLoad(&app->config, IZ_CONFIG_FILE_PATH)) { + return IZ_INITIALIZE_CONFIG_RESULT_ERROR; + } + + IZ_LogInfo(IZ_LOG_CATEGORY_GENERIC, "OK!"); + return IZ_INITIALIZE_CONFIG_RESULT_OK; +} + +IZ_AppResult IZ_Initialize(IZ_App* app, const char* app_name) { + if (IZ_InitializeFramework()) { + return IZ_APP_RESULT_FRAMEWORK_ERROR; + } + + if (IZ_InitializeConfig(app)) { + return IZ_APP_RESULT_CONFIG_ERROR; + } + + return IZ_APP_RESULT_OK; +} + + +IZ_AppResult IZ_AppRun( + IZ_App* app, + int argc, + char** argv, + const char* app_name, + unsigned int major_version, + unsigned int minor_version, + unsigned int patch_version +) { + IZ_TimerStart(); + IZ_LogInfo( + IZ_LOG_CATEGORY_GLOBAL, + "Application started (%s v.%d.%d.%d).", + app_name, + major_version, + minor_version, + patch_version + ); + IZ_LogArguments(argc, argv); + unsigned int status = IZ_Initialize(app, app_name); + + if (status) { + return status; + } + + return IZ_APP_RESULT_OK; +} diff --git a/src/packages/game/IZ_app.h b/src/packages/game/IZ_app.h new file mode 100644 index 0000000..291017b --- /dev/null +++ b/src/packages/game/IZ_app.h @@ -0,0 +1,31 @@ +#ifndef IZ_APP_H +#define IZ_APP_H + +#include +#include "config/IZ_config.h" +#include "timer/IZ_timer.h" +#include "logging/IZ_log.h" + +typedef struct { + IZ_Config config; +} IZ_App; + +typedef enum { + IZ_APP_RESULT_OK, + + IZ_APP_RESULT_FRAMEWORK_ERROR, + + IZ_APP_RESULT_CONFIG_ERROR, +} IZ_AppResult; + +IZ_AppResult IZ_AppRun( + IZ_App*, + int, + char**, + const char*, + unsigned int, + unsigned int, + unsigned int +); + +#endif diff --git a/src/packages/game/adapter/framework/IZ_keyboard.c b/src/packages/game/adapter/framework/IZ_keyboard.c new file mode 100644 index 0000000..cd6ae3b --- /dev/null +++ b/src/packages/game/adapter/framework/IZ_keyboard.c @@ -0,0 +1 @@ +#include "IZ_keyboard.h" diff --git a/src/packages/game/adapter/framework/IZ_keyboard.h b/src/packages/game/adapter/framework/IZ_keyboard.h new file mode 100644 index 0000000..cb71319 --- /dev/null +++ b/src/packages/game/adapter/framework/IZ_keyboard.h @@ -0,0 +1,45 @@ +#ifndef SDL_IZ_KEYBOARD_H +#define SDL_IZ_KEYBOARD_H + +#include + +/** + * Keyboard scancode. + */ +typedef SDL_Scancode IZ_KeyboardScancode; + +typedef enum { + IZ_SCANCODE_D = SDL_SCANCODE_D, + IZ_SCANCODE_S = SDL_SCANCODE_S, + IZ_SCANCODE_A = SDL_SCANCODE_A, + IZ_SCANCODE_W = SDL_SCANCODE_W, + IZ_SCANCODE_RETURN = SDL_SCANCODE_RETURN, + IZ_SCANCODE_BACKSPACE = SDL_SCANCODE_BACKSPACE, + IZ_SCANCODE_M = SDL_SCANCODE_M, + IZ_SCANCODE_COMMA = SDL_SCANCODE_COMMA, + IZ_SCANCODE_PERIOD = SDL_SCANCODE_PERIOD, + IZ_SCANCODE_SLASH = SDL_SCANCODE_SLASH, + IZ_SCANCODE_J = SDL_SCANCODE_J, + IZ_SCANCODE_K = SDL_SCANCODE_K, + IZ_SCANCODE_L = SDL_SCANCODE_L, + IZ_SCANCODE_SEMICOLON = SDL_SCANCODE_SEMICOLON, + IZ_SCANCODE_I = SDL_SCANCODE_I, + IZ_SCANCODE_O = SDL_SCANCODE_O, +} IZ_Scancode; + +typedef enum { + IZ_JOYSTICK_CODE_0 = 11, + IZ_JOYSTICK_CODE_1 = 10, + IZ_JOYSTICK_CODE_2 = 1, + IZ_JOYSTICK_CODE_3 = 0, + IZ_JOYSTICK_CODE_4 = 4, + IZ_JOYSTICK_CODE_5 = 3, + IZ_JOYSTICK_CODE_6 = 6, + IZ_JOYSTICK_CODE_7 = 7, + IZ_JOYSTICK_CODE_8 = 8, + IZ_JOYSTICK_CODE_9 = 9, + IZ_JOYSTICK_CODE_10 = 13, + IZ_JOYSTICK_CODE_11 = 14, +} IZ_JoystickCode; + +#endif diff --git a/src/packages/game/config/IZ_config.c b/src/packages/game/config/IZ_config.c index 88ecfc7..786c18b 100644 --- a/src/packages/game/config/IZ_config.c +++ b/src/packages/game/config/IZ_config.c @@ -1 +1,152 @@ #include "IZ_config.h" + +#ifdef _WIN64 +void realpath(const char* filename, char* resolved_path) { + TCHAR** lppPart = { NULL }; + GetFullPathNameA(filename, 256, resolved_path, lppPart); +} +#endif + +/** + * Writes the configuration to a file. + * @param config The pointer to the configuration data. + * @param filename The filename of the destination file. + * @return Error message, or NULL if there are no errors. + */ +unsigned int IZ_ConfigSave(IZ_Config* config, const char* filename) { + char resolved_path[256]; + realpath(filename, resolved_path); + IZ_LogInfo(IZ_LOG_CATEGORY_GENERIC, "Persisting configuration to: %s", resolved_path); + FILE* output = fopen(filename, "w"); + if (output == NULL) { + IZ_LogError("Could not persist config."); + return 1; + } + fprintf(output, "[Window]\n"); + fprintf(output, "Width = %d\n", config->window.width); + fprintf(output, "Height = %d\n", config->window.height); + + fprintf(output, "\n[Pool]\n"); + fprintf(output, "Characters = %d\n", config->pool.characters); + + unsigned int p; + unsigned int i; + for (p = 0; p < IZ_MAX_PLAYERS; p += 1) { + fprintf(output, "\n[Mapping(%d).Keyboard]\n", p); + for (i = 0; i < 16; i += 1) { + fprintf(output, "%s = %d\n", IZ_ACTION_NAMES[i], config->mapping[p].keyboard[i]); + } + fprintf(output, "\n[Mapping(%d).Joystick]\n", p); + for (i = 0; i < 12; i += 1) { + fprintf(output, "%s = %d\n", IZ_ACTION_NAMES[i + 4], config->mapping[p].joystick[i]); + } + } + fclose(output); + IZ_LogInfo(IZ_LOG_CATEGORY_GENERIC, "Config saved successfully."); + return 0; +} + +/** + * Reads the configuration from a file. + * @param config The pointer to the configuration data. + * @param filename The filename of the destination file. + * @return Error message, or NULL if there are no errors. + */ +unsigned int IZ_ConfigLoad(IZ_Config* config, const char* filename) { + char resolved_path[256]; + realpath(filename, resolved_path); + IZ_LogInfo(IZ_LOG_CATEGORY_GENERIC, "Loading configuration file: %s", resolved_path); + FILE* input = fopen(filename, "r"); + unsigned int p; + unsigned int i; + if (input == NULL) { + IZ_LogWarn(false, "Config file not found! Loading defaults."); + *config = (IZ_Config) { + .window = { .width = 320, .height = 240 }, + .pool = { + .characters = 64 + }, + .mapping = { + // player 1 + { + .keyboard = { + IZ_SCANCODE_D, + IZ_SCANCODE_S, + IZ_SCANCODE_A, + IZ_SCANCODE_W, + IZ_SCANCODE_RETURN, + IZ_SCANCODE_BACKSPACE, + IZ_SCANCODE_M, + IZ_SCANCODE_COMMA, + IZ_SCANCODE_PERIOD, + IZ_SCANCODE_SLASH, + IZ_SCANCODE_J, + IZ_SCANCODE_K, + IZ_SCANCODE_L, + IZ_SCANCODE_SEMICOLON, + IZ_SCANCODE_I, + IZ_SCANCODE_O, + }, + .joystick = { + IZ_JOYSTICK_CODE_0, + IZ_JOYSTICK_CODE_1, + IZ_JOYSTICK_CODE_2, + IZ_JOYSTICK_CODE_3, + IZ_JOYSTICK_CODE_4, + IZ_JOYSTICK_CODE_5, + IZ_JOYSTICK_CODE_6, + IZ_JOYSTICK_CODE_7, + IZ_JOYSTICK_CODE_8, + IZ_JOYSTICK_CODE_9, + IZ_JOYSTICK_CODE_10, + IZ_JOYSTICK_CODE_11, + } + } + } + }; + + unsigned int persist_status = IZ_ConfigSave(config, filename); + if (persist_status != 0) { + return persist_status; + } + IZ_Log("Window.Width=%d", config->window.width); + IZ_Log("Window.Height=%d", config->window.height); + for (p = 0; p < IZ_MAX_PLAYERS; p += 1) { + for (i = 0; i < 16; i += 1) { + IZ_Log("Mapping(%d).Keyboard.%s=%02x", p, IZ_ACTION_NAMES[i], config->mapping[p].keyboard[i]); + } + for (i = 0; i < 12; i += 1) { + IZ_Log("Mapping(%d).Joystick.%s=%02x", p, IZ_ACTION_NAMES[i + 4], config->mapping[p].joystick[i]); + } + } + } else { + fscanf(input, "[Window]\n"); + fscanf(input, "Width = %d\n", &config->window.width); + IZ_Log("Window.Width=%d", config->window.width); + + fscanf(input, "Height = %d\n", &config->window.height); + IZ_Log("Window.Height=%d", config->window.height); + + fscanf(input, "\n[Pool]\n"); + fscanf(input, "Characters = %d\n", &config->pool.characters); + IZ_Log("Pool.Characters=%d", config->pool.characters); + + static char action_name[7]; + int player_index; + for (p = 0; p < IZ_MAX_PLAYERS; p += 1) { + fscanf(input, "\n[Mapping(%d).Keyboard]\n", &player_index); + for (i = 0; i < 16; i += 1) { + fscanf(input, "%s = %d\n", action_name, &config->mapping[player_index].keyboard[i]); + IZ_Log("Mapping(%d).Keyboard.%s=%02x", player_index, action_name, config->mapping[player_index].keyboard[i]); + } + fscanf(input, "\n[Mapping(%d).Joystick]\n", &player_index); + for (i = 0; i < 12; i += 1) { + fscanf(input, "%s = %d\n", action_name, &config->mapping[player_index].joystick[i]); + IZ_Log("Mapping(%d).Joystick.%s=%02x", player_index, action_name, config->mapping[player_index].joystick[i]); + } + } + } + fclose(input); + IZ_LogInfo(IZ_LOG_CATEGORY_GENERIC,"%s", "Config loaded successfully."); + return 0; +} diff --git a/src/packages/game/config/IZ_config.h b/src/packages/game/config/IZ_config.h index 014021f..57f3341 100644 --- a/src/packages/game/config/IZ_config.h +++ b/src/packages/game/config/IZ_config.h @@ -1,7 +1,19 @@ #ifndef IZ_CONFIG_H #define IZ_CONFIG_H +#include +#include + +#if _WIN64 +#include +#include +#endif + +#include "../adapter/framework/IZ_keyboard.h" + #include "../core/IZ_constants.h" +#include "../logging/IZ_log.h" +#include "../input/IZ_action.h" #include "IZ_config_mapping.h" #include "IZ_config_pool.h" diff --git a/src/packages/game/logging/IZ_log.c b/src/packages/game/logging/IZ_log.c new file mode 100644 index 0000000..2071d1e --- /dev/null +++ b/src/packages/game/logging/IZ_log.c @@ -0,0 +1,92 @@ +#include "IZ_log.h" + +void IZ_LogError(const char* fmt, ...) { +#ifdef IZ_LOG_LEVEL_FLAG_ERROR + char buffer[4096]; + va_list args; + va_start(args, fmt); + vsnprintf(buffer, sizeof(buffer), fmt, args); + va_end(args); +#if IZ_LOG_DATE_FUNCTION == IZ_TimerElapsed + fprintf(stderr, RED "%12s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); +#elif IZ_LOG_DATE_FUNCTION == IZ_TimerNow + fprintf(stderr, RED "%24s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); +#endif +#endif +} + +void IZ_LogInfo(IZ_LogCategory category, const char* fmt, ...) { +#ifdef IZ_LOG_LEVEL_FLAG_INFO + char buffer[4096]; + va_list args; + va_start(args, fmt); + vsnprintf(buffer, sizeof(buffer), fmt, args); + va_end(args); +#if IZ_LOG_DATE_FUNCTION == IZ_TimerElapsed + switch (category) { + default: + case IZ_LOG_CATEGORY_GENERIC: + fprintf(stdout, CYN "%12s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); + break; + case IZ_LOG_CATEGORY_GLOBAL: + fprintf(stdout, MAG "%12s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); + break; + case IZ_LOG_CATEGORY_INPUT: + fprintf(stdout, GRN "%12s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); + break; + } + +#elif IZ_LOG_DATE_FUNCTION == IZ_TimerNow + switch (category) { + default: + case IZ_LOG_CATEGORY_GENERIC: + fprintf(stdout, CYN "%24s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); + break; + case IZ_LOG_CATEGORY_GLOBAL: + fprintf(stdout, MAG "%24s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); + break; + case IZ_LOG_CATEGORY_INPUT: + fprintf(stdout, GRN "%24s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); + break; + } +#endif +#endif +} + +void IZ_LogWarn(bool is_critical, const char* fmt, ...) { +#ifdef IZ_LOG_LEVEL_FLAG_WARN + char buffer[4096]; + va_list args; + va_start(args, fmt); + vsnprintf(buffer, sizeof(buffer), fmt, args); + va_end(args); +#if IZ_LOG_DATE_FUNCTION == IZ_TimerElapsed + if (is_critical) { + fprintf(stdout, WHT "%12s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); + } else { + fprintf(stdout, YEL "%12s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); + } +#elif IZ_LOG_DATE_FUNCTION == IZ_TimerNow + if (is_critical) { + fprintf(stdout, WHT "%24s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); + } else { + fprintf(stdout, YEL "%24s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); + } +#endif +#endif +} + +void IZ_Log(const char* fmt, ...) { +#ifdef IZ_LOG_LEVEL_FLAG_DEBUG + char buffer[4096]; + va_list args; + va_start(args, fmt); + vsnprintf(buffer, sizeof(buffer), fmt, args); + va_end(args); +#if IZ_LOG_DATE_FUNCTION == IZ_TimerElapsed + fprintf(stdout, BLU "%12s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); +#elif IZ_LOG_DATE_FUNCTION == IZ_TimerNow + fprintf(stdout, BLU "%24s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); +#endif +#endif +} diff --git a/src/packages/game/logging/IZ_log.h b/src/packages/game/logging/IZ_log.h new file mode 100644 index 0000000..85e6ee3 --- /dev/null +++ b/src/packages/game/logging/IZ_log.h @@ -0,0 +1,53 @@ +#ifndef IZ_LOG_H +#define IZ_LOG_H + +#ifdef _WIN64 + +#define RED "" +#define GRN "" +#define YEL "" +#define BLU "" +#define MAG "" +#define CYN "" +#define WHT "" +#define RESET "" + +#else + +#define RED "\x1B[31m" +#define GRN "\x1B[32m" +#define YEL "\x1B[33m" +#define BLU "\x1B[34m" +#define MAG "\x1B[35m" +#define CYN "\x1B[36m" +#define WHT "\x1B[37m" +#define RESET "\x1B[0m" + +#endif + +#define IZ_LOG_LEVEL_FLAG_DEBUG +#define IZ_LOG_LEVEL_FLAG_INFO +#define IZ_LOG_LEVEL_FLAG_WARN +#define IZ_LOG_LEVEL_FLAG_ERROR + +//#define IZ_LOG_DATE_FUNCTION IZ_TimerElapsed +#define IZ_LOG_DATE_FUNCTION IZ_TimerNow + +#include +#include +#include +#include +#include "../timer/IZ_timer.h" + +typedef enum { + IZ_LOG_CATEGORY_INPUT, + IZ_LOG_CATEGORY_GLOBAL, + IZ_LOG_CATEGORY_GENERIC, +} IZ_LogCategory; + +void IZ_LogError(const char* fmt, ...); +void IZ_LogInfo(IZ_LogCategory category, const char* fmt, ...); +void IZ_LogWarn(bool is_critical, const char* fmt, ...); +void IZ_Log(const char* fmt, ...); + +#endif diff --git a/src/packages/game/main.c b/src/packages/game/main.c index 94940a7..84b3166 100644 --- a/src/packages/game/main.c +++ b/src/packages/game/main.c @@ -1,74 +1,86 @@ #include #include #include +#include "IZ_app.h" const char* APP_NAME = "SDL2"; -const unsigned int SCREEN_WIDTH = 640; -const unsigned int SCREEN_HEIGHT = 480; -const unsigned int SCREEN_FPS = 30; +//const unsigned int SCREEN_WIDTH = 320; +//const unsigned int SCREEN_HEIGHT = 240; -#define SDL_GetTicks64 SDL_GetTicks +// NES frame rate +//const float SCREEN_FPS = 59.94f; -int main() { - SDL_Window* window = NULL; - SDL_Surface* screenSurface = NULL; +//#define SDL_GetTicks64 SDL_GetTicks +// +//SDL_Window* IZ_GetWindow() { +// if (SDL_Init(SDL_INIT_VIDEO) < 0) { +// printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError()); +// return NULL; +// } +// +// SDL_Window* window = SDL_CreateWindow( +// APP_NAME, +// SDL_WINDOWPOS_UNDEFINED, +// SDL_WINDOWPOS_UNDEFINED, +// (int) SCREEN_WIDTH, +// (int) SCREEN_HEIGHT, +// SDL_WINDOW_SHOWN +// ); +// +// if (window == NULL) { +// printf("Window could not be created! SDL_Error: %s\n", SDL_GetError()); +// return NULL; +// } +// +// return window; +//} - if (SDL_Init(SDL_INIT_VIDEO) < 0) { - printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError()); - return -1; - } +int main(int argc, char** argv) { + IZ_App app; + return IZ_AppRun(&app, argc, argv, APP_NAME, 0, 0, 0); - window = SDL_CreateWindow( - APP_NAME, - SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, - (int) SCREEN_WIDTH, - (int) SCREEN_HEIGHT, - SDL_WINDOW_SHOWN - ); - - if (window == NULL) { - printf("Window could not be created! SDL_Error: %s\n", SDL_GetError()); - return -2; - } - - bool quit = false; - SDL_Event e; - screenSurface = SDL_GetWindowSurface(window); - - uint64_t start = SDL_GetTicks64(); - unsigned int seconds_elapsed = 0; - uint64_t last_update = start; - unsigned int frames = 0; - while (!quit) { - while (SDL_PollEvent(&e) != 0) { - if (e.type == SDL_QUIT) { - quit = true; - } - } - - unsigned int current_ticks = SDL_GetTicks64(); - unsigned int delta = current_ticks - last_update; - unsigned int new_seconds_elapsed = current_ticks / 1000; - - if (new_seconds_elapsed > seconds_elapsed) { - printf("%u\n", frames); - frames = 0; - seconds_elapsed = new_seconds_elapsed; - } - - if ((float) delta < 1000.f / (float) (SCREEN_FPS + 1)) { - continue; - } - - last_update = current_ticks; - frames += 1; - SDL_FillRect(screenSurface, NULL, SDL_MapRGB(screenSurface->format, 0xFF, 0xFF, 0xFF)); - SDL_UpdateWindowSurface(window); - } - - SDL_DestroyWindow(window); - SDL_Quit(); - - return 0; +// SDL_Window* window = IZ_GetWindow(); +// if (!window) { +// return -1; +// } +// SDL_Surface* screenSurface = SDL_GetWindowSurface(window); +// +// uint64_t start = SDL_GetTicks64(); +// unsigned int seconds_elapsed = 0; +// uint64_t last_update = start; +// unsigned int frames = 0; +// bool quit = false; +// SDL_Event e; +// while (!quit) { +// while (SDL_PollEvent(&e) != 0) { +// if (e.type == SDL_QUIT) { +// quit = true; +// } +// } +// +// unsigned int current_ticks = SDL_GetTicks64(); +// unsigned int delta = current_ticks - last_update; +// unsigned int new_seconds_elapsed = current_ticks / 1000; +// +// if (new_seconds_elapsed > seconds_elapsed) { +// printf("%u\n", frames); +// frames = 0; +// seconds_elapsed = new_seconds_elapsed; +// } +// +// if ((float) delta < 1000.f / SCREEN_FPS) { +// continue; +// } +// +// last_update = current_ticks; +// frames += 1; +// +// SDL_FillRect(screenSurface, NULL, SDL_MapRGB(screenSurface->format, 0xFF, 0xFF, 0xFF)); +// SDL_UpdateWindowSurface(window); +// } +// +// SDL_DestroyWindow(window); +// SDL_Quit(); +// +// return 0; } diff --git a/src/packages/game/timer/IZ_timer.c b/src/packages/game/timer/IZ_timer.c new file mode 100644 index 0000000..7dd0add --- /dev/null +++ b/src/packages/game/timer/IZ_timer.c @@ -0,0 +1,69 @@ +#include "IZ_timer.h" + +#ifdef _WIN64 +typedef enum { + _CLOCK_REALTIME = 0, +#define CLOCK_REALTIME _CLOCK_REALTIME + _CLOCK_MONOTONIC = 6, +#define CLOCK_MONOTONIC _CLOCK_MONOTONIC +} clockid_t; + +int clock_gettime(clockid_t __clock_id, struct timespec *__tp) { + return timespec_get(__tp, TIME_UTC); +} +#endif + +/** + * Gets the start timestamp. + * @sa IZ_TIMER_START_TIMESTAMP + */ +void IZ_TimerStart() { + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + IZ_TIMER_START_TIMESTAMP = t.tv_sec; +} + +/** + * Gets the number of microseconds since the application timer has been started. + * @return The number of microseconds. + * @sa IZ_TimerElapsed() + */ +unsigned int IZ_TimerElapsedRaw() { + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + return (t.tv_sec - IZ_TIMER_START_TIMESTAMP) * 1000000 + (t.tv_nsec / 1000); +} + +/** + * Gets the formatted elapsed time since the application timer has been started. + * @return The formatted elapsed time. + * @sa IZ_TimerElapsedRaw() + */ +char* IZ_TimerElapsed() { + static char buffer[32]; + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + unsigned int seconds = t.tv_sec - IZ_TIMER_START_TIMESTAMP; + unsigned int milliseconds = t.tv_nsec / 1000000; + unsigned int minutes = seconds / 60; + unsigned int hours = seconds / 60 / 60; + sprintf(buffer, "%02d:%02d:%02d.%03d", hours, minutes % 60, seconds % 60, milliseconds % 1000); + return buffer; +} + +/** + * Gets the formatted time in the current instant. + * @return The formatted time in the current instant. + */ +char* IZ_TimerNow() { + struct timespec t; + clock_gettime(CLOCK_REALTIME, &t); + static char buffer[32]; + unsigned int seconds = t.tv_sec; + unsigned int milliseconds = t.tv_nsec / 1000000; + static char formatted[32]; + time_t current_time = seconds; + strftime(formatted, sizeof(formatted), "%Y-%m-%dT%H:%M:%S", gmtime(¤t_time)); + sprintf(buffer, "%s.%03dZ", formatted, milliseconds < 0 ? 0 : milliseconds % 1000); + return buffer; +} diff --git a/src/packages/game/timer/IZ_timer.h b/src/packages/game/timer/IZ_timer.h new file mode 100644 index 0000000..c71fe76 --- /dev/null +++ b/src/packages/game/timer/IZ_timer.h @@ -0,0 +1,42 @@ +#ifndef IZ_TIMER_H +#define IZ_TIMER_H + +//#define IZ_LOG_DATE_FRIENDLY +#define IZ_LOG_DATE_ELAPSED_FRIENDLY + +#include +#include + +/** + * The start timestamp. + * @sa IZ_TimerStart + */ +static time_t IZ_TIMER_START_TIMESTAMP = 0; + +/** + * Gets the start timestamp. + * @sa IZ_TIMER_START_TIMESTAMP + */ +void IZ_TimerStart(); + +/** + * Gets the number of microseconds since the application timer has been started. + * @return The number of microseconds. + * @sa IZ_TimerElapsed() + */ +unsigned int IZ_TimerElapsedRaw(); + +/** + * Gets the formatted elapsed time since the application timer has been started. + * @return The formatted elapsed time. + * @sa IZ_TimerElapsedRaw() + */ +char* IZ_TimerElapsed(); + +/** + * Gets the formatted time in the current instant. + * @return The formatted time in the current instant. + */ +char* IZ_TimerNow(); + +#endif