~ubuntu-branches/ubuntu/utopic/brutalchess/utopic

« back to all changes in this revision

Viewing changes to brutalchess.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Gürkan Sengün
  • Date: 2006-04-07 10:41:25 UTC
  • Revision ID: james.westby@ubuntu.com-20060407104125-18mnxbl1yzju7e84
Tags: upstream-0.0.20060314cvs
Import upstream version 0.0.20060314cvs

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
*       Brutal Chess Alpha Build
 
3
*       - brutalchess.cpp
 
4
*
 
5
*       Authors: Maxwell Lazaroff, Michael Cook, and Joe Flint
 
6
*       Date Created : May 26th, 2005
 
7
*       Last Modified: December 19th, 2005
 
8
*
 
9
*       - description - Handles the main function calls for brutal chess.  Loads
 
10
*       the SDL window and controls the drawing of OpenGL objects.  Also handles
 
11
*       the creation of players and game flow control.
 
12
***************************************************************************/
 
13
 
 
14
// Necessary if we're in Windows so we don't get a million linker errors.
 
15
#ifdef WIN32
 
16
        #include <windows.h>
 
17
#endif
 
18
 
 
19
#include <iostream>
 
20
#include <math.h>
 
21
 
 
22
#include "SDL.h"
 
23
#include "board.h"
 
24
#include "glhead.h"
 
25
#include "objfile.h"
 
26
#include "fontloader.h"
 
27
#include "console.h"
 
28
#include "timer.h"
 
29
#include "timerchain.h"
 
30
#include "movelog.h"
 
31
#include "textureloader.h"
 
32
 
 
33
// Including Players
 
34
#include "chessplayer.h"
 
35
#include "alphabetaplayer.h"
 
36
#include "humanplayer.h"
 
37
#include "randomplayer.h"
 
38
 
 
39
using namespace std;
 
40
 
 
41
// Key array
 
42
bool keys[SDLK_LAST] = { false };
 
43
 
 
44
// Mouse button array
 
45
// Currently there are only 5 SDL constants, numbered 1-5
 
46
bool mouseclick[6] = {false};
 
47
bool mouseOut = false;
 
48
int mouseX, mouseY;
 
49
int mouseDeltaX = 0, mouseDeltaY = 0;
 
50
 
 
51
// Material settings and light positions
 
52
GLfloat light_position[]       = { 3.0,   3.0,  5.0,  0.0 };
 
53
const GLfloat light_ambient[]  = { 0.1f, 0.1f, 0.1f, 1.0f };
 
54
const GLfloat light_diffuse[]  = { 1.0f, 1.0f, 1.0f, 1.0f };
 
55
const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
 
56
const GLfloat specularmat[]    = { 1.0f, 1.0f, 1.0f, 1.0f };
 
57
 
 
58
// Storage for loaded pieces
 
59
ObjFile pawn, rook, knight, bishop, queen, king;
 
60
 
 
61
bool reflect = true;
 
62
 
 
63
void
 
64
Quit(int returnCode)
 
65
/***************************************************************************
 
66
*       Quit()
 
67
*
 
68
*       - Releases the resources and returns control to the desktop
 
69
***************************************************************************/
 
70
{
 
71
        FontLoader::unload();
 
72
        SDL_Quit();
 
73
        exit(returnCode);
 
74
}
 
75
 
 
76
bool
 
77
resizeWindow(int width, int height)
 
78
/***************************************************************************
 
79
*       resizeWindow()
 
80
*
 
81
*       - Resizes the game window to 'width' and 'height'.
 
82
***************************************************************************/
 
83
{
 
84
        // Protect against devide by zero
 
85
        if (height == 0) { height = 1; }
 
86
        
 
87
        GLfloat aspectRatio;
 
88
        aspectRatio = (float)width/(float)height;
 
89
        
 
90
        // Set up our viewport.
 
91
        glViewport(0, 0, width, height);
 
92
        
 
93
        // Change to the projection matrix and set our viewing volume.
 
94
        glMatrixMode(GL_PROJECTION);
 
95
   glLoadIdentity();
 
96
        
 
97
        // Sets our persepective.
 
98
        gluPerspective(30.0f, aspectRatio, 0.1f, 150.0f);
 
99
        //glOrtho( -36, 36, -27, 27, 0.1, 100 );
 
100
        
 
101
        // Change to the modelview matrix and set out viewing volume.
 
102
        glMatrixMode(GL_MODELVIEW);
 
103
        glLoadIdentity();
 
104
        
 
105
        return true;
 
106
}
 
107
 
 
108
void
 
109
buildModels()
 
110
{
 
111
        // Build display lists for all pieces
 
112
        pawn.build();
 
113
        rook.build();
 
114
        knight.build();
 
115
        bishop.build();
 
116
        queen.build();
 
117
        king.build();
 
118
}
 
119
 
 
120
void
 
121
unbuildModels()
 
122
{
 
123
        // Delete display lists for all pieces
 
124
        pawn.unbuild();
 
125
        rook.unbuild();
 
126
        knight.unbuild();
 
127
        bishop.unbuild();
 
128
        queen.unbuild();
 
129
        king.unbuild();
 
130
}
 
131
 
 
132
bool
 
133
loadModels()
 
134
/***************************************************************************
 
135
*       loadModels()
 
136
*
 
137
*       - Loads the models needed by the game, must be called after initGL
 
138
***************************************************************************/
 
139
{
 
140
        // Recenter pieces so that the center is at the base of the piece
 
141
        pawn.setRecenter( true, false, true );
 
142
        knight.setRecenter( true, false, true );
 
143
        rook.setRecenter( true, false, true );
 
144
        bishop.setRecenter( true, false, true );
 
145
        queen.setRecenter( true, false, true );
 
146
        king.setRecenter( true, false, true );
 
147
 
 
148
        // Load all of the piece models
 
149
        if( !pawn.load( "models/pawn.obj" ) )
 
150
                return false;
 
151
        if( !knight.load( "models/knight.obj" ) )
 
152
                return false;
 
153
        if( !rook.load( "models/rook.obj" ) )
 
154
                return false;
 
155
        if( !bishop.load( "models/bishop.obj" ) )
 
156
                return false;
 
157
        if( !queen.load( "models/queen.obj" ) )
 
158
                return false;
 
159
        if( !king.load( "models/king.obj" ) )
 
160
                return false;
 
161
 
 
162
        // Generate smooth normals for the models
 
163
        pawn.findNorms();
 
164
        rook.findNorms();
 
165
        knight.findNorms();
 
166
        bishop.findNorms();
 
167
        queen.findNorms();
 
168
        king.findNorms();
 
169
 
 
170
        // Make all the pieces have the same base size
 
171
        pawn.setScale( pawn.scale()*7 );
 
172
        rook.setScale( pawn.scale() );
 
173
        knight.setScale( pawn.scale() );
 
174
        bishop.setScale( pawn.scale() );
 
175
        queen.setScale( pawn.scale() );
 
176
        king.setScale( pawn.scale() );
 
177
 
 
178
        buildModels();
 
179
        
 
180
        return true;
 
181
}
 
182
 
 
183
 
 
184
bool
 
185
initGL()
 
186
/***************************************************************************
 
187
*       initGL()
 
188
*
 
189
*       - Initializes GL settings.
 
190
***************************************************************************/
 
191
{
 
192
        // Enable smooth shading. 
 
193
    glShadeModel(GL_SMOOTH);
 
194
 
 
195
    // Set the background color to black. 
 
196
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
 
197
 
 
198
    // Depth buffer setup. 
 
199
    glClearDepth(1.0f);
 
200
 
 
201
    // Enables Depth Testing 
 
202
    glEnable(GL_DEPTH_TEST);
 
203
 
 
204
    // The Type Of Depth Test To Do 
 
205
    glDepthFunc(GL_LEQUAL);
 
206
 
 
207
    // Really Nice Perspective Calculations 
 
208
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
 
209
 
 
210
        glLightfv(GL_LIGHT0, GL_POSITION, light_position);
 
211
        glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
 
212
        glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
 
213
        glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
 
214
        glEnable( GL_LIGHTING );
 
215
        glEnable( GL_LIGHT0 );
 
216
        glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
 
217
        glEnable( GL_COLOR_MATERIAL );
 
218
        glMaterialfv(GL_FRONT, GL_SPECULAR, specularmat);
 
219
        glMaterialf(GL_FRONT, GL_SHININESS, 128);
 
220
 
 
221
        glEnable( GL_CULL_FACE );
 
222
 
 
223
        //glEnable( GL_NORMALIZE );
 
224
 
 
225
    return true;
 
226
}
 
