draw_states.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. #include "draw_states.h"
  2. #include "fxlib.h"
  3. #include "fixed.h"
  4. #include <stdio.h>
  5. // static functions
  6. static void drawPlayer(Camera *cam, int player_angle);
  7. static void drawPolygon(Camera *cam, int nb_lines, Line_Transition line_transition);
  8. static void drawDiagonals(Camera cam, int nb_lines, Line_Transition line_transition);
  9. static void drawHud(Game_Data *data);
  10. static void drawChrono(Game_Data *data);
  11. static void drawStep(Game_Data *data);
  12. static unsigned int length_of_print_string(unsigned char* txt);
  13. static void drawTopLeftCornerText(unsigned char* txt);
  14. static void drawTopRightCornerText(unsigned char* txt);
  15. static void drawBottomLeftCornerText(unsigned char* txt);
  16. static void drawBottomRightCornerText(unsigned char* txt);
  17. static const unsigned char title_spr[] = {0x07, 0xF6, 0x1B, 0xFD, 0xFE, 0xFE, 0x00, 0x00, 0x0F, 0xF6, 0x1B, 0xFD, 0xFE, 0xFF, 0x00, 0x00, 0x0C, 0x06, 0x1B, 0x0D, 0x80, 0xC3, 0x00, 0x00, 0x0F, 0xF6, 0x1B, 0x0D, 0xFE, 0xC3, 0x00, 0x00, 0x0F, 0xF6, 0x1B, 0xFD, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x36, 0x1B, 0xF9, 0x80, 0xFF, 0x00, 0x00, 0x0F, 0xF7, 0xFB, 0x01, 0xFE, 0xC3, 0x00, 0x00, 0x0F, 0xE3, 0xFB, 0x00, 0xFE, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x7F, 0xB0, 0xCF, 0xEF, 0xF3, 0xFB, 0xF8, 0xC3, 0x7F, 0xB0, 0xDF, 0xEF, 0xF7, 0xFB, 0xFC, 0xC3, 0x60, 0x30, 0xD8, 0x6C, 0x06, 0x1B, 0x0C, 0xFF, 0x7F, 0xBF, 0xD8, 0x6C, 0x36, 0x1B, 0x0C, 0xFF, 0x7F, 0x9F, 0x9F, 0xEC, 0x36, 0x1B, 0x0C, 0xC3, 0x60, 0x30, 0xDF, 0xEC, 0x36, 0x1B, 0x0C, 0xC3, 0x7F, 0xB0, 0xD8, 0x6F, 0xF7, 0xFB, 0x0C, 0xC3, 0x3F, 0xB0, 0xD8, 0x6F, 0xE7, 0xF3, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x9F, 0xCF, 0xEF, 0xF3, 0xF8, 0x00, 0x00, 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xF8, 0x00, 0x00, 0x60, 0x30, 0xD8, 0x01, 0x86, 0x18, 0x00, 0x00, 0x60, 0x30, 0xDF, 0xE1, 0x86, 0x18, 0x00, 0x00, 0x60, 0x3F, 0xDF, 0xE1, 0x86, 0x18, 0x00, 0x00, 0x60, 0x3F, 0xC0, 0x61, 0x86, 0x18, 0x00, 0x00, 0x7F, 0xB0, 0xDF, 0xEF, 0xF7, 0xF8, 0x00, 0x00, 0x3F, 0xB0, 0xDF, 0xCF, 0xF7, 0xF0, 0x00};
  18. static const unsigned char hex_border_top_left[8] = {0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0xC0, 0x80, 0x80};
  19. static const unsigned char hex_border_top_right[8] ={0x1F, 0x1F, 0x0F, 0x0F, 0x07, 0x07, 0x03, 0x03};
  20. static const unsigned char hex_border_bottom_left[8] = {0x80, 0x80, 0xC0, 0xC0, 0xE0, 0xE0, 0xF0, 0xF0};
  21. static const unsigned char hex_border_bottom_right[8] ={0x03, 0x03, 0x07, 0x07, 0x0F, 0x0F, 0x1F, 0x1F};
  22. void draw_game(Game_Data *data)
  23. {
  24. //draw the player and the lines
  25. drawPlayer(&(data->cam), data->player_angle);
  26. drawPolygon(&(data->cam), data->nb_lines, data->line_transition);
  27. drawDiagonals(data->cam, data->nb_lines, data->line_transition);
  28. //showing the walls
  29. if(data->list != NULL)
  30. drawWalls(data->list, &(data->cam), data->nb_lines, data->line_transition);
  31. drawHud(data);
  32. }
  33. void draw_title(Game_Data *data)
  34. {
  35. ML_bmp_or(title_spr, 12, (64-26)/2, 62, 26);
  36. drawPolygon(&(data->cam), data->nb_lines, data->line_transition);
  37. drawDiagonals(data->cam, data->nb_lines, data->line_transition);
  38. drawBottomLeftCornerText("Press Shift");
  39. drawBottomRightCornerText("By Eiyeron");
  40. }
  41. void draw_menu(Game_Data *data)
  42. {
  43. drawPolygon(&(data->cam), data->nb_lines, data->line_transition);
  44. drawDiagonals(data->cam, data->nb_lines, data->line_transition);
  45. drawTopRightCornerText("WIP Menu. Forget that.");
  46. }
  47. void draw_game_over(Game_Data *data)
  48. {
  49. }
  50. static void drawChrono(Game_Data *data) {
  51. unsigned char time_text[8] = "";
  52. unsigned short length_of_time, length_of_time_line;
  53. sprintf(time_text, "%.2f", data->chrono_time);
  54. length_of_time = strlen(time_text);
  55. length_of_time_line = 4 * length_of_time;
  56. if(data->chrono_time < 60) {
  57. PrintMini(0, 0, time_text, MINI_REV);
  58. ML_horizontal_line(6, 0, (data->chrono_time/60.) * (length_of_time_line - 2), BLACK);
  59. ML_horizontal_line(7, 0, length_of_time_line - 1, BLACK);
  60. }
  61. else {
  62. PrintMini(0, 1, time_text, MINI_REV);
  63. ML_horizontal_line(6, 0, length_of_time_line - 1, BLACK);
  64. ML_horizontal_line(7, 0, length_of_time_line - 1, BLACK);
  65. }
  66. ML_bmp_8_or(hex_border_top_left
  67. , length_of_time_line, 0);
  68. }
  69. static void drawStep(Game_Data *data) {
  70. unsigned char *step_text[6] = {
  71. "Point",
  72. "Line",
  73. "Triangle",
  74. "Square",
  75. "Pentagon",
  76. "Hexagon"
  77. };
  78. unsigned short step_time[5] = {
  79. 10,
  80. 20,
  81. 30,
  82. 45,
  83. 60
  84. };
  85. unsigned short current_step, i;
  86. current_step = 5;
  87. for(i = 0; i < 5; i++) {
  88. if(data->chrono_time < step_time[i]) {
  89. current_step = i;
  90. break;
  91. }
  92. }
  93. // Little patch because the font is not fixed width and 'n' chars are annoying me.
  94. // ML_vertical_line(125,0,5, BLACK);
  95. // ML_vertical_line(126,0,5, BLACK);
  96. // ML_vertical_line(127,0,5, BLACK);
  97. // PrintMini(127 - length_of_step, 1, step_text[current_step], MINI_REV);
  98. // ML_bmp_8_or(hex_border_top_right, 127 - length_of_step - 8, 0);
  99. // ML_horizontal_line(6, 127 - length_of_step - 2, 127, BLACK);
  100. // ML_horizontal_line(7, 127 - length_of_step - 2, 127, BLACK);
  101. drawTopRightCornerText(step_text[current_step]);
  102. }
  103. static void drawHud(Game_Data *data) {
  104. drawChrono(data);
  105. drawStep(data);
  106. }
  107. static void drawPolygon(Camera *cam, int nb_lines, Line_Transition line_transition) {
  108. int x[32];
  109. int y[32];
  110. int i = 0;
  111. int angle = 0;
  112. float tmp_angle = 0.0;
  113. float transition_angle = 0.0;
  114. float delta_angle = 0.0;
  115. if(line_transition.delta_nb_lines == 1)
  116. nb_lines ++;
  117. if(line_transition.counter_start != 0)
  118. transition_angle = (360.0 / (float)nb_lines) * ((float)line_transition.counter / (float)line_transition.counter_start);
  119. delta_angle = 360.0/nb_lines;
  120. do
  121. {
  122. // TODO : use fixed for only two trig calls?
  123. x[i] = (8. + cam->zoom)*cos(PI * (tmp_angle + cam->angle)/180.) + cam->cX;
  124. y[i] = (8. + cam->zoom)*sin(PI * (tmp_angle + cam->angle)/180.) + cam->cY;
  125. i++;
  126. switch(line_transition.delta_nb_lines)
  127. {
  128. case 0:
  129. tmp_angle += delta_angle;
  130. break;
  131. case 1:
  132. if(i < nb_lines)
  133. tmp_angle += (360 - (delta_angle - transition_angle)) / (nb_lines - 1);
  134. else
  135. tmp_angle += delta_angle - transition_angle;
  136. break;
  137. case -1:
  138. if(i < nb_lines)
  139. tmp_angle += (360 - transition_angle) / (nb_lines - 1);
  140. else
  141. tmp_angle = transition_angle;
  142. break;
  143. }
  144. }while(i <= nb_lines);
  145. //draw the aforementionned circle, depending on the camera's center
  146. //ML_filled_circle(cam.cX, cam.cY, 6, BLACK);
  147. ML_polygone(x, y, nb_lines, BLACK);
  148. //draw the player. At such a low scale, it was impossible to draw a rotating triangle, so its a radius 1 circle instead.
  149. // TODO : Replace it for a quick sprite blit, or unwrapped ML_pixel procedure.
  150. }
  151. //draws the player
  152. //at first, was supposed to draw an hexagon in the center, plus a triangle to show the player,
  153. //but the hexagon was not visible, and it was a pixel mess, so we're showing a circle instead.
  154. //there is still for code to calculate the vertices of the hexagon, in case we want to change that again
  155. static void drawPlayer(Camera *cam, int player_angle)
  156. {
  157. ML_filled_circle((9. + cam->zoom)*cos( PI*(player_angle + cam->angle)/180) + cam->cX, (9. + cam->zoom)*sin( PI*(player_angle+cam->angle)/180) + cam->cY, 1, BLACK);
  158. }
  159. //draws one of the three rotating lines
  160. static void drawDiagonals(Camera cam, int nb_lines, Line_Transition line_transition)
  161. {
  162. fix tmp_angle = FIX(cam.angle);
  163. int i = 0;
  164. fix x1 = 0, y1 = 0, x2 = 0, y2 = 0;
  165. fix delta_angle = 0;
  166. fix coeff = 0;
  167. fix transition_angle = 0;
  168. delta_angle = fdiv(FIX(360), FIX(nb_lines));
  169. if(line_transition.delta_nb_lines == 1)
  170. nb_lines ++;
  171. if(line_transition.counter_start != 0)
  172. coeff = fdiv(FIX(line_transition.counter), FIX(line_transition.counter_start));
  173. transition_angle = fmul(delta_angle, coeff);
  174. do{
  175. x1 = fmul(FIX(9) + ftofix(cam.zoom), fcos(tmp_angle));
  176. y1 = fmul(FIX(9) + ftofix(cam.zoom), fsin(tmp_angle));
  177. x2 = fmul(fcos(tmp_angle), FIX(128));
  178. y2 = fmul(fsin(tmp_angle), FIX(128));
  179. ML_line(UNFIX(x1) + cam.cX, UNFIX(y1) + cam.cY, UNFIX(x2) + cam.cX, UNFIX(y2) + cam.cY, BLACK);
  180. i++;
  181. switch(line_transition.delta_nb_lines){
  182. case 0:
  183. tmp_angle += fdiv(FIX(360), FIX(nb_lines));
  184. break;
  185. case 1:
  186. if(i < nb_lines - 1)
  187. {
  188. tmp_angle += fdiv(FIX(360) - (delta_angle - transition_angle), FIX(nb_lines - 1));
  189. }else{
  190. tmp_angle += delta_angle - transition_angle;
  191. }
  192. break;
  193. case -1:
  194. if(i < nb_lines - 1)
  195. {
  196. tmp_angle += fdiv(FIX(360) - transition_angle, FIX(nb_lines - 1));
  197. }else{
  198. tmp_angle += transition_angle;
  199. }
  200. break;
  201. }
  202. if(tmp_angle >= FIX(360)) tmp_angle = tmp_angle - FIX(359);
  203. }while(i < nb_lines);
  204. }
  205. static unsigned int length_of_print_string(unsigned char* txt) {
  206. // TODO : define
  207. unsigned int text_length = 0;
  208. unsigned int i;
  209. unsigned int current_char_length = 0;
  210. for(i = 0; i < strlen(txt); i++) {
  211. switch(txt[i]) {
  212. // upper case
  213. case 'K':
  214. case 'M':
  215. case 'N':
  216. case 'Q':
  217. case 'W':
  218. current_char_length = 6;
  219. break;
  220. // lower case
  221. case 'i':
  222. current_char_length = 2;
  223. break;
  224. case 'n':
  225. case 'r':
  226. current_char_length = 5;
  227. break;
  228. case 'm':
  229. case 'w':
  230. current_char_length = 6;
  231. break;
  232. //
  233. //
  234. default:
  235. current_char_length = 4;
  236. break;
  237. }
  238. text_length += current_char_length;
  239. }
  240. return text_length;
  241. }
  242. static void drawTopLeftCornerText(unsigned char* txt) {
  243. unsigned int text_length = length_of_print_string(txt);
  244. ML_bmp_8_or(hex_border_top_left, text_length, 0);
  245. ML_horizontal_line(7, 0, text_length, BLACK);
  246. PrintMini(0, 1, txt, MINI_REV);
  247. }
  248. static void drawTopRightCornerText(unsigned char* txt) {
  249. int text_length = length_of_print_string(txt);
  250. int xPosition = 128 - text_length;
  251. ML_bmp_8_or(hex_border_top_right, xPosition - 8, 0);
  252. ML_horizontal_line(7, xPosition, 127, BLACK);
  253. PrintMini(xPosition, 1, txt, MINI_REV);
  254. }
  255. static void drawBottomLeftCornerText(unsigned char* txt) {
  256. unsigned int text_length = length_of_print_string(txt);
  257. ML_bmp_8_or(hex_border_bottom_left, text_length - 1, 56);
  258. ML_horizontal_line(63, 0, text_length, BLACK);
  259. PrintMini(0, 57, txt, MINI_REV);
  260. }
  261. static void drawBottomRightCornerText(unsigned char* txt) {
  262. int text_length = length_of_print_string(txt);
  263. int xPosition = 128 - text_length;
  264. ML_bmp_8_or(hex_border_bottom_right, xPosition - 8, 56);
  265. ML_horizontal_line(63, xPosition, 127, BLACK);
  266. PrintMini(xPosition, 57, txt, MINI_REV);
  267. }