~george-edison55/opentracks/trunk

« back to all changes in this revision

Viewing changes to src/CEventManager.cpp

  • Committer: Nathan Osman
  • Date: 2010-12-11 23:29:43 UTC
  • Revision ID: admin@quickmediasolutions.com-20101211232943-g9t2km8zghey5eci
Finished game state rearrangement and restored functionality to game.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include "CEventManager.h"
2
 
 
3
 
#define PI2 (PI / 2.0f)
4
 
 
5
 
// GUI ID values
6
 
enum GUI_WINDOW_ID { TOOLBAR_EDIT_TRACK = 1,
7
 
                     TOOLBAR_ADD_TRAIN,
8
 
 
9
 
                     EDITTRACK_STRAIGHT,
10
 
                     EDITTRACK_CURVED,
11
 
 
12
 
                     ADDTRAIN_ADD };
13
 
 
14
 
CEventManager::CEventManager()
15
 
    : m_device(NULL), m_camera(NULL), fRot(0.0f), m_previous_time(0), m_up(false), m_down(false), m_left(false), m_right(false),
16
 
      m_r_down(false), m_x_prev(0), m_y_prev(0), m_x_cur(0), m_y_cur(0), m_x_diff(0), m_y_diff(0), m_radius(3.0f), m_mode(CM_SELECT),
17
 
      m_dialog_edittrack(NULL), m_dialog_addtrain(NULL)
18
 
{
19
 
}
20
 
 
21
 
CEventManager::~CEventManager()
22
 
{
23
 
    if(m_device)
24
 
        m_device->drop();
25
 
}
26
 
 
27
 
void CEventManager::SetDevice(IrrlichtDevice * pDevice, CTrackManager * track, CTrainManager * train, CGround * ground)
28
 
{
29
 
    // Here we initialize a few things...
30
 
 
31
 
    // Create the camera
32
 
    m_camera = pDevice->getSceneManager()->addCameraSceneNode();
33
 
 
34
 
    // Set the camera's rotation, target, FOV, etc.
35
 
    m_camera->bindTargetAndRotation(true);
36
 
    m_camera->setPosition(vector3df(30,4,2));
37
 
    m_camera->setTarget(vector3df(30,2,5));
38
 
    m_camera->setFOV(PI / 3.5f);
39
 
    m_camera->setAspectRatio(1.66f);
40
 
 
41
 
    // Grab a copy of the device
42
 
    m_device = pDevice;
43
 
    m_device->grab();
44
 
 
45
 
    // Grab a copy of the track manager
46
 
    // and the ground
47
 
    m_ground = ground;
48
 
    m_track = track;
49
 
    m_train = train;
50
 
 
51
 
    // Now start creating the GUI environment
52
 
    IGUIEnvironment* pGUI = m_device->getGUIEnvironment();
53
 
 
54
 
    // Create the toolbar
55
 
    CreateToolbar();
56
 
 
57
 
    //==================
58
 
 
59
 
    m_straight_ghost = m_device->getSceneManager()->getMesh(DATA_DIR "/models/track_straight.b3d");
60
 
    m_straight_ghost_node = m_device->getSceneManager()->addMeshSceneNode(m_straight_ghost);
61
 
 
62
 
    m_curve_ghost = m_device->getSceneManager()->getMesh(DATA_DIR "/models/track_small_curve.b3d");
63
 
    m_curve_ghost_node = m_device->getSceneManager()->addMeshSceneNode(m_curve_ghost);
64
 
 
65
 
    m_engine_ghost = m_device->getSceneManager()->getMesh(DATA_DIR "/models/simple_engine_ghost.b3d");
66
 
    m_engine_ghost_node = m_device->getSceneManager()->addMeshSceneNode(m_engine_ghost);
67
 
 
68
 
    // Make them all invisible
69
 
    m_straight_ghost_node->setVisible(false);
70
 
    m_curve_ghost_node->setVisible(false);
71
 
    m_engine_ghost_node->setVisible(false);
72
 
}
73
 
 
74
 
bool CEventManager::OnEvent(const SEvent& event)
75
 
