#define DEFAULTS "*delay: 20000 \n" \
"*showFPS: False \n" \
"*wireframe: False \n" \
+ "*reflections: True \n" \
# include "xlockmore.h"
static XrmOptionDescRec opts[] = {
{"+rotate", ".chess.rotate", XrmoptionNoArg, (caddr_t) "false" },
{"-rotate", ".chess.rotate", XrmoptionNoArg, (caddr_t) "true" },
+ {"+reflections", ".chess.reflections", XrmoptionNoArg, (caddr_t) "false" },
+ {"-reflections", ".chess.reflections", XrmoptionNoArg, (caddr_t) "true" },
+ {"+smooth", ".chess.smooth", XrmoptionNoArg, (caddr_t) "false" },
+ {"-smooth", ".chess.smooth", XrmoptionNoArg, (caddr_t) "true" },
};
-int rotate, spidey, spideydark;
+int rotate, reflections, smooth;
static argtype vars[] = {
{(caddr_t *) &rotate, "rotate", "Rotate", "True", t_Bool},
+ {(caddr_t *) &reflections, "reflections", "Reflections", "True", t_Bool},
+ {(caddr_t *) &smooth, "smooth", "Smooth", "True", t_Bool},
};
ModeSpecOpt chess_opts = {countof(opts), opts, countof(vars), vars, NULL};
#define M_PI 3.14159265
#endif
-/* ugggggggly */
-#define NONE 0
-#define KING 1
-#define QUEEN 2
-#define BISHOP 3
-#define KNIGHT 4
-#define ROOK 5
-#define PAWN 6
-#define BKING 8
-#define BQUEEN 9
-#define BBISHOP 10
-#define BKNIGHT 11
-#define BROOK 12
-#define BPAWN 13
-
#define BOARDSIZE 8
-#define PIECES 7
-
-/* definition of white/black colors */
-GLfloat colors[2][3] = { {1.0, 0.5, 0.0},
- {0.5, 0.5, 0.5} };
-
-/* int board[8][8] = */
-/* { {ROOK, KNIGHT, BISHOP, QUEEN, KING, BISHOP, KNIGHT, ROOK}, */
-/* {PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN}, */
-/* {NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE}, */
-/* {NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE}, */
-/* {NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE}, */
-/* {NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE}, */
-/* {BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN}, */
-/* {BROOK, BKNIGHT, BBISHOP, BQUEEN, BKING, BBISHOP, BKNIGHT, BROOK}}; */
-
-int board[8][8];
-
-void buildBoard(void) {
- board[0][5] = BKING;
- board[1][4] = BPAWN;
- board[1][2] = BPAWN;
- board[1][0] = BPAWN;
- board[2][2] = BPAWN;
- board[2][4] = BPAWN;
- board[2][7] = KNIGHT;
- board[3][0] = PAWN;
- board[3][2] = ROOK;
- board[4][0] = PAWN;
- board[4][4] = KING;
- board[4][5] = PAWN;
- board[6][0] = BPAWN;
- board[6][7] = PAWN;
- board[7][0] = BBISHOP;
-}
-#define MOVES 24
-
-int moves[MOVES][4] =
- { {3, 2, 6, 2},
- {7, 0, 6, 1},
- {6, 2, 6, 6},
- {0, 5, 0, 4},
- {6, 6, 0, 6},
- {0, 4, 1, 3},
- {2, 7, 1, 5},
- {2, 2, 3, 2},
- {0, 6, 0, 3},
- {1, 3, 2, 2},
- {0, 3, 6, 3},
- {3, 2, 4, 2}, /* pawn to bishop 5 */
- {1, 5, 0, 3}, /* check */
- {2, 2, 3, 2},
- {0, 3, 2, 4}, /* takes pawn */
- {3, 2, 2, 2},
- {2, 4, 0, 3},
- {2, 2, 3, 2},
- {6, 3, 6, 1}, /* rook takes bishop */
- {6, 0, 7, 0}, /* hack this in! */
- {6, 1, 3, 1},
- {3, 2, 2, 3},
- {3, 1, 3, 3},
- {0, 0, 2, 3},
+/** definition of white/black (orange/gray) colors */
+GLfloat colors[2][3] =
+ {
+ {1.0, 0.5, 0.0},
+ {0.5, 0.5, 0.5},
+ };
+
+#define WHITES 5
+
+/* i prefer silvertip */
+GLfloat whites[WHITES][3] =
+ {
+ {1.0, 0.5, 0.0},
+ {0.8, 0.45, 1.0},
+ {0.43, 0.54, 0.76},
+ {0.8, 0.8, 0.8},
+ {0.15, 0.77, 0.54},
};
+#include "chessgames.h"
+
+ChessGame game;
+int oldwhite = -1;
+
+void build_colors(void) {
+
+ /* find new white */
+ int newwhite = oldwhite;
+ while(newwhite == oldwhite)
+ newwhite = random()%WHITES;
+ oldwhite = newwhite;
+
+ colors[0][0] = whites[oldwhite][0];
+ colors[0][1] = whites[oldwhite][1];
+ colors[0][2] = whites[oldwhite][2];
+}
+
/* yay its c */
-int mpiece = 0, tpiece, steps = 0;
-double mcount = 0.0;
+int mpiece = 0, tpiece, steps = 0, done = 1;
double from[2], to[2];
double dx, dz;
-int moving = 0, take = 0, mc = 0, count = 0;
+int moving = 0, take = 0, mc = 0, count = 99, wire = 0;
+/** handle X event (trackball) */
Bool chess_handle_event (ModeInfo *mi, XEvent *event) {
Chesscreen *c = &qs[MI_SCREEN(mi)];
return False;
}
-/* clear board */
-void blank(void) {
- int i, j;
-
- for(i = 0; i < BOARDSIZE; ++i)
- for(j = 0; j < BOARDSIZE; ++j)
- board[i][j] = NONE;
-}
+GLfloat position[] = { 0.0, 5.0, 5.0, 1.0 };
+GLfloat position2[] = { 5.0, 5.0, 5.0, 1.0 };
+GLfloat diffuse2[] = {1.0, 1.0, 1.0, 1.0};
+GLfloat ambient2[] = {0.6, 0.6, 0.6, 1.0};
/* configure lighting */
void setup_lights(void) {
- GLfloat position[] = { 0.0, 8.0, 0.0, 1.0 };
-
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0, GL_POSITION, position);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse2);
glEnable(GL_LIGHT0);
+
+/* glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient2); */
+
+ glLightfv(GL_LIGHT1, GL_SPECULAR, diffuse2);
+ glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse2);
+ glEnable(GL_LIGHT1);
}
-/* draw pieces */
+/** draw pieces */
void drawPieces(void) {
int i, j;
for(i = 0; i < BOARDSIZE; ++i) {
for(j = 0; j < BOARDSIZE; ++j) {
- if(board[i][j]) {
- int c = board[i][j]/PIECES;
+ if(game.board[i][j]) {
+ int c = game.board[i][j]/PIECES;
glColor3fv(colors[c]);
- glCallList(board[i][j]%7);
+ glCallList(game.board[i][j]%PIECES);
}
glTranslatef(1.0, 0.0, 0.0);
glTranslatef(0.0, 0.0, -1.0*BOARDSIZE);
}
-void drawMovingPiece(int wire) {
- glTranslatef(from[1], 0.0, from[0]);
- glColor3fv(colors[mpiece/7]);
+/** draw a moving piece */
+void drawMovingPiece(void) {
+ int piece = mpiece % PIECES;
- /* assume a queening. should be more general */
+ glPushMatrix();
+ glColor3fv(colors[mpiece/PIECES]);
+
+ /** assume a queening. should be more general */
if((mpiece == PAWN && fabs(to[0]) < 0.01) ||
(mpiece == BPAWN && fabs(to[0]-7.0) < 0.01)) {
- if(!wire)
- glEnable(GL_BLEND);
-
+ glTranslatef(from[1]+steps*dx, 0.0, from[0]+steps*dz);
glColor4f(colors[mpiece/7][0], colors[mpiece/7][1], colors[mpiece/7][2],
(fabs(50.0-steps))/50.0);
-
- glCallList(steps < 50 ? PAWN : QUEEN);
+ piece = steps < 50 ? PAWN : QUEEN;
- /* what a kludge. yay for side effects */
+ /* what a kludge */
if(steps == 99)
mpiece = mpiece == PAWN ? QUEEN : BQUEEN;
+ }
+ else if(mpiece % PIECES == KNIGHT) {
+ glTranslatef(steps < 50 ? from[1] : to[1], 0.0,
+ steps < 50 ? from[0] : to[0]);
- if(!wire)
- glDisable(GL_BLEND);
+ glColor4f(colors[mpiece/7][0], colors[mpiece/7][1], colors[mpiece/7][2],
+ fabs(49-steps)/49.0);
+ glScalef(fabs(49-steps)/49.0, fabs(49-steps)/49.0, fabs(49-steps)/49.0);
}
else
- glCallList(mpiece % 7);
+ glTranslatef(from[1]+steps*dx, 0.0, from[0]+steps*dz);
+
+ if(!wire)
+ glEnable(GL_BLEND);
+
+ glCallList(piece);
+ glPopMatrix();
+
+ if(!wire)
+ glDisable(GL_BLEND);
}
-void drawTakePiece(int wire) {
+/** code to squish a taken piece */
+void drawTakePiece(void) {
if(!wire)
glEnable(GL_BLEND);
glColor4f(colors[tpiece/7][0], colors[tpiece/7][1], colors[tpiece/7][2],
(100-1.6*steps)/100.0);
- glTranslatef(to[1] - from[1], 0.0, to[0] - from[0]);
- glScalef(1.0, 1 - steps/50.0 > 0.01 ? 1 - steps/50.0 : 0.01, 1.0);
+ glTranslatef(to[1], 0.0, to[0]);
+
+ if(mpiece % PIECES == KNIGHT)
+ glScalef(1.0+steps/100.0, 1.0, 1.0+steps/100.0);
+ else
+ glScalef(1.0, 1 - steps/50.0 > 0.01 ? 1 - steps/50.0 : 0.01, 1.0);
glCallList(tpiece % 7);
if(!wire)
glDisable(GL_BLEND);
}
-/* draw board */
+/** draw board */
void drawBoard(void) {
int i, j;
+ glBegin(GL_QUADS);
+
for(i = 0; i < BOARDSIZE; ++i)
for(j = 0; j < BOARDSIZE; ++j) {
- glColor3fv(colors[(i+j)%2]);
+ /*glColor3fv(colors[(i+j)%2]);*/
+ glColor4f(colors[(i+j)%2][0], colors[(i+j)%2][1],
+ colors[(i+j)%2][2], 0.65);
glNormal3f(0.0, 1.0, 0.0);
+ glVertex3f(i, 0.0, j + 1.0);
+ glVertex3f(i + 1.0, 0.0, j + 1.0);
+ glVertex3f(i + 1.0, 0.0, j);
+ glVertex3f(i, 0.0, j);
+ }
- glBegin(GL_QUADS);
+ /* chop underneath board */
+/* glColor3f(0, 0, 0); */
+/* glNormal3f(0, -1, 0); */
+/* glVertex3f(0, 0, BOARDSIZE); */
+/* glVertex3f(0, 0, 0); */
+/* glVertex3f(BOARDSIZE, 0, 0); */
+/* glVertex3f(BOARDSIZE, 0, BOARDSIZE); */
+ glEnd();
+}
+
+double theta = 0.0;
+
+void draw_pieces(void) {
+ drawPieces();
+ if(moving) drawMovingPiece();
+ if(take) drawTakePiece();
+}
- glVertex3f(i - 0.5, 0.0, j + 0.5);
- glVertex3f(i + 0.5, 0.0, j + 0.5);
- glVertex3f(i + 0.5, 0.0, j - 0.5);
- glVertex3f(i - 0.5, 0.0, j - 0.5);
+/** reflectionboard */
+void draw_reflections(void) {
+ int i, j;
- /* draw the bottom, too */
- glNormal3f(0.0, -1.0, 0.0);
+ glEnable(GL_STENCIL_TEST);
+ glStencilFunc(GL_ALWAYS, 1, 1);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+ glColorMask(0,0,0,0);
+ glDisable(GL_CULL_FACE);
- glVertex3f(i - 0.5, 0.0, j - 0.5);
- glVertex3f(i + 0.5, 0.0, j - 0.5);
- glVertex3f(i + 0.5, 0.0, j + 0.5);
- glVertex3f(i - 0.5, 0.0, j + 0.5);
+ glDisable(GL_DEPTH_TEST);
+ glBegin(GL_QUADS);
- glEnd();
+ /* only draw white squares */
+ for(i = 0; i < BOARDSIZE; ++i) {
+ for(j = (BOARDSIZE+i) % 2; j < BOARDSIZE; j += 2) {
+ glVertex3f(i, 0.0, j + 1.0);
+ glVertex3f(i + 1.0, 0.0, j + 1.0);
+ glVertex3f(i + 1.0, 0.0, j);
+ glVertex3f(i, 0.0, j);
}
-}
+ }
+ glEnd();
+ glEnable(GL_DEPTH_TEST);
-#define SQ 0.5
+ glColorMask(1, 1, 1, 1);
+ glStencilFunc(GL_EQUAL, 1, 1);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+
+ glPushMatrix();
+ glScalef(1.0, -1.0, 1.0);
+ glTranslatef(0.5, 0.0, 0.5);
-double theta = 0.0;
+ glLightfv(GL_LIGHT0, GL_POSITION, position);
+ draw_pieces();
+ glPopMatrix();
+
+ glDisable(GL_STENCIL_TEST);
+ glLightfv(GL_LIGHT0, GL_POSITION, position);
+
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+ glColorMask(1,1,1,1);
+}
-void display(Chesscreen *c, int wire) {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+/** draws the scene */
+void display(Chesscreen *c) {
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
- glTranslatef(0.0, -3.0+fabs(sin(theta)), -1.3*BOARDSIZE);
+ /** setup perspectif */
+ glTranslatef(0.0, 0.0, -1.5*BOARDSIZE);
+ glRotatef(30.0, 1.0, 0.0, 0.0);
gltrackball_rotate (c->trackball);
glRotatef(theta*100, 0.0, 1.0, 0.0);
- glTranslatef(-0.5*(BOARDSIZE-1), 0.0, -0.5*(BOARDSIZE-1));
+ glTranslatef(-0.5*BOARDSIZE, 0.0, -0.5*BOARDSIZE);
+
+ position[0] = 4.0 + 1.0*-sin(theta*100*M_PI/180.0);
+ position[2] = 4.0 + 1.0*cos(theta*100*M_PI/180.0);
+ position[1] = 8.0;
+
+ position2[0] = 4.0 + 8.0*-sin(theta*100*M_PI/180.0);
+ position2[2] = 4.0 + 8.0*cos(theta*100*M_PI/180.0);
+
+ glEnable(GL_LIGHTING);
+ glLightfv(GL_LIGHT0, GL_POSITION, position);
+ glLightfv(GL_LIGHT1, GL_POSITION, position2);
+ glEnable(GL_LIGHT0);
+ /** draw board, pieces */
if(!wire) {
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
+
+ if(reflections) {
+ draw_reflections();
+ glEnable(GL_BLEND);
+ }
+
+ drawBoard();
+
+ if(reflections)
+ glDisable(GL_BLEND);
}
+ else
+ drawBoard();
+
+ glTranslatef(0.5, 0.0, 0.5);
+ draw_pieces();
- drawBoard();
- glTranslatef(0.0, .02, 0.0);
- drawPieces();
- if(moving) drawMovingPiece(wire);
- if(take) drawTakePiece(wire);
+ if(!wire) {
+ glDisable(GL_COLOR_MATERIAL);
+ glDisable(GL_LIGHTING);
+ }
- glDisable(GL_COLOR_MATERIAL);
- glDisable(GL_LIGHTING);
-
- theta += .002;
+ if (!c->button_down_p)
+ theta += .002;
}
+/** reshape handler */
void reshape_chess(ModeInfo *mi, int width, int height) {
GLfloat h = (GLfloat) height / (GLfloat) width;
glViewport(0,0, width, height);
glMatrixMode(GL_MODELVIEW);
}
+/** initialization handler */
void init_chess(ModeInfo *mi) {
- GLfloat mat_shininess[] = { 90.0 };
- GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
-
- int screen = MI_SCREEN(mi);
- int wire = MI_IS_WIREFRAME(mi);
Chesscreen *c;
+ int screen = MI_SCREEN(mi);
+ wire = MI_IS_WIREFRAME(mi);
if(!qs &&
!(qs = (Chesscreen *) calloc(MI_NUM_SCREENS(mi), sizeof(Chesscreen))))
glClearColor(0.0, 0.0, 0.0, 0.0);
+ glDepthFunc(GL_LEQUAL);
+ glClearStencil(0);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
- glLineWidth(1.0);
- glDepthFunc(GL_LEQUAL);
-
- setup_lights();
gen_model_lists();
- if (!wire) {
+ if(!wire) {
+ setup_lights();
glColorMaterial(GL_FRONT, GL_DIFFUSE);
-
- glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
- glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
- glShadeModel(GL_SMOOTH);
+ glShadeModel(smooth ? GL_SMOOTH : GL_FLAT);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_DEPTH_TEST);
}
else
glPolygonMode(GL_FRONT, GL_LINE);
-
- buildBoard();
}
+int oldgame = -1;
+
+/** does dirty work drawing scene, moving pieces */
void draw_chess(ModeInfo *mi) {
Chesscreen *c = &qs[MI_SCREEN(mi)];
Window w = MI_WINDOW(mi);
glXMakeCurrent(disp, w, *(c->glx_context));
- /* moving code */
- if(moving) {
- ++steps;
- from[0] += dz;
- from[1] += dx;
- }
-
- if(steps == 100) {
+ /** code for moving a piece */
+ if(moving && ++steps == 100) {
moving = count = steps = take = 0;
- board[moves[mc][2]][moves[mc][3]] = mpiece;
+ game.board[game.moves[mc][2]][game.moves[mc][3]] = mpiece;
++mc;
- if(mc == MOVES) {
- blank();
- buildBoard();
+ if(mc == game.movecount) {
+ done = 1;
mc = 0;
}
}
- if(count++ == 100) {
- moving = 1;
- mpiece = board[moves[mc][0]][moves[mc][1]];
- board[moves[mc][0]][moves[mc][1]] = NONE;
-
- if((tpiece = board[moves[mc][2]][moves[mc][3]]) != NONE) {
- board[moves[mc][2]][moves[mc][3]] = NONE;
- take = 1;
+ if(++count == 100) {
+ if(!done) {
+ mpiece = game.board[game.moves[mc][0]][game.moves[mc][1]];
+ game.board[game.moves[mc][0]][game.moves[mc][1]] = NONE;
+
+ if((tpiece = game.board[game.moves[mc][2]][game.moves[mc][3]])) {
+ game.board[game.moves[mc][2]][game.moves[mc][3]] = NONE;
+ take = 1;
+ }
+
+ from[0] = game.moves[mc][0];
+ from[1] = game.moves[mc][1];
+ to[0] = game.moves[mc][2];
+ to[1] = game.moves[mc][3];
+
+ dz = (to[0] - from[0]) / 100;
+ dx = (to[1] - from[1]) / 100;
+ steps = 0;
+ moving = 1;
}
-
- mcount = 0.0;
- from[0] = moves[mc][0];
- from[1] = moves[mc][1];
- to[0] = moves[mc][2];
- to[1] = moves[mc][3];
-
- dz = (to[0] - from[0]) / 100;
- dx = (to[1] - from[1]) / 100;
- steps = 0;
+ else if(done == 1) {
+ int newgame = oldgame;
+ while(newgame == oldgame)
+ newgame = random()%GAMES;
+
+ /* same old game */
+ oldgame = newgame;
+ game = games[oldgame];
+ build_colors();
+ done = 2;
+ count = 0;
+ }
+ else {
+ done = 0;
+ count = 0;
+ }
+ }
+
+ /* set lighting */
+ if(done) {
+ glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION,
+ done == 1 ? 1.0+0.1*count : 100.0/count);
+ glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION,
+ done == 1 ? 1.0+0.1*count : 100.0/count);
+ glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.15);
+ glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.15);
}
- display(c, MI_IS_WIREFRAME(mi));
+ display(c);
if(mi->fps_p) do_fps(mi);
glFinish();
glXSwapBuffers(disp, w);
}
+/** bust it */
void release_chess(ModeInfo *mi) {
if(qs)
free((void *) qs);