2D Run-and-gun shooter inspired by One Man's Doomsday, Counter-Strike, and Metal Slug.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

167 lines
4.9 KiB

  1. #include "IZ_app.h"
  2. u64 IZ_AppGetTicks(struct IZ_App* app) {
  3. return app->ticks;
  4. }
  5. void IZ_AppBindConnection(struct IZ_App* app, struct lws* wsi) {
  6. app->net_state.binding.connection = wsi;
  7. }
  8. IZ_NetClientState* IZ_AppGetNetState(struct IZ_App* app) {
  9. return &app->net_state;
  10. }
  11. IZ_InputState* IZ_AppGetInputState(struct IZ_App* app) {
  12. return &app->input_state;
  13. }
  14. typedef enum {
  15. IZ_APP_INITIALIZE_RESULT_NETWORKING_ERROR = -6,
  16. IZ_APP_INITIALIZE_RESULT_POOL_ERROR,
  17. IZ_APP_INITIALIZE_RESULT_INPUT_ERROR,
  18. IZ_APP_INITIALIZE_RESULT_AUDIO_ERROR,
  19. IZ_APP_INITIALIZE_RESULT_VIDEO_ERROR,
  20. IZ_APP_INITIALIZE_RESULT_SDL_ERROR,
  21. IZ_APP_INITIALIZE_RESULT_OK,
  22. } IZ_AppInitializeResult;
  23. IZ_AppInitializeResult IZ_AppInitialize(struct IZ_App* app, u8 argc, const char* argv[]) {
  24. IZ_LogInitialize("game", false);
  25. IZ_LogInterceptWSMessages(LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE);
  26. IZ_LogInfo(IZ_LOG_CATEGORY_GLOBAL, "global", "Starting %s...", IZ_APP_NAME);
  27. IZ_memset(app, 0, sizeof(struct IZ_App));
  28. const char* cmdline_buffer;
  29. char config_path[128];
  30. // TODO abstract command line args parsing
  31. if ((cmdline_buffer = INI_ConfigGetCommandlineOption(argc, argv, "-c"))) {
  32. IZ_memcpy(config_path, 128, cmdline_buffer, 128);
  33. } else {
  34. IZ_ConfigGetDefaultPath(config_path, 128);
  35. }
  36. u32 flags = (
  37. SDL_INIT_VIDEO
  38. | SDL_INIT_GAMECONTROLLER
  39. | SDL_INIT_EVENTS
  40. );
  41. if (SDL_Init(flags) < 0) {
  42. IZ_LogError("global", "Framework initialization failed! Reason: %s", SDL_GetError());
  43. return IZ_APP_INITIALIZE_RESULT_SDL_ERROR;
  44. }
  45. if (IZ_VideoInitialize(&app->video_state, app, config_path, argc, argv)) {
  46. return IZ_APP_INITIALIZE_RESULT_VIDEO_ERROR;
  47. }
  48. if (IZ_InputInitialize(&app->input_state, config_path, argc, argv)) {
  49. return IZ_APP_INITIALIZE_RESULT_INPUT_ERROR;
  50. }
  51. if (IZ_NetClientInitialize(&app->net_state, app, IZ_AppRunNetworkingThread, config_path, argc, argv)) {
  52. return IZ_APP_INITIALIZE_RESULT_NETWORKING_ERROR;
  53. }
  54. IZ_PoolInitialize(&app->pool, POOL_MAX_SIZE);
  55. app->ticks = 0;
  56. return IZ_APP_INITIALIZE_RESULT_OK;
  57. }
  58. void IZ_AppTeardown(struct IZ_App* app) {
  59. IZ_PoolTeardown(&app->pool);
  60. IZ_NetClientTeardown(&app->net_state);
  61. IZ_InputTeardown(&app->input_state);
  62. IZ_VideoTeardown(&app->video_state);
  63. IZ_LogInfo(IZ_LOG_CATEGORY_GLOBAL, "global", "Stopping %s...", IZ_APP_NAME);
  64. IZ_LogTeardown();
  65. SDL_Quit();
  66. }
  67. void IZ_AppPrintHelpOptions() {
  68. printf("\n");
  69. printf("Options:\n");
  70. printf("\n");
  71. printf(
  72. "\n"
  73. "Options:\n"
  74. "\n"
  75. " -c <path> Specifies the path to the config file. (default: \"./" IZ_CONFIG_GAME_PATH "\")\n"
  76. " -f <value> Specifies the frames per second. (default: 30)\n"
  77. " -h Displays this help screen.\n"
  78. " -i <value> Specifies the interval of sending packets (default: 200)\n"
  79. " in milliseconds.\n"
  80. );
  81. }
  82. void IZ_AppPrintHelpUsage() {
  83. printf("\n");
  84. printf("Usage:");
  85. printf(" %s [options]\n", "game.exe");
  86. }
  87. void IZ_AppPrintHelpHeader() {
  88. printf("\n");
  89. printf("%s - %s\n", IZ_APP_NAME, IZ_APP_DESCRIPTION);
  90. }
  91. void IZ_AppPrintHelp() {
  92. IZ_AppPrintHelpHeader();
  93. IZ_AppPrintHelpUsage();
  94. IZ_AppPrintHelpOptions();
  95. }
  96. IZ_AppResult IZ_AppRun(struct IZ_App* app, u8 argc, const char* argv[]) {
  97. IZ_TimerStart();
  98. if (INI_ConfigGetCommandlineOption(argc, argv, "-h")) {
  99. IZ_AppPrintHelp();
  100. return IZ_APP_RESULT_OK;
  101. }
  102. if (IZ_AppInitialize(app, argc, argv) < 0) {
  103. return IZ_APP_RESULT_INITIALIZATION_ERROR;
  104. }
  105. char asset_dir[255];
  106. IZ_AssetResolveDir("weapon-operator", asset_dir);
  107. u16 sprite_slot_index = IZ_VideoGetNextFreeSpriteSlot(&app->video_state, IZ_VIDEO_SPRITE_PRIORITY_MEDIUM);
  108. IZ_VideoLoadSprite(&app->video_state, (IZ_VideoLoadSpriteParams) {
  109. .dir = asset_dir,
  110. .filename = "sprite.svg",
  111. .priority = IZ_VIDEO_SPRITE_PRIORITY_MEDIUM,
  112. }, &app->video_state.active_sprites[sprite_slot_index]);
  113. app->video_state.active_sprites[sprite_slot_index].sprite.scale_factor = 0.25f;
  114. app->video_state.active_sprites[sprite_slot_index].sprite.position = (IZ_Vector2D) { 100.f, 100.f };
  115. IZ_AssetResolveDir("weapon-specialist", asset_dir);
  116. sprite_slot_index = IZ_VideoGetNextFreeSpriteSlot(&app->video_state, IZ_VIDEO_SPRITE_PRIORITY_MEDIUM);
  117. IZ_VideoLoadSprite(&app->video_state, (IZ_VideoLoadSpriteParams) {
  118. .dir = asset_dir,
  119. .filename = "sprite.svg",
  120. .priority = IZ_VIDEO_SPRITE_PRIORITY_MEDIUM,
  121. }, &app->video_state.active_sprites[sprite_slot_index]);
  122. app->video_state.active_sprites[sprite_slot_index].sprite.scale_factor = 0.25f;
  123. app->video_state.active_sprites[sprite_slot_index].sprite.position = (IZ_Vector2D) { 50.f, 50.f };
  124. app->video_state.active_sprites[sprite_slot_index].sprite.flip_x = true;
  125. while (true) {
  126. app->ticks = SDL_GetTicks64();
  127. // TODO do audio processing
  128. // TODO do inbound networking
  129. if (IZ_AppHandleInputEvents(app)) {
  130. break;
  131. }
  132. IZ_AppHandleOutboundNetworking(app);
  133. IZ_VideoUpdate(&app->video_state);
  134. }
  135. IZ_AppTeardown(app);
  136. return IZ_APP_RESULT_OK;
  137. }