#ifndef C_MATCHBLOXENGINE_HEADER_FILE #define C_MATCHBLOXENGINE_HEADER_FILE #include "message_queue.h" #include "message_input.h" #include "typedefs.h" #include //#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; BoxSize m_BoxSize; GameSession(int f_iNrOfBlocks, BoxSize f_BS) : m_iTotalTurns(f_iNrOfBlocks), m_iCurrentTurn(0), m_BoxSize(f_BS) { 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; } BlockType StartSession() { m_uiSessionStart = m_uiTurnStart = glutGet(GLUT_ELAPSED_TIME); return GetRandomBlockType(); } BlockType NewTurn() { unsigned int l_uiTime = glutGet(GLUT_ELAPSED_TIME); //save turn result m_puiTurnResult[m_iCurrentTurn] = l_uiTime - m_uiTurnStart; m_iCurrentTurn++; m_uiTurnStart = l_uiTime; return GetRandomBlockType(); } 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; //typedef pair dotpair; //list m_DotHist; int m_DotHistSize; 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 Render_Basics(unsigned int f_uiElapsedTime); //event/input handlers void CursorMove(Vect3D_t &f_NewCursorPos); //bool CursorMove_PutBlock(Vect3D_t &f_CursPos, BoundingBox_t &f_CusrBBox); //bool CursorMove_GrabBlock(Vect3D_t &f_CursPos, BoundingBox_t &f_CusrBBox); //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