#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; } IZ_ProcedureResult 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_RUN_SDL_INIT_ERROR; } if (IZ_VideoInitialize(&app->video_state, app, config_path, argc, argv)) { return IZ_APP_RUN_VIDEO_INIT_ERROR; } if (IZ_InputInitialize(&app->input_state, config_path, argc, argv)) { return IZ_APP_RUN_INPUT_INIT_ERROR; } if (IZ_NetClientInitialize(&app->net_state, app, IZ_AppRunNetworkingThread, config_path, argc, argv)) { return IZ_APP_RUN_NETWORKING_ERROR; } IZ_PoolInitialize(&app->pool, POOL_MAX_SIZE); app->ticks = 0; return IZ_APP_RUN_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_ProcedureResult IZ_AppRun(struct IZ_App* app, u8 argc, const char* argv[]) { // TODO have a config subsystem that handles these. if (IZ_ConfigGetCommandlineOption(argc, argv, "-h")) { IZ_AppPrintHelp(); return IZ_APP_RUN_RESULT_OK; } IZ_ProcedureResult init_result = IZ_AppInitialize(app, argc, argv); if (init_result) { return init_result; } 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_RUN_RESULT_OK; }