diff options
| author | Simon Rettberg | 2024-09-06 14:42:37 +0200 |
|---|---|---|
| committer | Simon Rettberg | 2024-09-06 14:42:37 +0200 |
| commit | badef32037f52f79abc1f1440b786cd71afdf270 (patch) | |
| tree | 412b792d4cab4a7a110db82fcf74fe8a1ac55ec1 /hacks/glx/queens.c | |
| parent | Delete pre-6.00 files (diff) | |
| download | xscreensaver-master.tar.gz xscreensaver-master.tar.xz xscreensaver-master.zip | |
Diffstat (limited to 'hacks/glx/queens.c')
| -rw-r--r-- | hacks/glx/queens.c | 607 |
1 files changed, 0 insertions, 607 deletions
diff --git a/hacks/glx/queens.c b/hacks/glx/queens.c deleted file mode 100644 index 199842c..0000000 --- a/hacks/glx/queens.c +++ /dev/null @@ -1,607 +0,0 @@ -/* - * queens - solves n queens problem, displays - * i make no claims that this is an optimal solution to the problem, - * good enough for xss - * hacked from glchess - * - * version 1.0 - May 10, 2002 - * - * Copyright (C) 2002 Blair Tennessy (tennessy@cs.ubc.ca) - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation. No representations are made about the suitability of this - * software for any purpose. It is provided "as is" without express or - * implied warranty. - */ - -#ifdef STANDALONE -#define DEFAULTS "*delay: 20000 \n" \ - "*showFPS: False \n" \ - "*wireframe: False \n" \ - -# define release_queens 0 -# include "xlockmore.h" -#else -# include "xlock.h" -#endif - -#ifdef USE_GL - -#include "gltrackball.h" -#include "chessmodels.h" - -static XrmOptionDescRec opts[] = { - {"+rotate", ".queens.rotate", XrmoptionNoArg, "false" }, - {"-rotate", ".queens.rotate", XrmoptionNoArg, "true" }, - {"+flat", ".queens.flat", XrmoptionNoArg, "false" }, - {"-flat", ".queens.flat", XrmoptionNoArg, "true" }, -}; - -static int rotate, wire, clearbits, flat; - -static argtype vars[] = { - {&rotate, "rotate", "Rotate", "True", t_Bool}, - {&flat, "flat", "Flat", "False", t_Bool}, -}; - -ENTRYPOINT ModeSpecOpt queens_opts = {countof(opts), opts, countof(vars), vars, NULL}; - -#ifdef USE_MODULES -ModStruct queens_description = -{"queens", "init_queens", "draw_queens", NULL, - "draw_queens", "init_queens", NULL, &queens_opts, - 1000, 1, 2, 1, 4, 1.0, "", - "Queens", 0, NULL}; - -#endif - -#define NONE 0 -#define MINBOARD 5 -#define MAXBOARD 10 -#define COLORSETS 5 - -typedef struct { - GLXContext *glx_context; - Window window; - trackball_state *trackball; - Bool button_down_p; - GLfloat position[4]; - int queen_list; - - int board[MAXBOARD][MAXBOARD]; - int steps, colorset, BOARDSIZE; - double theta; - int queen_polys; - -} Queenscreen; - -static Queenscreen *qss = NULL; - -/* definition of white/black colors */ -static const GLfloat colors[COLORSETS][2][3] = - { - {{0.43, 0.54, 0.76}, {0.8, 0.8, 0.8}}, - {{0.5, 0.7, 0.9}, {0.2, 0.3, 0.6}}, - {{0.53725490196, 0.360784313725, 0.521568627451}, {0.6, 0.6, 0.6}}, - {{0.15, 0.77, 0.54}, {0.5, 0.5, 0.5}}, - {{0.9, 0.45, 0.0}, {0.5, 0.5, 0.5}}, - }; - -ENTRYPOINT Bool -queens_handle_event (ModeInfo *mi, XEvent *event) -{ - Queenscreen *qs = &qss[MI_SCREEN(mi)]; - - if (gltrackball_event_handler (event, qs->trackball, - MI_WIDTH (mi), MI_HEIGHT (mi), - &qs->button_down_p)) - return True; - else if (screenhack_event_helper (MI_DISPLAY(mi), MI_WINDOW(mi), event)) - { - qs->steps = 1024 - 1; - return True; - } - - return False; -} - - - -/* returns true if placing a queen on column c causes a conflict */ -static int conflictsCols(Queenscreen *qs, int c) -{ - int i; - - for(i = 0; i < qs->BOARDSIZE; ++i) - if(qs->board[i][c]) - return 1; - - return 0; -} - -/* returns true if placing a queen on (r,c) causes a diagonal conflict */ -static int conflictsDiag(Queenscreen *qs, int r, int c) -{ - int i; - - /* positive slope */ - int n = r < c ? r : c; - for(i = 0; i < qs->BOARDSIZE-abs(r-c); ++i) - if(qs->board[r-n+i][c-n+i]) - return 1; - - /* negative slope */ - n = r < qs->BOARDSIZE - (c+1) ? r : qs->BOARDSIZE - (c+1); - for(i = 0; i < qs->BOARDSIZE-abs(qs->BOARDSIZE - (1+r+c)); ++i) - if(qs->board[r-n+i][c+n-i]) - return 1; - - return 0; -} - -/* returns true if placing a queen at (r,c) causes a conflict */ -static int conflicts(Queenscreen *qs, int r, int c) -{ - return !conflictsCols(qs, c) ? conflictsDiag(qs, r, c) : 1; -} - -/* clear board */ -static void blank(Queenscreen *qs) -{ - int i, j; - - for(i = 0; i < MAXBOARD; ++i) - for(j = 0; j < MAXBOARD; ++j) - qs->board[i][j] = NONE; -} - -/* recursively determine solution */ -static int findSolution(Queenscreen *qs, int row, int col) -{ - if(row == qs->BOARDSIZE) - return 1; - - while(col < qs->BOARDSIZE) { - if(!conflicts(qs, row, col)) { - qs->board[row][col] = 1; - - if(findSolution(qs, row+1, 0)) - return 1; - - qs->board[row][col] = 0; - } - - ++col; - } - - return 0; -} - -/** driver for finding solution */ -static void go(Queenscreen *qs) { while(!findSolution(qs, 0, random()%qs->BOARDSIZE)); } - -/* lighting variables */ -static const GLfloat front_shininess[] = {60.0}; -static const GLfloat front_specular[] = {0.4, 0.4, 0.4, 1.0}; -static const GLfloat ambient[] = {0.3, 0.3, 0.3, 1.0}; -static const GLfloat diffuse[] = {0.8, 0.8, 0.8, 1.0}; - -/* configure lighting */ -static void setup_lights(Queenscreen *qs) -{ - - /* setup twoside lighting */ - glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); - glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); - glLightfv(GL_LIGHT0, GL_POSITION, qs->position); - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - - /* setup material properties */ - glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_shininess); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_specular); - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -} - -#define checkImageWidth 8 -#define checkImageHeight 8 -/*static GLubyte checkImage[checkImageWidth][checkImageHeight][3];*/ - -/* return alpha value for fading */ -static GLfloat findAlpha(Queenscreen *qs) -{ - return qs->steps < 128 ? qs->steps/128.0 : qs->steps < 1024-128 ?1.0:(1024-qs->steps)/128.0; -} - -/* draw pieces */ -static int drawPieces(Queenscreen *qs) -{ - int i, j; - int polys = 0; - - for(i = 0; i < qs->BOARDSIZE; ++i) { - for(j = 0; j < qs->BOARDSIZE; ++j) { - if(qs->board[i][j]) { - glColor3fv(colors[qs->colorset][i%2]); - glCallList(qs->queen_list); - polys += qs->queen_polys; - } - - glTranslatef(1.0, 0.0, 0.0); - } - - glTranslatef(-1.0*qs->BOARDSIZE, 0.0, 1.0); - } - return polys; -} - -/** reflectionboard */ -static int draw_reflections(Queenscreen *qs) -{ - int i, j; - int polys = 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); - - glDisable(GL_DEPTH_TEST); - glBegin(GL_QUADS); - - /* only draw white squares */ - for(i = 0; i < qs->BOARDSIZE; ++i) { - for(j = (qs->BOARDSIZE+i) % 2; j < qs->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); - polys++; - } - } - glEnd(); - glEnable(GL_DEPTH_TEST); - - 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.001, 0.5); - glLightfv(GL_LIGHT0, GL_POSITION, qs->position); - polys += drawPieces(qs); - glPopMatrix(); - glDisable(GL_STENCIL_TEST); - - /* replace lights */ - glLightfv(GL_LIGHT0, GL_POSITION, qs->position); - - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - glColorMask(1,1,1,1); - return polys; -} - -/* draw board */ -static int drawBoard(Queenscreen *qs) -{ - int i, j; - int polys = 0; - - glBegin(GL_QUADS); - - for(i = 0; i < qs->BOARDSIZE; ++i) - for(j = 0; j < qs->BOARDSIZE; ++j) { - int par = (i-j+qs->BOARDSIZE)%2; - glColor4f(colors[qs->colorset][par][0], - colors[qs->colorset][par][1], - colors[qs->colorset][par][2], - 0.70); - 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); - polys++; - } - - glEnd(); - - { - GLfloat off = 0.01; - GLfloat w = qs->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(); - polys += 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(); - polys += 4; - glPopMatrix(); - if (!wire) - glEnable(GL_LIGHTING); - } - - return polys; -} - -static int display(ModeInfo *mi, Queenscreen *qs) -{ - int max = 1024; - int polys = 0; - glClear(clearbits); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glRotatef(current_device_rotation(), 0, 0, 1); - - /* setup light attenuation */ - /* #### apparently this does nothing */ - glEnable(GL_COLOR_MATERIAL); - glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.8/(0.01+findAlpha(qs))); - glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.06); - - /** setup perspective */ - glTranslatef(0.0, 0.0, -1.5*qs->BOARDSIZE); - glRotatef(30.0, 1.0, 0.0, 0.0); - gltrackball_rotate (qs->trackball); - glRotatef(qs->theta*100, 0.0, 1.0, 0.0); - glTranslatef(-0.5*qs->BOARDSIZE, 0.0, -0.5*qs->BOARDSIZE); - - /* find light positions */ - qs->position[0] = qs->BOARDSIZE/2.0 + qs->BOARDSIZE/1.4*-sin(qs->theta*100*M_PI/180.0); - qs->position[2] = qs->BOARDSIZE/2.0 + qs->BOARDSIZE/1.4*cos(qs->theta*100*M_PI/180.0); - qs->position[1] = 6.0; - - if(!wire) { - glEnable(GL_LIGHTING); - glLightfv(GL_LIGHT0, GL_POSITION, qs->position); - glEnable(GL_LIGHT0); - } - - /* Since the lighting attenuation trick up there doesn't seem to be working, - let's drop the old board down and drop the new board in. */ - if (qs->steps < (max/8.0)) { - GLfloat y = qs->steps / (max/8.0); - y = sin (M_PI/2 * y); - glTranslatef (0, 10 - (y * 10), 0); - } else if (qs->steps > max-(max/8.0)) { - GLfloat y = (qs->steps - (max-(max/8.0))) / (GLfloat) (max/8.0); - y = 1 - sin (M_PI/2 * (1-y)); - glTranslatef (0, -y * 15, 0); - } - - /* draw reflections */ - if(!wire) { - polys += draw_reflections(qs); - glEnable(GL_BLEND); - } - polys += drawBoard(qs); - if(!wire) - glDisable(GL_BLEND); - - glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.1); - - glTranslatef(0.5, 0.0, 0.5); - polys += drawPieces(qs); - - /* rotate camera */ - if(!qs->button_down_p) - qs->theta += .002; - - /* zero out board, find new solution of size MINBOARD <= i <= MAXBOARD */ - if(++qs->steps == max) { - qs->steps = 0; - blank(qs); - qs->BOARDSIZE = MINBOARD + (random() % (MAXBOARD - MINBOARD + 1)); - qs->colorset = (qs->colorset+1)%COLORSETS; - go(qs); - } - return polys; -} - -#define EPSILON 0.001 - -#if 0 -/** draws cylindermodel */ -static int draw_model(int chunks, const GLfloat model[][3], int r) -{ - int i = 0; - int polys = 0; - glPushMatrix(); - glRotatef(-90.0, 1.0, 0.0, 0.0); - - for(i = 0; i < chunks; ++i) { - if(model[i][0] > EPSILON || model[i][1] > EPSILON) { - polys += tube (0, 0, 0, - 0, 0, model[i][1], - model[i][0], 0, - r, False, False, False); -/* gluCylinder(quadric, model[i][0], model[i][1], model[i][2], r, 1); - polys += r;*/ - } - glTranslatef(0.0, 0.0, model[i][2]); - } - - glPopMatrix(); - return polys; -} -#endif - -ENTRYPOINT void reshape_queens(ModeInfo *mi, int width, int height) -{ - GLfloat h = (GLfloat) height / (GLfloat) width; - int y = 0; - - if (width > height * 5) { /* tiny window: show middle */ - height = width; - y = -height/2; - h = height / (GLfloat) width; - } - glViewport(0,y, width, height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(45, 1/h, 2.0, 30.0); - glMatrixMode(GL_MODELVIEW); -} - -ENTRYPOINT void init_queens(ModeInfo *mi) -{ - int screen = MI_SCREEN(mi); - Queenscreen *qs; - int poly_counts[PIECES]; - wire = MI_IS_WIREFRAME(mi); - -# ifdef HAVE_JWZGLES /* #### glPolygonMode other than GL_FILL unimplemented */ - wire = 0; -# endif - - MI_INIT (mi, qss); - - qs = &qss[screen]; - qs->window = MI_WINDOW(mi); - - if((qs->glx_context = init_GL(mi))) - reshape_queens(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); - else - MI_CLEARWINDOW(mi); - - qs->trackball = gltrackball_init (False); - - qs->BOARDSIZE = 8; /* 8 cuz its classic */ - - chessmodels_gen_lists(-1, poly_counts); - qs->queen_list = QUEEN; - qs->queen_polys = poly_counts[QUEEN]; - - /* find a solution */ - go(qs); -} - -ENTRYPOINT void draw_queens(ModeInfo *mi) -{ - Queenscreen *qs = &qss[MI_SCREEN(mi)]; - Window w = MI_WINDOW(mi); - Display *disp = MI_DISPLAY(mi); - - if(!qs->glx_context) - return; - - glXMakeCurrent(disp, w, *qs->glx_context); - - if(flat) - glShadeModel(GL_FLAT); - - clearbits = GL_COLOR_BUFFER_BIT; - - glColorMaterial(GL_FRONT, GL_DIFFUSE); - glEnable(GL_COLOR_MATERIAL); - - if(!wire) { - setup_lights(qs); - glEnable(GL_DEPTH_TEST); - clearbits |= GL_DEPTH_BUFFER_BIT; - clearbits |= GL_STENCIL_BUFFER_BIT; - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - } - else - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - - mi->polygon_count = display(mi, qs); - mi->recursion_depth = qs->BOARDSIZE; - - if(mi->fps_p) do_fps(mi); - glFinish(); - glXSwapBuffers(disp, w); -} - - -ENTRYPOINT void free_queens(ModeInfo *mi) -{ - Queenscreen *qs = &qss[MI_SCREEN(mi)]; - int i; - if (!qs->glx_context) return; - glXMakeCurrent (MI_DISPLAY(mi), MI_WINDOW(mi), *qs->glx_context); - gltrackball_free (qs->trackball); - - /* this is horrible! List numbers are hardcoded! */ - for (i = 1; i <= 20; i++) - if (glIsList(i)) glDeleteLists(i, 1); -} - -XSCREENSAVER_MODULE ("Queens", queens) - -#endif |
