Prototype game engine for Heroes of Might & Magic, featuring a gameplay plot-twist...
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

354 linhas
14KB

  1. -- Copyright (c) 2024 - Ognjen 'xolatile' Milan Robovic
  2. --
  3. -- GNU General Public Licence (version 3 or later)
  4. with core, ray;
  5. package body core is
  6. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  7. type terminal_colour is (
  8. grey, red, green, yellow, blue, pink,
  9. cyan, white
  10. );
  11. type terminal_effect is (
  12. normal, bold, italic, underline, blink, invert
  13. );
  14. ------------------------------------------------------------------------------------------
  15. type texture_data_array is array (natural range <>) of ray.texture;
  16. type sound_data_array is array (natural range <>) of ray.sound;
  17. type font_data_array is array (natural range <>) of ray.font;
  18. ------------------------------------------------------------------------------------------
  19. texture_count : integer := 0;
  20. sound_count : integer := 0;
  21. font_count : integer := 0;
  22. texture_array : access texture_data_array;
  23. sound_array : access sound_data_array;
  24. font_array : access font_data_array;
  25. ------------------------------------------------------------------------------------------
  26. procedure terminal (colour : in terminal_colour := white;
  27. effect : in terminal_effect := normal) is
  28. format : string := character'val (27) & "[" & character'val (terminal_effect'pos (effect) + 48) & ";3" & character'val (terminal_colour'pos (colour) + 48) & "m";
  29. begin
  30. put (format);
  31. end terminal;
  32. ------------------------------------------------------------------------------------------
  33. procedure echo (status : in echo_status;
  34. text : in string) is
  35. begin
  36. if not echo_mark (status) then
  37. return;
  38. end if;
  39. --
  40. put ("[");
  41. case status is
  42. when failure => terminal (red, bold); put ("Failure");
  43. when warning => terminal (yellow, bold); put ("Warning");
  44. when success => terminal (green, bold); put ("Success");
  45. when comment => terminal (grey, bold); put ("Comment");
  46. when import => terminal (cyan, bold); put (" + ");
  47. when export => terminal (pink, bold); put (" - ");
  48. end case;
  49. terminal;
  50. put ("]");
  51. put_line (text);
  52. end echo;
  53. ------------------------------------------------------------------------------------------
  54. procedure dash is
  55. begin
  56. terminal (grey, bold);
  57. put ("------------------------------------------------------------------------------------------");
  58. put ("------------------------------------------------------------------------------------------");
  59. terminal;
  60. new_line;
  61. end dash;
  62. ------------------------------------------------------------------------------------------
  63. procedure semi_dash is
  64. begin
  65. terminal (grey, bold);
  66. put (" ");
  67. put ("------------------------------------------------------------------------------------------");
  68. terminal;
  69. new_line;
  70. end semi_dash;
  71. ------------------------------------------------------------------------------------------
  72. function c_string (ada_string : string) return string is
  73. begin
  74. return (ada_string & character'val (0));
  75. end c_string;
  76. ------------------------------------------------------------------------------------------
  77. function random (minimum, maximum : in integer) return integer is
  78. begin
  79. return ray.get_random (minimum, maximum);
  80. end random;
  81. ------------------------------------------------------------------------------------------
  82. function clip (value, minimum, maximum : in integer) return integer is
  83. begin
  84. if value < minimum then return minimum; end if;
  85. if value > maximum then return maximum; end if;
  86. return value;
  87. end clip;
  88. ------------------------------------------------------------------------------------------
  89. function import_sprite (file_path : in string; frames, states : in integer) return sprite is
  90. this : sprite;
  91. begin
  92. texture_array (texture_count) := ray.load_texture (c_string (file_path));
  93. --
  94. texture_count := texture_count + 1;
  95. this.index := texture_count - 1;
  96. this.width := texture_array (this.index).width / states;
  97. this.height := texture_array (this.index).height / frames;
  98. this.frames := frames;
  99. this.states := states;
  100. --
  101. if this.width = 0 or this.height = 0 then
  102. echo (failure, file_path);
  103. end if;
  104. --
  105. return this;
  106. end import_sprite;
  107. ------------------------------------------------------------------------------------------
  108. function import_font (file_path : in string; scale, space : in integer) return font is
  109. this : font;
  110. begin
  111. font_array (font_count) := ray.load_font (c_string (file_path));
  112. --
  113. font_count := font_count + 1;
  114. this.index := font_count - 1;
  115. this.scale := scale;
  116. this.space := space;
  117. --
  118. return this;
  119. end import_font;
  120. ------------------------------------------------------------------------------------------
  121. function import_song (file_path : in string) return song is
  122. this : song;
  123. begin
  124. sound_array (sound_count) := ray.load_sound (c_string (file_path));
  125. --
  126. sound_count := sound_count + 1;
  127. this.index := sound_count - 1;
  128. --
  129. return this;
  130. end import_song;
  131. ------------------------------------------------------------------------------------------
  132. procedure draw (data : in sprite;
  133. x : in integer := 0;
  134. y : in integer := 0;
  135. u : in integer := 0;
  136. v : in integer := 0;
  137. width : in integer := 0;
  138. height : in integer := 0;
  139. state : in integer := 0) is
  140. resize : vector := (0, 0);
  141. begin
  142. resize.x := (if width = 0 then texture_array (data.index).width else width);
  143. resize.y := (if height = 0 then texture_array (data.index).height else height);
  144. --
  145. ray.draw_texture (data => texture_array (data.index),
  146. uv => (float ((animation_time mod data.frames) * u), float (v), float (resize.x), float (resize.y)),
  147. view => (float (x), float (y), float (resize.x) * float (zoom), float (resize.y) * float (zoom)));
  148. end draw;
  149. ------------------------------------------------------------------------------------------
  150. procedure write (text : in string := "";
  151. x : in integer := 0;
  152. y : in integer := 0;
  153. data : in font) is
  154. begin
  155. ray.draw_text (data => font_array (data.index),
  156. text => c_string (text),
  157. view => (float ((icon - data.scale) / 2 + x), float ((icon - data.scale) / 2 + y)),
  158. scale => float (data.scale),
  159. space => float (data.space));
  160. end write;
  161. ------------------------------------------------------------------------------------------
  162. function lowercase (text : in string) return string is
  163. result : string (1 .. text'length);
  164. begin
  165. for index in text'range
  166. loop
  167. if text (index) in 'A' .. 'Z' then
  168. result (index) := character'val (character'pos (text (index)) + 32);
  169. else
  170. result (index) := text (index);
  171. end if;
  172. end loop;
  173. --
  174. return result;
  175. end lowercase;
  176. ------------------------------------------------------------------------------------------
  177. function read_text_box return string is
  178. begin
  179. return to_string (text_box.data);
  180. end read_text_box;
  181. ------------------------------------------------------------------------------------------
  182. procedure write_text_box (text : in string) is
  183. begin
  184. text_box.data := to_unbounded_string (text);
  185. end write_text_box;
  186. ------------------------------------------------------------------------------------------
  187. function window_width return integer is begin return ray.get_screen_width; end window_width;
  188. function window_height return integer is begin return ray.get_screen_height; end window_height;
  189. ------------------------------------------------------------------------------------------
  190. procedure initialize is
  191. begin
  192. echo (comment, "Initializing core components...");
  193. --
  194. engine_active := true;
  195. texture_array := new texture_data_array (0 .. 1600);
  196. sound_array := new sound_data_array (0 .. 4);
  197. font_array := new font_data_array (0 .. 4);
  198. --
  199. echo (comment, "-- Setting trace log level to none (ignoring all default Raylib logs).");
  200. ray.set_trace_log_level (ray.log_none);
  201. echo (comment, "-- Initializing Raylib window data...");
  202. echo (comment, "-- -- Window title : Chads of Might & Magic");
  203. echo (comment, "-- -- Window width : 1800");
  204. echo (comment, "-- -- Window height : 900");
  205. ray.open_window (1800, 900, "Chads of Might & Magic");
  206. echo (comment, "-- Initializing Raylib audio device data...");
  207. ray.open_audio_device;
  208. --
  209. ray.randomization (25071997);
  210. ray.set_target_fps (60);
  211. --
  212. echo (success, "Initialized core components.");
  213. end initialize;
  214. ------------------------------------------------------------------------------------------
  215. procedure deinitialize is
  216. begin
  217. echo (comment, "Deinitializing core components...");
  218. --
  219. engine_active := false;
  220. --
  221. echo (comment, "-- -- Unloading Raylib" & texture_count'image & " textures.");
  222. echo (comment, "-- -- Unloading Raylib" & sound_count'image & " sounds.");
  223. echo (comment, "-- -- Unloading Raylib" & font_count'image & " fonts.");
  224. --
  225. for index in 0 .. texture_count - 1 loop ray.unload_texture (texture_array (index)); end loop;
  226. for index in 0 .. sound_count - 1 loop ray.unload_sound (sound_array (index)); end loop;
  227. for index in 0 .. font_count - 1 loop ray.unload_font (font_array (index)); end loop;
  228. --
  229. echo (comment, "-- Deinitializing Raylib audio device data...");
  230. ray.close_audio_device;
  231. --
  232. echo (comment, "-- Deinitializing Raylib window data...");
  233. ray.close_window;
  234. --
  235. echo (success, "Deinitialized core components.");
  236. end deinitialize;
  237. ------------------------------------------------------------------------------------------
  238. procedure synchronize is
  239. signal : integer := signal_code'pos (signal_none);
  240. begin
  241. global_time := global_time + 1;
  242. global_time := global_time mod (gameplay_framerate * animation_framerate);
  243. gameplay_time := global_time mod (gameplay_framerate);
  244. animation_time := global_time / (gameplay_framerate / animation_framerate);
  245. framerate := integer (ray.get_fps);
  246. signal := ray.get_key_pressed;
  247. cursor.x := ray.get_mouse_x;
  248. cursor.y := ray.get_mouse_y;
  249. --
  250. ray.end_drawing;
  251. --
  252. if ray.exit_key_is_pressed then
  253. engine_active := false;
  254. end if;
  255. --
  256. if ray.mouse_button_is_pressed (ray.mouse_button_left) then cursor_mode := 1; end if;
  257. if ray.mouse_button_is_pressed (ray.mouse_button_right) then cursor_mode := 2; end if;
  258. if ray.mouse_button_is_pressed (ray.mouse_button_middle) then cursor_mode := 3; end if;
  259. if ray.mouse_button_is_released (ray.mouse_button_left) then cursor_mode := 0; end if;
  260. if ray.mouse_button_is_released (ray.mouse_button_right) then cursor_mode := 0; end if;
  261. if ray.mouse_button_is_released (ray.mouse_button_middle) then cursor_mode := 0; end if;
  262. --
  263. case signal is
  264. when 48 .. 57 => signal_mode := signal - 48 + signal_code'pos (signal_0);
  265. when 65 .. 90 => signal_mode := signal - 65 + signal_code'pos (signal_a);
  266. when 320 .. 329 => signal_mode := signal - 320 + signal_code'pos (signal_kp_0);
  267. --
  268. when 0 => signal_mode := signal_code'pos (signal_none);
  269. when 32 => signal_mode := signal_code'pos (signal_space);
  270. when 96 => signal_mode := signal_code'pos (signal_grave);
  271. when 340 => signal_mode := signal_code'pos (signal_left_shift);
  272. when 341 => signal_mode := signal_code'pos (signal_left_control);
  273. when 333 => signal_mode := signal_code'pos (signal_kp_subtract);
  274. when 334 => signal_mode := signal_code'pos (signal_kp_add);
  275. when 256 => signal_mode := signal_code'pos (signal_escape);
  276. when 257 => signal_mode := signal_code'pos (signal_enter);
  277. when 258 => signal_mode := signal_code'pos (signal_tab);
  278. when 259 => signal_mode := signal_code'pos (signal_backspace);
  279. when 262 => signal_mode := signal_code'pos (signal_right);
  280. when 263 => signal_mode := signal_code'pos (signal_left);
  281. when 264 => signal_mode := signal_code'pos (signal_down);
  282. when 265 => signal_mode := signal_code'pos (signal_up);
  283. when others => signal_mode := signal_code'pos (signal_none);
  284. end case;
  285. --
  286. ray.begin_drawing;
  287. --
  288. ray.clear_background ((50, 60, 70, 255));
  289. end synchronize;
  290. ------------------------------------------------------------------------------------------
  291. procedure play (index : in integer) is begin ray.play_sound (sound_array (index)); end play;
  292. procedure stop (index : in integer) is begin ray.stop_sound (sound_array (index)); end stop;
  293. ------------------------------------------------------------------------------------------
  294. procedure overlay is
  295. begin
  296. ray.draw_rectangle (0, 0, window_width, window_height, (0, 0, 0, 127));
  297. end overlay;
  298. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  299. end core;