{
76
 
    // Switch on the event type
77
 
    switch(event.EventType)
78
 
    {
79
 
        case EET_KEY_INPUT_EVENT:
80
 
 
81
 
            // We do two seperate things here.
82
 
            // If the key was held down, we process
83
 
            // it in the following switch block
84
 
 
85
 
            // See which key was pushed.
86
 
            switch(event.KeyInput.Key)
87
 
            {
88
 
                case KEY_UP:
89
 
                    m_up = event.KeyInput.PressedDown;
90
 
                    break;
91
 
 
92
 
                case KEY_DOWN:
93
 
                    m_down = event.KeyInput.PressedDown;
94
 
                    break;
95
 
 
96
 
                case KEY_LEFT:
97
 
                    m_left = event.KeyInput.PressedDown;
98
 
                    break;
99
 
 
100
 
                case KEY_RIGHT:
101
 
                    m_right = event.KeyInput.PressedDown;
102
 
                    break;
103
 
 
104
 
                default:
105
 
                    break;
106
 
            }
107
 
 
108
 
            // Otherwise, react to a key-up event
109
 
            if(!event.KeyInput.PressedDown)
110
 
            {
111
 
                if(event.KeyInput.Key == KEY_RETURN)
112
 
                {
113
 
                    if(m_mode == CM_PLACE_STRAIGHT_TRACK)
114
 
                    {
115
 
                        if(cur == TT_VERTICAL_STRAIGHT) cur = TT_HORIZONTAL_STRAIGHT;
116
 
                        else if(cur == TT_HORIZONTAL_STRAIGHT) cur = TT_VERTICAL_STRAIGHT;
117
 
                    }
118
 
                    if(m_mode == CM_PLACE_CURVE_TRACK)
119
 
                    {
120
 
                        if(cur == TT_CURVE_NE) cur = TT_CURVE_SE;
121
 
                        else if(cur == TT_CURVE_SE) cur = TT_CURVE_SW;
122
 
                        else if(cur == TT_CURVE_SW) cur = TT_CURVE_NW;
123
 
                        else if(cur == TT_CURVE_NW) cur = TT_CURVE_NE;
124
 
                    }
125
 
                }
126
 
                else if(event.KeyInput.Key == KEY_ESCAPE)
127
 
                {
128
 
                    m_device->drop();
129
 
                    m_device->drop();
130
 
                }
131
 
            }
132
 
 
133
 
            break;
134
 
 
135
 
        case EET_MOUSE_INPUT_EVENT:
136
 
 
137
 
            // First, make sure that the coords
138
 
            // do not confilct with the GUI
139
 
            // Get the current values
140
 
            m_x_cur = event.MouseInput.X;
141
 
            m_y_cur = event.MouseInput.Y;
142
 
 
143
 
            {
144
 
                IGUIElement * root = m_device->getGUIEnvironment()->getRootGUIElement();
145
 
 
146
 
                if(root != root->getElementFromPoint(position2d<s32>(m_x_cur,m_y_cur)))
147
 
                {
148
 
                    m_device->getGUIEnvironment()->postEventFromUser(event);
149
 
 
150
 
                    break;
151
 
                }
152
 
            }
153
 
 
154
 
            // See which event was generated
155
 
            switch(event.MouseInput.Event)
156
 
            {
157
 
                case EMIE_RMOUSE_PRESSED_DOWN:
158
 
                    m_r_down = true;
159
 
 
160
 
                    // Also reset mousemove values
161
 
                    m_x_diff = m_y_diff = 0;
162
 
 
163
 
                    break;
164
 
 
165
 
                case EMIE_RMOUSE_LEFT_UP:
166
 
                    m_r_down = false;
167
 
 
168
 
                case EMIE_MOUSE_MOVED:
169
 
 
170
 
                    // Add the new offsets to the existing ones
171
 
                    m_x_diff += m_x_cur - m_x_prev;
172
 
                    m_y_diff += m_y_cur - m_y_prev;
173
 
 
174
 
                    // Now set the previous values
175
 
                    m_x_prev = m_x_cur;
176
 
                    m_y_prev = m_y_cur;
177
 
 
178
 
                    // Given the cursor position, calculate a ray
179
 
                    // that projects from the camera.
180
 
                    m_cursor_ray = m_device->getSceneManager()->
181
 
                                             getSceneCollisionManager()->
182
 
                                             getRayFromScreenCoordinates(position2d<s32>(m_x_cur,m_y_cur),
183
 
                                                                         NULL);
184
 
 
185
 
                    break;
186
 
 
187
 
                case EMIE_LMOUSE_LEFT_UP:
188
 
 
189
 
                    // Now we need to place the piece of track
190
 
                    // at the current place.
191
 
                    if(m_mode == CM_PLACE_STRAIGHT_TRACK || m_mode == CM_PLACE_CURVE_TRACK)
192
 
                    {
193
 
                        int x = 0, z = 0;
194
 
 
195
 
                        // Now place this piece
196
 
                        if(m_ground->Intersection(m_device,m_cursor_ray,x,z))
197
 
                            m_track->SetPiece(cur,x,z);
198
 
                    }
199
 
                    else if(m_mode == CM_PLACE_TRAIN)
200
 
                    {
201
 
                        int x = 0, z = 0;
202
 
 
203
 
                        // Now place this train
204
 
                        if(m_ground->Intersection(m_device,m_cursor_ray,x,z))
205
 
                        {
206
 
                            m_train->AddTrain(m_device, m_device->getTimer()->getTime(), x, z);
207
 
                            m_mode = CM_SELECT;
208
 
 
209
 
                            UpdateGhostItems();
210
 
                        }
211
 
                    }
212
 
 
213
 
                    break;
214
 
 
215
 
                case EMIE_MOUSE_WHEEL:
216
 
 
217
 
                    {
218
 
                        float fChange = event.MouseInput.Wheel * 0.1f;
219
 
 
220
 
                        // Now calculate the amount to move the camera
221
 
                        // along the vector defined by the camera to target
222
 
                        vector3df v_target   = m_camera->getTarget();
223
 
                        vector3df v_position = m_camera->getPosition();
224
 
 
225
 
                        float x_total = v_position.X - v_target.X;
226
 
                        float y_total = v_position.Y - v_target.Y;
227
 
                        float z_total = v_position.Z - v_target.Z;
228
 
 
229
 
                        // Calculate the amount to move along the vector
230
 
                        v_position.X -= x_total * fChange;
231
 
                        v_position.Y -= y_total * fChange;
232
 
                        v_position.Z -= z_total * fChange;
233
 
 
234
 
                        m_radius -= m_radius * fChange;
235
 
 
236
 
                        m_camera->setPosition(v_position);
237
 
                    }
238
 
 
239
 
                    break;
240
 
 
241
 
                default:
242
 
 
243
 
                    break;
244
 
            }
245
 
 
246
 
            break;
247
 
 
248
 
        case EET_GUI_EVENT:
249
 
 
250
 
            switch(event.GUIEvent.EventType)
251
 
            {
252
 
                // This will be the case for the toolbar buttons
253
 
 
254
 
                case EGET_BUTTON_CLICKED:
255
 
 
256
 
                    if(event.GUIEvent.Caller->getID() == TOOLBAR_EDIT_TRACK)
257
 
                    {
258
 
                        if(!m_dialog_edittrack)
259
 
                        {
260
 
                            // Show the track edit dialog
261
 
                            m_dialog_edittrack = m_device->getGUIEnvironment()->addWindow(rect<s32>(12,50,230,195), false, L"Edit Track");
262
 
 
263
 
                            // Put the buttons in the window
264
 
                            m_device->getGUIEnvironment()->addStaticText(L"Track type:", rect<s32>(10,35,100,52), false, false, m_dialog_edittrack);
265
 
                            IGUIButton * pStraight = m_device->getGUIEnvironment()->addButton(rect<s32>(10,55,74,119),m_dialog_edittrack,EDITTRACK_STRAIGHT);
266
 
                            IGUIButton * pCurved = m_device->getGUIEnvironment()->addButton(rect<s32>(80,55,144,119),m_dialog_edittrack,EDITTRACK_CURVED);
267
 
 
268
 
                            pStraight->setImage(m_device->getVideoDriver()->getTexture(DATA_DIR "/icons/straight_track.png"));
269
 
                            pCurved->setImage(m_device->getVideoDriver()->getTexture(DATA_DIR "/icons/curved_track.png"));
270
 
 
271
 
                            pStraight->setUseAlphaChannel(true);
272
 
                            pCurved->setUseAlphaChannel(true);
273
 
                        }
274
 
                        else
275
 
                        {
276
 
                            // Close the dialog
277
 
                            m_dialog_edittrack->remove();
278
 
                            m_dialog_edittrack = NULL;
279
 
                        }
280
 
                    }
281
 
                    else if(event.GUIEvent.Caller->getID() == TOOLBAR_ADD_TRAIN)
282
 
                    {
283
 
                        if(!m_dialog_addtrain)
284
 
                        {
285
 
                            // Show the add train dialog
286
 
                            m_dialog_addtrain = m_device->getGUIEnvironment()->addWindow(rect<s32>(12,50,230,195), false, L"Add Train");
287
 
 
288
 
                            m_device->getGUIEnvironment()->addStaticText(L"Engine:", rect<s32>(10,35,100,60), false, false, m_dialog_addtrain);
289
 
 
290
 
                            // At this point, we only have one engine
291
 
                            // so we only really need one entry in the
292
 
                            // drop down box
293
 
                            IGUIComboBox * pBox = m_device->getGUIEnvironment()->addComboBox(rect<s32>(8,58,210,83), m_dialog_addtrain);
294
 
 
295
 
                            pBox->addItem(L"Standard Diesel");
296
 
 
297
 
                            // And add a button
298
 
                            m_device->getGUIEnvironment()->addButton(rect<s32>(8,100,210,126),m_dialog_addtrain,ADDTRAIN_ADD,L"Add train...");
299
 
                        }
300
 
                        else
301
 
                        {
302
 
                            m_dialog_addtrain->remove();
303
 
                            m_dialog_addtrain = NULL;
304
 
                        }
305
 
                    }
306
 
                    else if(event.GUIEvent.Caller->getID() == EDITTRACK_STRAIGHT)
307
 
                    {
308
 
                        m_mode = CM_PLACE_STRAIGHT_TRACK;
309
 
 
310
 
                        cur = TT_VERTICAL_STRAIGHT;
311
 
                        UpdateGhostItems();
312
 
                    }
313
 
                    else if(event.GUIEvent.Caller->getID() == EDITTRACK_CURVED)
314
 
                    {
315
 
                        m_mode = CM_PLACE_CURVE_TRACK;
316
 
 
317
 
                        cur = TT_CURVE_NE;
318
 
                        UpdateGhostItems();
319
 
                    }
320
 
                    else if(event.GUIEvent.Caller->getID() == ADDTRAIN_ADD)
321
 
                    {
322
 
                        m_mode = CM_PLACE_TRAIN;
323
 
                        UpdateGhostItems();
324
 
 
325
 
                        // Close the dialog
326
 
                        m_dialog_addtrain->remove();
327
 
                        m_dialog_addtrain = NULL;
328
 
 
329
 
                        // Switch off the train dialog
330
 
                        IGUIButton * pButton = dynamic_cast<IGUIButton *>(m_toolbar->getElementFromId(TOOLBAR_ADD_TRAIN));
331
 
                        pButton->setPressed(false);
332
 
                    }
333
 
 
334
 
                    break;
335
 
 
336
 
                case EGET_ELEMENT_CLOSED:
337
 
 
338
 
                    // Set the mode and update the ghost items
339
 
                    m_mode = CM_SELECT;
340
 
                    UpdateGhostItems();
341
 
 
342
 
                    // Depending on which dialog was closed, we
343
 
                    // may need to unhighlight a button
344
 
                    if(event.GUIEvent.Caller == m_dialog_edittrack)
345
 
                    {
346
 
                        IGUIButton * pButton = dynamic_cast<IGUIButton *>(m_toolbar->getElementFromId(TOOLBAR_EDIT_TRACK));
347
 
                        pButton->setPressed(false);
348
 
 
349
 
                        m_dialog_edittrack = NULL;
350
 
                    }
351
 
                    else if(event.GUIEvent.Caller == m_dialog_addtrain)
352
 
                    {
353
 
                        IGUIButton * pButton = dynamic_cast<IGUIButton *>(m_toolbar->getElementFromId(TOOLBAR_ADD_TRAIN));
354
 
                        pButton->setPressed(false);
355
 
 
356
 
                        m_dialog_addtrain = NULL;
357
 
                    }
358
 
 
359
 
                    return false;
360
 
 
361
 
                default:
362
 
                    break;
363
 
            }
364
 
 
365
 
            break;
366
 
 
367
 
        default:
368
 
 
369
 
            break;
370
 
    }
371
 
 
372
 
    return true;
373
 
}
374
 
 
375
 
