/* ******************************************************************* * Includes * ******************************************************************/ #include "HumanPlayer.h" #include "System.h" #include "Cursor.h" #include #include #include #include #include /* ******************************************************************* * Defines * ******************************************************************/ /* ******************************************************************* * Types definition * ******************************************************************/ /* ******************************************************************* * Global variables definition * ******************************************************************/ /* ******************************************************************* * Local variables definition * ******************************************************************/ /* ******************************************************************* * Local prototypes declaration * ******************************************************************/ /* ******************************************************************* * Functions definition * ******************************************************************/ /*****************************************************************//** * * \brief Event handler executed when human player presses * left arrow button. * *********************************************************************/ void HumanPlayer::buttonHandler(void) { for (size_t szBtn = 0; szBtn < NUM_BTN; szBtn++) { if (gb.buttons.timeHeld(static_cast(szBtn)) > 0) { /* Update player attributes * according to pressed button. */ playerButtonPressedHandler(szBtn); /* Update camera attributes * according to pressed button. */ cameraButtonPressedHandler(szBtn); } else if (gb.buttons.released(static_cast(szBtn))) { /* Key has not been pressed. */ /* Update player attributes * according to released button. */ playerButtonReleasedHandler(szBtn); } } } /*****************************************************************//** * * \brief This function executes button pressed handler events * used on a \ref HumanPlayer object. * * \param szBtn * Pressed button ID. * *********************************************************************/ void HumanPlayer::playerButtonPressedHandler(const size_t szBtn) { /* This array of member functions lists * button pressed event handlers for each button. */ static void (HumanPlayer::*const apBtnHandlerTable[NUM_BTN])(void) = { [BTN_LEFT] = NULL, [BTN_UP] = NULL, [BTN_RIGHT] = NULL, [BTN_DOWN] = NULL, [BTN_A] = &HumanPlayer::onABtnPressed, [BTN_B] = &HumanPlayer::onBBtnPressed }; /* Key has been pressed. Execute both * HumanPlayer and Camera handlers, if available. */ /* Get pointer to HumanPlayer member function for selected button. */ void (HumanPlayer::*const pBtnHandler)(void) = apBtnHandlerTable[szBtn]; if (pBtnHandler != NULL) { /* HumanPlayer member function * pointer is available. Execute. */ (this->*pBtnHandler)(); } else { /* Undefined callback for selected button. */ } } /*****************************************************************//** * * \brief This function executes button pressed handler events * used on a \ref Camera object. * * \param szBtn * Pressed button ID. * *********************************************************************/ void HumanPlayer::cameraButtonPressedHandler(const size_t szBtn) { if (not _cam.isLocked()) { static void (Camera::*const apBtnCameraHandlerTable[NUM_BTN])(Cursor&) = { [BTN_LEFT] = &Camera::onLeftBtnPressed, [BTN_UP] = &Camera::onUpBtnPressed, [BTN_RIGHT] = &Camera::onRightBtnPressed, [BTN_DOWN] = &Camera::onDownBtnPressed }; /* Get pointer to Camera member function for selected button. */ void (Camera::*const pCameraBtnHandler)(Cursor&) = apBtnCameraHandlerTable[szBtn]; if (pCameraBtnHandler != NULL) { /* Camera member function pointer * is available. * Note: "const" qualifier must be * removed since camera button event * handler modifies Camera class members. */ ((Camera&)_cam.*pCameraBtnHandler)(_cursor); } else { /* Undefined callback for selected button. */ } } } /*****************************************************************//** * * \brief This function executes button released handler events * used on a \ref HumanPlayer object. * * \param szBtn * Released button ID. * *********************************************************************/ void HumanPlayer::playerButtonReleasedHandler(const size_t szBtn) { /* This array of member functions lists * button pressed event handlers for each button. */ static void (HumanPlayer::*const apBtnHandlerTable[NUM_BTN])(void) = { [BTN_LEFT] = NULL, [BTN_UP] = NULL, [BTN_RIGHT] = NULL, [BTN_DOWN] = NULL, [BTN_A] = &HumanPlayer::onABtnReleased, [BTN_B] = &HumanPlayer::onBBtnReleased }; /* Key has been pressed. Execute both * HumanPlayer and Camera handlers, if available. */ /* Get pointer to HumanPlayer member function for selected button. */ void (HumanPlayer::*const pBtnHandler)(void) = apBtnHandlerTable[szBtn]; if (pBtnHandler != NULL) { /* HumanPlayer member function * pointer is available. Execute. */ (this->*pBtnHandler)(); } else { /* Undefined callback for selected button. */ } } /*****************************************************************//** * * \brief Event handler executed when human player presses * A button. * *********************************************************************/ void HumanPlayer::onABtnPressed(void) { switch (_eState) { case PLAYER_STATE_IDLE: /* Select nearest unit, if possible. */ _eState = selectUnit(); break; case PLAYER_STATE_UNIT_SELECTED: if (_ABtnFrames < UCHAR_MAX) { /* Increase number of frames * A button has been pressed. */ _ABtnFrames++; } break; default: /* Undefined player state. Exit. */ break; } } /*****************************************************************//** * * \brief Event handler executed when human player presses * B button. * *********************************************************************/ void HumanPlayer::onBBtnPressed(void) { enum { /* Number of frames that B button must * be pressed in order to cancel unit selection. */ CANCEL_SELECTION_FRAMES = 10 }; if (++_BBtnFrames >= CANCEL_SELECTION_FRAMES) { switch (_eState) { case PLAYER_STATE_UNIT_SELECTED: { /* Iterator that will be used * to move along _unitsMap. */ size_t i; for (i = 0; i < (sizeof (_unitsMap) / sizeof (_unitsMap[0])); i++) { Unit& u = _unitsMap[i]; /* Reset selected flags. */ u.setSelected(false); } /* Reset to default state. */ _eState = PLAYER_STATE_IDLE; } /* Fall through. */ case PLAYER_STATE_IDLE: /* Fall through. */ default: /* Reset pressed B button frames counter. */ _BBtnFrames = 0; /* Undefined player state. Exit. */ break; } } } /*****************************************************************//** * * \brief Event handler executed when human player releases * A button. * *********************************************************************/ void HumanPlayer::onABtnReleased(void) { switch (_eState) { case PLAYER_STATE_UNIT_SELECTED: { enum { /* Number of frames where A button * must be pressed in order to enter * unit menu. */ ENTER_MENU_FRAMES = 5 }; if (_ABtnFrames >= ENTER_MENU_FRAMES) { /* Enable unit menu. */ _eState = PLAYER_STATE_UNIT_MENU; } else { /* Short button press. Exit. */ } } /* Fall through. */ case PLAYER_STATE_IDLE: /* Fall through. */ default: /* Undefined player state. Exit. */ /* Reset pressed A button frames counter. */ _ABtnFrames = 0; break; } } /*****************************************************************//** * * \brief Event handler executed when human player releases * B button. * *********************************************************************/ void HumanPlayer::onBBtnReleased(void) { switch (_eState) { case PLAYER_STATE_UNIT_SELECTED: { /* Iterator that will be used * to move along _unitsMap. */ size_t i; for (i = 0; i < (sizeof (_unitsMap) / sizeof (_unitsMap[0])); i++) { Unit& u = _unitsMap[i]; if (u.isSelected()) { /* Get cursor coordinates. */ const uint16_t x = _cursor.getX(); const uint16_t y = _cursor.getY(); /* Move unit to cursor position. */ u.moveTo(x, y); } else { /* Unit is not selected by the player. Continue. */ } } } /* Fall through.*/ case PLAYER_STATE_IDLE: /* Fall through. */ default: /* Undefined player state. Exit. */ /* Reset pressed B button frames counter. */ _BBtnFrames = 0; break; } }