227
 
 
228
BoardMove 
 
229
getMousePos(double & mx, double & my, double & mz)
 
230
{
 
231
        GLdouble mvmatrix[16];
 
232
        GLdouble pjmatrix[16];
 
233
        GLint viewport[4];
 
234
 
 
235
        // Get the current setup.
 
236
        glGetDoublev( GL_MODELVIEW_MATRIX, mvmatrix );
 
237
        glGetDoublev( GL_PROJECTION_MATRIX, pjmatrix );
 
238
        glGetIntegerv( GL_VIEWPORT, viewport );
 
239
 
 
240
        // Y Coordinate must be measured from the bottom of the window.
 
241
        int mouseycorr = viewport[3] - mouseY;
 
242
 
 
243
        GLfloat depth;
 
244
        GLdouble x, y, z;
 
245
 
 
246
        glReadPixels( mouseX, mouseycorr, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, 
 
247
                        &depth );
 
248
        gluUnProject( mouseX, mouseycorr, depth, mvmatrix, pjmatrix, viewport, 
 
249
                        &x, &y, &z);
 
250
        
 
251
        mx = x;
 
252
        my = y;
 
253
        mz = z + 8;
 
254
 
 
255
        x += 0.5;
 
256
        z += 0.5;
 
257
 
 
258
        if( y < -0.05 )
 
259
                return BoardMove( 9, 9, 9, 9 );
 
260
 
 
261
 
 
262
        int boardy = (int)floor( x );
 
263
        int boardx = 8 + (int)floor( z );
 
264
        
 
265
        if( boardx >= 0 && boardx < 8 && boardy >= 0 && boardy < 8 )
 
266
                return BoardMove( boardx, boardy, 9, 9 );
 
267
                
 
268
        return BoardMove( 9, 9, 9, 9 );
 
269
}
 
270
 
 
271
int sign( int i )
 
272
{
 
273
        return ( i >= 0 ) ? 1 : -1; 
 
274
}
 
275
 
 
276
void 
 
277
setupMoveAnims( const BoardMove & move, const Board & board, TimerChain & chainx, TimerChain & chainy )
 
278
{
 
279
        int deltax, deltay;
 
280
 
 
281
        deltax = int( move.getEndx() ) - int( move.getStartx() );
 
282
        deltay = int( move.getEndy() ) - int( move.getStarty() );
 
283
 
 
284
        Timer temp, temp2( Timer::LOGARITHMIC );
 
285
        temp2.setDuration( 0.5 );
 
286
 
 
287
        chainx.clear();
 
288
        chainy.clear();
 
289
 
 
290
        // chainx moves things in the x direction, deltay is being used due to the stupid way that moves are done (x is the row!?)
 
291
        if( board._board[ move.getStartx() ][ move.getStarty() ].getUnit() != KNIGHT ) {
 
292
                // Always take the same ammount of time to move one square
 
293
                temp.setDuration( 0.25*sqrt(double(deltax*deltax + deltay*deltay)) );
 
294
                
 
295
                if( deltay == 0 ) {
 
296
                        temp.setRange( 0, 0 );
 
297
                        chainx.add( temp );
 
298
                        temp2.setRange( 0, 0 );
 
299
                        chainx.add( temp2 );
 
300
                } else {
 
301
                        temp.setRange( 0, deltay - sign(deltay)*0.5 );
 
302
                        chainx.add( temp );
 
303
                        temp2.setRange( deltay - sign(deltay)*0.5, deltay );
 
304
                        chainx.add( temp2 );
 
305
                }
 
306
 
 
307
                if( deltax == 0 ) {
 
308
                        temp.setRange( 0, 0 );
 
309
                        chainy.add( temp );
 
310
                        temp2.setRange( 0, 0 );
 
311
                        chainy.add( temp2 );
 
312
                } else {
 
313
                        temp.setRange( 0, deltax - sign(deltax)*0.5 );
 
314
                        chainy.add( temp );
 
315
                        temp2.setRange( deltax - sign(deltax)*0.5, deltax );
 
316
                        chainy.add( temp2 );
 
317
                }
 
318
        } else {
 
319
                temp.setDuration( 0.25*1.0 );
 
320
 
 
321
                // Always move along the short side first
 
322
                if( abs( deltax ) < abs( deltay ) ) {
 
323
                        // Move along short side
 
324
                        temp.setRange( 0, 0 );
 
325
                        chainx.add( temp );
 
326
 
 
327
                        temp.setRange( 0, deltax );
 
328
                        chainy.add( temp );
 
329
 
 
330
                        // Move along long side
 
331
                        temp.setDuration( 0.25*1.5 );
 
332
 
 
333
                        temp.setRange( deltax, deltax );
 
334
                        chainy.add( temp );
 
335
 
 
336
                        temp.setRange( 0, deltay - sign(deltay)*0.5 );
 
337
                        chainx.add( temp );
 
338
 
 
339
                        temp2.setRange( deltax, deltax );
 
340
                        chainy.add( temp2 );
 
341
 
 
342
                        temp2.setRange( deltay - sign(deltay)*0.5, deltay );
 
343
                        chainx.add( temp2 );
 
344
 
 
345
                } else {
 
346
                        // Move along short side
 
347
                        temp.setRange( 0, 0 );
 
348
                        chainy.add( temp );
 
349
 
 
350
                        temp.setRange( 0, deltay );
 
351
                        chainx.add( temp );
 
352
 
 
353
                        // Move along long side
 
354
                        temp.setDuration( 0.25*1.5 );
 
355
 
 
356
                        temp.setRange( deltay, deltay );
 
357
                        chainx.add( temp );
 
358
 
 
359
                        temp.setRange( 0, deltax - sign(deltax)*0.5 );
 
360
                        chainy.add( temp );
 
361
 
 
362
                        temp2.setRange( deltay, deltay );
 
363
                        chainx.add( temp2 );
 
364
 
 
365
                        temp2.setRange( deltax - sign(deltax)*0.5, deltax );
 
366
                        chainy.add( temp2 );
 
367
                }
 
368
        }
 
369
}
 
370
 
 
371
void
 
372
drawBoardEdge()
 