void CEventManager::Process(u32 cur_time)
376
 
{
377
 
    // Get the difference from the previous time
378
 
    u32 diff = cur_time - m_previous_time;
379
 
 
380
 
    // Now get the current position of everything
381
 
    vector3df cur_pos = m_camera->getPosition();
382
 
    vector3df cur_tar = m_camera->getTarget();
383
 
 
384
 
    // Our rotation is increased everytime
385
 
    // the left / right arrow keys are used
386
 
    float fBefore = fRot;
387
 
 
388
 
    if(m_left)
389
 
        fRot += (diff * 0.003f);
390
 
    if(m_right)
391
 
        fRot -= (diff * 0.003f);
392
 
 
393
 
    // Calculate the cos/sin of the before values
394
 
    float bx = cosf(fBefore - PI2) * m_radius;
395
 
    float bz = sinf(fBefore - PI2) * m_radius;
396
 
 
397
 
    // Now for the new values
398
 
    float ax = cosf(fRot - PI2) * m_radius;
399
 
    float az = sinf(fRot - PI2) * m_radius;
400
 
 
401
 
    // Now get the difference
402
 
    cur_tar.X += bx - ax;
403
 
    cur_tar.Z += bz - az;
404
 
 
405
 
    if(m_r_down)
406
 
    {
407
 
        // When the mouse is moved, we track
408
 
        // the amount and move the target and
409
 
        // camera accordingly.
410
 
 
411
 
        // We need to make sure that the angle
412
 
        // of rotation (about the Y-Axis) is
413
 
        // taken into account here.
414
 
 
415
 
        // Precalculated numbers
416
 
        float xdiff = (m_x_diff * 0.01f * (m_radius / 3.0f));
417
 
        float zdiff = (m_y_diff * 0.02f * (m_radius / 3.0f));
418
 
 
419
 
        float xtrans = xdiff * cosf(fRot) + zdiff * sinf(fRot);
420
 
        float ztrans = zdiff * cosf(fRot) + xdiff * sinf(fRot - PI);
421
 
 
422
 
        cur_pos.X -= xtrans;
423
 
        cur_tar.X -= xtrans;
424
 
        cur_pos.Z += ztrans;
425
 
        cur_tar.Z += ztrans;
426
 
 
427
 
        m_x_diff = m_y_diff = 0;
428
 
    }
429
 
 
430
 
    m_camera->setPosition(cur_pos);
431
 
    m_camera->setTarget(cur_tar);
432
 
 
433
 
    // Deal with the track piece
434
 
    if(m_mode == CM_PLACE_STRAIGHT_TRACK || m_mode == CM_PLACE_CURVE_TRACK)
435
 
    {
436
 
        int x = 0, z = 0;
437
 
        if(m_ground->Intersection(m_device,m_cursor_ray,x,z))
438
 
        {
439
 
            // Depending on what the current piece is...
440
 
            float x_off = g_trackOrientationInfo[cur].fTrans_x;
441
 
            float z_off = g_trackOrientationInfo[cur].fTrans_z;
442
 
 
443
 
            float y_rot = g_trackOrientationInfo[cur].fRot_y;
444
 
 
445
 
            if(cur <= TT_HORIZONTAL_STRAIGHT)
446
 
            {
447
 
                m_straight_ghost_node->setPosition(vector3df(x * 2.0f + x_off, 0.05, z * 2.0f + z_off));
448
 
                m_straight_ghost_node->setRotation(vector3df(0,y_rot,0));
449
 
            }
450
 
            else
451
 
            {
452
 
                m_curve_ghost_node->setPosition(vector3df(x * 2.0f + x_off, 0.05, z * 2.0f + z_off));
453
 
                m_curve_ghost_node->setRotation(vector3df(0,y_rot,0));
454
 
            }
455
 
        }
456
 
    }
457
 
    else if(m_mode == CM_PLACE_TRAIN)
458
 
    {
459
 
        int x = 0, z = 0;
460
 
 
461
 
        if(m_ground->Intersection(m_device,m_cursor_ray,x,z))
462
 
            m_engine_ghost_node->setPosition(vector3df(x * 2.0f + 1.0f, 0.05, z * 2.0f + 1.0f));
463
 
    }
464
 
 
465
 
    m_previous_time = cur_time;
466
 
}
467
 
 
468
 
