pokemon_pokerus.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #include <gui/modules/variable_item_list.h>
  2. #include <furi.h>
  3. #include "../pokemon_app.h"
  4. #include "pokemon_menu.h"
  5. static const char* pokerus_states[] = {
  6. "Clean",
  7. "Infected",
  8. "Cured",
  9. "",
  10. };
  11. static const char* strains[] = {
  12. "None",
  13. "A",
  14. "B",
  15. "C",
  16. "D",
  17. "",
  18. };
  19. const char* select_pokerus_status(PokemonFap* pokemon_fap) {
  20. uint8_t pokerus;
  21. pokerus = pokemon_stat_get(pokemon_fap->pdata, STAT_POKERUS, NONE);
  22. if(pokerus == 0x00) return pokerus_states[0];
  23. if((pokerus & 0x0f) != 0x00) return pokerus_states[1];
  24. return pokerus_states[2];
  25. }
  26. struct pokerus_itemlist {
  27. VariableItem* strain;
  28. VariableItem* days;
  29. };
  30. static struct pokerus_itemlist pokerus = {0};
  31. static void select_pokerus_rebuild_list(PokemonFap* pokemon_fap);
  32. static void select_strain_callback(VariableItem* item) {
  33. uint8_t index = variable_item_get_current_value_index(item);
  34. uint8_t pokerus;
  35. PokemonFap* pokemon_fap = variable_item_get_context(item);
  36. /* Need to read/modify/write the existing stat */
  37. pokerus = pokemon_stat_get(pokemon_fap->pdata, STAT_POKERUS, NONE);
  38. pokerus &= 0x0f;
  39. /* Need to set the new text from the mangled index */
  40. variable_item_set_current_value_text(item, strains[index]);
  41. /* demangle the index to the value we need to set in trade struct */
  42. if(index == 0)
  43. ;
  44. else if(index == 0x01)
  45. index = 0x04; // Map this back to the A strain
  46. else
  47. index--;
  48. pokerus |= (index << 4);
  49. if((pokerus & 0xf0) == 0x00) pokerus = 0;
  50. pokemon_stat_set(pokemon_fap->pdata, STAT_POKERUS, NONE, pokerus);
  51. select_pokerus_rebuild_list(pokemon_fap);
  52. variable_item_list_set_selected_item(pokemon_fap->variable_item_list, 0);
  53. }
  54. static void select_days_callback(VariableItem* item) {
  55. uint8_t index = variable_item_get_current_value_index(item);
  56. uint8_t pokerus;
  57. PokemonFap* pokemon_fap = variable_item_get_context(item);
  58. /* Need to read/modify/write the existing stat */
  59. pokerus = pokemon_stat_get(pokemon_fap->pdata, STAT_POKERUS, NONE);
  60. pokerus &= 0xf0;
  61. pokerus |= index;
  62. pokemon_stat_set(pokemon_fap->pdata, STAT_POKERUS, NONE, pokerus);
  63. select_pokerus_rebuild_list(pokemon_fap);
  64. variable_item_list_set_selected_item(pokemon_fap->variable_item_list, 1);
  65. }
  66. static void select_pokerus_rebuild_list(PokemonFap* pokemon_fap) {
  67. uint8_t strain;
  68. uint8_t days;
  69. FuriString* daystring = NULL;
  70. days = pokemon_stat_get(pokemon_fap->pdata, STAT_POKERUS, NONE);
  71. strain = (days >> 4);
  72. days &= 0x0f;
  73. variable_item_list_reset(pokemon_fap->variable_item_list);
  74. pokerus.strain = variable_item_list_add(
  75. pokemon_fap->variable_item_list, "Strain:", 5, select_strain_callback, pokemon_fap);
  76. pokerus.days = variable_item_list_add(
  77. pokemon_fap->variable_item_list,
  78. "Days remain:",
  79. (strain == 0 ? 0 : 16),
  80. select_days_callback,
  81. pokemon_fap);
  82. /* Strain is a bit weird in that there are only 4 strains, but, a strain of
  83. * 0 with a days remaining of 0 means the pokemon never had the pokerus.
  84. * To combat this, we only ever set nibble values 4-7 for the 4 strains,
  85. * with a value of 0 being specifically reserved for having never had it.
  86. */
  87. /* A
  88. * 0000
  89. * 0100
  90. * 1000
  91. * 1100
  92. *
  93. * B
  94. * 0001
  95. * 0101
  96. * 1001
  97. * 1101
  98. *
  99. * C
  100. * 0010
  101. * 0110
  102. * 1010
  103. * 1110
  104. *
  105. * D
  106. * 0011
  107. * 0111
  108. * 1011
  109. * 1111
  110. *
  111. * So, if the whole thing is 0, then it should be considered "Clean"
  112. * If the lower bits are cleared, but any of the upper bits are set, modify
  113. * it to be equal to 0100 for our housekeeping.
  114. * Anything else, we just clear the upper bits and are now in a known good
  115. * state.
  116. *
  117. * So everything is in order, at this point, make a value of 0x04 == 0x1 "A",
  118. * leave 0x0 as 0, and add 1 to the remaining.
  119. *
  120. * When setting, we need to translate this back to the above bit values.
  121. */
  122. if(strain == 0)
  123. ;
  124. else if(((strain & 0x03) == 0) && ((strain & 0xc0) != 0))
  125. strain = 0x01; // This would be A
  126. else {
  127. strain &= 0x03;
  128. strain++;
  129. }
  130. daystring = furi_string_alloc_printf("%d", days);
  131. variable_item_set_current_value_index(pokerus.strain, strain);
  132. variable_item_set_current_value_text(pokerus.strain, strains[strain]);
  133. variable_item_set_current_value_index(pokerus.days, (strain == 0 ? 0 : days));
  134. variable_item_set_current_value_text(pokerus.days, furi_string_get_cstr(daystring));
  135. furi_string_free(daystring);
  136. }
  137. void select_pokerus_scene_on_enter(void* context) {
  138. PokemonFap* pokemon_fap = (PokemonFap*)context;
  139. select_pokerus_rebuild_list(pokemon_fap);
  140. view_dispatcher_add_view(
  141. pokemon_fap->view_dispatcher,
  142. AppViewOpts,
  143. variable_item_list_get_view(pokemon_fap->variable_item_list));
  144. view_dispatcher_switch_to_view(pokemon_fap->view_dispatcher, AppViewOpts);
  145. }