373
{
 
374
        glEnable( GL_LIGHTING );
 
375
 
 
376
        // Move back to the center of the board.
 
377
        glTranslated( 3.5, 0, -4.5 );
 
378
        
 
379
        // Select the edgestyle to be used.
 
380
        int edgestyle = 2;
 
381
 
 
382
        if (edgestyle == 1)
 
383
        {
 
384
                glBegin( GL_QUADS );
 
385
                
 
386
                glColor3d( 0.3, 0.3, 0.3 );
 
387
 
 
388
                glNormal3d( 0, 1.87083, 1.87083);
 
389
                glVertex3d( -4.075, -0.01,  4.075 );
 
390
                glVertex3d(  4.075, -0.01,  4.075 );
 
391
                glVertex3d(  4.0, 0,  4.0 );
 
392
                glVertex3d( -4.0, 0,  4.0 );
 
393
 
 
394
                glNormal3d( 0, 0, 7);
 
395
                glVertex3d( -4.075, -0.15, 4.075 );
 
396
                glVertex3d(  4.075, -0.15, 4.075 );
 
397
                glVertex3d(  4.075, -0.01, 4.075 );
 
398
                glVertex3d( -4.075, -0.01, 4.075 );
 
399
 
 
400
                glNormal3d( 1.87083, 1.87083, 0);
 
401
                glVertex3d(  4.075, -0.01,  4.075 );
 
402
                glVertex3d(  4.075, -0.01, -4.075 );
 
403
                glVertex3d(  4.0, 0, -4.0 );
 
404
                glVertex3d(  4.0, 0,  4.0 );
 
405
 
 
406
                glNormal3d( 7, 0, 0 );
 
407
                glVertex3d(  4.075, -0.15,  4.075 );
 
408
                glVertex3d(  4.075, -0.15, -4.075 );
 
409
                glVertex3d(  4.075, -0.01, -4.075 );
 
410
                glVertex3d(  4.075, -0.01,  4.075 );
 
411
 
 
412
                glNormal3d( 0, 1.87083, -1.87083);
 
413
                glVertex3d(  4.075, -0.01, -4.075 );
 
414
                glVertex3d( -4.075, -0.01, -4.075 );
 
415
                glVertex3d( -4.0, 0, -4.0 );
 
416
                glVertex3d(  4.0, 0, -4.0 );
 
417
 
 
418
                glNormal3d( 0, 0, -7 );
 
419
                glVertex3d(  4.075, -0.15, -4.075 );
 
420
                glVertex3d( -4.075, -0.15, -4.075 );
 
421
                glVertex3d( -4.075, -0.01, -4.075 );
 
422
                glVertex3d(  4.075, -0.01, -4.075 );
 
423
 
 
424
                glNormal3d( -1.87083, 1.87083, 0);
 
425
                glVertex3d( -4.075, -0.01, -4.075 );
 
426
                glVertex3d( -4.075, -0.01,  4.075 );
 
427
                glVertex3d( -4.0, 0,  4.0 );
 
428
                glVertex3d( -4.0, 0, -4.0 );
 
429
 
 
430
                glNormal3d( -7, 0, 0 );
 
431
                glVertex3d( -4.075, -0.15, -4.075 );
 
432
                glVertex3d( -4.075, -0.15,  4.075 );
 
433
                glVertex3d( -4.075, -0.01,  4.075 );
 
434
                glVertex3d( -4.075, -0.01, -4.075 );
 
435
 
 
436
                glEnd();
 
437
        }
 
438
        else if (edgestyle == 2)
 
439
        {
 
440
                glBegin( GL_QUADS );
 
441
                
 
442
                // Darker of the edge colors.
 
443
                glColor4d( 0.2, 0.2, 0.2, 0.95 );
 
444
 
 
445
                glNormal3d( 0, 7, 0);
 
446
                
 
447
                // White side.
 
448
                glVertex3d( -4.1, 0,  4.1 );
 
449
                glVertex3d(  4.1, 0,  4.1 );
 
450
                glVertex3d(  4.0, 0,  4.0 );
 
451
                glVertex3d( -4.0, 0,  4.0 );
 
452
 
 
453
                // Right of white side.
 
454
                glVertex3d( -4.1, 0, -4.1 );
 
455
                glVertex3d( -4.1, 0,  4.1 );
 
456
                glVertex3d( -4.0, 0,  4.0 );
 
457
                glVertex3d( -4.0, 0, -4.0 );
 
458
 
 
459
                // Black side.
 
460
                glVertex3d(  4.1, 0, -4.1 );
 
461
                glVertex3d( -4.1, 0, -4.1 );
 
462
                glVertex3d( -4.0, 0, -4.0 );
 
463
                glVertex3d(  4.0, 0, -4.0 );
 
464
 
 
465
                // Left of white side.
 
466
                glVertex3d(  4.1, 0,  4.1 );
 
467
                glVertex3d(  4.1, 0, -4.1 );
 
468
                glVertex3d(  4.0, 0, -4.0 );
 
469
                glVertex3d(  4.0, 0,  4.0 );
 
470
 
 
471
                glColor3d( 0.2, 0.2, 0.2 );
 
472
 
 
473
                // Drawing sides of the darker portion.
 
474
                glNormal3d( 0, 0, 7);
 
475
                glVertex3d( -4.1, -0.075, 4.1 );
 
476
                glVertex3d(  4.1, -0.075, 4.1 );
 
477
                glVertex3d(  4.1, 0, 4.1 );
 
478
                glVertex3d( -4.1, 0, 4.1 );
 
479
 
 
480
                glNormal3d( 7, 0, 0 );
 
481
                glVertex3d(  4.1, -0.075,  4.1 );
 
482
                glVertex3d(  4.1, -0.075, -4.1 );
 
483
                glVertex3d(  4.1, 0, -4.1 );
 
484
                glVertex3d(  4.1, 0,  4.1 );
 
485
                
 
486
                glNormal3d( 0, 0, -7 );
 
487
                glVertex3d(  4.1, -0.075, -4.1 );
 
488
                glVertex3d( -4.1, -0.075, -4.1 );
 
489
                glVertex3d( -4.1, 0, -4.1 );
 
490
                glVertex3d(  4.1, 0, -4.1 );
 
491
 
 
492
                glNormal3d( -7, 0, 0 );
 
493
                glVertex3d( -4.1, -0.075, -4.1 );
 
494
                glVertex3d( -4.1, -0.075,  4.1 );
 
495
                glVertex3d( -4.1, 0,  4.1 );
 
496
                glVertex3d( -4.1, 0, -4.1 );
 
497
 
 
498
                // Now draw the outer border in light gray.
 
499
                glColor4d( 0.45, 0.45, 0.45, 0.95 );
 
500
 
 
501
                glNormal3d( 0, 7, 0 );
 
502
 
 
503
                // White side.
 
504
                glVertex3d( -4.2, -0.075,  4.2 );
 
505
                glVertex3d(  4.2, -0.075,  4.2 );
 
506
                glVertex3d(  4.1, -0.075,  4.1 );
 
507
                glVertex3d( -4.1, -0.075,  4.1 );
 
508
 
 
509
                // Right of white side.
 
510
                glVertex3d( -4.2, -0.075, -4.2 );
 
511
                glVertex3d( -4.2, -0.075,  4.2 );
 
512
                glVertex3d( -4.1, -0.075,  4.1 );
 
513
                glVertex3d( -4.1, -0.075, -4.1 );
 
514
 
 
515
                // Black side.
 
516
                glVertex3d(  4.2, -0.075, -4.2 );
 
517
                glVertex3d( -4.2, -0.075, -4.2 );
 
518
                glVertex3d( -4.1, -0.075, -4.1 );
 
519
                glVertex3d(  4.1, -0.075, -4.1 );
 
520
 
 
521
                // Left of white side.
 
522
                glVertex3d(  4.2, -0.075,  4.2 );
 
523
                glVertex3d(  4.2, -0.075, -4.2 );
 
524
                glVertex3d(  4.1, -0.075, -4.1 );
 
525
                glVertex3d(  4.1, -0.075,  4.1 );
 
526
 
 
527
                glColor3d( 0.45, 0.45, 0.45 );
 
528
 
 
529
        // Drawing sides of the darker portion.
 
530
                glNormal3d( 0, 0, 7);
 
531
                glVertex3d( -4.2, -0.15, 4.2 );
 
532
                glVertex3d(  4.2, -0.15, 4.2 );
 
533
                glVertex3d(  4.2, -0.075, 4.2 );
 
534
                glVertex3d( -4.2, -0.075, 4.2 );
 
535
 
 
536
                glNormal3d( 7, 0, 0 );
 
537
                glVertex3d(  4.2, -0.15,  4.2 );
 
538
                glVertex3d(  4.2, -0.15, -4.2 );
 
539
                glVertex3d(  4.2, -0.075, -4.2 );
 
540
                glVertex3d(  4.2, -0.075,  4.2 );
 
541
                
 
542
                glNormal3d( 0, 0, -7 );
 
543
                glVertex3d(  4.2, -0.15, -4.2 );
 
544
                glVertex3d( -4.2, -0.15, -4.2 );
 
545
                glVertex3d( -4.2, -0.075, -4.2 );
 
546
                glVertex3d(  4.2, -0.075, -4.2 );
 
547
 
 
548
                glNormal3d( -7, 0, 0 );
 
549
                glVertex3d( -4.2, -0.15, -4.2);
 
550
                glVertex3d( -4.2, -0.15,  4.2 );
 
551
                glVertex3d( -4.2, -0.075,  4.2 );
 
552
                glVertex3d( -4.2, -0.075, -4.2 );
 
553
 
 
554
                glEnd();
 
555
        }
 
556
 
 
557
        return;
 
558
}
 
