@@ -7,7 +7,7 @@ set(SDL2PATH "${PROJECT_SOURCE_DIR}/dependencies/SDL2-2.0.16/x86_64-w64-mingw32" | |||||
find_package(SDL2 REQUIRED) | find_package(SDL2 REQUIRED) | ||||
include_directories(${SDL2_INCLUDE_DIR}) | 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}) | target_link_libraries(izanami ${SDL2_LIBRARY}) | ||||
@@ -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; | |||||
} |
@@ -0,0 +1,31 @@ | |||||
#ifndef IZ_APP_H | |||||
#define IZ_APP_H | |||||
#include <SDL.h> | |||||
#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 |
@@ -0,0 +1 @@ | |||||
#include "IZ_keyboard.h" |
@@ -0,0 +1,45 @@ | |||||
#ifndef SDL_IZ_KEYBOARD_H | |||||
#define SDL_IZ_KEYBOARD_H | |||||
#include <SDL_scancode.h> | |||||
/** | |||||
* 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 |
@@ -1 +1,152 @@ | |||||
#include "IZ_config.h" | #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; | |||||
} |
@@ -1,7 +1,19 @@ | |||||
#ifndef IZ_CONFIG_H | #ifndef IZ_CONFIG_H | ||||
#define IZ_CONFIG_H | #define IZ_CONFIG_H | ||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#if _WIN64 | |||||
#include <windows.h> | |||||
#include <fileapi.h> | |||||
#endif | |||||
#include "../adapter/framework/IZ_keyboard.h" | |||||
#include "../core/IZ_constants.h" | #include "../core/IZ_constants.h" | ||||
#include "../logging/IZ_log.h" | |||||
#include "../input/IZ_action.h" | |||||
#include "IZ_config_mapping.h" | #include "IZ_config_mapping.h" | ||||
#include "IZ_config_pool.h" | #include "IZ_config_pool.h" | ||||
@@ -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 | |||||
} |
@@ -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 <stdbool.h> | |||||
#include <stdarg.h> | |||||
#include <stdio.h> | |||||
#include <time.h> | |||||
#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 |
@@ -1,74 +1,86 @@ | |||||
#include <SDL.h> | #include <SDL.h> | ||||
#include <stdbool.h> | #include <stdbool.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include "IZ_app.h" | |||||
const char* APP_NAME = "SDL2"; | 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; | |||||
} | } |
@@ -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; | |||||
} |
@@ -0,0 +1,42 @@ | |||||
#ifndef IZ_TIMER_H | |||||
#define IZ_TIMER_H | |||||
//#define IZ_LOG_DATE_FRIENDLY | |||||
#define IZ_LOG_DATE_ELAPSED_FRIENDLY | |||||
#include <stdio.h> | |||||
#include <time.h> | |||||
/** | |||||
* 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 |