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.
 
 
 
 
 
 

160 lines
4.5 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 = -5,
  16. IZ_APP_INITIALIZE_RESULT_POOL_ERROR,
  17. IZ_APP_INITIALIZE_RESULT_INPUT_ERROR,
  18. IZ_APP_INITIALIZE_RESULT_VIDEO_ERROR,
  19. IZ_APP_INITIALIZE_RESULT_SDL_ERROR,
  20. IZ_APP_INITIALIZE_RESULT_OK,
  21. } IZ_AppInitializeResult;
  22. IZ_AppInitializeResult IZ_AppInitialize(struct IZ_App* app, u8 argc, const char* argv[]) {
  23. memset(app, 0, sizeof(struct IZ_App));
  24. const char* cmdline_buffer;
  25. char config_path[128];
  26. // TODO abstract command line args parsing
  27. if ((cmdline_buffer = IZ_ConfigGetCommandlineOption(argc, argv, "-c"))) {
  28. memcpy_s(config_path, 128, cmdline_buffer, 128);
  29. } else {
  30. IZ_ConfigGetDefaultPath(config_path, 128);
  31. }
  32. u32 flags = (
  33. SDL_INIT_VIDEO
  34. | SDL_INIT_GAMECONTROLLER
  35. | SDL_INIT_EVENTS
  36. );
  37. if (SDL_Init(flags) < 0) {
  38. SDL_LogError(SDL_LOG_CATEGORY_ERROR, "SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
  39. return IZ_APP_INITIALIZE_RESULT_SDL_ERROR;
  40. }
  41. if (IZ_VideoInitialize(&app->video_state, app, config_path, argc, argv)) {
  42. return IZ_APP_INITIALIZE_RESULT_VIDEO_ERROR;
  43. }
  44. if (IZ_InputInitialize(&app->input_state, config_path, argc, argv)) {
  45. return IZ_APP_INITIALIZE_RESULT_INPUT_ERROR;
  46. }
  47. if (IZ_NetClientInitialize(&app->net_state, app, IZ_AppRunNetworkingThread, config_path, argc, argv)) {
  48. return IZ_APP_INITIALIZE_RESULT_NETWORKING_ERROR;
  49. }
  50. IZ_PoolInitialize(&app->pool, POOL_MAX_SIZE);
  51. app->ticks = 0;
  52. return IZ_APP_INITIALIZE_RESULT_OK;
  53. }
  54. void IZ_AppTeardown(struct IZ_App* app) {
  55. IZ_NetClientDisconnect(&app->net_state);
  56. IZ_PoolTeardown(&app->pool);
  57. IZ_InputTeardown(&app->input_state);
  58. IZ_VideoTeardown(&app->video_state);
  59. SDL_Quit();
  60. }
  61. void IZ_AppPrintHelpOptions() {
  62. printf("\n");
  63. printf("Options:\n");
  64. printf("\n");
  65. printf(
  66. "\n"
  67. "Options:\n"
  68. "\n"
  69. " -c <path> Specifies the path to the config file. (default: \"./config-game.ini\")\n"
  70. " -f <value> Specifies the frames per second. (default: 30)\n"
  71. " -h Displays this help screen.\n"
  72. " -i <value> Specifies the interval of sending packets (default: 200)\n"
  73. " in milliseconds.\n"
  74. );
  75. }
  76. void IZ_AppPrintHelpUsage() {
  77. printf("\n");
  78. printf("Usage:");
  79. printf(" %s [options]\n", "game.exe");
  80. }
  81. void IZ_AppPrintHelpHeader() {
  82. printf("\n");
  83. printf("%s - %s\n", IZ_APP_NAME, IZ_APP_DESCRIPTION);
  84. }
  85. void IZ_AppPrintHelp() {
  86. IZ_AppPrintHelpHeader();
  87. IZ_AppPrintHelpUsage();
  88. IZ_AppPrintHelpOptions();
  89. }
  90. IZ_AppResult IZ_AppRun(struct IZ_App* app, u8 argc, const char* argv[]) {
  91. if (IZ_ConfigGetCommandlineOption(argc, argv, "-h")) {
  92. IZ_AppPrintHelp();
  93. return IZ_APP_RESULT_OK;
  94. }
  95. if (IZ_AppInitialize(app, argc, argv) < 0) {
  96. return IZ_APP_RESULT_INITIALIZATION_ERROR;
  97. }
  98. char asset_dir[255];
  99. IZ_AssetResolveDir("weapon-operator", asset_dir);
  100. u16 sprite_slot_index = IZ_VideoGetNextFreeSpriteSlot(&app->video_state, IZ_VIDEO_SPRITE_PRIORITY_MEDIUM);
  101. IZ_VideoLoadSprite(&app->video_state, (IZ_VideoLoadSpriteParams) {
  102. .dir = asset_dir,
  103. .filename = "sprite.svg",
  104. .priority = IZ_VIDEO_SPRITE_PRIORITY_MEDIUM,
  105. }, &app->video_state.active_sprites[sprite_slot_index]);
  106. app->video_state.active_sprites[sprite_slot_index].sprite.scale_factor = 0.25f;
  107. app->video_state.active_sprites[sprite_slot_index].sprite.position = (IZ_Vector2D) { 100.f, 100.f };
  108. IZ_AssetResolveDir("weapon-specialist", asset_dir);
  109. sprite_slot_index = IZ_VideoGetNextFreeSpriteSlot(&app->video_state, IZ_VIDEO_SPRITE_PRIORITY_MEDIUM);
  110. IZ_VideoLoadSprite(&app->video_state, (IZ_VideoLoadSpriteParams) {
  111. .dir = asset_dir,
  112. .filename = "sprite.svg",
  113. .priority = IZ_VIDEO_SPRITE_PRIORITY_MEDIUM,
  114. }, &app->video_state.active_sprites[sprite_slot_index]);
  115. app->video_state.active_sprites[sprite_slot_index].sprite.scale_factor = 0.25f;
  116. app->video_state.active_sprites[sprite_slot_index].sprite.position = (IZ_Vector2D) { 50.f, 50.f };
  117. app->video_state.active_sprites[sprite_slot_index].sprite.flip_x = true;
  118. while (true) {
  119. app->ticks = SDL_GetTicks64();
  120. // TODO do audio processing
  121. // TODO do networking
  122. if (IZ_AppHandleInputEvents(app)) {
  123. break;
  124. }
  125. IZ_AppHandleOutboundNetworking(app);
  126. IZ_VideoUpdate(&app->video_state);
  127. }
  128. IZ_AppTeardown(app);
  129. return IZ_APP_RESULT_OK;
  130. }