559
 
 
560
void 
 
561
drawSquares( uint mousex, uint mousey, bool allowselect )
 
562
{
 
563
        static double alpha[8][8] = { 0 };
 
564
        static Timer alphatimers[8][8];
 
565
        
 
566
        
 
567
        //bool selected;
 
568
        bool alternate = true;
 
569
        
 
570
        glEnable( GL_TEXTURE_2D );
 
571
 
 
572
        /*if( !TextureLoader::setTexture( "marblewhite" ) )
 
573
                cerr << "Failed to find texture" << endl;*/
 
574
 
 
575
        glPushMatrix();
 
576
 
 
577
        for( int i = 0; i < 8; i++ ) {
 
578
                for( int j = 0; j < 8; j++ ) {
 
579
                        
 
580
                        bool selected = i == mousex && j == mousey;
 
581
 
 
582
                        if( alphatimers[i][j].started() ) {
 
583
                                alphatimers[i][j]++;
 
584
                                alpha[i][j] += alphatimers[i][j].change();
 
585
                        }
 
586
 
 
587
                        // !noselection && activePlayer->requiresInput()
 
588
                        if( selected && allowselect ) {
 
589
                                alpha[i][j] = 0.7;
 
590
                                alphatimers[i][j].stop();
 
591
                        }
 
592
                        if( alpha[i][j] > 0 ) {
 
593
                                alphatimers[i][j].setDuration( 0.25 );
 
594
                                alphatimers[i][j].setRange( alpha[i][j], 0 );
 
595
                                alphatimers[i][j].start();
 
596
                        } else {
 
597
                                alpha[i][j] = 0;
 
598
                        }
 
599
 
 
600
                        if( alternate )
 
601
                                TextureLoader::setTexture( "marblewhite" );
 
602
                        else
 
603
                                TextureLoader::setTexture( "marbleblack" );
 
604
                        //glColor4d( color[i][j], color[i][j], color[i][j], 0.7 );
 
605
                        glColor4d( 1.0, 1.0, 1.0, 0.7 );
 
606
                        alternate = !alternate;
 
607
 
 
608
                        glBegin( GL_QUADS );
 
609
                        glNormal3d( 0, 7, 0 );
 
610
                        //glTexCoord2d( 0, 1 );
 
611
                        glTexCoord2d( j*1/8.0, (i+1)*1/8.0 );
 
612
                        glVertex3d( -0.5, 0,  0.5 );
 
613
                        //glTexCoord2d( 1, 1 );
 
614
                        glTexCoord2d( (j+1)*1/8.0, (i+1)*1/8.0 );
 
615
                        glVertex3d(  0.5, 0,  0.5 );
 
616
                        //glTexCoord2d( 1, 0 );
 
617
                        glTexCoord2d( (j+1)*1/8.0, i*1/8.0 );
 
618
                        glVertex3d(  0.5, 0, -0.5 );
 
619
                        //glTexCoord2d( 0, 0 );
 
620
                        glTexCoord2d( j*1/8.0, i*1/8.0 );
 
621
                        glVertex3d( -0.5, 0, -0.5 );
 
622
                        glEnd();
 
623
 
 
624
                        if( alpha[i][j] != 0 ) {
 
625
                                glDisable( GL_TEXTURE_2D );
 
626
                                glDisable( GL_DEPTH_TEST );
 
627
                                glBegin( GL_QUADS );
 
628
                                glColor4d( 0.5, 0.5, 0.5, alpha[i][j] );
 
629
                                glNormal3d( 0, 7, 0 );
 
630
                                glVertex3d( -0.5, 0,  0.5 );
 
631
                                glVertex3d(  0.5, 0,  0.5 );
 
632
                                glVertex3d(  0.5, 0, -0.5 );
 
633
                                glVertex3d( -0.5, 0, -0.5 );
 
634
                                glEnd();
 
635
                                glEnable( GL_DEPTH_TEST );
 
636
                                glEnable( GL_TEXTURE_2D );
 
637
                        }
 
638
 
 
639
 
 
640
 
 
641
                        glTranslated( 1, 0, 0 );
 
642
                }
 
643
                glTranslated( -8, 0, 1 );
 
644
                alternate = !alternate;
 
645
        }
 
646
 
 
647
        glDisable( GL_TEXTURE_2D );
 
648
 
 
649
        drawBoardEdge();
 
650
 
 
651
        glPopMatrix();  
 
652
}
 
653
 
 
654
void 
 
655
drawPiece( Unit whichpiece, bool reverse )
 
656
{
 
657
        if( reverse )
 
658
                glRotated( 180, 0, 1, 0 );
 
659
        glScaled( 1/7.0, 1/7.0, 1/7.0 );
 
660
        switch( whichpiece ) {
 
661
                case PAWN:
 
662
                        pawn.draw();
 
663
                        break;
 
664
                case KNIGHT:
 
665
                        glRotated( 90, 0, 1, 0 );
 
666
                        knight.draw();
 
667
                        glRotated( -90, 0, 1, 0 );
 
668
                        break;
 
669
                case BISHOP:
 
670
                        glRotated( 180, 0, 1, 0 );
 
671
                        bishop.draw();
 
672
                        glRotated( 180, 0, -1, 0 );
 
673
                        break;
 
674
                case ROOK:
 
675
                        rook.draw();
 
676
                        break;
 
677
                case QUEEN:
 
678
                        queen.draw();
 
679
                        break;
 
680
                case KING:
 
681
                        /*if( board.inDanger( board._board[ i ][ j ].getColor() == WHITE, i, j ) )
 
682
                                glColor3d( 0.5, 0, 0 );*/
 
683
                        king.draw();
 
684
                default:
 
685
                        break;
 
686
        }
 
687
        glScaled( 7, 7, 7 );
 
688
        if( reverse )
 
689
                glRotated( 180, 0, -1, 0 );     
 
690
}                       
 
691
                        
 
692
double 
 
693
dist( double x1, double y1, double x2, double y2 )
 
694
{
 
695
                return sqrt( (x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2) );
 
696
}
 
697
 
 
698
void 
 
699
drawBoard( const Board & board, bool white, uint mousei, uint mousej, 
 
700
                   bool allowselect, bool firstclick, uint movei, uint movej, 
 
701
                   const TimerChain & moveanimx, const TimerChain & moveanimy,
 
702
                   double mousex, double mousez )
 
