1
/***************************************************************************
2
* Brutal Chess Alpha Build
5
* Authors: Maxwell Lazaroff, Michael Cook, and Joe Flint
6
* Date Created : May 26th, 2005
7
* Last Modified: December 19th, 2005
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
***************************************************************************/
14
// Necessary if we're in Windows so we don't get a million linker errors.
26
#include "fontloader.h"
29
#include "timerchain.h"
31
#include "textureloader.h"
34
#include "chessplayer.h"
35
#include "alphabetaplayer.h"
36
#include "humanplayer.h"
37
#include "randomplayer.h"
42
bool keys[SDLK_LAST] = { false };
45
// Currently there are only 5 SDL constants, numbered 1-5
46
bool mouseclick[6] = {false};
47
bool mouseOut = false;
49
int mouseDeltaX = 0, mouseDeltaY = 0;
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 };
58
// Storage for loaded pieces
59
ObjFile pawn, rook, knight, bishop, queen, king;
65
/***************************************************************************
68
* - Releases the resources and returns control to the desktop
69
***************************************************************************/
77
resizeWindow(int width, int height)
78
/***************************************************************************
81
* - Resizes the game window to 'width' and 'height'.
82
***************************************************************************/
84
// Protect against devide by zero
85
if (height == 0) { height = 1; }
88
aspectRatio = (float)width/(float)height;
90
// Set up our viewport.
91
glViewport(0, 0, width, height);
93
// Change to the projection matrix and set our viewing volume.
94
glMatrixMode(GL_PROJECTION);
97
// Sets our persepective.
98
gluPerspective(30.0f, aspectRatio, 0.1f, 150.0f);
99
//glOrtho( -36, 36, -27, 27, 0.1, 100 );
101
// Change to the modelview matrix and set out viewing volume.
102
glMatrixMode(GL_MODELVIEW);
111
// Build display lists for all pieces
123
// Delete display lists for all pieces
134
/***************************************************************************
137
* - Loads the models needed by the game, must be called after initGL
138
***************************************************************************/
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 );
148
// Load all of the piece models
149
if( !pawn.load( "models/pawn.obj" ) )
151
if( !knight.load( "models/knight.obj" ) )
153
if( !rook.load( "models/rook.obj" ) )
155
if( !bishop.load( "models/bishop.obj" ) )
157
if( !queen.load( "models/queen.obj" ) )
159
if( !king.load( "models/king.obj" ) )
162
// Generate smooth normals for the models
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() );
186
/***************************************************************************
189
* - Initializes GL settings.
190
***************************************************************************/
192
// Enable smooth shading.
193
glShadeModel(GL_SMOOTH);
195
// Set the background color to black.
196
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
198
// Depth buffer setup.
201
// Enables Depth Testing
202
glEnable(GL_DEPTH_TEST);
204
// The Type Of Depth Test To Do
205
glDepthFunc(GL_LEQUAL);
207
// Really Nice Perspective Calculations
208
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
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);
221
glEnable( GL_CULL_FACE );
223
//glEnable( GL_NORMALIZE );
229
getMousePos(double & mx, double & my, double & mz)
231
GLdouble mvmatrix[16];
232
GLdouble pjmatrix[16];
235
// Get the current setup.
236
glGetDoublev( GL_MODELVIEW_MATRIX, mvmatrix );
237
glGetDoublev( GL_PROJECTION_MATRIX, pjmatrix );
238
glGetIntegerv( GL_VIEWPORT, viewport );
240
// Y Coordinate must be measured from the bottom of the window.
241
int mouseycorr = viewport[3] - mouseY;
246
glReadPixels( mouseX, mouseycorr, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
248
gluUnProject( mouseX, mouseycorr, depth, mvmatrix, pjmatrix, viewport,
259
return BoardMove( 9, 9, 9, 9 );
262
int boardy = (int)floor( x );
263
int boardx = 8 + (int)floor( z );
265
if( boardx >= 0 && boardx < 8 && boardy >= 0 && boardy < 8 )
266
return BoardMove( boardx, boardy, 9, 9 );
268
return BoardMove( 9, 9, 9, 9 );
273
return ( i >= 0 ) ? 1 : -1;
277
setupMoveAnims( const BoardMove & move, const Board & board, TimerChain & chainx, TimerChain & chainy )
281
deltax = int( move.getEndx() ) - int( move.getStartx() );
282
deltay = int( move.getEndy() ) - int( move.getStarty() );
284
Timer temp, temp2( Timer::LOGARITHMIC );
285
temp2.setDuration( 0.5 );
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)) );
296
temp.setRange( 0, 0 );
298
temp2.setRange( 0, 0 );
301
temp.setRange( 0, deltay - sign(deltay)*0.5 );
303
temp2.setRange( deltay - sign(deltay)*0.5, deltay );
308
temp.setRange( 0, 0 );
310
temp2.setRange( 0, 0 );
313
temp.setRange( 0, deltax - sign(deltax)*0.5 );
315
temp2.setRange( deltax - sign(deltax)*0.5, deltax );
319
temp.setDuration( 0.25*1.0 );
321
// Always move along the short side first
322
if( abs( deltax ) < abs( deltay ) ) {
323
// Move along short side
324
temp.setRange( 0, 0 );
327
temp.setRange( 0, deltax );
330
// Move along long side
331
temp.setDuration( 0.25*1.5 );
333
temp.setRange( deltax, deltax );
336
temp.setRange( 0, deltay - sign(deltay)*0.5 );
339
temp2.setRange( deltax, deltax );
342
temp2.setRange( deltay - sign(deltay)*0.5, deltay );
346
// Move along short side
347
temp.setRange( 0, 0 );
350
temp.setRange( 0, deltay );
353
// Move along long side
354
temp.setDuration( 0.25*1.5 );
356
temp.setRange( deltay, deltay );
359
temp.setRange( 0, deltax - sign(deltax)*0.5 );
362
temp2.setRange( deltay, deltay );
365
temp2.setRange( deltax - sign(deltax)*0.5, deltax );
374
glEnable( GL_LIGHTING );
376
// Move back to the center of the board.
377
glTranslated( 3.5, 0, -4.5 );
379
// Select the edgestyle to be used.
386
glColor3d( 0.3, 0.3, 0.3 );
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 );
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 );
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 );
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 );
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 );
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 );
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 );
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 );
438
else if (edgestyle == 2)
442
// Darker of the edge colors.
443
glColor4d( 0.2, 0.2, 0.2, 0.95 );
445
glNormal3d( 0, 7, 0);
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 );
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 );
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 );
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 );
471
glColor3d( 0.2, 0.2, 0.2 );
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 );
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 );
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 );
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 );
498
// Now draw the outer border in light gray.
499
glColor4d( 0.45, 0.45, 0.45, 0.95 );
501
glNormal3d( 0, 7, 0 );
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 );
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 );
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 );
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 );
527
glColor3d( 0.45, 0.45, 0.45 );
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 );
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 );
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 );
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 );
561
drawSquares( uint mousex, uint mousey, bool allowselect )
563
static double alpha[8][8] = { 0 };
564
static Timer alphatimers[8][8];
568
bool alternate = true;
570
glEnable( GL_TEXTURE_2D );
572
/*if( !TextureLoader::setTexture( "marblewhite" ) )
573
cerr << "Failed to find texture" << endl;*/
577
for( int i = 0; i < 8; i++ ) {
578
for( int j = 0; j < 8; j++ ) {
580
bool selected = i == mousex && j == mousey;
582
if( alphatimers[i][j].started() ) {
584
alpha[i][j] += alphatimers[i][j].change();
587
// !noselection && activePlayer->requiresInput()
588
if( selected && allowselect ) {
590
alphatimers[i][j].stop();
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();
601
TextureLoader::setTexture( "marblewhite" );
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;
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 );
624
if( alpha[i][j] != 0 ) {
625
glDisable( GL_TEXTURE_2D );
626
glDisable( GL_DEPTH_TEST );
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 );
635
glEnable( GL_DEPTH_TEST );
636
glEnable( GL_TEXTURE_2D );
641
glTranslated( 1, 0, 0 );
643
glTranslated( -8, 0, 1 );
644
alternate = !alternate;
647
glDisable( GL_TEXTURE_2D );
655
drawPiece( Unit whichpiece, bool reverse )
658
glRotated( 180, 0, 1, 0 );
659
glScaled( 1/7.0, 1/7.0, 1/7.0 );
660
switch( whichpiece ) {
665
glRotated( 90, 0, 1, 0 );
667
glRotated( -90, 0, 1, 0 );
670
glRotated( 180, 0, 1, 0 );
672
glRotated( 180, 0, -1, 0 );
681
/*if( board.inDanger( board._board[ i ][ j ].getColor() == WHITE, i, j ) )
682
glColor3d( 0.5, 0, 0 );*/
689
glRotated( 180, 0, -1, 0 );
693
dist( double x1, double y1, double x2, double y2 )
695
return sqrt( (x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2) );
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 )
705
static double height[8][8] = { 0 };
706
static Timer timers[8][8];
710
if( board._board[ movei ][ movej ].getColor() == WHITE )
711
glColor3d( 0.7, 0.7, 0.7 );
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);
722
for( int i = 0; i < 8; i++ ) {
723
for( int j = 0; j < 8; j++ ) {
726
glTranslated( 0, height[i][j], 0 );
728
if( movei == i && movej == j
729
&& ( moveanimx.started() || moveanimy.started() ) ) {
730
glTranslated( moveanimx.value(), 0, moveanimy.value() );
735
if( !firstclick && mousei == i && mousej == j)
736
alpha = 0.2 + dist( mousex, mousez, j, i )/0.5*0.8;
738
// Sets the piece render color.
739
if( board._board[ i ][ j ].getColor() == WHITE )
740
glColor4d( 0.7, 0.7, 0.7, alpha );
742
glColor4d( 0.2, 0.2, 0.2, alpha );
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
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 );
757
glEnable( GL_BLEND );
758
drawPiece( board._board[ i ][ j ].getUnit(), board._board[ i ][ j ].getColor() == WHITE );
760
glDisable( GL_BLEND );
764
if( movei == i && movej == j
765
&& ( moveanimx.started() || moveanimy.started() ) ) {
766
glTranslated( -moveanimx.value(), 0, -moveanimy.value() );
769
glTranslated( 1, -height[i][j], 0 );
771
if( timers[i][j].started() ) {
773
height[i][j] += timers[i][j].change();
775
if ( timers[i][j].done() ) {
776
height[i][j] = timers[i][j].end();
777
timers[i][j].resetDone();
780
static bool bounceup = true;
781
if( board._board[i][j].getUnit() != EMPTY ) {
782
if( !firstclick && i == movei && j == movej ) {
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();
790
if( height[i][j] >= 0.4 ) {
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();
801
if( height[i][j] <= 0.2 ) {
806
} else if( firstclick && i == mousei && j == mousej &&
807
(board._board[i][j].getColor() == WHITE) == white &&
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();
815
if( height[i][j] < 0.2 ) {
820
if( 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();
835
glTranslated( -8, 0, 1 );
842
/***************************************************************************
845
* - Handles the drawing of a frame.
846
***************************************************************************/
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 );
854
// Creating our players.
855
static ChessPlayer *playOne = new HumanPlayer;
856
static ChessPlayer *playTwo = new AlphaBetaPlayer;
858
// Setting player 1 to the active player.
859
static ChessPlayer *activePlayer = playOne;
860
static ChessPlayer *inactivePlayer = playTwo;
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;
868
// These are to calculate our fps.
870
static int Frames = 0;
872
// Clear The Screen And The Depth Buffer.
873
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
877
glTranslated( 0, 0, -106 );
879
glRotated( 42, 1, 0, 0 );
882
static BoardMove animmove;
883
static TimerChain moveanimx, moveanimy;
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 );
891
movelog.write(filename);
893
if (inactivePlayer->inCheckmate(test, white))
895
Console::out << inactivePlayer->getName() << " in Checkmate!\n";
896
Console::out << activePlayer->getName() << " wins!\n";
902
activePlayer = inactivePlayer;
903
inactivePlayer = temp;
906
light_position[0] = -light_position[0];
907
light_position[2] = -light_position[2];
908
showwhite = !showwhite;
909
movelog.write(filename);
911
else if(inactivePlayer->inStalemate(test, white))
913
Console::out << "The game ended in a stalemate caused";
914
Console::out << " by " << inactivePlayer->getName() << "!\n";
920
activePlayer = inactivePlayer;
921
inactivePlayer = temp;
924
showwhite = !showwhite;
925
light_position[0] = -light_position[0];
926
light_position[2] = -light_position[2];
927
movelog.write(filename);
933
activePlayer = inactivePlayer;
934
inactivePlayer = temp;
936
moveanimx.resetDone();
937
moveanimy.resetDone();
942
if( tablerot != 0 && tablerot < 360 )
954
glRotated( tablerot, 0, 1, 0 );
958
glTranslated( -3.5, 0, -3.5 );
960
bool alternate = true;
963
static int movei, movej;
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 );
970
glEnable( GL_STENCIL_TEST );
971
glStencilOp( GL_REPLACE, GL_REPLACE, GL_REPLACE );
972
glStencilFunc( GL_ALWAYS, 1, 0xffffffff );
976
glTranslated( 3.5, 0, 3.5 );
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) );
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 );
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 );
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 );
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 );
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 );
1016
glDisable( GL_STENCIL_TEST );
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 );
1026
// Get the mouse position
1027
glTranslated( -3.5, 0, 4.5 );
1028
mouse = getMousePos( mousex, mousey, mousez );
1031
// OK to draw to the color buffer again
1032
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
1034
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
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);
1045
// The lighting is actually wrong here, need to fix it
1046
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
1048
// Draw the reflected pieces
1049
drawBoard( test, white, mouse.getStartx(), mouse.getStarty(),
1050
activePlayer->requiresInput(), firstclick, movei,
1051
movej, moveanimx, moveanimy, mousex, mousez );
1053
// Return to normal (not inverted)
1054
glCullFace(GL_BACK);
1055
glScalef( 1, -1, 1 );
1056
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
1058
// Draw the board squares
1059
glDisable( GL_STENCIL_TEST );
1061
glEnable( GL_BLEND );
1062
//glDisable( GL_LIGHTING );
1063
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
1065
drawSquares( mouse.getStartx(), mouse.getStarty(),
1066
activePlayer->requiresInput() );
1067
//glEnable( GL_LIGHTING );
1068
glDisable( GL_BLEND );
1070
// Draw the "real" pieces
1071
drawBoard( test, white, mouse.getStartx(), mouse.getStarty(),
1072
activePlayer->requiresInput(), firstclick, movei, movej,
1073
moveanimx, moveanimy, mousex, mousez );
1077
if( moveanimx.started() )
1079
if( moveanimy.started() )
1082
if( mouseclick[SDL_BUTTON_RIGHT] ) {
1084
SDL_ShowCursor(SDL_ENABLE);
1085
mouseclick[SDL_BUTTON_RIGHT] = false;
1088
if( mouseclick[SDL_BUTTON_LEFT] )
1090
if( activePlayer->requiresInput() ) {
1093
Piece * undermouse = &test._board[ mouse.getStartx() ]
1094
[ mouse.getStarty() ];
1095
if( undermouse->getUnit() != EMPTY
1096
&& ( (undermouse->getColor() == WHITE) == white ) )
1098
move.setStart( mouse.getStartx(), mouse.getStarty() );
1099
movei = move.getStartx();
1100
movej = move.getStarty();
1101
SDL_ShowCursor(SDL_DISABLE);
1104
mouseclick[SDL_BUTTON_LEFT] = false;
1108
move.setEnd( mouse.getStartx(), mouse.getStarty() );
1109
if( move.getStartx() != move.getEndx()
1110
|| move.getStarty() != move.getEndy() )
1112
if( activePlayer->check_move(move, test, white))
1114
Console::out << (white ? "White" : "Black");
1115
Console::out << " moves " << test._board[ move.getStartx() ][ move.getStarty() ].getName() << " from " << move << endl;
1118
//test.updateBoard(move);
1120
//setupMoveAnims( move, test, moveanimx, moveanimy );
1124
cout << (white ? "White" : "Black");
1125
cout << " moves " << test._board[ move.getStartx() ][ move.getStarty() ].getName() << " from " << move << endl;
1128
movelog.push(test, move);
1130
// Move valid, allow another
1132
SDL_ShowCursor(SDL_ENABLE);
1135
// Clicked on same piece, deselect
1137
SDL_ShowCursor(SDL_ENABLE);
1139
mouseclick[SDL_BUTTON_LEFT] = false;
1142
mouseclick[SDL_BUTTON_LEFT] = false;
1146
if( !activePlayer->requiresInput() && oneframe && !moveanimx.started() && !moveanimy.started() && !moveanimx.done() && !moveanimy.done() ) {
1147
animmove = activePlayer->decide_move( test, white );
1149
Console::out << (white ? "White" : "Black");
1150
Console::out << " moves " << test._board[ animmove.getStartx() ][ animmove.getStarty() ].getName() << " from " << animmove << endl;
1153
setupMoveAnims( animmove, test, moveanimx, moveanimy );
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;
1161
movelog.push(test, animmove);
1164
if( keys[SDLK_BACKQUOTE] ) {
1166
keys[SDLK_BACKQUOTE] = false;
1169
// Handle console commands
1170
Console::getKeyboardInput(keys);
1171
string cmd = Console::fetchCommand();
1173
if (cmd == "reflections 1") {
1174
Console::out << "console: reflections enabled" << endl;
1176
} else if (cmd == "reflections 0") {
1177
Console::out << "console: reflections disabled" << endl;
1180
Console::out << "console: bad command: " << cmd;
1192
// Draw it to the screen.
1193
SDL_GL_SwapBuffers();
1195
// Gather our frames per second.
1197
int t = SDL_GetTicks();
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";
1214
main(int argc, char *argv[])
1215
/***************************************************************************
1217
***************************************************************************/
1220
const int WINDOW_WIDTH = 800;
1221
const int WINDOW_HEIGHT = 600;
1222
const int WINDOW_BPP = 16;
1224
// Declares our SDL surface
1225
SDL_Surface *surface;
1227
bool mouseb[6] = {false};
1229
vector<string> args;
1230
for( int i = 0; i < argc; i++ )
1231
args.push_back( argv[i] );
1233
// TODO Better commandline argument system
1234
for( int i = 1; i < argc; i++ )
1235
if( args[i] == "-r" )
1240
// Flags to pass to SDL_SetVideoMode.
1243
// Used to collect events.
1246
// This holds some info about our display.
1247
const SDL_VideoInfo *videoInfo;
1249
// Whether or not the window is active.
1250
bool isActive = true;
1253
if (SDL_Init(SDL_INIT_VIDEO) < 0)
1255
cerr << "Video initialization faild: " << SDL_GetError() << endl;
1259
// Fetch the video info.
1260
videoInfo = SDL_GetVideoInfo();
1264
cerr << "Video query faild: " << SDL_GetError() << endl;
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.
1274
// This checks to see if surfaces can be stored in memory.
1275
if (videoInfo->hw_available)
1276
videoFlags |= SDL_HWSURFACE;
1278
videoFlags |= SDL_SWSURFACE;
1280
// This checks if hardware blits can be done.
1281
if (videoInfo->blit_hw)
1282
videoFlags |= SDL_HWACCEL;
1284
// Sets up OpenGL double buffering.
1285
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
1287
// Need some a bit for the stencil buffer
1288
SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 1 );
1290
// Sets the string displayed as the title of the window.
1291
SDL_WM_SetCaption("Brutal Chess Alpha 0.3", NULL);
1293
// Get a SDL surface.
1294
surface = SDL_SetVideoMode(WINDOW_WIDTH,WINDOW_HEIGHT,WINDOW_BPP,videoFlags);
1296
// Verify there is a surface.
1299
cerr << "Video mode set failed: " << SDL_GetError() << endl;
1303
// Initialize OpenGL.
1307
if( !FontLoader::loadFont("sans", "VeraMono.ttf", 32) )
1309
cerr << "Failed to load fonts" << endl;
1314
cerr << "Failed to load models" << endl;
1318
if( !TextureLoader::loadTexture( "marblehugewhite.png", "marblewhite" ) ||
1319
!TextureLoader::loadTexture( "marblehugeblack.png", "marbleblack" ) )
1321
cerr << "Failed to load texture" << endl;
1324
// Resize the initial window.
1325
resizeWindow(WINDOW_WIDTH, WINDOW_HEIGHT);
1330
// Handle the events in the queue.
1332
while (SDL_PollEvent(&event))
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;
1343
case SDL_MOUSEBUTTONUP:
1344
// Mouse button released
1345
mouseX = event.button.x;
1346
mouseY = event.button.y;
1347
mouseb[event.button.button] = false;
1349
case SDL_MOUSEMOTION:
1350
mouseX = event.motion.x;
1351
mouseY = event.motion.y;
1352
if(event.motion.state)
1354
mouseDeltaX += event.motion.xrel;
1355
mouseDeltaY += event.motion.yrel;
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)
1368
// Track when the mouse enters and leaves the window
1369
if( event.active.gain == 0
1370
&& event.active.state == SDL_APPMOUSEFOCUS)
1372
else if( event.active.gain == 1
1373
&& event.active.state == SDL_APPMOUSEFOCUS)
1376
case SDL_VIDEORESIZE:
1377
// Delete display lists first
1379
FontLoader::unloadGL();
1380
TextureLoader::unloadGL();
1382
// Handle resize event.
1383
surface = SDL_SetVideoMode(event.resize.w,event.resize.h,
1387
cerr << "Could not get a surface after resize: " << SDL_GetError() << endl;
1390
resizeWindow(event.resize.w, event.resize.h);
1392
// Windows driver bug, pieces disappear on resize
1395
FontLoader::reload();
1396
TextureLoader::reload();
1400
keys[ event.key.keysym.sym ] = true;
1403
keys[ event.key.keysym.sym ] = false;
1406
// Handle quit requests.
1414
if( keys[SDLK_q] || keys[SDLK_ESCAPE] )
1419
//This only works with X
1420
SDL_WM_ToggleFullScreen( surface );
1421
keys[SDLK_F2]=false;
1436
// Clean ourselves up and exit.
1439
// Should never get here.
1440
cerr << "Shouldn't have reached this... End of brutalchess.cpp.\n";
1444
// End of file brutalchess.cpp