summaryrefslogtreecommitdiffstats
path: root/hacks/glx/topblock.c
diff options
context:
space:
mode:
Diffstat (limited to 'hacks/glx/topblock.c')
-rw-r--r--hacks/glx/topblock.c889
1 files changed, 0 insertions, 889 deletions
diff --git a/hacks/glx/topblock.c b/hacks/glx/topblock.c
deleted file mode 100644
index 4976a6f..0000000
--- a/hacks/glx/topblock.c
+++ /dev/null
@@ -1,889 +0,0 @@
-/* topblock, Copyright (c) 2006-2012 rednuht <topblock.xscreensaver@jumpstation.co.uk>
- *
- * 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.
- *
- *
- *
-
-topBlock - a simple openGL 3D hack of falling blocks
-based on jwz's dangerball hack
-
-The proporations of the blocks and their features is not even close to the commercial building block products offered by a variety companies.
-
-information on this hack might be found at
-http://www.jumpstation.co.uk/xscreensaver/topblock/
-
-History
-25/02/2006 v1.0 release
-29/04/2006 v1.11 updated to better fit with xscreensaver v5
- colors defaults to 7 (no black)
-19/06/2006 v1.2 fixed dropSpeed = 7 bug, added gltrackball support and some code neatening, thanks to Valdis Kletnieks and JWZ for their input.
-*/
-
-#include <math.h>
-
-# define release_topBlock 0
-
-#define DEFAULTS "*delay: 10000 \n" \
- "*count: 30 \n" \
- "*showFPS: False \n" \
- "*wireframe: False \n" \
-
-#include "xlockmore.h"
-#include "topblock.h"
-#include "sphere.h"
-#include "tube.h"
-#include "gltrackball.h"
-#include <ctype.h>
-
-#ifdef USE_GL /* whole file */
-
-#ifndef HAVE_JWXYZ
-# include <GL/glu.h>
-#endif
-
-typedef struct
-{
- GLXContext *glx_context;
- trackball_state *trackball;
- GLfloat rotateSpeed;
- GLfloat dropSpeed;
- int maxFalling;
- int resolution;
- Bool button_down_p;
- int numFallingBlocks;
- GLfloat highest,highestFalling;
- GLfloat eyeLine,eyeX,eyeY,eyeZ;
- int carpetWidth, carpetLength;
- int followMode;
- GLfloat followRadius,followAngle;
- int plusheight;
- GLuint carpet;
- GLuint block;
- int carpet_polys, block_polys;
- NODE *blockNodeRoot;
- NODE *blockNodeFollow;
- GLfloat rotation;
-} topBlockSTATE;
-
-/* parameter vars */
-static Bool override;
-static Bool rotate;
-static Bool follow;
-static Bool drawCarpet;
-static Bool drawBlob;
-static Bool drawNipples;
-static GLfloat rotateSpeed;
-static GLfloat camX;
-static GLfloat camY;
-static GLfloat camZ;
-static GLfloat dropSpeed;
-static int maxFalling;
-static int maxColors;
-static int size;
-static int spawn;
-static int resolution;
-
-static XrmOptionDescRec opts[] = {
- { "-size", ".size", XrmoptionSepArg, 0 },
- { "-spawn", ".spawn", XrmoptionSepArg, 0 },
- { "-camX", ".camX", XrmoptionSepArg, 0 },
- { "-camY", ".camY", XrmoptionSepArg, 0 },
- { "-camZ", ".camZ", XrmoptionSepArg, 0 },
- { "+rotate", ".rotate", XrmoptionNoArg, "False" },
- { "-rotate", ".rotate", XrmoptionNoArg, "True" },
- { "+carpet", ".carpet", XrmoptionNoArg, "False" },
- { "+nipples", ".nipples", XrmoptionNoArg, "False" },
- { "-blob", ".blob", XrmoptionNoArg, "True" },
- { "-rotateSpeed", ".rotateSpeed", XrmoptionSepArg, 0 },
- { "-follow", ".follow", XrmoptionNoArg, "True" },
- { "-maxFalling", ".maxFalling", XrmoptionSepArg, 0 },
- { "-resolution", ".resolution", XrmoptionSepArg, 0 },
- { "-maxColors", ".maxColors", XrmoptionSepArg, 0 },
- { "-dropSpeed", ".dropSpeed", XrmoptionSepArg, 0 },
- { "-override", ".override", XrmoptionNoArg, "True" },
-};
-
-#define DEF_OVERRIDE "False"
-#define DEF_ROTATE "True"
-#define DEF_FOLLOW "False"
-#define DEF_CARPET "True"
-#define DEF_BLOB "False"
-#define DEF_NIPPLES "True"
-#define DEF_ROTATE_SPEED "10"
-#define DEF_MAX_FALLING "500"
-#define DEF_MAX_COLORS "7"
-#define DEF_SIZE "2"
-#define DEF_SPAWN "50"
-#define DEF_RESOLUTION "4"
-#define DEF_CAM_X "1"
-#define DEF_CAM_Y "20"
-#define DEF_CAM_Z "25"
-#define DEF_DROP_SPEED "4"
-
-static argtype vars[] = {
- {&override, "override", "Override", DEF_OVERRIDE, t_Bool},
- {&rotate, "rotate", "Rotate", DEF_ROTATE, t_Bool},
- {&drawCarpet, "carpet", "Carpet", DEF_CARPET, t_Bool},
- {&drawNipples, "nipples", "Nipples", DEF_NIPPLES, t_Bool},
- {&drawBlob, "blob", "Blob", DEF_BLOB, t_Bool},
- {&rotateSpeed, "rotateSpeed", "RotateSpeed", DEF_ROTATE_SPEED, t_Float},
- {&follow, "follow", "Follow", DEF_FOLLOW, t_Bool},
- {&camX, "camX", "camX", DEF_CAM_X, t_Float},
- {&camY, "camY", "camY", DEF_CAM_Y, t_Float},
- {&camZ, "camZ", "camZ", DEF_CAM_Z, t_Float},
- {&size, "size", "size", DEF_SIZE, t_Int},
- {&spawn, "spawn", "spawn", DEF_SPAWN, t_Int},
- {&maxFalling, "maxFalling", "maxFalling", DEF_MAX_FALLING, t_Int},
- {&resolution, "resolution", "resolution", DEF_RESOLUTION, t_Int},
- {&maxColors, "maxColors", "maxColors", DEF_MAX_COLORS, t_Int},
- {&dropSpeed, "dropSpeed", "DropSpeed", DEF_DROP_SPEED, t_Float},
-};
-
-static topBlockSTATE *tbs = NULL;
-
-static ModeSpecOpt topBlock_opts = {countof(opts), opts, countof(vars), vars, NULL};
-
-/* Window management, etc */
-ENTRYPOINT void
-reshape_topBlock (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*1.5;
- y = -height*0.2;
- h = height / (GLfloat) width;
- }
- glViewport (0, y, (GLint) width, (GLint) height);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective (60.0, 1/h, 1.0, 1000.0);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glClear(GL_COLOR_BUFFER_BIT);
-}
-
-/* clean up on exit, not required ... */
-ENTRYPOINT void
-free_topBlock(ModeInfo *mi)
-{
- topBlockSTATE *tb = &tbs[MI_SCREEN(mi)];
- NODE *llCurrent, *llOld;
-
- if (!tb->glx_context) return;
- glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *tb->glx_context);
-
- llCurrent = tb->blockNodeRoot;
- while (llCurrent != NULL) {
- llOld = llCurrent;
- llCurrent = llCurrent->next;
- free(llOld);
- }
- if (tb->trackball) gltrackball_free (tb->trackball);
- if (glIsList(tb->carpet)) glDeleteLists(tb->carpet, 1);
- if (glIsList(tb->block)) glDeleteLists(tb->block, 1);
-}
-
-/* setup */
-ENTRYPOINT void
-init_topBlock (ModeInfo *mi)
-{
- topBlockSTATE *tb;
- int wire = MI_IS_WIREFRAME(mi);
-
- MI_INIT (mi, tbs);
-
- tb = &tbs[MI_SCREEN(mi)];
-
- tb->glx_context = init_GL(mi);
-
- reshape_topBlock (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
-
-/* if (wire) { drawNipples=False; }*/
- tb->numFallingBlocks=0;
-
- if (size>10) { size = 10; }
- if (size<1) { size = 2; }
- tb->carpetWidth = 8 * size;
- tb->carpetLength = tb->carpetWidth;
-
- tb->maxFalling = maxFalling;
- tb->maxFalling*=size;
-
- if (spawn<4) { spawn=4; }
- if (spawn>1000) { spawn=1000; }
-
- tb->rotateSpeed = rotateSpeed;
- if (tb->rotateSpeed<1) {tb->rotateSpeed=1; }
- if (tb->rotateSpeed>1000) {tb->rotateSpeed=1000;}
- tb->rotateSpeed /= 100;
-
- tb->resolution = resolution;
- if (tb->resolution<4) {tb->resolution=4;}
- if (tb->resolution>20) {tb->resolution=20;}
- tb->resolution*=2;
-
- if (maxColors<1) {maxColors=1;}
- if (maxColors>8) {maxColors=8;}
-
- tb->dropSpeed = dropSpeed;
- if (tb->dropSpeed<1) {tb->dropSpeed=1;}
- if (tb->dropSpeed>9) {tb->dropSpeed=9;} /* 10+ produces blocks that can pass through each other */
-
- tb->dropSpeed = 80/tb->dropSpeed;
- tb->dropSpeed = (blockHeight/tb->dropSpeed);
-
- reshape_topBlock (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
- glClearDepth(1.0f);
- if (!wire) {
- GLfloat pos[4] = {10.0, 10.0, 1.0, 0.0};
- GLfloat amb[4] = {0.1, 0.1, 0.1, 1.0};
- GLfloat dif[4] = {1.0, 1.0, 1.0, 1.0};
- GLfloat spc[4] = {0.0, 1.0, 1.0, 1.0};
-
- glEnable(GL_LIGHTING);
- glEnable(GL_LIGHT0);
- glLightfv(GL_LIGHT0, GL_POSITION, pos);
- glLightfv(GL_LIGHT0, GL_AMBIENT, amb);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, dif);
- glLightfv(GL_LIGHT0, GL_SPECULAR, spc);
- }
- glDepthFunc(GL_LEQUAL);
- glEnable(GL_DEPTH_TEST);
- glDisable(GL_CULL_FACE); /* all objects exhibit a reverse side */
- glCullFace(GL_BACK);
-
- if (drawBlob) {
- buildBlobBlock(mi);
- } else {
- buildBlock(mi); /* build the display list holding the simple block */
- }
- buildCarpet(mi); /* build the base */
- tb->highest=0;
- tb->highestFalling=0;
- tb->eyeLine=tb->highest;
- tb->eyeX=0;
- tb->eyeY=0;
- tb->eyeZ=0;
- tb->followMode=0;
- if (follow) {
- tb->plusheight=100;
- camZ=camZ-60;
- } else {
- tb->rotation=random() % 360;
- tb->eyeY=10;
- tb->plusheight=30;
- }
- tb->followRadius=0;
- /* override camera settings */
- if (override) {
- tb->plusheight=100;
- drawCarpet=False;
- camX=0;
- camY=1;
- camZ=0;
- tb->eyeX=-1;
- tb->eyeY=20;
- tb->eyeZ=0;
- }
- tb->trackball = gltrackball_init (False);
-}
-
-/* provides the per frame entertainment */
-ENTRYPOINT void
-draw_topBlock (ModeInfo *mi)
-{
- Display *dpy = MI_DISPLAY(mi);
- Window window = MI_WINDOW(mi);
- NODE *llCurrent;
- NODE *llNode;
- topBlockSTATE *tb = &tbs[MI_SCREEN(mi)];
- GLfloat spcN1x,spcN1y,spcN2x,spcN2y;
- GLfloat spcC1x,spcC1y,spcC2x,spcC2y;
- int wire = MI_IS_WIREFRAME(mi);
- GLfloat color[4];
-
- if (!tb->glx_context)
- return;
- glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *tb->glx_context);
- mi->polygon_count = 0;
-
- generateNewBlock(mi);
-
- if (rotate && (!tb->button_down_p)) { tb->rotation += tb->rotateSpeed; }
- if (tb->rotation>=360) { tb->rotation=tb->rotation-360; }
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* clear current */
- glLoadIdentity(); /* resets directions, do it every time ! */
- glRotatef(current_device_rotation(), 0, 0, 1);
-
- if (!follow) {
- if (tb->highest>tb->eyeLine) { tb->eyeLine+=((tb->highest-tb->eyeLine)/100); } /* creates a smooth camera transition */
- gluLookAt(camX, camY+tb->eyeLine, camZ, tb->eyeX, tb->eyeY+tb->eyeLine, tb->eyeZ, 0.0, 1.0, 0.0); /* setup viewer, xyz cam, xyz looking at and where is up normaly 0,1,0 */
- glRotatef(90, 1.0, 0.0, 0.0); /* x axis */
- } else {
- glRotatef(90, 0.0, 0.0, 1.0); /* z axis */
- followBlock(mi);
- }
-
- /* Rotate the scene around a point that's a little higher up. */
- glTranslatef (0, 0, -5);
- gltrackball_rotate (tb->trackball);
- glTranslatef (0, 0, 5);
-
- /* rotate the world */
- glRotatef(tb->rotation, 0.0, 0.0, 1.0);
-
-#if 0 /* This makes the blocks pop into existence already on screen */
- /* We should just make them drop from higher, but it's not obvious
- to me where that is set. */
- {
- GLfloat s = (MI_WIDTH(mi) < MI_HEIGHT(mi)
- ? (MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi))
- : 1);
- glScalef (s, s, s);
- }
-#endif
-
- llCurrent = tb->blockNodeRoot;
- if (drawCarpet) {
- /* center carpet */
- glTranslatef(0.0-(tb->carpetWidth/2),0.0-(tb->carpetLength/2),0.0);
- glCallList(tb->carpet);
- mi->polygon_count += tb->carpet_polys;
- glTranslatef(0.0+(tb->carpetWidth/2),0.0+(tb->carpetLength/2),0.0);
- glTranslatef(0.0,0.0,-0.55);
- }
- tb->highestFalling=0;
- while (llCurrent != NULL) { /* for each block */
- glPushMatrix(); /* save state */
- /* set color */
- switch (llCurrent->color) {
- case 0:
- color[0] = 1.0f;
- color[1] = 0.0f;
- color[2] = 0.0f;
- color[3] = 1.0f;
- break;
- case 1:
- color[0] = 0.0f;
- color[1] = 1.0f;
- color[2] = 0.0f;
- color[3] = 1.0f;
- break;
- case 2:
- color[0] = 0.0f;
- color[1] = 0.0f;
- color[2] = 1.0f;
- color[3] = 1.0f;
- break;
- case 3:
- color[0] = 0.95f;
- color[1] = 0.95f;
- color[2] = 0.95f;
- color[3] = 1.0f;
- break;
- case 4:
- color[0] = 1.0f;
- color[1] = 0.5f;
- color[2] = 0.0f;
- color[3] = 1.0f;
- break;
- case 5:
- color[0] = 1.0f;
- color[1] = 1.0f;
- color[2] = 0.0f;
- color[3] = 1.0f;
- break;
- case 6:
- color[0] = 0.5f;
- color[1] = 0.5f;
- color[2] = 0.5f;
- color[3] = 1.0f;
- break;
- case 7:
- color[0] = 0.05f;
- color[1] = 0.05f;
- color[2] = 0.05f;
- color[3] = 1.0f;
- break;
- }
- if (wire) { glColor3fv(color); }
- else { glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); }
-
- if (llCurrent->falling==1) {
- spcC2x = 0;
- spcC2y = 0;
- spcN2x = 0;
- spcN2y = 0;
- if (llCurrent->height>tb->highestFalling) {tb->highestFalling=llCurrent->height;}
- /* all blocks fall at the same rate to avoid mid air collisions */
- llCurrent->height-=tb->dropSpeed;
- if (llCurrent->height<=0) {
- llCurrent->falling=0;
- if (tb->highest==0) {
- tb->highest+=blockHeight;
- }
- }
- if ( (llCurrent->height<=tb->highest+1) && (llCurrent->falling==1) ) {
- /* check for collision */
- llNode = tb->blockNodeRoot;
- spcC1x = llCurrent->x;
- spcC1y = llCurrent->y;
- switch(llCurrent->rotation) {
- case getOrientation(0):
- spcC2x = spcC1x;
- spcC2y = spcC1y-2;
- break;
- case getOrientation(1):
- spcC2x = spcC1x+2;
- spcC2y = spcC1y;
- break;
- case getOrientation(2):
- spcC2x = spcC1x;
- spcC2y = spcC1y+2;
- break;
- case getOrientation(3):
- spcC2x = spcC1x-2;
- spcC2y = spcC1y;
- break;
- }
- while (llNode != NULL) {
- if ( (llNode->falling==0) && (llCurrent->falling==1) ) {
- spcN1x = llNode->x;
- spcN1y = llNode->y;
- switch(llNode->rotation) {
- case getOrientation(0):
- spcN2x = spcN1x;
- spcN2y = spcN1y-2;
- break;
- case getOrientation(1):
- spcN2x = spcN1x+2;
- spcN2y = spcN1y;
- break;
- case getOrientation(2):
- spcN2x = spcN1x;
- spcN2y = spcN1y+2;
- break;
- case getOrientation(3):
- spcN2x = spcN1x-2;
- spcN2y = spcN1y;
- break;
- }
- if (
- ( (spcC1x==spcN1x) && (spcC1y==spcN1y) ) ||
- ( (spcC1x==spcN2x) && (spcC1y==spcN2y) ) ||
- ( (spcC2x==spcN2x) && (spcC2y==spcN2y) ) ||
- ( (spcC2x==spcN1x) && (spcC2y==spcN1y) )
- ){
- if ( fabs(llCurrent->height-(llNode->height+blockHeight)) <= TOLERANCE) {
-
- llCurrent->falling=0;
- llCurrent->height=llNode->height+blockHeight; /* if this is missing then small errors build up until the model fails */
- if ( fabs(llCurrent->height-tb->highest) <= TOLERANCE+blockHeight ) {
- tb->highest+=blockHeight;
- }
- }
- }
- }
- llNode=llNode->next;
- }
- }
- }
- /* set location in space */
- glTranslatef(llCurrent->x,llCurrent->y,-llCurrent->height);
- /* rotate */
- glRotatef(llCurrent->rotation, 0.0f, 0.0f, 1.0f);
- if ((tb->followMode==0) && (llCurrent->next==NULL)) {
- tb->blockNodeFollow = llCurrent;
- tb->followMode=1;
- }
- llCurrent = llCurrent->next;
- /* draw */
- glCallList(tb->block);
- mi->polygon_count += tb->block_polys;
- glPopMatrix(); /* restore state */
- }
- if (mi->fps_p) do_fps (mi);
- glFinish();
-
- if (tb->highest>(5*tb->maxFalling)) { drawCarpet=False; }
- glXSwapBuffers(dpy, window);
-}
-
-
-
-/* camera is in follow mode, work out where we should be looking */
-static void followBlock(ModeInfo *mi)
-{
- GLfloat xLen,yLen,cx,cy,rangle,xTarget,yTarget;
- topBlockSTATE *tb = &tbs[MI_SCREEN(mi)];
- cx=0;cy=0;
- if ((tb->blockNodeFollow!=NULL) && (tb->followMode==1)){
-
- if (tb->highest>tb->eyeLine) { tb->eyeLine+= ((tb->highest-tb->eyeLine)/100); }
- /*tb->blockNodeFollow->color=1; only noticable if you set the colors to 1 */
-
- if (tb->blockNodeFollow->height > tb->eyeZ) { tb->eyeZ+= ((tb->blockNodeFollow->height - tb->eyeZ)/100); }
- if (tb->blockNodeFollow->height < tb->eyeZ) { tb->eyeZ-= ((tb->eyeZ - tb->blockNodeFollow->height)/100); }
-
-
- /* when the scene is rotated we need to know where the block is in the 2 dimensional coordinates of the carpet area
- (see http://www.jumpstation.co.uk/rotation/)
- */
-
- if (tb->followRadius==0) {
- xLen = tb->blockNodeFollow->x-cx;
- yLen = tb->blockNodeFollow->y-cy;
- tb->followRadius=sqrt( (xLen*xLen) + (yLen*yLen) );
- tb->followAngle = (180/M_PI) * asin(xLen/tb->followRadius);
- tb->followAngle = quadrantCorrection(tb->followAngle,(int)cx,(int)cy,(int)tb->blockNodeFollow->x,(int)tb->blockNodeFollow->y);
- }
- rangle = (tb->followAngle+tb->rotation) * M_PI /180;
- xTarget = cos(rangle) * tb->followRadius + cx;
- yTarget = sin(rangle) * tb->followRadius + cy;
- if (tb->followAngle>360) { tb->followAngle=tb->followAngle-360; }
-
- if (xTarget < tb->eyeX) { tb->eyeX-= ((tb->eyeX - xTarget)/100); }
- if (xTarget > tb->eyeX) { tb->eyeX+= ((xTarget - tb->eyeX)/100); }
-
- if (yTarget < tb->eyeY) { tb->eyeY-= ((tb->eyeY - yTarget)/100); }
- if (yTarget > tb->eyeY) { tb->eyeY+= ((yTarget - tb->eyeY)/100); }
- if (!tb->blockNodeFollow->falling) {
- tb->followMode=0;
- /*tb->blockNodeFollow->color=2; only noticable if you set the colors to 1 */
- tb->followRadius=0;
- }
- }
- gluLookAt(camX, camY, camZ-tb->eyeLine, tb->eyeX, tb->eyeY, -tb->eyeZ,-1.0,0.0,0.0);
-}
-
-/* each quater of the circle has to be adjusted for */
-static double quadrantCorrection(double angle,int cx,int cy,int x,int y)
-{
- if ((x>=cx) && (y>=cy)) {
- angle += (90-(angle-90) * 2);
- } else if ((x>=cx) && (y<=cy)) {
- angle += 90;
- } else if ((x<=cx) && (y<=cy)) {
- angle += 90;
- } else if ((x<=cx) && (y>=cy)) {
- angle += (90-(angle-90) * 2);
- }
- return(angle-180);
-}
-
-/* if random chance then create a new falling block */
-static void generateNewBlock(ModeInfo *mi)
-{
- NODE *llCurrent, *llTail;
- GLfloat startOffx, startOffy;
- int endOffx, endOffy;
- topBlockSTATE *tb = &tbs[MI_SCREEN(mi)];
- if ( ((random() % spawn) == 1) && (tb->highestFalling<getHeight((tb->plusheight-blockHeight)+tb->highest)) ) {
- startOffx=0;
- endOffx=0;
- startOffy=0;
- endOffy=0;
- tb->numFallingBlocks++;
- llTail = tb->blockNodeRoot;
- if (llTail == NULL) {
- llCurrent = ((NODE*) malloc(sizeof(NODE)));
- if (!llCurrent) abort();
- llTail = llCurrent;
- tb->blockNodeRoot = llCurrent;
- } else {
- if (tb->numFallingBlocks>=tb->maxFalling) {
- /* recycle */
- llCurrent=llTail->next;
- tb->blockNodeRoot=llCurrent->next;
- } else {
- llCurrent = ((NODE*) malloc(sizeof(NODE)));
- if (!llCurrent) abort();
- }
- while (llTail->next != NULL) { llTail = llTail->next; } /* find last item in list */
- }
- llCurrent->falling=1;
- llCurrent->rotation=getOrientation(random() % 4);
- if (llCurrent->rotation==getOrientation(0)) {
- startOffx=1.0;
- endOffx=0;
- startOffy=3.0;
- endOffy=-1;
- } else if (llCurrent->rotation==getOrientation(1)) {
- startOffx=1.0;
- endOffx=-1;
- startOffy=1.0;
- endOffy=0;
- } else if (llCurrent->rotation==getOrientation(2)) {
- startOffx=1.0;
- endOffx=0;
- startOffy=3.0;
- endOffy=-1;
- } else if (llCurrent->rotation==getOrientation(3)) {
- startOffx=5.0;
- endOffx=-1;
- startOffy=1.0;
- endOffy=0;
- }
-
- llCurrent->x=(startOffx-(tb->carpetLength/2)) + getLocation(random() % ((tb->carpetLength/2)+endOffx) );
- llCurrent->y=(startOffy-(tb->carpetLength/2)) + getLocation(random() % ((tb->carpetLength/2)+endOffy) );
- llCurrent->color=(random() % maxColors);
- llCurrent->height=getHeight(tb->plusheight+tb->highest);
- if (tb->numFallingBlocks>=tb->maxFalling) {
- tb->numFallingBlocks--;
- tb->numFallingBlocks--;
- }
- llTail->next = llCurrent;
- llTail = llCurrent;
- llTail->next = NULL;
-
- }
-}
-
-/* called at init this creates the 'carpet' display list item */
-static void buildCarpet(ModeInfo *mi)
-{
- int i,c,x,y;
- GLfloat color[4];
- int wire = MI_IS_WIREFRAME(mi);
- topBlockSTATE *tb = &tbs[MI_SCREEN(mi)];
- color[0] = 0.0f;
- color[1] = 1.0f;
- color[2] = 0.0f;
- color[3] = 1.0f;
- tb->carpet=glGenLists(1); /* only one */
- glNewList(tb->carpet,GL_COMPILE);
- tb->carpet_polys=0;
- glPushMatrix(); /* save state */
- x=tb->carpetWidth;
- y=tb->carpetLength;
- if (wire) { glColor3fv(color); }
- else { glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); }
- /* draw carpet plane */
- glBegin( wire ? GL_LINE_LOOP : GL_QUADS );
- /* draw top */
- glNormal3f( 0, 0, -1 );
- glVertex3f(0.0,0.0,0.0);
- glVertex3f(x,0.0,0.0);
- glVertex3f(x,y,0.0);
- glVertex3f(0.0,y,0.0);
- tb->carpet_polys++;
- if (!wire) {
- /* add edge pieces */
- /* side 1 */
- glNormal3f( 0, -1, 0 );
- glVertex3f(0.0,0.0,0.0);
- glVertex3f(x,0.0,0.0);
- glVertex3f(x,0,singleThick);
- glVertex3f(0.0,0,singleThick);
- tb->carpet_polys++;
- /* side 2 */
- glNormal3f( -1, 0, 0 );
- glVertex3f(0.0,0.0,0.0);
- glVertex3f(0,y,0.0);
- glVertex3f(0,y,singleThick);
- glVertex3f(0.0,0,singleThick);
- tb->carpet_polys++;
- /* side 3 */
- glNormal3f( 1, 0, 0 );
- glVertex3f(x,0.0,0.0);
- glVertex3f(x,y,0.0);
- glVertex3f(x,y,singleThick);
- glVertex3f(x,0,singleThick);
- tb->carpet_polys++;
- /* side 4 */
- glNormal3f( 0, 1, 0 );
- glVertex3f(0,y,0.0);
- glVertex3f(x,y,0.0);
- glVertex3f(x,y,singleThick);
- glVertex3f(0,y,singleThick);
- tb->carpet_polys++;
- }
- glEnd();
- /* nipples */
- if (drawNipples) {
- glTranslatef(0.5f,0.5f,-.25); /* move to the cylinder center */
- for (c=0;c<x;c++) {
- glPushMatrix(); /* save state */
- for (i=0;i<y;i++) {
- tb->carpet_polys += tube(0, 0, -0.1,
- 0, 0, 0.26,
- cylSize, 0,
- tb->resolution, True, True,
- wire);
- glRotatef(180, 0.0f, 1.0f, 0.0f); /* they are upside down */
- glRotatef(180, 0.0f, 1.0f, 0.0f); /* recover */
- glTranslatef(0.0f,1.0f,0.0f); /* move to the next cylinder center (backward) */
- }
- glPopMatrix(); /* save state */
- glTranslatef(1.0f,0.0f,0.0f); /* reset */
- }
- }
- glPopMatrix(); /* restore state */
- glEndList();
-}
-
-/* using the verticies arrays builds the plane, now with normals */
-static void polygonPlane(int wire, int a, int b, int c , int d, int i)
-{
- GLfloat topBlockNormals[5][3] = { {0,0,-1}, {0,1,0}, {1,0,0}, {0,0,1}, {0,-1,0} };
- GLfloat topBlockVertices[8][3] = { {-0.49,-2.97,-0.99}, {0.99,-2.97,-0.99}, {0.99,0.99,-0.99} , {-0.49,0.99,-0.99}, {-0.49,-2.97,0.99} , {0.99,-2.97,0.99}, {0.99,0.99,0.99} , {-0.49,0.99,0.99} };
- glBegin( wire ? GL_LINE_LOOP : GL_POLYGON);
- glNormal3fv(topBlockNormals[i] );
- glVertex3fv(topBlockVertices[a]);
- glVertex3fv(topBlockVertices[b]);
- glVertex3fv(topBlockVertices[c]);
- glVertex3fv(topBlockVertices[d]);
- glEnd();
-}
-
-/* called at init this creates the 'block' display list item */
-/* the spheres came about originaly as quick way to test the directional lighting/normals */
-static void buildBlock(ModeInfo *mi)
-{
- int i,c;
- int wire = MI_IS_WIREFRAME(mi);
- topBlockSTATE *tb = &tbs[MI_SCREEN(mi)];
- tb->block=glGenLists(1); /* only one */
- glNewList(tb->block,GL_COMPILE);
- tb->block_polys=0;
- glPushMatrix(); /* save state */
- glRotatef(90, 0.0f, 1.0f, 0.0f);
- /* base */
- polygonPlane(wire, 0,3,2,1,0); tb->block_polys++;
- polygonPlane(wire, 2,3,7,6,1); tb->block_polys++;
- polygonPlane(wire, 1,2,6,5,2); tb->block_polys++;
- polygonPlane(wire, 4,5,6,7,3); tb->block_polys++;
- polygonPlane(wire, 0,1,5,4,4); tb->block_polys++;
- if (drawNipples) {
- /* nipples */
- /* draw 8 cylinders each with a disk cap */
- glRotatef(90, 0.0f, 1.0f, 0.0f); /* 'aim' the pointer ready for the cylinder */
- glTranslatef(0.5f,0.5f,0.99f); /* move to the cylinder center */
- for (c=0;c<2;c++) {
- for (i=0;i<4;i++) {
- tb->block_polys += tube(0, 0, 0,
- 0, 0, 0.25,
- cylSize, 0,
- tb->resolution, True, True,
- wire);
- glTranslatef(0.0f,0.0f,0.25f); /* move to the cylinder cap */
- glTranslatef(0.0f,0.0f,-0.25f); /* move back from the cylinder cap */
- if (c==0) {
- glTranslatef(0.0f,-1.0f,0.0f); /* move to the next cylinder center (forward) */
- } else {
- glTranslatef(0.0f,1.0f,0.0f); /* move to the next cylinder center (backward) */
- }
- }
- glTranslatef(-1.0f,1.0f,0.0f); /* move to the cylinder center */
- }
- /* udders */
- /* 3 cylinders on the underside */
- glTranslatef(1.5f,-2.5f,-1.5f); /* move to the center, under the top of the brick */
- if (! wire)
- for (c=0;c<3;c++) {
- tb->block_polys += tube(0, 0, 0.1,
- 0, 0, 1.4,
- uddSize, 0,
- tb->resolution, True, True, wire);
- glTranslatef(0.0f,-1.0f,0.0f); /* move to the center */
- }
- }
- glPopMatrix(); /* restore state */
- glEndList();
-}
-
-/*
- rip off of the builBlock() function creating the GL compilied pointer "block" but only creates two spheres.
- spheres are created with unit_sphere from spheres.h to allow wire frame
-*/
-static void buildBlobBlock(ModeInfo *mi)
-{
- int wire = MI_IS_WIREFRAME(mi);
- topBlockSTATE *tb = &tbs[MI_SCREEN(mi)];
- tb->block=glGenLists(1); /* only one */
- glNewList(tb->block,GL_COMPILE);
- glPushMatrix();
- glScalef(1.4,1.4,1.4);
- unit_sphere (tb->resolution/2,tb->resolution, wire);
- glPopMatrix();
- glTranslatef(0.0f,-2.0f,0.0f);
- glScalef(1.4,1.4,1.4);
- unit_sphere (tb->resolution/2,tb->resolution, wire);
- glEndList();
-}
-
-
-/* handle input events or not if daemon running the show */
-ENTRYPOINT Bool
-topBlock_handle_event (ModeInfo *mi, XEvent *event)
-{
- topBlockSTATE *tb = &tbs[MI_SCREEN(mi)];
-
- if (gltrackball_event_handler (event, tb->trackball,
- MI_WIDTH (mi), MI_HEIGHT (mi),
- &tb->button_down_p))
- return True;
- else if (event->xany.type == KeyPress) {
- KeySym keysym;
- char c = 0;
- XLookupString (&event->xkey, &c, 1, &keysym, 0);
- if (c == 'a') {
- tb->eyeX++;
- return True;
- } else if (c == 'z') {
- tb->eyeX--;
- return True;
- } else if (c == 's') {
- tb->eyeY--;
- return True;
- } else if (c == 'x') {
- tb->eyeY++;
- return True;
- } else if (c == 'd') {
- tb->eyeZ++;
- return True;
- } else if (c == 'c') {
- tb->eyeZ--;
- return True;
- } else if (c == 'f') {
- camX++;
- return True;
- } else if (c == 'v') {
- camX--;
- return True;
- } else if (c == 'g') {
- camY++;
- return True;
- } else if (c == 'b') {
- camY--;
- return True;
- } else if (c == 'h') {
- camZ++;
- return True;
- } else if (c == 'n') {
- camZ--;
- return True;
- } else if (c == 'r') {
- tb->rotation++;
- return True;
- }
- }
-
- return False;
-}
-
-/* this is tha main change for v5 compatability and acompanying ENTRYPOINTS */
-XSCREENSAVER_MODULE_2 ("TopBlock", topblock, topBlock)
-
-#endif /* USE_GL */