"*showFPS: False \n" \
"*wireframe: False \n" \
-# define refresh_chess 0
+# define free_chess 0
+# define release_chess 0
# include "xlockmore.h"
#else
#ifdef USE_MODULES
ModStruct chess_description =
-{"chess", "init_chess", "draw_chess", "release_chess",
+{"chess", "init_chess", "draw_chess", NULL,
"draw_chess", "init_chess", NULL, &chess_opts,
1000, 1, 2, 1, 4, 1.0, "",
"Chess", 0, NULL};
{
Chesscreen *cs = &qs[MI_SCREEN(mi)];
- if(event->xany.type == ButtonPress && event->xbutton.button == Button1) {
- cs->button_down_p = True;
- gltrackball_start (cs->trackball,
- event->xbutton.x, event->xbutton.y,
- MI_WIDTH (mi), MI_HEIGHT (mi));
+ if (gltrackball_event_handler (event, cs->trackball,
+ MI_WIDTH (mi), MI_HEIGHT (mi),
+ &cs->button_down_p))
return True;
- }
- else if(event->xany.type == ButtonRelease
- && event->xbutton.button == Button1) {
- cs->button_down_p = False;
- return True;
- }
- else if (event->xany.type == ButtonPress &&
- (event->xbutton.button == Button4 ||
- event->xbutton.button == Button5 ||
- event->xbutton.button == Button6 ||
- event->xbutton.button == Button7))
+ else if (screenhack_event_helper (MI_DISPLAY(mi), MI_WINDOW(mi), event))
{
- gltrackball_mousewheel (cs->trackball, event->xbutton.button, 5,
- !event->xbutton.state);
+ cs->done = 1;
return True;
}
- else if(event->xany.type == MotionNotify && cs->button_down_p) {
- gltrackball_track (cs->trackball,
- event->xmotion.x, event->xmotion.y,
- MI_WIDTH (mi), MI_HEIGHT (mi));
- return True;
- }
-
+
return False;
}
{
int piece = cs->mpiece % PIECES;
+ if (piece == NONE) return;
+
glPushMatrix();
if(shadow) glColor4fv(MaterialShadow);
cs->mpiece = cs->mpiece == PAWN ? QUEEN : BQUEEN;
}
else if(cs->mpiece % PIECES == KNIGHT) {
- GLfloat shine[1];
- GLfloat spec[4];
- GLfloat mult;
- glTranslatef(cs->steps < 50 ? cs->from[1] : cs->to[1], 0.0,
- cs->steps < 50 ? cs->from[0] : cs->to[0]);
-
- mult = cs->steps < 10
- ? (1.0 - cs->steps / 10.0) : 100 - cs->steps < 10
- ? (1.0 - (100 - cs->steps) / 10.0) : 0.0;
-
- shine[0] = mult*shininess[0];
- spec[0] = mult*specular[0];
- spec[1] = mult*specular[1];
- spec[2] = mult*specular[2];
- spec[3] = 1.0;
- glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shine);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
+ /* If there is nothing in the path of a knight, move it by sliding,
+ just like the other pieces. But if there are any pieces on the
+ middle two squares in its path, the knight would intersect them,
+ so in that case, move it in an airborne arc. */
+ GLfloat y;
+ int i, j;
+ Bool blocked_p = False;
+ int fromx = MIN(cs->from[1], cs->to[1]);
+ int fromy = MIN(cs->from[0], cs->to[0]);
+ int tox = MAX(cs->from[1], cs->to[1]);
+ int toy = MAX(cs->from[0], cs->to[0]);
+ if (fromx == tox-2) fromx = tox = fromx+1;
+ if (fromy == toy-2) fromy = toy = fromy+1;
+ for (i = fromy; i <= toy; i++) {
+ for (j = fromx; j <= tox; j++) {
+ if (cs->game.board[i][j]) {
+ blocked_p = True;
+ break;
+ }
+ }
+ }
- glColor4f(shadow ? MaterialShadow[0] : cs->colors[cs->mpiece/7][0],
- shadow ? MaterialShadow[1] : cs->colors[cs->mpiece/7][1],
- shadow ? MaterialShadow[2] : cs->colors[cs->mpiece/7][2],
- fabs(49-cs->steps)/49.0);
+ if (!blocked_p)
+ goto SLIDE;
- glScalef(fabs(49-cs->steps)/49.0, fabs(49-cs->steps)/49.0, fabs(49-cs->steps)/49.0);
- }
- else
+ /* Move by hopping. */
+ y = 1.5 * sin (M_PI * cs->steps / 100.0);
+ glTranslatef(cs->from[1]+cs->steps*cs->dx, y,
+ cs->from[0]+cs->steps*cs->dz);
+
+ } else {
+ SLIDE:
+ /* Move by sliding. */
glTranslatef(cs->from[1]+cs->steps*cs->dx, 0.0, cs->from[0]+cs->steps*cs->dz);
+ }
+
if(!cs->wire)
glEnable(GL_BLEND);
mi->polygon_count++;
}
-
- /* 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();
+
+ {
+ GLfloat off = 0.01;
+ GLfloat w = BOARDSIZE;
+ GLfloat h = 0.1;
+
+ /* Give the board a slight lip. */
+ /* #### oops, normals are wrong here, but you can't tell */
+
+ glColor3f(0.3, 0.3, 0.3);
+ glBegin (GL_QUADS);
+ glVertex3f (0, 0, 0);
+ glVertex3f (0, -h, 0);
+ glVertex3f (0, -h, w);
+ glVertex3f (0, 0, w);
+
+ glVertex3f (0, 0, w);
+ glVertex3f (0, -h, w);
+ glVertex3f (w, -h, w);
+ glVertex3f (w, 0, w);
+
+ glVertex3f (w, 0, w);
+ glVertex3f (w, -h, w);
+ glVertex3f (w, -h, 0);
+ glVertex3f (w, 0, 0);
+
+ glVertex3f (w, 0, 0);
+ glVertex3f (w, -h, 0);
+ glVertex3f (0, -h, 0);
+ glVertex3f (0, 0, 0);
+
+ glVertex3f (0, -h, 0);
+ glVertex3f (w, -h, 0);
+ glVertex3f (w, -h, w);
+ glVertex3f (0, -h, w);
+ glEnd();
+ mi->polygon_count += 4;
+
+ /* Fill in the underside of the board with an invisible black box
+ to hide the reflections that are not on tiles. Probably there's
+ a way to do this with stencils instead.
+ */
+ w -= off*2;
+ h = 5;
+
+ glPushMatrix();
+ glTranslatef (off, 0, off);
+ glDisable(GL_LIGHTING);
+ glColor3f(0,0,0);
+ glBegin (GL_QUADS);
+ glVertex3f (0, 0, 0);
+ glVertex3f (0, -h, 0);
+ glVertex3f (0, -h, w);
+ glVertex3f (0, 0, w);
+
+ glVertex3f (0, 0, w);
+ glVertex3f (0, -h, w);
+ glVertex3f (w, -h, w);
+ glVertex3f (w, 0, w);
+
+ glVertex3f (w, 0, w);
+ glVertex3f (w, -h, w);
+ glVertex3f (w, -h, 0);
+ glVertex3f (w, 0, 0);
+
+ glVertex3f (w, 0, 0);
+ glVertex3f (w, -h, 0);
+ glVertex3f (0, -h, 0);
+ glVertex3f (0, 0, 0);
+
+ glVertex3f (0, -h, 0);
+ glVertex3f (w, -h, 0);
+ glVertex3f (w, -h, w);
+ glVertex3f (0, -h, w);
+ glEnd();
+ mi->polygon_count += 4;
+ glPopMatrix();
+ if (!cs->wire)
+ glEnable(GL_LIGHTING);
+ }
}
static void draw_pieces(ModeInfo *mi, Chesscreen *cs, int wire)
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
+ glRotatef(current_device_rotation(), 0, 0, 1);
/** setup perspectiv */
glTranslatef(0.0, 0.0, -1.5*BOARDSIZE);
glRotatef(30.0, 1.0, 0.0, 0.0);
gltrackball_rotate (cs->trackball);
- glRotatef(cs->theta*100, 0.0, 1.0, 0.0);
+
+ if (rotate)
+ glRotatef(cs->theta*100, 0.0, 1.0, 0.0);
glTranslatef(-0.5*BOARDSIZE, 0.0, -0.5*BOARDSIZE);
/* cs->position[0] = 4.0 + 1.0*-sin(cs->theta*100*M_PI/180.0); */
ENTRYPOINT void reshape_chess(ModeInfo *mi, int width, int height)
{
GLfloat h = (GLfloat) height / (GLfloat) width;
- glViewport(0,0, width, height);
+ int y = 0;
+
+ if (width > height * 5) { /* tiny window: show middle */
+ height = width * 9/16;
+ y = -height/2;
+ h = height / (GLfloat) width;
+ }
+
+ glViewport(0,y, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, 1/h, 2.0, 30.0);
Chesscreen *cs;
int screen = MI_SCREEN(mi);
- if(!qs &&
- !(qs = (Chesscreen *) calloc(MI_NUM_SCREENS(mi), sizeof(Chesscreen))))
- return;
+ MI_INIT(mi, qs);
cs = &qs[screen];
cs->window = MI_WINDOW(mi);
cs->wire = MI_IS_WIREFRAME(mi);
- cs->trackball = gltrackball_init ();
+ cs->trackball = gltrackball_init (False);
cs->oldwhite = -1;
make_piece_texture(cs);
make_board_texture(cs);
}
- gen_model_lists( classic, cs->poly_counts);
+ chessmodels_gen_lists( classic, cs->poly_counts);
+
+# ifdef HAVE_JWZGLES /* #### glPolygonMode other than GL_FILL unimplemented */
+ cs->wire = 0;
+# endif
if(!cs->wire) {
setup_lights(cs);
glXSwapBuffers(disp, w);
}
-/** bust it */
-ENTRYPOINT void release_chess(ModeInfo *mi)
-{
- if(qs)
- free((void *) qs);
- qs = 0;
-
- FreeAllGL(mi);
-}
-
XSCREENSAVER_MODULE_2 ("Endgame", endgame, chess)
#endif