703
{
 
704
        glPushMatrix();
 
705
        static double height[8][8] = { 0 };
 
706
        static Timer timers[8][8];
 
707
        double alpha = 1.0;
 
708
        
 
709
        if( !firstclick ) {
 
710
                if( board._board[ movei ][ movej ].getColor() == WHITE )
 
711
                        glColor3d( 0.7, 0.7, 0.7 );
 
712
                else
 
713
                        glColor3d( 0.2, 0.2, 0.2 );
 
714
                if( board._board[ movei ][ movej ].getUnit() == KING &&
 
715
                        board.inDanger( board._board[ movei ][ movej ].getColor() == WHITE, movei, movej ) )
 
716
                                        glColor3d( 0.5, 0, 0 );
 
717
                glTranslated( mousex, height[movei][movej], mousez );
 
718
                drawPiece( board._board[ movei ][ movej ].getUnit(), board._board[ movei ][ movej ].getColor() == WHITE );
 
719
                glTranslated( -mousex, -height[movei][movej], -mousez);
 
720
        }
 
721
        
 
722
        for( int i = 0; i < 8; i++ ) {
 
723
                for( int j = 0; j < 8; j++ ) {
 
724
 
 
725
 
 
726
                        glTranslated( 0, height[i][j], 0 );
 
727
                                
 
728
                        if( movei == i && movej == j 
 
729
                                && ( moveanimx.started() || moveanimy.started() ) ) {
 
730
                                        glTranslated( moveanimx.value(), 0, moveanimy.value() );
 
731
                        }
 
732
 
 
733
                        alpha = 1;
 
734
                        
 
735
                        if( !firstclick && mousei == i && mousej == j)
 
736
                                alpha = 0.2 + dist( mousex, mousez, j, i )/0.5*0.8;
 
737
 
 
738
                        // Sets the piece render color.
 
739
                        if( board._board[ i ][ j ].getColor() == WHITE )
 
740
                                glColor4d( 0.7, 0.7, 0.7, alpha );
 
741
                        else
 
742
                                glColor4d( 0.2, 0.2, 0.2, alpha );
 
743
                        
 
744
                        // If the king is in check, sets the piece render color to red. 
 
745
                        if( board._board[ i ][ j ].getUnit() == KING &&
 
746
                                board.inDanger( board._board[ i ][ j ].getColor() == WHITE, i, j ) )
 
747
                                                glColor4d( 0.5, 0, 0, alpha );
 
748
                        // If a piece has already been selected, translate is drawn location to match the cursors
 
749
                        // position.  
 
750
                        if( !firstclick && i == movei && j == movej ) {
 
751
                                glColor4d( 0.5, 0.5, 0.5, 0.5 );
 
752
                                glEnable( GL_BLEND );
 
753
                                drawPiece( board._board[ i ][ j ].getUnit(), board._board[ i ][ j ].getColor() == WHITE );
 
754
                                glDisable( GL_BLEND );
 
755
                        } else {                        
 
756
                                if( alpha != 1 )
 
757
                                        glEnable( GL_BLEND );
 
758
                                drawPiece( board._board[ i ][ j ].getUnit(), board._board[ i ][ j ].getColor() == WHITE );
 
759
                                if( alpha != 1 )
 
760
                                        glDisable( GL_BLEND );
 
761
                        }
 
762
                        
 
763
 
 
764
                        if( movei == i && movej == j 
 
765
                                && ( moveanimx.started() || moveanimy.started() ) ) {
 
766
                                        glTranslated( -moveanimx.value(), 0, -moveanimy.value() );
 
767
                        }
 
768
 
 
769
                        glTranslated( 1, -height[i][j], 0 );
 
770
                        
 
771
                        if( timers[i][j].started() ) {
 
772
                                timers[i][j]++;
 
773
                                height[i][j] += timers[i][j].change();
 
774
                        } 
 
775
                        if ( timers[i][j].done() ) {
 
776
                                height[i][j] = timers[i][j].end();
 
777
                                timers[i][j].resetDone();
 
778
                        }
 
779
                        
 
780
                        static bool bounceup = true;
 
781
                        if( board._board[i][j].getUnit() != EMPTY ) {
 
782
                                if( !firstclick && i == movei && j == movej ) {
 
783
                                        /*if( bounceup ) {
 
784
                                                if( height[i][j] < 0.4  && !timers[i][j].started() ) {
 
785
                                                        timers[i][j].setRange( 0.2, 0.4 );
 
786
                                                        timers[i][j].setDuration( 0.4 );
 
787
                                                        timers[i][j].setProgress( height[i][j] );
 
788
                                                        timers[i][j].start();
 
789
                                                }
 
790
                                                if( height[i][j] >= 0.4 ) {
 
791
                                                        height[i][j] = 0.4;
 
792
                                                        bounceup = false;
 
793
                                                }
 
794
                                        } else {
 
795
                                                if( height[i][j] > 0.2 && !timers[i][j].started() ) {
 
796
                                                        timers[i][j].setRange( 0.4, 0.2 );
 
797
                                                        timers[i][j].setDuration( 0.4 );
 
798
                                                        timers[i][j].setProgress( height[i][j] );
 
799
                                                        timers[i][j].start();
 
800
                                                }
 
801
                                                if( height[i][j] <= 0.2 ) {
 
802
                                                        height[i][j] = 0.2;
 
803
                                                        bounceup = true;
 
804
                                                }
 
805
                                        }*/
 
806
                                } else if( firstclick && i == mousei && j == mousej &&
 
807
                                                (board._board[i][j].getColor() == WHITE) == white && 
 
808
                                                allowselect ) {
 
809
                                        if( height[i][j] > 0.2 && !timers[i][j].started() ) {
 
810
                                                timers[i][j].setRange( 0.4, 0.2 );
 
811
                                                timers[i][j].setDuration( 0.25 );
 
812
                                                timers[i][j].setProgress( height[i][j] );
 
813
                                                timers[i][j].start();
 
814
                                        }
 
815
                                        if( height[i][j] < 0.2 ) {
 
816
                                                timers[i][j].stop();
 
817
                                                height[i][j] = 0.2;
 
818
                                        }
 
819
                                } else { 
 
820
                                        if( height[i][j] < 0.01 )
 
821
                                                height[i][j] = 0.01;
 
822
                                        if( height[i][j] > 0.01 && !timers[i][j].started()) {
 
823
                                                timers[i][j].setType( Timer::LOGARITHMIC );
 
824
                                                timers[i][j].setRange( 0.4, 0.01 );
 
825
                                                timers[i][j].setDuration( 1.0 );
 
826
                                                timers[i][j].setProgress( height[i][j] );
 
827
                                                timers[i][j].start();
 
828
                                        }
 
829
                                }
 
830
                        } else {
 
831
                                timers[i][j].stop();
 
832
                                height[i][j] = 0.01;
 
833
                        }
 
834
                }
 
835
                glTranslated( -8, 0, 1 );
 
836
        }
 
837
        glPopMatrix();
 
838
}
 
839
 
 
840
bool
 
841
drawGLScene()
 
842
/***************************************************************************
 
843
*       drawGLScene()
 
844
*
 
845
*       - Handles the drawing of a frame.
 
846
***************************************************************************/
 
