@@ -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}) | |||
@@ -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" | |||
#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 | |||
#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 "../logging/IZ_log.h" | |||
#include "../input/IZ_action.h" | |||
#include "IZ_config_mapping.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 <stdbool.h> | |||
#include <stdio.h> | |||
#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; | |||
} |
@@ -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 |