X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fglx%2Fendgame.c;h=5bac990a231bb2bcaec707c1c22f039598667cac;hb=96a411663168b0ba5432b407a83be55f3df0c802;hp=96db27618ea69abe704051b585583a221d6c4fec;hpb=723c9eeee862766a1534b2ce17b78adbfac1c3be;p=xscreensaver diff --git a/hacks/glx/endgame.c b/hacks/glx/endgame.c index 96db2761..5bac990a 100644 --- a/hacks/glx/endgame.c +++ b/hacks/glx/endgame.c @@ -29,6 +29,7 @@ #define DEFAULTS "*delay: 20000 \n" \ "*showFPS: False \n" \ "*wireframe: False \n" \ + "*reflections: True \n" \ # include "xlockmore.h" @@ -48,12 +49,18 @@ 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}; @@ -85,94 +92,52 @@ static Chesscreen *qs = 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)]; @@ -198,34 +163,35 @@ Bool chess_handle_event (ModeInfo *mi, XEvent *event) { 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); @@ -237,107 +203,204 @@ void drawPieces(void) { 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); @@ -347,13 +410,11 @@ void reshape_chess(ModeInfo *mi, int width, int 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)))) @@ -370,30 +431,27 @@ void init_chess(ModeInfo *mi) { 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); @@ -404,53 +462,74 @@ void draw_chess(ModeInfo *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);