847
{
 
848
        static bool firstclick = true;
 
849
        static bool white = true;
 
850
        static bool showwhite = true;
 
851
        static BoardMove move;
 
852
        static BoardMove mouse( 9, 9, 9, 9 );
 
853
 
 
854
        // Creating our players.
 
855
        static ChessPlayer *playOne = new HumanPlayer;
 
856
        static ChessPlayer *playTwo = new AlphaBetaPlayer;
 
857
 
 
858
        // Setting player 1 to the active player.
 
859
        static ChessPlayer *activePlayer = playOne;
 
860
        static ChessPlayer *inactivePlayer = playTwo;
 
861
 
 
862
        static double tablerot = 0;
 
863
        static MoveLog movelog;
 
864
        static double mousex, mousey, mousez;
 
865
        string filename = "log.txt";
 
866
        static bool oneframe = false;
 
867
        
 
868
        // These are to calculate our fps. 
 
869
    static int T0     = 0;
 
870
    static int Frames = 0;
 
871
        
 
872
        // Clear The Screen And The Depth Buffer.
 
873
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
 
874
 
 
875
        glLoadIdentity();
 
876
 
 
877
        glTranslated( 0, 0, -106 );
 
878
 
 
879
        glRotated( 42, 1, 0, 0 );
 
880
 
 
881
        static Board test;
 
882
        static BoardMove animmove;
 
883
        static TimerChain moveanimx, moveanimy;
 
884
 
 
885
        // Update the board when the move animations are finished
 
886
        // Don't reset done yet, do it at the end of the frame otherwise selections can get messed up
 
887
        if( moveanimx.done() && moveanimy.done() ) {
 
888
                inactivePlayer->opponent_move( animmove, !white );
 
889
                test.updateBoard( animmove );
 
890
                white = !white;
 
891
                movelog.write(filename);
 
892
 
 
893
                if (inactivePlayer->inCheckmate(test, white))
 
894
                {
 
895
                        Console::out << inactivePlayer->getName() << " in Checkmate!\n";
 
896
                        Console::out << activePlayer->getName() << " wins!\n";
 
897
                        test.reset();
 
898
                        if (white)
 
899
                        {
 
900
                                ChessPlayer *temp;
 
901
                                temp = activePlayer;
 
902
                                activePlayer = inactivePlayer;
 
903
                                inactivePlayer = temp;
 
904
                        }
 
905
                        white = true;
 
906
                        light_position[0] = -light_position[0];
 
907
                        light_position[2] = -light_position[2];
 
908
                        showwhite = !showwhite;
 
909
                        movelog.write(filename);
 
910
                }
 
911
                else if(inactivePlayer->inStalemate(test, white))
 
912
                {
 
913
                        Console::out << "The game ended in a stalemate caused";
 
914
                        Console::out << " by " << inactivePlayer->getName() << "!\n";
 
915
                        test.reset();
 
916
                        if (white)
 
917
                        {
 
918
                                ChessPlayer *temp;
 
919
                                temp = activePlayer;
 
920
                                activePlayer = inactivePlayer;
 
921
                                inactivePlayer = temp;
 
922
                        }
 
923
                        white = true;
 
924
                        showwhite = !showwhite;
 
925
                        light_position[0] = -light_position[0];
 
926
                        light_position[2] = -light_position[2];
 
927
                        movelog.write(filename);
 
928
                }
 
929
 
 
930
                // Swap the players
 
931
                ChessPlayer *temp;
 
932
                temp = activePlayer;
 
933
                activePlayer = inactivePlayer;
 
934
                inactivePlayer = temp;
 
935
                oneframe = false;
 
936
                moveanimx.resetDone();
 
937
                moveanimy.resetDone();          
 
938
                firstclick = true;
 
939
        }
 
940
 
 
941
        if( showwhite ) {
 
942
                if( tablerot != 0 && tablerot < 360 )
 
943
                        tablerot += 10;
 
944
                if( tablerot > 360 )
 
945
                        tablerot = 0;
 
946
                tablerot = 0;
 
947
        } else {
 
948
                if( tablerot < 180 )
 
949
                        tablerot += 10;
 
950
                if( tablerot > 180 )
 
951
                        tablerot = 0;
 
952
                tablerot = 180;
 
953
        }
 
954
        glRotated( tablerot, 0, 1, 0 );
 
955
 
 
956
        glScaled( 7, 7, 7 );
 
957
 
 
958
        glTranslated( -3.5, 0, -3.5 );
 
959
 
 
960
        bool alternate = true;
 
961
 
 
962
 
 
963
        static int movei, movej;
 
964
        
 
965
        // This plane is drawn and then erased. The purpose is to obtain the mouse
 
966
        // coordinates, and set the stencil buffer for the reflections
 
967
        // It is exactly the same size as the board, and is in exactly the same spot
 
968
        glDisable( GL_DEPTH_TEST );     
 
969
        if( reflect ) {
 
970
                glEnable( GL_STENCIL_TEST );
 
971
                glStencilOp( GL_REPLACE, GL_REPLACE, GL_REPLACE );
 
972
                glStencilFunc( GL_ALWAYS, 1, 0xffffffff );
 
973
        }
 
974
        
 
975
        glPushMatrix();
 
976
        glTranslated( 3.5, 0, 3.5 );
 
977
        
 
978
        glBegin( GL_QUADS );
 
979
        glNormal3d( 0, 7, 0 );
 
980
        glVertex3d( -(8*0.5+0.1), 0,  (8*0.5+0.1) );
 
981
        glVertex3d(  (8*0.5+0.1), 0,  (8*0.5+0.1) );
 
982
        glVertex3d(  (8*0.5+0.1), 0, -(8*0.5+0.1) );
 
983
        glVertex3d( -(8*0.5+0.1), 0, -(8*0.5+0.1) );
 
984
 
 
985
        // White side.
 
986
        glVertex3d( -4.2, -0.075,  4.2 );
 
987
        glVertex3d(  4.2, -0.075,  4.2 );
 
988
        glVertex3d(  4.1, -0.075,  4.1 );
 
989
        glVertex3d( -4.1, -0.075,  4.1 );
 
990
 
 
991
        // Right of white side.
 
992
        glVertex3d( -4.2, -0.075, -4.2 );
 
993
        glVertex3d( -4.2, -0.075,  4.2 );
 
994
        glVertex3d( -4.1, -0.075,  4.1 );
 
995
        glVertex3d( -4.1, -0.075, -4.1 );
 
996
 
 
997
        // Black side.
 
998
        glVertex3d(  4.2, -0.075, -4.2 );
 
999
        glVertex3d( -4.2, -0.075, -4.2 );
 
1000
        glVertex3d( -4.1, -0.075, -4.1 );
 
1001
        glVertex3d(  4.1, -0.075, -4.1 );
 
1002
 
 
1003
        // Left of white side.
 
1004
        glVertex3d(  4.2, -0.075,  4.2 );
 
1005
        glVertex3d(  4.2, -0.075, -4.2 );
 
1006
        glVertex3d(  4.1, -0.075, -4.1 );
 
1007
        glVertex3d(  4.1, -0.075,  4.1 );
 
1008
 
 
1009
        glEnd();
 
1010
        
 
1011
        // Draw the plane through the board so the mouse moves right off the board
 
1012
        // Will need to be tweaked a bit if the viewport changes, turn color writing
 
1013
        // on to see the plane, make sure it covers the whole viewport
 
1014
        glEnable( GL_DEPTH_TEST );      
 
1015
        if(reflect) {
 
1016
                glDisable( GL_STENCIL_TEST );
 
1017
        }
 
1018
        glBegin( GL_QUADS );
 
1019
        glNormal3d( 0, 7, 0 );
 
1020
        glVertex3d( -30*0.5, 0,  9*0.5 );
 
1021
        glVertex3d(  30*0.5, 0,  9*0.5 );
 
1022
        glVertex3d(  30*0.5, 0, -34*0.5 );
 
1023
        glVertex3d( -30*0.5, 0, -34*0.5 );
 
1024
        glEnd();
 
1025
 
 
1026
        // Get the mouse position
 
1027
        glTranslated( -3.5, 0, 4.5 );
 
1028
        mouse = getMousePos( mousex, mousey, mousez );
 
1029
        glPopMatrix();
 
1030
        
 
1031
        // OK to draw to the color buffer again
 
1032
        glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
 
1033
        
 
1034
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
1035
 
 
1036
        if( reflect ) {
 
1037
                // Only draw if the stencil buffer has a 1 here
 
1038
                glEnable( GL_STENCIL_TEST );
 
1039
                glStencilFunc( GL_EQUAL, 1, 0xffffffff );
 
1040
                glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
 
1041
                // Invert over the board plane
 
1042
                glScalef( 1, -1, 1 );
 
1043
                glCullFace(GL_FRONT);
 
1044
        
 
1045
                // The lighting is actually wrong here, need to fix it
 
1046
                glLightfv(GL_LIGHT0, GL_POSITION, light_position);
 
1047
        
 
1048
                // Draw the reflected pieces
 
1049
                drawBoard( test, white, mouse.getStartx(), mouse.getStarty(),
 
1050
                                                        activePlayer->requiresInput(), firstclick, movei,
 
1051
                                                        movej, moveanimx, moveanimy, mousex, mousez );  
 
1052
        
 
1053
                // Return to normal (not inverted)
 
1054
                glCullFace(GL_BACK);
 
1055
                glScalef( 1, -1, 1 );
 
1056
                glLightfv(GL_LIGHT0, GL_POSITION, light_position);
 
1057
        
 
1058
                // Draw the board squares
 
1059
                glDisable( GL_STENCIL_TEST );
 
1060
        }
 
1061
        glEnable( GL_BLEND );
 
1062
        //glDisable( GL_LIGHTING );
 
1063
        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
 
1064
                
 
1065
        drawSquares( mouse.getStartx(), mouse.getStarty(), 
 
1066
                                        activePlayer->requiresInput() );
 
1067
        //glEnable( GL_LIGHTING );
 
1068
        glDisable( GL_BLEND );
 
1069
        
 
1070
        // Draw the "real" pieces
 
1071
        drawBoard( test, white, mouse.getStartx(), mouse.getStarty(),
 
1072
                                                activePlayer->requiresInput(), firstclick, movei, movej,
 
1073
                                                moveanimx, moveanimy, mousex, mousez );         
 
1074
 
 
1075
 
 
1076
        // Prevent glitch
 
1077
        if( moveanimx.started() )
 
1078
                moveanimx++;
 
1079
        if( moveanimy.started() )
 
1080
                moveanimy++;
 
1081
 
 
1082
        if( mouseclick[SDL_BUTTON_RIGHT] ) {
 
1083
                firstclick = true;
 
1084
                SDL_ShowCursor(SDL_ENABLE);
 
1085
                mouseclick[SDL_BUTTON_RIGHT] = false;
 
1086
        }
 
1087
 
 
1088
        if( mouseclick[SDL_BUTTON_LEFT] ) 
 
1089
        {
 
1090
                if( activePlayer->requiresInput() ) {
 
1091
                        if( firstclick ) 
 
1092
                        {
 
1093
                                Piece * undermouse = &test._board[ mouse.getStartx() ]
 
1094
                                        [ mouse.getStarty() ];
 
1095
                                if( undermouse->getUnit() != EMPTY 
 
1096
                                        && ( (undermouse->getColor() == WHITE) == white ) ) 
 
1097
                                {
 
1098
                                        move.setStart( mouse.getStartx(), mouse.getStarty() );
 
1099
                                        movei = move.getStartx();
 
1100
                                        movej = move.getStarty();
 
1101
                                        SDL_ShowCursor(SDL_DISABLE);
 
1102
                                        firstclick = false;
 
1103
                                }
 
1104
                                mouseclick[SDL_BUTTON_LEFT] = false;
 
1105
                        } 
 
1106
                        else 
 
1107
                        {
 
1108
                                move.setEnd( mouse.getStartx(), mouse.getStarty() );
 
1109
                                if( move.getStartx() != move.getEndx() 
 
1110
                                        || move.getStarty() != move.getEndy() ) 
 
1111
                                {
 
1112
                                        if( activePlayer->check_move(move, test, white)) 
 
1113
                                        {
 
1114
                                                Console::out << (white ? "White" : "Black");
 
1115
                                                Console::out << " moves " << test._board[ move.getStartx() ][ move.getStarty() ].getName() << " from " << move << endl;
 
1116
 
 
1117
                                                animmove = move;
 
1118
                                                //test.updateBoard(move);
 
1119
 
 
1120
                                                //setupMoveAnims( move, test, moveanimx, moveanimy );
 
1121
                                                moveanimx.clear();
 
1122
                                                moveanimy.clear();
 
1123
 
 
1124
                                                cout << (white ? "White" : "Black");
 
1125
                                                cout << " moves " << test._board[ move.getStartx() ][ move.getStarty() ].getName() << " from " << move << endl;
 
1126
                                                moveanimx.start();
 
1127
                                                moveanimy.start();
 
1128
                                                movelog.push(test, move);
 
1129
 
 
1130
                                                // Move valid, allow another
 
1131
                                                firstclick = true;
 
1132
                                                SDL_ShowCursor(SDL_ENABLE);
 
1133
                                        }
 
1134
                                } else {
 
1135
                                        // Clicked on same piece, deselect
 
1136
                                        firstclick = true;
 
1137
                                        SDL_ShowCursor(SDL_ENABLE);
 
1138
                                }
 
1139
                                mouseclick[SDL_BUTTON_LEFT] = false;
 
1140
                        }
 
1141
                } else {
 
1142
                        mouseclick[SDL_BUTTON_LEFT] = false;
 
1143
                }
 
1144
        }
 
1145
 
 
1146
        if( !activePlayer->requiresInput() && oneframe && !moveanimx.started() && !moveanimy.started() && !moveanimx.done() && !moveanimy.done() ) {
 
1147
                animmove = activePlayer->decide_move( test, white );
 
1148
 
 
1149
                Console::out << (white ? "White" : "Black");
 
1150
                Console::out << " moves " << test._board[ animmove.getStartx() ][ animmove.getStarty() ].getName() << " from " << animmove << endl;
 
1151
 
 
1152
 
 
1153
                setupMoveAnims( animmove, test, moveanimx, moveanimy );
 
1154
 
 
1155
                movei = animmove.getStartx();
 
1156
                movej = animmove.getStarty();
 
1157
                cout << (white ? "White" : "Black");
 
1158
                cout << " moves " << test._board[ animmove.getStartx() ][ animmove.getStarty() ].getName() << " from " << animmove << endl;
 
1159
                moveanimx.start();
 
1160
                moveanimy.start();
 
1161
                movelog.push(test, animmove);
 
1162
        }
 
1163
   
 
1164
   if( keys[SDLK_BACKQUOTE] ) {
 
1165
                Console::toggle();
 
1166
                keys[SDLK_BACKQUOTE] = false;
 
1167
        }
 
1168
 
 
1169
   // Handle console commands
 
1170
   Console::getKeyboardInput(keys);
 
1171
        string cmd = Console::fetchCommand();
 
1172
   if (cmd != "") {
 
1173
      if (cmd == "reflections 1") {
 
1174
         Console::out << "console: reflections enabled" << endl;
 
1175
         reflect = true;
 
1176
      } else if (cmd == "reflections 0") {
 
1177
         Console::out << "console: reflections disabled" << endl;
 
1178
         reflect = false;
 
1179
      } else {
 
1180
         Console::out << "console: bad command: " << cmd;
 
1181
      }
 
1182
   }
 
1183
   
 
1184
        Console::draw();
 
1185
 
 
1186
        #ifdef WIN32
 
1187
        Sleep(1);
 
1188
        #else
 
1189
        usleep(1);
 
1190
        #endif
 
1191
        
 
1192
        // Draw it to the screen. 
 
1193
    SDL_GL_SwapBuffers();
 
1194
 
 
1195
    // Gather our frames per second. 
 
1196
    Frames++;
 
1197
    int t = SDL_GetTicks();
 
1198
        if (t - T0 >= 5000) 
 
1199
        {
 
1200
                float sec = (float)((t-T0)/1000.0);
 
1201
            float fps = Frames / sec;
 
1202
                cout << Frames << " frames in "<< sec << " seconds = "<< fps << " FPS\n";
 
1203
                //Console::out << Frames << " frames in "<< sec << " seconds = "<< fps << " FPS\n";
 
1204
            T0 = t;
 
1205
            Frames = 0;
 
1206
        }
 
1207
    
 
1208
        oneframe = true;
 
1209
        
 
1210
        return true;
 
1211
}
 
