summaryrefslogtreecommitdiffstats
path: root/matchblox/engine/C_MatchBloxEngine.h
blob: 9b5bc98445196ade8ac4bd0c12068b72a86c84dd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#ifndef C_MATCHBLOXENGINE_HEADER_FILE

#define C_MATCHBLOXENGINE_HEADER_FILE

#include "message_queue.h"
#include "message_input.h"
#include "typedefs.h"
#include <list>
//#include <pair>

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<input_payload_wiimote::dot, input_payload_wiimote::dot> dotpair;
  //list<dotpair>   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