void CEventManager::CreateToolbar()
469
 
{
470
 
    IGUIEnvironment* pGUI = m_device->getGUIEnvironment();
471
 
 
472
 
    // Begin by creating the toolbar
473
 
    m_toolbar = pGUI->addToolBar();
474
 
 
475
 
    IGUIButton * pEditTrack = m_toolbar->addButton(TOOLBAR_EDIT_TRACK, NULL, NULL, m_device->getVideoDriver()->getTexture(DATA_DIR "/icons/edit_track.png"), NULL, false, true);
476
 
    IGUIButton * pAddTrain = m_toolbar->addButton(TOOLBAR_ADD_TRAIN,  NULL, NULL, m_device->getVideoDriver()->getTexture(DATA_DIR "/icons/add_train.png"), NULL, false, true);
477
 
 
478
 
    pEditTrack->setIsPushButton(true);
479
 
    pAddTrain->setIsPushButton(true);
480
 
}
481
 
 
482
 
void CEventManager::UpdateGhostItems()
483
 
{
484
 
    m_straight_ghost_node->setVisible(m_mode == CM_PLACE_STRAIGHT_TRACK);
485
 
    m_curve_ghost_node->setVisible(m_mode == CM_PLACE_CURVE_TRACK);
486
 
    m_engine_ghost_node->setVisible(m_mode == CM_PLACE_TRAIN);
487
 
}