#ifndef C_MATCHBLOXENGINE_HEADER_FILE #define C_MATCHBLOXENGINE_HEADER_FILE #include "message_queue.h" #include "message_input.h" #include "typedefs.h" #include #include "C_Smoother.h" //#include using namespace std; class C_3DObject; class C_Block; class C_Hand; class C_Log; class C_Environment; class C_Box; typedef enum GameResult { GR_FINISHED, GR_BUSY, GR_ERROR } GameResult; enum EngineState { ES_INITIALISED, ES_ERROR, ES_GET_READY, //game initialised, waiting for start signal from player ES_PLAYING_GRAB_BLOCK, //no block in hand -> grab floating block ES_PLAYING_PUT_BLOCK, //block in hand -> put block in box ES_PAUSED, //pause... ES_FINISHED //finished -> show score and goto init }; enum BlockType { BT_SQUARE = 0, BT_CIRCLE = 1, BT_TRIANGLE = 2, BT_CROSS = 3 }; enum BoxSize { BS_SMALL = 0, BS_MED = 1, BS_LARGE = 2 }; struct GameSettings { int m_iNrOfTurns; double m_dMinProximity, //The minimum allowed squared (xz) distance between //the center of the block and the center of the hole //for the block to be considered to be in the hole m_dHoleDepth; //Depth of a hole; the minimum z distance between block //and a hole, for the block to be successfully inserted //into the box }; struct GameSession { int m_iTotalTurns, m_iCurrentTurn; unsigned int m_uiSessionStart, //time in ms m_uiTurnStart, m_uiPauseStart, *m_puiTurnResult; int m_iBlocksLeft[4]; //number of blocks per type BlockType m_CurrentBlockType; GameSession(int f_iNrOfBlocks, BoxSize f_BS) : m_iTotalTurns(f_iNrOfBlocks), m_iCurrentTurn(0) { m_puiTurnResult = new unsigned int[f_iNrOfBlocks]; //divide the number of blocks between the block types int l_iNrPerType = f_iNrOfBlocks/4, l_iLeft = f_iNrOfBlocks%4; //the left-over count for(int i=0; i<4; i++) { m_iBlocksLeft[i] = l_iNrPerType; if (l_iLeft > 0) { m_iBlocksLeft[i]++; l_iLeft--; } } } ~GameSession() { delete m_puiTurnResult; } bool NextTurn(BlockType &f_NewBlock) { unsigned int l_uiTime = glutGet(GLUT_ELAPSED_TIME); if (m_iCurrentTurn == 0) { //session start m_uiSessionStart = m_uiTurnStart = l_uiTime; m_iCurrentTurn++; } else { //next turn -> save turn result m_puiTurnResult[m_iCurrentTurn] = l_uiTime - m_uiTurnStart; m_iCurrentTurn++; m_uiTurnStart = l_uiTime; } if (m_iCurrentTurn < m_iTotalTurns) { f_NewBlock = GetRandomBlockType(); return true; } else { return false; } } BlockType GetRandomBlockType() { int l_iBlockType = rand()%4; while (m_iBlocksLeft[l_iBlockType] <= 0) l_iBlockType = (l_iBlockType+1)%4; m_iBlocksLeft[l_iBlockType]--; return (BlockType)l_iBlockType; } void PauseSession() { //record the time at which the pause starts m_uiPauseStart = glutGet(GLUT_ELAPSED_TIME); } void ResumeSession() { //add the total pause time to the timers unsigned int l_uiPauseTime = glutGet(GLUT_ELAPSED_TIME) - m_uiPauseStart; m_uiSessionStart += l_uiPauseTime; m_uiTurnStart += l_uiPauseTime; } }; class C_MatchBloxEngine { public: C_MatchBloxEngine(const char *f_strModelPath, const char *f_strLogFile, GameSettings f_GameSettings); ~C_MatchBloxEngine(); GameResult ProcessMsgs(void); void Render(unsigned int f_uiElapsedTime); bool NewGame(int f_iUserID, int f_iGameId, BoxSize f_BS); bool StartGame(); bool Pause(); bool Resume(); bool Abort(); private: C_Environment *m_pEnvMap; C_Block *m_pBlock[4]; C_Hand *m_pHand; C_3DObject *m_pTiles[5]; C_Box *m_pBox[3]; C_Log *m_pLog; GLuint m_uiWood1Tex, m_uiWood2Tex, m_uiWood3Tex; EngineState m_State, m_SavedState; GameSession *m_pCurrentSession; GameSettings m_GameSettings; BoxSize m_CurrentBox; BlockType m_CurrentBlock; unsigned int m_uiCurrentTime, m_uiLastPosValid; C_Smoother *m_pWorldZSmoother[2]; //2 to smooth the computed world z coordinate double m_dInitialWiimoteDist; //initial distance of wiimote in mm, this distance is //mapped to the z=0.0 in world coordinates BoundingBox_t m_WorldBox; //an invisible box that limits the movement of the //player //init routines bool LoadModels(const char* f_strModelDir); void DeleteModels(); void LoadTexture(const char* f_BmpName, GLuint &f_uiTexHandle); //render routines void RenderGetReady(); void RenderHUD(unsigned int f_uiElapsedTime); void RenderResults(); void RenderPointHere(); void RenderText(GLint x, GLint y, char *string, struct ColorStruct f_sColor); //event/input handlers void CursorMove(Vect3D_t &f_NewCursorPos); bool CursorMove_GrabBlock(Vect3D_t &f_NewCursorPos); bool CursorMove_PutBlock(Vect3D_t &f_NewCursorPos); bool Check_PutBlock(Vect3D_t &f_CursPos, BoundingBox_t &f_CusrBBox); //bool Check_GrabBlock(Vect3D_t &f_CursPos, BoundingBox_t &f_CusrBBox); void NewBlock(); void GameFinished(); //wiimote functions //bool FindIRDots(input_payload_wiimote *f_pWiimote, ir_dot_t f_Dot[2]); //bool CalcWiimoteRelativeCursorPos(input_payload_wiimote *f_pWiimote, Vect3D_t *f_pRelPos); bool ConvertWiimoteToWorld(input_payload_wiimote *f_pWiimote, Vect3D_t *f_WorldPos); }; #endif //C_MATCHBLOXENGINE_HEADER_FILE