quicksave.diff 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. This mod adds a simple quicksave/quickload functionality, quicksaves do NOT
  2. survive game restart, they are only kept in RAM. By drummyfish, released under
  3. CC0 1.0, public domain.
  4. diff --git a/game.h b/game.h
  5. index 991058d..14644f3 100755
  6. --- a/game.h
  7. +++ b/game.h
  8. @@ -335,7 +335,9 @@ typedef struct
  9. #define SFG_MENU_ITEM_LOAD 3
  10. #define SFG_MENU_ITEM_SOUND 4
  11. #define SFG_MENU_ITEM_SHEAR 5
  12. -#define SFG_MENU_ITEM_EXIT 6
  13. +#define SFG_MENU_ITEM_QUICKSAVE 6
  14. +#define SFG_MENU_ITEM_QUICKLOAD 7
  15. +#define SFG_MENU_ITEM_EXIT 8
  16. #define SFG_MENU_ITEM_NONE 255
  17. @@ -348,7 +350,7 @@ typedef struct
  18. Groups global variables related to the game as such in a single struct. There
  19. are still other global structs for player, level etc.
  20. */
  21. -struct
  22. +typedef struct
  23. {
  24. uint8_t state; ///< Current game state.
  25. uint32_t stateTime; ///< Time in ms from last state change.
  26. @@ -407,7 +409,9 @@ struct
  27. 6 32b little endian total play time, in 10ths of sec
  28. 10 16b little endian total enemies killed from start */
  29. uint8_t continues; ///< Whether the game continues or was exited.
  30. -} SFG_game;
  31. +} SFG_Game;
  32. +
  33. +SFG_Game SFG_game;
  34. #define SFG_SAVE_TOTAL_TIME (SFG_game.save[6] + SFG_game.save[7] * 256 + \
  35. SFG_game.save[8] * 65536 + SFG_game.save[9] * 4294967296)
  36. @@ -415,7 +419,7 @@ struct
  37. /**
  38. Stores player state.
  39. */
  40. -struct
  41. +typedef struct
  42. {
  43. RCL_Camera camera;
  44. int8_t squarePosition[2];
  45. @@ -437,12 +441,14 @@ struct
  46. the last 2 bits are a blink reset counter. */
  47. uint8_t justTeleported;
  48. int8_t previousWeaponDirection; ///< Direction (+/0/-) of previous weapon.
  49. -} SFG_player;
  50. +} SFG_Player;
  51. +
  52. +SFG_Player SFG_player;
  53. /**
  54. Stores the current level and helper precomputed values for better performance.
  55. */
  56. -struct
  57. +typedef struct
  58. {
  59. const SFG_Level *levelPointer;
  60. uint8_t levelNumber;
  61. @@ -476,7 +482,13 @@ struct
  62. uint8_t itemCollisionMap[(SFG_MAP_SIZE * SFG_MAP_SIZE) / 8];
  63. /**< Bit array, for each map square says whether there
  64. is a colliding item or not. */
  65. -} SFG_currentLevel;
  66. +} SFG_CurrentLevel;
  67. +
  68. +SFG_CurrentLevel SFG_currentLevel;
  69. +
  70. +SFG_Game SFG_quickSaveGame;
  71. +SFG_Player SFG_quickSavePlayer;
  72. +SFG_CurrentLevel SFG_quickSaveCurrentLevel;
  73. #if SFG_AVR
  74. /**
  75. @@ -633,6 +645,25 @@ void SFG_gameLoad(void)
  76. SFG_game.saved = SFG_CANT_SAVE;
  77. }
  78. +void SFG_quickSave(void)
  79. +{
  80. + SFG_quickSaveGame = SFG_game;
  81. + SFG_quickSavePlayer = SFG_player;
  82. + SFG_quickSaveCurrentLevel = SFG_currentLevel;
  83. + SFG_LOG("quicksaved");
  84. +}
  85. +
  86. +void SFG_quickLoad(void)
  87. +{
  88. + uint32_t frameTime = SFG_game.frameTime;
  89. +
  90. + SFG_game = SFG_quickSaveGame;
  91. + SFG_player = SFG_quickSavePlayer;
  92. + SFG_currentLevel = SFG_quickSaveCurrentLevel;
  93. + SFG_game.frameTime = frameTime;
  94. + SFG_LOG("quickloaded");
  95. +}
  96. +
  97. /**
  98. Returns ammo type for given weapon.
  99. */
  100. @@ -1685,6 +1716,8 @@ void SFG_init()
  101. {
  102. SFG_LOG("initializing game")
  103. + SFG_quickSaveGame.frame = 0; // indicate no quicksave performed yet
  104. +
  105. SFG_game.frame = 0;
  106. SFG_game.frameTime = 0;
  107. SFG_game.currentRandom = 0;
  108. @@ -3784,7 +3817,10 @@ uint8_t SFG_getMenuItem(uint8_t index)
  109. {
  110. if ( // skip non-legitimate items
  111. ((current <= SFG_MENU_ITEM_MAP) && (SFG_currentLevel.levelPointer == 0))
  112. - || ((current == SFG_MENU_ITEM_LOAD) && ((SFG_game.save[0] >> 4) == 0)))
  113. + || ((current == SFG_MENU_ITEM_LOAD) && ((SFG_game.save[0] >> 4) == 0))
  114. + || (current == SFG_MENU_ITEM_QUICKLOAD && SFG_quickSaveGame.frame == 0)
  115. + || (current == SFG_MENU_ITEM_QUICKSAVE &&
  116. + SFG_currentLevel.levelPointer == 0))
  117. {
  118. current++;
  119. continue;
  120. @@ -3924,6 +3960,18 @@ void SFG_gameStepMenu(void)
  121. SFG_setGameState(SFG_GAME_STATE_MAP);
  122. break;
  123. + case SFG_MENU_ITEM_QUICKSAVE:
  124. + SFG_quickSave();
  125. + SFG_game.selectedMenuItem = 0;
  126. + SFG_setGameState(SFG_GAME_STATE_PLAYING);
  127. + break;
  128. +
  129. + case SFG_MENU_ITEM_QUICKLOAD:
  130. + SFG_quickLoad();
  131. + SFG_game.selectedMenuItem = 0;
  132. + SFG_setGameState(SFG_GAME_STATE_PLAYING);
  133. + break;
  134. +
  135. case SFG_MENU_ITEM_SOUND:
  136. SFG_LOG("sound changed");
  137. @@ -4982,7 +5030,6 @@ uint8_t SFG_mainLoopBody()
  138. SFG_processEvent(SFG_EVENT_PLAYER_CHANGES_WEAPON,SFG_player.weapon);
  139. timeSinceLastFrame -= SFG_MS_PER_FRAME;
  140. -
  141. SFG_game.frame++;
  142. steps++;
  143. }
  144. diff --git a/texts.h b/texts.h
  145. index b7e53d4..0964b91 100644
  146. --- a/texts.h
  147. +++ b/texts.h
  148. @@ -26,6 +26,8 @@ static const char *SFG_menuItemTexts[] =
  149. "load",
  150. "sound",
  151. "look",
  152. + "qsave",
  153. + "qload",
  154. "exit"
  155. };