1212
 
 
1213
int 
 
1214
main(int argc, char *argv[])
 
1215
/***************************************************************************
 
1216
*       MAIN
 
1217
***************************************************************************/
 
1218
{
 
1219
   // Screen Settings
 
1220
   const int   WINDOW_WIDTH  = 800;
 
1221
   const int   WINDOW_HEIGHT = 600;
 
1222
   const int   WINDOW_BPP    = 16;
 
1223
   
 
1224
   // Declares our SDL surface
 
1225
   SDL_Surface *surface;
 
1226
   
 
1227
   bool mouseb[6] = {false};
 
1228
   
 
1229
        vector<string> args;
 
1230
        for( int i = 0; i < argc; i++ )
 
1231
                args.push_back( argv[i] );
 
1232
 
 
1233
        // TODO Better commandline argument system
 
1234
        for( int i = 1; i < argc; i++ )
 
1235
                if( args[i] == "-r" )
 
1236
                        reflect = false;
 
1237
        
 
1238
    bool done = false;
 
1239
    
 
1240
        // Flags to pass to SDL_SetVideoMode.
 
1241
    int videoFlags;
 
1242
        
 
1243
        // Used to collect events. 
 
1244
    SDL_Event event;
 
1245
    
 
1246
        // This holds some info about our display.
 
1247
    const SDL_VideoInfo *videoInfo;
 
1248
    
 
1249
        // Whether or not the window is active.
 
1250
    bool isActive = true;
 
1251
 
 
1252
    // Initialize SDL.
 
1253
    if (SDL_Init(SDL_INIT_VIDEO) < 0)
 
1254
        {
 
1255
            cerr << "Video initialization faild: " << SDL_GetError() << endl;
 
1256
            Quit(1);
 
1257
        }
 
1258
 
 
1259
    // Fetch the video info.
 
1260
    videoInfo = SDL_GetVideoInfo();
 
1261
 
 
1262
    if (!videoInfo)
 
1263
        {
 
1264
                cerr << "Video query faild: " << SDL_GetError() << endl;
 
1265
                Quit(1);
 
1266
        }
 
1267
 
 
1268
    // The flags to pass to SDL_SetVideoMode.
 
1269
    videoFlags  = SDL_OPENGL;          // Enable OpenGL in SDL.
 
1270
    videoFlags |= SDL_GL_DOUBLEBUFFER; // Enable double buffering.
 
1271
    videoFlags |= SDL_HWPALETTE;       // Store the palette in hardware.
 
1272
    videoFlags |= SDL_RESIZABLE;       // Enable window resizing.
 
1273
 
 
1274
    // This checks to see if surfaces can be stored in memory.
 
1275
    if (videoInfo->hw_available)
 
1276
                videoFlags |= SDL_HWSURFACE;
 
1277
    else
 
1278
                videoFlags |= SDL_SWSURFACE;
 
1279
 
 
1280
    // This checks if hardware blits can be done.
 
1281
    if (videoInfo->blit_hw)
 
1282
                videoFlags |= SDL_HWACCEL;
 
1283
 
 
1284
    // Sets up OpenGL double buffering.
 
1285
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
 
1286
        
 
1287
        // Need some a bit for the stencil buffer
 
1288
        SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 1 );
 
