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.

248 lines
7.7 KiB

  1. /**********************************************************************************************
  2. *
  3. * raylib - Advance Game template
  4. *
  5. * Ending Screen Functions Definitions (Init, Update, Draw, Unload)
  6. *
  7. * Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
  8. *
  9. * This software is provided "as-is", without any express or implied warranty. In no event
  10. * will the authors be held liable for any damages arising from the use of this software.
  11. *
  12. * Permission is granted to anyone to use this software for any purpose, including commercial
  13. * applications, and to alter it and redistribute it freely, subject to the following restrictions:
  14. *
  15. * 1. The origin of this software must not be misrepresented; you must not claim that you
  16. * wrote the original software. If you use this software in a product, an acknowledgment
  17. * in the product documentation would be appreciated but is not required.
  18. *
  19. * 2. Altered source versions must be plainly marked as such, and must not be misrepresented
  20. * as being the original software.
  21. *
  22. * 3. This notice may not be removed or altered from any source distribution.
  23. *
  24. **********************************************************************************************/
  25. #include "raylib.h"
  26. #include "screens.h"
  27. #include <string.h>
  28. #include <stdlib.h>
  29. #define MAX_TITLE_CHAR 256
  30. #define MAX_SUBTITLE_CHAR 256
  31. //----------------------------------------------------------------------------------
  32. // Global Variables Definition (local to this module)
  33. //----------------------------------------------------------------------------------
  34. static char *codingWords[MAX_CODING_WORDS] = {
  35. "pollo\0",
  36. "conejo\0",
  37. "huevo\0",
  38. "nido\0",
  39. "aire\0",
  40. "armario\0",
  41. "agujero\0",
  42. "platano\0",
  43. "pastel\0",
  44. "mercado\0",
  45. "raton\0",
  46. "melon\0",
  47. };
  48. // Ending screen global variables
  49. static int framesCounter;
  50. static int finishScreen;
  51. static Texture2D texBackground;
  52. static Texture2D texNewspaper;
  53. static Texture2D texVignette;
  54. static Sound fxNews;
  55. static float rotation = 0.1f;
  56. static float scale = 0.05f;
  57. static int state = 0;
  58. static Mission *missions = NULL;
  59. static char headline[MAX_TITLE_CHAR] = "\0";
  60. SpriteFont fontNews;
  61. // String (const char *) replacement function
  62. static char *StringReplace(char *orig, char *rep, char *with);
  63. //----------------------------------------------------------------------------------
  64. // Ending Screen Functions Definition
  65. //----------------------------------------------------------------------------------
  66. // Ending Screen Initialization logic
  67. void InitEndingScreen(void)
  68. {
  69. framesCounter = 0;
  70. finishScreen = 0;
  71. rotation = 0.1f;
  72. scale = 0.05f;
  73. state = 0;
  74. texBackground = LoadTexture("resources/textures/ending_background.png");
  75. texVignette = LoadTexture("resources/textures/message_vignette.png");
  76. fxNews = LoadSound("resources/audio/fx_batman.ogg");
  77. missions = LoadMissions("resources/missions.txt");
  78. int wordsCount = missions[currentMission].wordsCount;
  79. strcpy(headline, missions[currentMission].msg); // Base headline
  80. int len = strlen(headline);
  81. // Remove @ from headline
  82. // TODO: Also remove additional spaces
  83. for (int i = 0; i < len; i++)
  84. {
  85. if (headline[i] == '@') headline[i] = ' ';
  86. }
  87. for (int i = 0; i < wordsCount; i++)
  88. {
  89. if (messageWords[i].id != missions[currentMission].sols[i])
  90. {
  91. // WARNING: It fails if the last sentence word has a '.' after space
  92. char *title = StringReplace(headline, messageWords[i].text, codingWords[messageWords[i].id]);
  93. strcpy(headline, title); // Base headline updated
  94. if (title != NULL) free(title);
  95. }
  96. }
  97. TraceLog(LOG_WARNING, "Titular: %s", headline);
  98. // Generate newspaper with title and subtitle
  99. Image imNewspaper = LoadImage("resources/textures/ending_newspaper.png");
  100. fontNews = LoadSpriteFontEx("resources/fonts/Lora-Bold.ttf", 32, 250, 0);
  101. ImageDrawTextEx(&imNewspaper, (Vector2){ 50, 220 }, fontNews, headline, fontNews.baseSize, 0, DARKGRAY);
  102. texNewspaper = LoadTextureFromImage(imNewspaper);
  103. //UnloadSpriteFont(fontNews);
  104. UnloadImage(imNewspaper);
  105. }
  106. // Ending Screen Update logic
  107. void UpdateEndingScreen(void)
  108. {
  109. framesCounter++;
  110. if (framesCounter == 10) PlaySound(fxNews);
  111. if (state == 0)
  112. {
  113. rotation += 18.0f;
  114. scale += 0.0096f;
  115. if (scale >= 1.0f)
  116. {
  117. scale = 1.0f;
  118. state = 1;
  119. }
  120. }
  121. if ((state == 1) && (IsKeyPressed(KEY_ENTER) || IsButtonPressed()))
  122. {
  123. currentMission++;
  124. if (currentMission >= totalMissions) finishScreen = 2;
  125. else finishScreen = 1;
  126. }
  127. }
  128. // Ending Screen Draw logic
  129. void DrawEndingScreen(void)
  130. {
  131. DrawTexture(texBackground, 0, 0, WHITE);
  132. DrawTexturePro(texNewspaper, (Rectangle){ 0, 0, texNewspaper.width, texNewspaper.height },
  133. (Rectangle){ GetScreenWidth()/2, GetScreenHeight()/2, texNewspaper.width*scale, texNewspaper.height*scale },
  134. (Vector2){ (float)texNewspaper.width*scale/2, (float)texNewspaper.height*scale/2 }, rotation, WHITE);
  135. DrawTextureEx(texVignette, (Vector2){ 0, 0 }, 0.0f, 2.0f, WHITE);
  136. // Draw debug information
  137. DrawTextEx(fontNews, headline, (Vector2){ 10, 10 }, fontNews.baseSize, 0, RAYWHITE);
  138. for (int i = 0; i < missions[currentMission].wordsCount; i++)
  139. {
  140. DrawText(codingWords[messageWords[i].id], 10, 60 + 30*i, 20, (messageWords[i].id == missions[currentMission].sols[i]) ? GREEN : RED);
  141. }
  142. if (state == 1) DrawButton("continuar");
  143. }
  144. // Ending Screen Unload logic
  145. void UnloadEndingScreen(void)
  146. {
  147. UnloadTexture(texBackground);
  148. UnloadTexture(texNewspaper);
  149. UnloadTexture(texVignette);
  150. UnloadSound(fxNews);
  151. free(missions);
  152. }
  153. // Ending Screen should finish?
  154. int FinishEndingScreen(void)
  155. {
  156. return finishScreen;
  157. }
  158. // String (const char *) replacement function
  159. // NOTE: Internally allocated memory must be freed by the user (if return != NULL)
  160. // https://stackoverflow.com/questions/779875/what-is-the-function-to-replace-string-in-c
  161. static char *StringReplace(char *orig, char *rep, char *with)
  162. {
  163. char *result; // the return string
  164. char *ins; // the next insert point
  165. char *tmp; // varies
  166. int len_rep; // length of rep (the string to remove)
  167. int len_with; // length of with (the string to replace rep with)
  168. int len_front; // distance between rep and end of last rep
  169. int count; // number of replacements
  170. // Sanity checks and initialization
  171. if (!orig || !rep) return NULL;
  172. len_rep = strlen(rep);
  173. if (len_rep == 0) return NULL; // Empty rep causes infinite loop during count
  174. if (!with) with = ""; // Replace with nothing if not provided
  175. len_with = strlen(with);
  176. // Count the number of replacements needed
  177. ins = orig;
  178. for (count = 0; tmp = strstr(ins, rep); ++count)
  179. {
  180. ins = tmp + len_rep;
  181. }
  182. tmp = result = malloc(strlen(orig) + (len_with - len_rep)*count + 1);
  183. if (!result) return NULL; // Memory could not be allocated
  184. // First time through the loop, all the variable are set correctly from here on,
  185. // tmp points to the end of the result string
  186. // ins points to the next occurrence of rep in orig
  187. // orig points to the remainder of orig after "end of rep"
  188. while (count--)
  189. {
  190. ins = strstr(orig, rep);
  191. len_front = ins - orig;
  192. tmp = strncpy(tmp, orig, len_front) + len_front;
  193. tmp = strcpy(tmp, with) + len_with;
  194. orig += len_front + len_rep; // move to next "end of rep"
  195. }
  196. strcpy(tmp, orig);
  197. return result;
  198. }