3 * plays through a chess game ending. enjoy.
5 * version 1.0 - June 6, 2002
7 * Copyright (C) 2002 Blair Tennessy (tennessb@unbc.ca)
9 * Permission to use, copy, modify, distribute, and sell this software and its
10 * documentation for any purpose is hereby granted without fee, provided that
11 * the above copyright notice appear in all copies and that both that
12 * copyright notice and this permission notice appear in supporting
13 * documentation. No representations are made about the suitability of this
14 * software for any purpose. It is provided "as is" without express or
19 #define DEFAULTS "*delay: 20000 \n" \
20 "*showFPS: False \n" \
21 "*wireframe: False \n" \
23 # define refresh_chess 0
24 # include "xlockmore.h"
35 #include "gltrackball.h"
36 #include "chessmodels.h"
37 #include "chessgames.h"
40 #define countof(x) (sizeof((x))/sizeof((*x)))
42 static XrmOptionDescRec opts[] = {
43 {"+rotate", ".chess.rotate", XrmoptionNoArg, "false" },
44 {"-rotate", ".chess.rotate", XrmoptionNoArg, "true" },
45 {"+reflections", ".chess.reflections", XrmoptionNoArg, "false" },
46 {"-reflections", ".chess.reflections", XrmoptionNoArg, "true" },
47 {"+shadows", ".chess.shadows", XrmoptionNoArg, "false" },
48 {"-shadows", ".chess.shadows", XrmoptionNoArg, "true" },
49 {"+smooth", ".chess.smooth", XrmoptionNoArg, "false" },
50 {"-smooth", ".chess.smooth", XrmoptionNoArg, "true" },
51 {"+classic", ".chess.classic", XrmoptionNoArg, "false" },
52 {"-classic", ".chess.classic", XrmoptionNoArg, "true" },
55 static int rotate, reflections, smooth, shadows, classic;
57 static argtype vars[] = {
58 {&rotate, "rotate", "Rotate", "True", t_Bool},
59 {&reflections, "reflections", "Reflections", "True", t_Bool},
60 {&shadows, "shadows", "Shadows", "True", t_Bool},
61 {&smooth, "smooth", "Smooth", "True", t_Bool},
62 {&classic, "classic", "Classic", "False", t_Bool},
65 ENTRYPOINT ModeSpecOpt chess_opts = {countof(opts), opts, countof(vars), vars, NULL};
68 ModStruct chess_description =
69 {"chess", "init_chess", "draw_chess", "release_chess",
70 "draw_chess", "init_chess", NULL, &chess_opts,
71 1000, 1, 2, 1, 4, 1.0, "",
76 #define checkImageWidth 16
77 #define checkImageHeight 16
80 GLXContext *glx_context;
82 trackball_state *trackball;
88 /** definition of white/black (orange/gray) colors */
91 GLubyte checkImage[checkImageWidth][checkImageHeight][3];
92 GLuint piecetexture, boardtexture;
94 int mpiece, tpiece, steps, done;
95 double from[2], to[2];
97 int moving, take, mc, count, wire;
101 GLfloat position2[4];
109 int poly_counts[PIECES]; /* polygon count of each type of piece */
114 static Chesscreen *qs = NULL;
116 static const GLfloat MaterialShadow[] = {0.0, 0.0, 0.0, 0.3};
119 /* i prefer silvertip */
120 static const GLfloat whites[WHITES][3] =
129 static void build_colors(Chesscreen *cs)
133 int newwhite = cs->oldwhite;
134 while(newwhite == cs->oldwhite)
135 newwhite = random()%WHITES;
136 cs->oldwhite = newwhite;
138 cs->colors[0][0] = whites[cs->oldwhite][0];
139 cs->colors[0][1] = whites[cs->oldwhite][1];
140 cs->colors[0][2] = whites[cs->oldwhite][2];
143 /* build piece texture */
144 static void make_piece_texture(Chesscreen *cs)
148 for (i = 0; i < checkImageWidth; i++) {
149 for (j = 0; j < checkImageHeight; j++) {
150 c = ((j%2) == 0 || i%2 == 0) ? 240 : 180+random()%16;
151 cs->checkImage[i][j][0] = (GLubyte) c;
152 cs->checkImage[i][j][1] = (GLubyte) c;
153 cs->checkImage[i][j][2] = (GLubyte) c;
157 glGenTextures(1, &cs->piecetexture);
158 glBindTexture(GL_TEXTURE_2D, cs->piecetexture);
160 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
161 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
162 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
163 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
164 glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth,
165 checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,
166 &cs->checkImage[0][0]);
169 /* build board texture (uniform noise in [180,180+50]) */
170 static void make_board_texture(Chesscreen *cs)
174 for (i = 0; i < checkImageWidth; i++) {
175 for (j = 0; j < checkImageHeight; j++) {
176 c = 180 + random()%51;
177 cs->checkImage[i][j][0] = (GLubyte) c;
178 cs->checkImage[i][j][1] = (GLubyte) c;
179 cs->checkImage[i][j][2] = (GLubyte) c;
183 glGenTextures(1, &cs->boardtexture);
184 glBindTexture(GL_TEXTURE_2D, cs->boardtexture);
186 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
187 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
188 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
189 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
190 glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth,
191 checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,
192 &cs->checkImage[0][0]);
195 /** handle X event (trackball) */
196 ENTRYPOINT Bool chess_handle_event (ModeInfo *mi, XEvent *event)
198 Chesscreen *cs = &qs[MI_SCREEN(mi)];
200 if(event->xany.type == ButtonPress && event->xbutton.button == Button1) {
201 cs->button_down_p = True;
202 gltrackball_start (cs->trackball,
203 event->xbutton.x, event->xbutton.y,
204 MI_WIDTH (mi), MI_HEIGHT (mi));
207 else if(event->xany.type == ButtonRelease
208 && event->xbutton.button == Button1) {
209 cs->button_down_p = False;
212 else if (event->xany.type == ButtonPress &&
213 (event->xbutton.button == Button4 ||
214 event->xbutton.button == Button5))
216 gltrackball_mousewheel (cs->trackball, event->xbutton.button, 5,
217 !event->xbutton.state);
220 else if(event->xany.type == MotionNotify && cs->button_down_p) {
221 gltrackball_track (cs->trackball,
222 event->xmotion.x, event->xmotion.y,
223 MI_WIDTH (mi), MI_HEIGHT (mi));
230 static const GLfloat diffuse2[] = {1.0, 1.0, 1.0, 1.0};
231 /*static const GLfloat ambient2[] = {0.7, 0.7, 0.7, 1.0};*/
232 static const GLfloat shininess[] = {60.0};
233 static const GLfloat specular[] = {0.4, 0.4, 0.4, 1.0};
235 /* configure lighting */
236 static void setup_lights(Chesscreen *cs)
238 glEnable(GL_LIGHTING);
239 glLightfv(GL_LIGHT0, GL_POSITION, cs->position);
240 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse2);
243 /* glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient2); */
245 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
246 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
248 glLightfv(GL_LIGHT1, GL_SPECULAR, diffuse2);
249 glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse2);
254 static void drawPieces(ModeInfo *mi, Chesscreen *cs)
258 for(i = 0; i < BOARDSIZE; ++i) {
259 for(j = 0; j < BOARDSIZE; ++j) {
260 if(cs->game.board[i][j]) {
261 int c = cs->game.board[i][j]/PIECES;
262 glColor3fv(cs->colors[c]);
263 glCallList(cs->game.board[i][j]%PIECES);
264 mi->polygon_count += cs->poly_counts[cs->game.board[i][j]%PIECES];
267 glTranslatef(1.0, 0.0, 0.0);
270 glTranslatef(-1.0*BOARDSIZE, 0.0, 1.0);
273 glTranslatef(0.0, 0.0, -1.0*BOARDSIZE);
277 static void drawPiecesShadow(ModeInfo *mi, Chesscreen *cs)
281 for(i = 0; i < BOARDSIZE; ++i) {
282 for(j = 0; j < BOARDSIZE; ++j) {
283 if(cs->game.board[i][j]) {
284 glColor4f(0.0, 0.0, 0.0, 0.4);
285 glCallList(cs->game.board[i][j]%PIECES);
286 mi->polygon_count += cs->poly_counts[cs->game.board[i][j]%PIECES];
289 glTranslatef(1.0, 0.0, 0.0);
292 glTranslatef(-1.0*BOARDSIZE, 0.0, 1.0);
295 glTranslatef(0.0, 0.0, -1.0*BOARDSIZE);
298 /* draw a moving piece */
299 static void drawMovingPiece(ModeInfo *mi, Chesscreen *cs, int shadow)
301 int piece = cs->mpiece % PIECES;
305 if(shadow) glColor4fv(MaterialShadow);
306 else glColor3fv(cs->colors[cs->mpiece/PIECES]);
308 /** assume a queening. should be more general */
309 if((cs->mpiece == PAWN && fabs(cs->to[0]) < 0.01) ||
310 (cs->mpiece == BPAWN && fabs(cs->to[0]-7.0) < 0.01)) {
311 glTranslatef(cs->from[1]+cs->steps*cs->dx, 0.0, cs->from[0]+cs->steps*cs->dz);
313 glColor4f(shadow ? MaterialShadow[0] : cs->colors[cs->mpiece/7][0],
314 shadow ? MaterialShadow[1] : cs->colors[cs->mpiece/7][1],
315 shadow ? MaterialShadow[2] : cs->colors[cs->mpiece/7][2],
316 (fabs(50.0-cs->steps))/50.0);
318 piece = cs->steps < 50 ? PAWN : QUEEN;
322 cs->mpiece = cs->mpiece == PAWN ? QUEEN : BQUEEN;
324 else if(cs->mpiece % PIECES == KNIGHT) {
328 glTranslatef(cs->steps < 50 ? cs->from[1] : cs->to[1], 0.0,
329 cs->steps < 50 ? cs->from[0] : cs->to[0]);
331 mult = cs->steps < 10
332 ? (1.0 - cs->steps / 10.0) : 100 - cs->steps < 10
333 ? (1.0 - (100 - cs->steps) / 10.0) : 0.0;
335 shine[0] = mult*shininess[0];
336 spec[0] = mult*specular[0];
337 spec[1] = mult*specular[1];
338 spec[2] = mult*specular[2];
340 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shine);
341 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
343 glColor4f(shadow ? MaterialShadow[0] : cs->colors[cs->mpiece/7][0],
344 shadow ? MaterialShadow[1] : cs->colors[cs->mpiece/7][1],
345 shadow ? MaterialShadow[2] : cs->colors[cs->mpiece/7][2],
346 fabs(49-cs->steps)/49.0);
348 glScalef(fabs(49-cs->steps)/49.0, fabs(49-cs->steps)/49.0, fabs(49-cs->steps)/49.0);
351 glTranslatef(cs->from[1]+cs->steps*cs->dx, 0.0, cs->from[0]+cs->steps*cs->dz);
357 mi->polygon_count += cs->poly_counts[cs->mpiece % PIECES];
359 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
360 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
368 /** code to squish a taken piece */
369 static void drawTakePiece(ModeInfo *mi, Chesscreen *cs, int shadow)
374 glColor4f(shadow ? MaterialShadow[0] : cs->colors[cs->tpiece/7][0],
375 shadow ? MaterialShadow[1] : cs->colors[cs->tpiece/7][1],
376 shadow ? MaterialShadow[0] : cs->colors[cs->tpiece/7][2],
377 (100-1.6*cs->steps)/100.0);
379 glTranslatef(cs->to[1], 0.0, cs->to[0]);
381 if(cs->mpiece % PIECES == KNIGHT)
382 glScalef(1.0+cs->steps/100.0, 1.0, 1.0+cs->steps/100.0);
384 glScalef(1.0, 1 - cs->steps/50.0 > 0.01 ? 1 - cs->steps/50.0 : 0.01, 1.0);
385 glCallList(cs->tpiece % 7);
386 mi->polygon_count += cs->poly_counts[cs->tpiece % PIECES];
393 static void drawBoard(ModeInfo *mi, Chesscreen *cs)
399 for(i = 0; i < BOARDSIZE; ++i)
400 for(j = 0; j < BOARDSIZE; ++j) {
401 double ma1 = (i+j)%2 == 0 ? cs->mod*i : 0.0;
402 double mb1 = (i+j)%2 == 0 ? cs->mod*j : 0.0;
403 double ma2 = (i+j)%2 == 0 ? cs->mod*(i+1.0) : 0.01;
404 double mb2 = (i+j)%2 == 0 ? cs->mod*(j+1.0) : 0.01;
406 /*glColor3fv(colors[(i+j)%2]);*/
407 glColor4f(cs->colors[(i+j)%2][0], cs->colors[(i+j)%2][1],
408 cs->colors[(i+j)%2][2], 0.65);
410 glNormal3f(0.0, 1.0, 0.0);
411 /* glTexCoord2f(mod*i, mod*(j+1.0)); */
412 glTexCoord2f(ma1, mb2);
413 glVertex3f(i, 0.0, j + 1.0);
414 /* glTexCoord2f(mod*(i+1.0), mod*(j+1.0)); */
415 glTexCoord2f(ma2, mb2);
416 glVertex3f(i + 1.0, 0.0, j + 1.0);
417 glTexCoord2f(ma2, mb1);
418 /* glTexCoord2f(mod*(i+1.0), mod*j); */
419 glVertex3f(i + 1.0, 0.0, j);
420 glTexCoord2f(ma1, mb1);
421 /* glTexCoord2f(mod*i, mod*j); */
422 glVertex3f(i, 0.0, j);
427 /* chop underneath board */
428 /* glColor3f(0, 0, 0); */
429 /* glNormal3f(0, -1, 0); */
430 /* glVertex3f(0, 0, BOARDSIZE); */
431 /* glVertex3f(0, 0, 0); */
432 /* glVertex3f(BOARDSIZE, 0, 0); */
433 /* glVertex3f(BOARDSIZE, 0, BOARDSIZE); */
437 static void draw_pieces(ModeInfo *mi, Chesscreen *cs, int wire)
440 glEnable(GL_TEXTURE_2D);
441 glBindTexture(GL_TEXTURE_2D, cs->piecetexture);
442 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
444 glColor4f(0.5, 0.5, 0.5, 1.0);
445 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialShadow);
449 if(cs->moving) drawMovingPiece(mi, cs, 0);
450 if(cs->take) drawTakePiece(mi, cs, 0);
451 glDisable(GL_TEXTURE_2D);
454 static void draw_shadow_pieces(ModeInfo *mi, Chesscreen *cs, int wire)
457 glEnable(GL_TEXTURE_2D);
458 glBindTexture(GL_TEXTURE_2D, cs->piecetexture);
459 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
462 drawPiecesShadow(mi, cs);
463 if(cs->moving) drawMovingPiece(mi, cs, shadows);
464 if(cs->take) drawTakePiece(mi, cs, shadows);
465 glDisable(GL_TEXTURE_2D);
471 /* create a matrix that will project the desired shadow */
472 static void shadowmatrix(GLfloat shadowMat[4][4],
473 GLfloat groundplane[4],
478 /* find dot product between light position vector and ground plane normal */
479 dot = groundplane[X] * lightpos[X] +
480 groundplane[Y] * lightpos[Y] +
481 groundplane[Z] * lightpos[Z] +
482 groundplane[W] * lightpos[W];
484 shadowMat[0][0] = dot - lightpos[X] * groundplane[X];
485 shadowMat[1][0] = 0.f - lightpos[X] * groundplane[Y];
486 shadowMat[2][0] = 0.f - lightpos[X] * groundplane[Z];
487 shadowMat[3][0] = 0.f - lightpos[X] * groundplane[W];
489 shadowMat[X][1] = 0.f - lightpos[Y] * groundplane[X];
490 shadowMat[1][1] = dot - lightpos[Y] * groundplane[Y];
491 shadowMat[2][1] = 0.f - lightpos[Y] * groundplane[Z];
492 shadowMat[3][1] = 0.f - lightpos[Y] * groundplane[W];
494 shadowMat[X][2] = 0.f - lightpos[Z] * groundplane[X];
495 shadowMat[1][2] = 0.f - lightpos[Z] * groundplane[Y];
496 shadowMat[2][2] = dot - lightpos[Z] * groundplane[Z];
497 shadowMat[3][2] = 0.f - lightpos[Z] * groundplane[W];
499 shadowMat[X][3] = 0.f - lightpos[W] * groundplane[X];
500 shadowMat[1][3] = 0.f - lightpos[W] * groundplane[Y];
501 shadowMat[2][3] = 0.f - lightpos[W] * groundplane[Z];
502 shadowMat[3][3] = dot - lightpos[W] * groundplane[W];
505 /** reflectionboard */
506 static void draw_reflections(ModeInfo *mi, Chesscreen *cs)
510 glEnable(GL_STENCIL_TEST);
511 glStencilFunc(GL_ALWAYS, 1, 1);
512 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
513 glColorMask(0,0,0,0);
514 glDisable(GL_CULL_FACE);
516 glDisable(GL_DEPTH_TEST);
519 /* only draw white squares */
520 for(i = 0; i < BOARDSIZE; ++i) {
521 for(j = (BOARDSIZE+i) % 2; j < BOARDSIZE; j += 2) {
522 glVertex3f(i, 0.0, j + 1.0);
523 glVertex3f(i + 1.0, 0.0, j + 1.0);
524 glVertex3f(i + 1.0, 0.0, j);
525 glVertex3f(i, 0.0, j);
530 glEnable(GL_DEPTH_TEST);
532 glColorMask(1, 1, 1, 1);
533 glStencilFunc(GL_EQUAL, 1, 1);
534 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
537 glScalef(1.0, -1.0, 1.0);
538 glTranslatef(0.5, 0.0, 0.5);
540 glLightfv(GL_LIGHT0, GL_POSITION, cs->position);
541 draw_pieces(mi, cs, cs->wire);
544 glDisable(GL_STENCIL_TEST);
545 glLightfv(GL_LIGHT0, GL_POSITION, cs->position);
547 glEnable(GL_CULL_FACE);
549 glColorMask(1,1,1,1);
552 /** draws the scene */
553 static void display(ModeInfo *mi, Chesscreen *cs)
555 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
557 mi->polygon_count = 0;
559 glMatrixMode(GL_MODELVIEW);
562 /** setup perspectif */
563 glTranslatef(0.0, 0.0, -1.5*BOARDSIZE);
564 glRotatef(30.0, 1.0, 0.0, 0.0);
565 gltrackball_rotate (cs->trackball);
566 glRotatef(cs->theta*100, 0.0, 1.0, 0.0);
567 glTranslatef(-0.5*BOARDSIZE, 0.0, -0.5*BOARDSIZE);
569 cs->position[0] = 4.0 + 1.0*-sin(cs->theta*100*M_PI/180.0);
570 cs->position[2] = 4.0 + 1.0* cos(cs->theta*100*M_PI/180.0);
571 cs->position[1] = 5.0;
573 cs->position2[0] = 4.0 + 8.0*-sin(cs->theta*100*M_PI/180.0);
574 cs->position2[2] = 4.0 + 8.0* cos(cs->theta*100*M_PI/180.0);
577 glEnable(GL_LIGHTING);
578 glLightfv(GL_LIGHT0, GL_POSITION, cs->position);
579 glLightfv(GL_LIGHT1, GL_POSITION, cs->position2);
583 /** draw board, pieces */
585 glEnable(GL_LIGHTING);
586 glEnable(GL_COLOR_MATERIAL);
588 if(reflections && !cs->wire) {
589 draw_reflections(mi, cs);
593 glEnable(GL_TEXTURE_2D);
594 glBindTexture(GL_TEXTURE_2D, cs->boardtexture);
596 glDisable(GL_TEXTURE_2D);
601 shadowmatrix(m, cs->ground, cs->position);
603 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialShadow);
605 glDisable(GL_LIGHTING);
606 glDisable(GL_DEPTH_TEST);
608 /* display ant shadow */
610 glTranslatef(0.0, 0.001, 0.0);
612 glTranslatef(0.5, 0.01, 0.5);
613 draw_shadow_pieces(mi, cs, cs->wire);
616 glEnable(GL_LIGHTING);
618 glEnable(GL_DEPTH_TEST);
627 glTranslatef(0.5, 0.0, 0.5);
628 draw_pieces(mi, cs, cs->wire);
631 glDisable(GL_COLOR_MATERIAL);
632 glDisable(GL_LIGHTING);
635 if (!cs->button_down_p)
639 /** reshape handler */
640 ENTRYPOINT void reshape_chess(ModeInfo *mi, int width, int height)
642 GLfloat h = (GLfloat) height / (GLfloat) width;
643 glViewport(0,0, width, height);
644 glMatrixMode(GL_PROJECTION);
646 gluPerspective(45, 1/h, 2.0, 30.0);
647 glMatrixMode(GL_MODELVIEW);
650 /** initialization handler */
651 ENTRYPOINT void init_chess(ModeInfo *mi)
654 int screen = MI_SCREEN(mi);
657 !(qs = (Chesscreen *) calloc(MI_NUM_SCREENS(mi), sizeof(Chesscreen))))
661 cs->window = MI_WINDOW(mi);
662 cs->wire = MI_IS_WIREFRAME(mi);
663 cs->trackball = gltrackball_init ();
667 cs->colors[0][0] = 1.0;
668 cs->colors[0][1] = 0.5;
669 cs->colors[0][2] = 0.0;
671 cs->colors[1][0] = 0.6;
672 cs->colors[1][1] = 0.6;
673 cs->colors[1][2] = 0.6;
679 cs->position[0] = 0.0;
680 cs->position[1] = 5.0;
681 cs->position[2] = 5.0;
682 cs->position[3] = 1.0;
684 cs->position2[0] = 5.0;
685 cs->position2[1] = 5.0;
686 cs->position2[2] = 5.0;
687 cs->position2[3] = 1.0;
692 cs->ground[3] = -0.00001;
697 if((cs->glx_context = init_GL(mi)))
698 reshape_chess(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
702 glClearColor(0.0, 0.0, 0.0, 0.0);
705 glDepthFunc(GL_LEQUAL);
707 glEnable(GL_CULL_FACE);
710 make_piece_texture(cs);
711 make_board_texture(cs);
713 gen_model_lists( classic, cs->poly_counts);
717 glColorMaterial(GL_FRONT, GL_DIFFUSE);
718 glShadeModel(smooth ? GL_SMOOTH : GL_FLAT);
719 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
720 glEnable(GL_DEPTH_TEST);
723 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
726 /** does dirty work drawing scene, moving pieces */
727 ENTRYPOINT void draw_chess(ModeInfo *mi)
729 Chesscreen *cs = &qs[MI_SCREEN(mi)];
730 Window w = MI_WINDOW(mi);
731 Display *disp = MI_DISPLAY(mi);
736 glXMakeCurrent(disp, w, *(cs->glx_context));
738 /** code for moving a piece */
739 if(cs->moving && ++cs->steps == 100) {
740 cs->moving = cs->count = cs->steps = cs->take = 0;
741 cs->game.board[cs->game.moves[cs->mc][2]][cs->game.moves[cs->mc][3]] = cs->mpiece;
744 if(cs->mc == cs->game.movecount) {
750 if(++cs->count == 100) {
752 cs->mpiece = cs->game.board[cs->game.moves[cs->mc][0]][cs->game.moves[cs->mc][1]];
753 cs->game.board[cs->game.moves[cs->mc][0]][cs->game.moves[cs->mc][1]] = NONE;
755 if((cs->tpiece = cs->game.board[cs->game.moves[cs->mc][2]][cs->game.moves[cs->mc][3]])) {
756 cs->game.board[cs->game.moves[cs->mc][2]][cs->game.moves[cs->mc][3]] = NONE;
760 cs->from[0] = cs->game.moves[cs->mc][0];
761 cs->from[1] = cs->game.moves[cs->mc][1];
762 cs->to[0] = cs->game.moves[cs->mc][2];
763 cs->to[1] = cs->game.moves[cs->mc][3];
765 cs->dz = (cs->to[0] - cs->from[0]) / 100;
766 cs->dx = (cs->to[1] - cs->from[1]) / 100;
770 else if(cs->done == 1) {
771 int newgame = cs->oldgame;
772 while(newgame == cs->oldgame)
773 newgame = random()%GAMES;
776 cs->mod = 0.6 + (random()%20)/10.0;
779 cs->oldgame = newgame;
780 cs->game = games[cs->oldgame];
793 glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION,
794 cs->done == 1 ? 1.0+0.1*cs->count : 100.0/cs->count);
795 glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION,
796 cs->done == 1 ? 1.0+0.1*cs->count : 100.0/cs->count);
797 glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.14);
798 glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.14);
803 if(mi->fps_p) do_fps(mi);
805 glXSwapBuffers(disp, w);
809 ENTRYPOINT void release_chess(ModeInfo *mi)
818 XSCREENSAVER_MODULE_2 ("Endgame", endgame, chess)