level.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #include <game/level.h>
  2. static void level_start(Level *level, GameManager *manager, void *context)
  3. {
  4. UNUSED(manager);
  5. if (!level || !context)
  6. {
  7. FURI_LOG_E("Game", "Level or context is NULL");
  8. return;
  9. }
  10. level_clear(level);
  11. player_spawn(level, manager);
  12. LevelContext *level_context = context;
  13. // check if the world exists
  14. if (!world_exists(level_context->id))
  15. {
  16. FURI_LOG_E("Game", "World does not exist.. downloading now");
  17. FuriString *world_data = fetch_world(level_context->id);
  18. if (!world_data)
  19. {
  20. FURI_LOG_E("Game", "Failed to fetch world data");
  21. draw_tree_world(level);
  22. return;
  23. }
  24. if (!draw_json_world(level, furi_string_get_cstr(world_data)))
  25. {
  26. FURI_LOG_E("Game", "Failed to draw world");
  27. draw_tree_world(level);
  28. }
  29. // world_data is guaranteed non-NULL here
  30. furi_string_free(world_data);
  31. return;
  32. }
  33. // get the world data
  34. FuriString *world_data = load_furi_world(level_context->id);
  35. if (!world_data)
  36. {
  37. FURI_LOG_E("Game", "Failed to load world data");
  38. draw_tree_world(level);
  39. return;
  40. }
  41. // draw the world
  42. if (!draw_json_world(level, furi_string_get_cstr(world_data)))
  43. {
  44. FURI_LOG_E("Game", "World exists but failed to draw.");
  45. draw_tree_world(level);
  46. }
  47. // world_data is guaranteed non-NULL here
  48. furi_string_free(world_data);
  49. }
  50. static LevelContext *level_context_generic;
  51. static LevelContext *level_generic_alloc(const char *id, int index)
  52. {
  53. if (level_context_generic == NULL)
  54. {
  55. level_context_generic = malloc(sizeof(LevelContext));
  56. }
  57. snprintf(level_context_generic->id, sizeof(level_context_generic->id), "%s", id);
  58. level_context_generic->index = index;
  59. return level_context_generic;
  60. }
  61. static void level_generic_free()
  62. {
  63. if (level_context_generic != NULL)
  64. {
  65. free(level_context_generic);
  66. level_context_generic = NULL;
  67. }
  68. }
  69. static void level_free(Level *level, GameManager *manager, void *context)
  70. {
  71. UNUSED(level);
  72. UNUSED(manager);
  73. UNUSED(context);
  74. level_generic_free();
  75. }
  76. static void level_alloc_generic_world(Level *level, GameManager *manager, void *context)
  77. {
  78. UNUSED(manager);
  79. UNUSED(level);
  80. if (!level_context_generic)
  81. {
  82. FURI_LOG_E("Game", "Generic level context not set");
  83. return;
  84. }
  85. if (!context)
  86. {
  87. FURI_LOG_E("Game", "Context is NULL");
  88. return;
  89. }
  90. LevelContext *level_context = context;
  91. snprintf(level_context->id, sizeof(level_context->id), "%s", level_context_generic->id);
  92. level_context->index = level_context_generic->index;
  93. }
  94. const LevelBehaviour _generic_level = {
  95. .alloc = level_alloc_generic_world,
  96. .free = level_free,
  97. .start = level_start,
  98. .stop = NULL,
  99. .context_size = sizeof(LevelContext),
  100. };
  101. const LevelBehaviour *generic_level(const char *id, int index)
  102. {
  103. // free any old context before allocating a new one
  104. level_generic_free();
  105. level_context_generic = level_generic_alloc(id, index);
  106. return &_generic_level;
  107. }