| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- #include "StateMachine.h"
- #include "Logger.h"
- #include "Timing.h"
- #include "platform.h"
- #include "Graphics.h"
- #include "render/Text.h"
- #include "version.h"
- #include "input/Input.h"
- using namespace WalrusRPG; /*::StateMachine*/
- using namespace WalrusRPG::Graphics;
- using namespace WalrusRPG::Timing;
- using namespace WalrusRPG::Logger;
- using WalrusRPG::Input::Key;
- using WalrusRPG::Input::KeyState;
- using WalrusRPG::States::State;
- namespace
- {
- /**
- * Debug function showing a button state.
- */
- void draw_button(signed x, signed y, KeyState state)
- {
- put_horizontal_line(x + 1, x + 5, y, Gray);
- put_horizontal_line(x + 1, x + 5, y + 6, Gray);
- put_vertical_line(x, y + 1, y + 5, Gray);
- put_vertical_line(x + 6, y + 1, y + 5, Gray);
- switch (state)
- {
- case KeyState::KS_RELEASED:
- put_rectangle({x + 1, y + 1, 5, 5}, White);
- break;
- case KeyState::KS_JUST_RELEASED:
- put_rectangle({x + 1, y + 1, 5, 5}, Magenta);
- break;
- case KeyState::KS_JUST_PRESSED:
- put_rectangle({x + 1, y + 1, 5, 5}, Cyan);
- break;
- case KeyState::KS_PRESSED:
- put_rectangle({x + 1, y + 1, 5, 5}, Black);
- break;
- }
- }
- /**
- * Draws WRPG's buttons states.
- */
- void draw_buttons()
- {
- draw_button(0, 24, key_get_state(Key::K_L));
- draw_button(56, 24, key_get_state(Key::K_R));
- draw_button(8, 32, key_get_state(Key::K_UP));
- draw_button(0, 40, key_get_state(Key::K_LEFT));
- draw_button(16, 40, key_get_state(Key::K_RIGHT));
- draw_button(8, 48, key_get_state(Key::K_DOWN));
- draw_button(28, 48, key_get_state(Key::K_SELECT));
- draw_button(36, 48, key_get_state(Key::K_START));
- draw_button(48, 44, key_get_state(Key::K_B));
- draw_button(56, 36, key_get_state(Key::K_A));
- }
- // State stack. Pointer because polymorphism.
- static tinystl::vector<WalrusRPG::States::State *> stack;
- } /* namespace */
- void StateMachine::init()
- {
- log("State Machine init");
- }
- void StateMachine::deinit()
- {
- log("State Machine deinit");
- stack.clear();
- }
- void StateMachine::push(State *state)
- {
- stack.push_back(state);
- }
- void StateMachine::pop()
- {
- // Mmmh, should StateMachine manage the state's destruction?...
- delete stack.back();
- stack.pop_back();
- }
- void StateMachine::run()
- {
- const unsigned loop_time = TIMER_FREQ / 60;
- unsigned loop_next = loop_time;
- unsigned last_update = 0, update_stamp, update_time;
- unsigned last_frame = 0, frame_stamp, frame_time;
- // TODO : Better way to handle FPS while not breaking anything. There are some issues
- // if the update loop takes too much time.
- while (!stack.empty())
- {
- update_stamp = Timing::gettime();
- update_time = update_stamp - last_update;
- Input::key_poll();
- stack.back()->update(100 * update_time / TIMER_FREQ);
- last_update = update_stamp;
- if (Timing::gettime() < loop_next)
- {
- frame_stamp = Timing::gettime();
- frame_time = frame_stamp - last_frame;
- Graphics::frame_begin();
- // Update the current state
- stack.back()->render(100 * frame_time / TIMER_FREQ);
- last_frame = frame_stamp;
- // Text::print_format(0, 0, "WRPG build %s", git_version);
- if (frame_time != 0 && update_time != 0)
- {
- Text::print_format(0, 240 - 8, "%ufps, %uups", TIMER_FREQ / frame_time,
- TIMER_FREQ / update_time);
- }
- // TODO : use a boolean to show/hide and to avoid that frigging wanring.
- // draw_buttons();
- Graphics::frame_end();
- }
- // TODO : better exit handling.
- if (Input::key_pressed(Key::K_SELECT))
- {
- while (Input::key_down(Key::K_SELECT))
- Input::key_poll();
- StateMachine::pop();
- }
- #ifdef ACTIVE_WAIT
- while (Timing::gettime() < loop_next)
- ;
- #endif
- loop_next += loop_time;
- }
- }
|