1289
 
 
1290
        // Sets the string displayed as the title of the window.
 
1291
        SDL_WM_SetCaption("Brutal Chess Alpha 0.3", NULL);
 
1292
 
 
1293
    // Get a SDL surface.
 
1294
    surface = SDL_SetVideoMode(WINDOW_WIDTH,WINDOW_HEIGHT,WINDOW_BPP,videoFlags);
 
1295
 
 
1296
    // Verify there is a surface.
 
1297
    if (!surface)
 
1298
        {
 
1299
                cerr << "Video mode set failed: " << SDL_GetError() << endl;
 
1300
                Quit( 1 );
 
1301
        }
 
1302
 
 
1303
    // Initialize OpenGL.
 
1304
    initGL();
 
1305
 
 
1306
 
 
1307
        if( !FontLoader::loadFont("sans", "VeraMono.ttf", 32) )
 
1308
        {
 
1309
                cerr << "Failed to load fonts" << endl;
 
1310
        }
 
1311
 
 
1312
        if( !loadModels() )
 
1313
        {
 
1314
                cerr << "Failed to load models" << endl;
 
1315
                Quit( 1 );
 
1316
        }
 
1317
 
 
1318
        if( !TextureLoader::loadTexture( "marblehugewhite.png", "marblewhite" ) ||
 
1319
                !TextureLoader::loadTexture( "marblehugeblack.png", "marbleblack" ) )
 
1320
        {
 
1321
                cerr << "Failed to load texture" << endl;
 
1322
        }
 
1323
 
 
1324
    // Resize the initial window.
 
1325
    resizeWindow(WINDOW_WIDTH, WINDOW_HEIGHT);
 
1326
 
 
1327
    // Wait for events.
 
1328
    while (!done)
 
1329
        {
 
1330
            // Handle the events in the queue.
 
1331
 
 
1332
            while (SDL_PollEvent(&event))
 
1333
                {
 
1334
                    switch(event.type)
 
1335
                        {
 
1336
                        case SDL_MOUSEBUTTONDOWN:
 
1337
                                // Mouse button pressed
 
1338
                                mouseX = event.button.x;
 
1339
                                mouseY = event.button.y;
 
1340
                                mouseb[event.button.button] = true;
 
1341
                                mouseclick[event.button.button] = true;
 
1342
                                break;
 
1343
                        case SDL_MOUSEBUTTONUP:
 
1344
                                // Mouse button released
 
1345
                                mouseX = event.button.x;
 
1346
                                mouseY = event.button.y;
 
1347
                                mouseb[event.button.button] = false;
 
1348
                                break;
 
1349
                        case SDL_MOUSEMOTION:
 
1350
                                mouseX = event.motion.x;
 
1351
                                mouseY = event.motion.y;
 
1352
                                if(event.motion.state)
 
1353
                                {
 
1354
                                        mouseDeltaX += event.motion.xrel;
 
1355
                                        mouseDeltaY += event.motion.yrel;
 
1356
                                }
 
1357
                                break;
 
1358
                        case SDL_ACTIVEEVENT:
 
1359
                            // Something's happened with our focus. If we lost focus or we 
 
1360
                            // are iconified, we shouldn't draw the screen... Only stop 
 
1361
                            // drawing if the app is actually minimized or hidden
 
1362
                            if(   event.active.gain == 0 
 
1363
                                   && event.active.state != SDL_APPMOUSEFOCUS)
 
1364
                                        isActive = false;
 
1365
                            else
 
1366
                                        isActive = true;
 
1367
 
 
1368
                                // Track when the mouse enters and leaves the window
 
1369
                                if(   event.active.gain == 0 
 
1370
                                   && event.active.state == SDL_APPMOUSEFOCUS)
 
1371
                                        mouseOut = true;
 
1372
                                else if(   event.active.gain == 1
 
1373
                                                && event.active.state == SDL_APPMOUSEFOCUS)
 
1374
                                        mouseOut = false;
 
1375
                            break;                          
 
1376
                        case SDL_VIDEORESIZE:
 
1377
                                // Delete display lists first
 
1378
                                unbuildModels();
 
1379
                                FontLoader::unloadGL();
 
1380
                                TextureLoader::unloadGL();
 
1381
 
 
1382
                            // Handle resize event.
 
1383
                            surface = SDL_SetVideoMode(event.resize.w,event.resize.h,
 
1384
                                                                       16, videoFlags);
 
1385
                            if (!surface)
 
1386
                                {
 
1387
                                        cerr << "Could not get a surface after resize: " << SDL_GetError() << endl;
 
1388
                                    Quit( 1 );
 
1389
                                }
 
1390
                            resizeWindow(event.resize.w, event.resize.h);
 
1391
                                initGL();
 
1392
                                // Windows driver bug, pieces disappear on resize
 
1393
 
 
1394
                                buildModels();
 
1395
                                FontLoader::reload();
 
1396
                                TextureLoader::reload();
 
1397
 
 
1398
                            break;
 
1399
                        case SDL_KEYDOWN:
 
1400
                                keys[ event.key.keysym.sym ] = true;
 
1401
                                break;
 
1402
                        case SDL_KEYUP:
 
1403
                                keys[ event.key.keysym.sym ] = false;
 
1404
                                break;
 
1405
                        case SDL_QUIT:
 
1406
                            // Handle quit requests.
 
1407
                            done = true;
 
1408
                            break;
 
1409
                        default:
 
1410
                            break;
 
1411
                        }
 
1412
                }
 
1413
 
 
1414
                if( keys[SDLK_q] || keys[SDLK_ESCAPE] )
 
1415
                        done = true;
 
1416
 
 
1417
#ifndef WIN32
 
1418
                if(keys[SDLK_F2]) {
 
1419
                        //This only works with X
 
1420
                        SDL_WM_ToggleFullScreen( surface );
 
1421
                        keys[SDLK_F2]=false;
 
1422
                }
 
1423
#endif
 
1424
 
 
1425
            // Draw the scene.
 
1426
                if (isActive)
 
1427
                        drawGLScene();
 
1428
                else
 
1429
                        #ifdef WIN32
 
1430
                        Sleep(1);
 
1431
                        #else
 
1432
                        usleep(1);
 
1433
                        #endif
 
1434
        }
 
1435
 
 
1436
    // Clean ourselves up and exit.
 
1437
    Quit(0);
 
1438
 
 
1439
    // Should never get here.
 
1440
        cerr << "Shouldn't have reached this... End of brutalchess.cpp.\n";
 
1441
    return 0;
 
1442
}
 
1443
 
 
1444
// End of file brutalchess.cpp