StateMachine.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #include "StateMachine.h"
  2. #include "Logger.h"
  3. #include "Timing.h"
  4. #include "platform.h"
  5. #include "Graphics.h"
  6. #include "render/Text.h"
  7. #include "version.h"
  8. #include "input/Input.h"
  9. using namespace WalrusRPG; /*::StateMachine*/
  10. using namespace WalrusRPG::Graphics;
  11. using namespace WalrusRPG::Timing;
  12. using namespace WalrusRPG::Logger;
  13. using WalrusRPG::Input::Key;
  14. using WalrusRPG::Input::KeyState;
  15. using WalrusRPG::States::State;
  16. namespace
  17. {
  18. /**
  19. * Debug function showing a button state.
  20. */
  21. void draw_button(signed x, signed y, KeyState state)
  22. {
  23. put_horizontal_line(x + 1, x + 5, y, Gray);
  24. put_horizontal_line(x + 1, x + 5, y + 6, Gray);
  25. put_vertical_line(x, y + 1, y + 5, Gray);
  26. put_vertical_line(x + 6, y + 1, y + 5, Gray);
  27. switch (state)
  28. {
  29. case KeyState::KS_RELEASED:
  30. put_rectangle({x + 1, y + 1, 5, 5}, White);
  31. break;
  32. case KeyState::KS_JUST_RELEASED:
  33. put_rectangle({x + 1, y + 1, 5, 5}, Magenta);
  34. break;
  35. case KeyState::KS_JUST_PRESSED:
  36. put_rectangle({x + 1, y + 1, 5, 5}, Cyan);
  37. break;
  38. case KeyState::KS_PRESSED:
  39. put_rectangle({x + 1, y + 1, 5, 5}, Black);
  40. break;
  41. }
  42. }
  43. /**
  44. * Draws WRPG's buttons states.
  45. */
  46. void draw_buttons()
  47. {
  48. draw_button(0, 24, key_get_state(Key::K_L));
  49. draw_button(56, 24, key_get_state(Key::K_R));
  50. draw_button(8, 32, key_get_state(Key::K_UP));
  51. draw_button(0, 40, key_get_state(Key::K_LEFT));
  52. draw_button(16, 40, key_get_state(Key::K_RIGHT));
  53. draw_button(8, 48, key_get_state(Key::K_DOWN));
  54. draw_button(28, 48, key_get_state(Key::K_SELECT));
  55. draw_button(36, 48, key_get_state(Key::K_START));
  56. draw_button(48, 44, key_get_state(Key::K_B));
  57. draw_button(56, 36, key_get_state(Key::K_A));
  58. }
  59. // State stack. Pointer because polymorphism.
  60. static tinystl::vector<WalrusRPG::States::State *> stack;
  61. } /* namespace */
  62. void StateMachine::init()
  63. {
  64. log("State Machine init");
  65. }
  66. void StateMachine::deinit()
  67. {
  68. log("State Machine deinit");
  69. stack.clear();
  70. }
  71. void StateMachine::push(State *state)
  72. {
  73. stack.push_back(state);
  74. }
  75. void StateMachine::pop()
  76. {
  77. // Mmmh, should StateMachine manage the state's destruction?...
  78. delete stack.back();
  79. stack.pop_back();
  80. }
  81. void StateMachine::run()
  82. {
  83. const unsigned loop_time = TIMER_FREQ / 60;
  84. unsigned loop_next = loop_time;
  85. unsigned last_update = 0, update_stamp, update_time;
  86. unsigned last_frame = 0, frame_stamp, frame_time;
  87. // TODO : Better way to handle FPS while not breaking anything. There are some issues
  88. // if the update loop takes too much time.
  89. while (!stack.empty())
  90. {
  91. update_stamp = Timing::gettime();
  92. update_time = update_stamp - last_update;
  93. Input::key_poll();
  94. stack.back()->update(100 * update_time / TIMER_FREQ);
  95. last_update = update_stamp;
  96. if (Timing::gettime() < loop_next)
  97. {
  98. frame_stamp = Timing::gettime();
  99. frame_time = frame_stamp - last_frame;
  100. Graphics::frame_begin();
  101. // Update the current state
  102. stack.back()->render(100 * frame_time / TIMER_FREQ);
  103. last_frame = frame_stamp;
  104. // Text::print_format(0, 0, "WRPG build %s", git_version);
  105. if (frame_time != 0 && update_time != 0)
  106. {
  107. Text::print_format(0, 240 - 8, "%ufps, %uups", TIMER_FREQ / frame_time,
  108. TIMER_FREQ / update_time);
  109. }
  110. // TODO : use a boolean to show/hide and to avoid that frigging wanring.
  111. // draw_buttons();
  112. Graphics::frame_end();
  113. }
  114. // TODO : better exit handling.
  115. if (Input::key_pressed(Key::K_SELECT))
  116. {
  117. while (Input::key_down(Key::K_SELECT))
  118. Input::key_poll();
  119. StateMachine::pop();
  120. }
  121. #ifdef ACTIVE_WAIT
  122. while (Timing::gettime() < loop_next)
  123. ;
  124. #endif
  125. loop_next += loop_time;
  126. }
  127. }