#include "IZ_app.h" u64 IZ_AppGetTicks(struct IZ_App* app) { return app->ticks; } void IZ_AppBindConnection(struct IZ_App* app, struct lws* wsi) { app->net_state.binding.connection = wsi; } IZ_NetClientState* IZ_AppGetNetState(struct IZ_App* app) { return &app->net_state; } IZ_InputState* IZ_AppGetInputState(struct IZ_App* app) { return &app->input_state; } typedef enum { IZ_APP_INITIALIZE_RESULT_NETWORKING_ERROR = -5, IZ_APP_INITIALIZE_RESULT_POOL_ERROR, IZ_APP_INITIALIZE_RESULT_INPUT_ERROR, IZ_APP_INITIALIZE_RESULT_VIDEO_ERROR, IZ_APP_INITIALIZE_RESULT_SDL_ERROR, IZ_APP_INITIALIZE_RESULT_OK, } IZ_AppInitializeResult; IZ_AppInitializeResult IZ_AppInitialize(struct IZ_App* app, u8 argc, const char* argv[]) { memset(app, 0, sizeof(struct IZ_App)); const char* cmdline_buffer; char config_path[128]; // TODO abstract command line args parsing if ((cmdline_buffer = IZ_ConfigGetCommandlineOption(argc, argv, "-c"))) { memcpy_s(config_path, 128, cmdline_buffer, 128); } else { IZ_ConfigGetDefaultPath(config_path, 128); } u32 flags = ( SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS ); if (SDL_Init(flags) < 0) { SDL_LogError(SDL_LOG_CATEGORY_ERROR, "SDL could not initialize! SDL_Error: %s\n", SDL_GetError()); return IZ_APP_INITIALIZE_RESULT_SDL_ERROR; } if (IZ_VideoInitialize(&app->video_state, app, config_path, argc, argv)) { return IZ_APP_INITIALIZE_RESULT_VIDEO_ERROR; } if (IZ_InputInitialize(&app->input_state, config_path, argc, argv)) { return IZ_APP_INITIALIZE_RESULT_INPUT_ERROR; } if (IZ_NetClientInitialize(&app->net_state, app, IZ_AppRunNetworkingThread, config_path, argc, argv)) { return IZ_APP_INITIALIZE_RESULT_NETWORKING_ERROR; } IZ_PoolInitialize(&app->pool, POOL_MAX_SIZE); app->ticks = 0; return IZ_APP_INITIALIZE_RESULT_OK; } void IZ_AppTeardown(struct IZ_App* app) { IZ_NetClientDisconnect(&app->net_state); IZ_PoolTeardown(&app->pool); IZ_InputTeardown(&app->input_state); IZ_VideoTeardown(&app->video_state); SDL_Quit(); } void IZ_AppPrintHelpOptions() { printf("\n"); printf("Options:\n"); printf("\n"); printf( "\n" "Options:\n" "\n" " -c Specifies the path to the config file. (default: \"./config-game.ini\")\n" " -f Specifies the frames per second. (default: 30)\n" " -h Displays this help screen.\n" " -i Specifies the interval of sending packets (default: 200)\n" " in milliseconds.\n" ); } void IZ_AppPrintHelpUsage() { printf("\n"); printf("Usage:"); printf(" %s [options]\n", "game.exe"); } void IZ_AppPrintHelpHeader() { printf("\n"); printf("%s - %s\n", IZ_APP_NAME, IZ_APP_DESCRIPTION); } void IZ_AppPrintHelp() { IZ_AppPrintHelpHeader(); IZ_AppPrintHelpUsage(); IZ_AppPrintHelpOptions(); } IZ_AppResult IZ_AppRun(struct IZ_App* app, u8 argc, const char* argv[]) { if (IZ_ConfigGetCommandlineOption(argc, argv, "-h")) { IZ_AppPrintHelp(); return IZ_APP_RESULT_OK; } if (IZ_AppInitialize(app, argc, argv) < 0) { return IZ_APP_RESULT_INITIALIZATION_ERROR; } char asset_dir[255]; IZ_AssetResolveDir("weapon-operator", asset_dir); u16 sprite_slot_index = IZ_VideoGetNextFreeSpriteSlot(&app->video_state, IZ_VIDEO_SPRITE_PRIORITY_MEDIUM); IZ_VideoLoadSprite(&app->video_state, (IZ_VideoLoadSpriteParams) { .dir = asset_dir, .filename = "sprite.svg", .priority = IZ_VIDEO_SPRITE_PRIORITY_MEDIUM, }, &app->video_state.active_sprites[sprite_slot_index]); app->video_state.active_sprites[sprite_slot_index].sprite.scale_factor = 0.25f; app->video_state.active_sprites[sprite_slot_index].sprite.position = (IZ_Vector2D) { 100.f, 100.f }; IZ_AssetResolveDir("weapon-specialist", asset_dir); sprite_slot_index = IZ_VideoGetNextFreeSpriteSlot(&app->video_state, IZ_VIDEO_SPRITE_PRIORITY_MEDIUM); IZ_VideoLoadSprite(&app->video_state, (IZ_VideoLoadSpriteParams) { .dir = asset_dir, .filename = "sprite.svg", .priority = IZ_VIDEO_SPRITE_PRIORITY_MEDIUM, }, &app->video_state.active_sprites[sprite_slot_index]); app->video_state.active_sprites[sprite_slot_index].sprite.scale_factor = 0.25f; app->video_state.active_sprites[sprite_slot_index].sprite.position = (IZ_Vector2D) { 50.f, 50.f }; app->video_state.active_sprites[sprite_slot_index].sprite.flip_x = true; while (true) { app->ticks = SDL_GetTicks64(); // TODO do audio processing // TODO do networking if (IZ_AppHandleInputEvents(app)) { break; } IZ_AppHandleOutboundNetworking(app); IZ_VideoUpdate(&app->video_state); } IZ_AppTeardown(app); return IZ_APP_RESULT_OK; }