From d3a98cf6cbc3bd0b9efc570f58e8812c03931c18 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 16 Oct 2018 10:08:48 +0200 Subject: Original 5.40 --- hacks/glx/blinkbox.c | 608 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 608 insertions(+) create mode 100644 hacks/glx/blinkbox.c (limited to 'hacks/glx/blinkbox.c') diff --git a/hacks/glx/blinkbox.c b/hacks/glx/blinkbox.c new file mode 100644 index 0000000..f777371 --- /dev/null +++ b/hacks/glx/blinkbox.c @@ -0,0 +1,608 @@ +/* blinkbox, Copyright (c) 2003 Jeremy English + * + * 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. + */ + +/* motion blur added March 2005 by John Boero + */ + +#define DEFAULTS "*delay: 30000 \n" \ + "*wireframe: False \n" \ + "*suppressRotationAnimation: True\n" \ + +# define free_ball 0 +# define release_ball 0 +# define ball_handle_event xlockmore_no_events +#undef countof +#define countof(x) (sizeof((x))/sizeof((*x))) + +#include "xlockmore.h" +#include "sphere.h" +#include + +#ifdef USE_GL /* whole file */ + +#define MAX_COUNT 20 +#define ALPHA_AMT 0.05 + +/* this should be between 1 and 8 */ +#define DEF_BOXSIZE "2" +#define DEF_DISSOLVE "False" +#define DEF_FADE "True" +#define DEF_BLUR "True" + + +typedef struct{ + GLfloat x,y,z; +} Tdpos; + +typedef struct{ + int hit; + Tdpos pos; + int counter; + GLfloat color[3]; + GLfloat rot[4]; + int des_count; + int alpha_count; +}Side; + +struct Bounding_box { + Tdpos top; + Tdpos bottom; +}; + +struct Ball { + GLfloat x; + GLfloat y; + GLfloat z; + int d; +}; + +struct bscale { + GLfloat wh; /*width Height*/ + GLfloat d; /*depth*/ +}; + +static const struct Bounding_box bbox = {{14,14,20},{-14,-14,-20}}; + +typedef struct { + GLXContext *glx_context; + + struct Ball ball; + + struct bscale bscale; + + Tdpos mo; /*motion*/ + Tdpos moh; /*hold motion value*/ + + Tdpos bpos; + + GLuint ballList; + GLuint boxList; + GLfloat des_amt; + + /*sides*/ + Side lside;/*Red*/ + Side rside;/*Green*/ + Side tside;/*Blue*/ + Side bside;/*Orange*/ + Side fside;/*Yellow*/ + Side aside;/*Purple*/ + Side *sp; + +} blinkboxstruct; + +static blinkboxstruct *blinkbox = (blinkboxstruct *) NULL; + + +/* lights */ +static const float LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f }; +static const float LightPosition[]= { 20.0f, 100.0f, 20.0f, 1.0f }; + +static Bool do_dissolve; +static Bool do_fade; +static Bool do_blur; +static float bscale_wh; + +static XrmOptionDescRec opts[] = { + { "-boxsize", ".boxsize", XrmoptionSepArg, 0 }, + { "-dissolve", ".dissolve", XrmoptionNoArg, "True" }, + { "+dissolve", ".dissolve", XrmoptionNoArg, "False" }, + { "-fade", ".fade", XrmoptionNoArg, "True" }, + { "+fade", ".fade", XrmoptionNoArg, "False" }, + { "-blur", ".blur", XrmoptionNoArg, "True" }, + { "+blur", ".blur", XrmoptionNoArg, "False" } + +}; + +static argtype vars[] = { + {&bscale_wh, "boxsize", "Boxsize", DEF_BOXSIZE, t_Float}, + {&do_dissolve, "dissolve", "Dissolve", DEF_DISSOLVE, t_Bool}, + {&do_fade, "fade", "Fade", DEF_FADE, t_Bool}, + {&do_blur, "blur", "Blur", DEF_BLUR, t_Bool}, +}; + +ENTRYPOINT ModeSpecOpt ball_opts = {countof(opts), opts, countof(vars), vars, NULL}; + +static void +swap(GLfloat *a, GLfloat *b) +{ + GLfloat t = *a; + *a = *b; + *b = t; +} + +static float +get_rand(void) +{ + GLfloat j = 1+(random() % 2); + return (j); +} + +static void +swap_mov(GLfloat *a, GLfloat *b) +{ + int j; + swap(a,b); + j = get_rand(); + if (*a < 0) + *a = j * -1; + else + *a = j; +} + +static void +cp_b_pos(blinkboxstruct *bp, Tdpos *s_pos) +{ + s_pos->x = bp->ball.x; + s_pos->y = bp->ball.y; + s_pos->z = bp->ball.z; +} + +static void +hit_side(blinkboxstruct *bp) +{ + if ((bp->ball.x - bp->ball.d) <= bbox.bottom.x){ + bp->lside.hit = 1; + bp->lside.counter = MAX_COUNT; + bp->lside.des_count = 1; + bp->lside.alpha_count = 0; + cp_b_pos(bp, &bp->lside.pos); + swap_mov(&bp->mo.x,&bp->moh.x); + }else + if ((bp->ball.x + bp->ball.d) >= bbox.top.x){ + bp->rside.hit = 1; + bp->rside.counter = MAX_COUNT; + bp->rside.des_count = 1; + bp->rside.alpha_count = 0; + cp_b_pos(bp, &bp->rside.pos); + swap_mov(&bp->mo.x,&bp->moh.x); + } +} + +static void +hit_top_bottom(blinkboxstruct *bp) +{ + if ((bp->ball.y - bp->ball.d) <= bbox.bottom.y){ + bp->bside.hit = 1; + bp->bside.counter = MAX_COUNT; + bp->bside.des_count = 1; + bp->bside.alpha_count = 0; + cp_b_pos(bp, &bp->bside.pos); + swap_mov(&bp->mo.y,&bp->moh.y); + }else + if ((bp->ball.y + bp->ball.d) >= bbox.top.y){ + bp->tside.hit = 1; + bp->tside.counter = MAX_COUNT; + bp->tside.des_count = 1; + bp->tside.alpha_count = 0; + cp_b_pos(bp, &bp->tside.pos); + swap_mov(&bp->mo.y,&bp->moh.y); + } +} + +static void +hit_front_back(blinkboxstruct *bp) +{ + if ((bp->ball.z - bp->ball.d) <= bbox.bottom.z){ + bp->aside.hit = 1; + bp->aside.counter = MAX_COUNT; + bp->aside.des_count = 1; + bp->aside.alpha_count = 0; + cp_b_pos(bp, &bp->aside.pos); + swap_mov(&bp->mo.z,&bp->moh.z); + }else + if((bp->ball.z + bp->ball.d) >= bbox.top.z){ + bp->fside.hit = 1; + bp->fside.counter = MAX_COUNT; + bp->fside.des_count = 1; + bp->fside.alpha_count = 0; + cp_b_pos(bp, &bp->fside.pos); + swap_mov(&bp->mo.z,&bp->moh.z); + } +} + +ENTRYPOINT void +reshape_ball (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 * 9/16; + y = -height/2; + h = height / (GLfloat) width; + } + + glViewport (0, y, (GLint) width, (GLint) height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective (30.0, 1/h, 1.0, 100.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt( 0.0, 0.0, 40.0, + 0.0, 0.0, 0.0, + 0.0, 2.0, 10.0); + +# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */ + { + int o = (int) current_device_rotation(); + if (o != 0 && o != 180 && o != -180) + glScalef (1/h, 1/h, 1/h); + } +# endif +} + +static void +unit_cube(int wire) +{ + glBegin((wire)?GL_LINE_LOOP:GL_QUADS); + glNormal3f( 0.0f, -1.0f, 0.0f); + glVertex3f(-1.0f, -1.0f, -1.0f); + glVertex3f( 1.0f, -1.0f, -1.0f); + glVertex3f( 1.0f, -1.0f, 1.0f); + glVertex3f(-1.0f, -1.0f, 1.0f); + glNormal3f( 0.0f, 0.0f, 1.0f); + glVertex3f(-1.0f, -1.0f, 1.0f); + glVertex3f( 1.0f, -1.0f, 1.0f); + glVertex3f( 1.0f, 1.0f, 1.0f); + glVertex3f(-1.0f, 1.0f, 1.0f); + glNormal3f( 0.0f, 0.0f, -1.0f); + glVertex3f(-1.0f, -1.0f, -1.0f); + glVertex3f(-1.0f, 1.0f, -1.0f); + glVertex3f( 1.0f, 1.0f, -1.0f); + glVertex3f( 1.0f, -1.0f, -1.0f); + glNormal3f( 1.0f, 0.0f, 0.0f); + glVertex3f( 1.0f, -1.0f, -1.0f); + glVertex3f( 1.0f, 1.0f, -1.0f); + glVertex3f( 1.0f, 1.0f, 1.0f); + glVertex3f( 1.0f, -1.0f, 1.0f); + glNormal3f( -1.0f, 0.0f, 0.0f); + glVertex3f(-1.0f, -1.0f, -1.0f); + glVertex3f(-1.0f, -1.0f, 1.0f); + glVertex3f(-1.0f, 1.0f, 1.0f); + glVertex3f(-1.0f, 1.0f, -1.0f); + glNormal3f( 1.0f, 1.0f, 0.0f); + glVertex3f(-1.0f, 1.0f, -1.0f); + glVertex3f(-1.0f, 1.0f, 1.0f); + glVertex3f( 1.0f, 1.0f, 1.0f); + glVertex3f( 1.0f, 1.0f, -1.0f); + glEnd(); +} + +ENTRYPOINT void +init_ball (ModeInfo *mi) +{ + int wire = MI_IS_WIREFRAME(mi); + blinkboxstruct *bp; + + MI_INIT (mi, blinkbox); + bp = &blinkbox[MI_SCREEN(mi)]; + + if ((bp->glx_context = init_GL(mi)) != NULL) { + reshape_ball(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); + glDrawBuffer(GL_BACK); + } + else + MI_CLEARWINDOW(mi); + + bp->ball.d = 1; + bp->bscale.wh = bscale_wh; + bp->bscale.d = 0.25; + + bp->mo.x = 1; + bp->mo.y = 1; + bp->mo.z = 1; + + bp->moh.x = -1.0; + bp->moh.y = -1.5; + bp->moh.z = -1.5; + + bp->bpos.x = 1; + bp->bpos.y = 1; + bp->bpos.z = 1; + + bp->des_amt = 1; + + bp->lside.counter = MAX_COUNT; + bp->rside.counter = MAX_COUNT; + bp->tside.counter = MAX_COUNT; + bp->bside.counter = MAX_COUNT; + bp->fside.counter = MAX_COUNT; + bp->aside.counter = MAX_COUNT; + + bp->lside.color[0] = 1; + bp->rside.color[1] = 1; + bp->tside.color[2] = 1; + + bp->bside.color[0] = 1; + bp->bside.color[1] = 0.5; + + bp->fside.color[0] = 1; + bp->fside.color[1] = 1; + + bp->aside.color[0] = 0.5; + bp->aside.color[2] = 1; + + bp->lside.rot[0] = 90; + bp->rside.rot[0] = 90; + bp->tside.rot[0] = 90; + bp->bside.rot[0] = 90; + bp->fside.rot[0] = 90; + bp->aside.rot[0] = 90; + + bp->lside.rot[2] = 1; + bp->rside.rot[2] = 1; + bp->tside.rot[1] = 1; + bp->bside.rot[1] = 1; + bp->fside.rot[3] = 1; + bp->aside.rot[3] = 1; + + bp->lside.des_count = 1; + bp->rside.des_count = 1; + bp->tside.des_count = 1; + bp->bside.des_count = 1; + bp->fside.des_count = 1; + bp->aside.des_count = 1; + + bp->lside.alpha_count = 1; + bp->rside.alpha_count = 1; + bp->tside.alpha_count = 1; + bp->bside.alpha_count = 1; + bp->fside.alpha_count = 1; + bp->aside.alpha_count = 1; + + +#define SPHERE_SLICES 12 /* how densely to render spheres */ +#define SPHERE_STACKS 16 + + bp->sp = malloc(sizeof(*bp->sp)); + if(bp->sp == NULL){ + fprintf(stderr,"Could not allocate memory\n"); + exit(1); + } + if( (bp->bscale.wh < 1) || + (bp->bscale.wh > 8) ) { + fprintf(stderr,"Boxsize out of range. Using default\n"); + bp->bscale.wh = 2; + } + if (do_dissolve){ + bp->des_amt = bp->bscale.wh / MAX_COUNT; + } + + reshape_ball(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); + bp->ballList = glGenLists(1); + glNewList(bp->ballList, GL_COMPILE); + unit_sphere (SPHERE_STACKS, SPHERE_SLICES, wire); + glEndList (); + + bp->boxList = glGenLists(1); + glNewList(bp->boxList, GL_COMPILE); + unit_cube(wire); + glEndList(); + + if (wire) return; + + glEnable(GL_COLOR_MATERIAL); + glShadeModel(GL_SMOOTH); + glClearDepth(1.0f); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + glEnable(GL_LIGHTING); + glClearDepth(1); + glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); + glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); + glEnable(GL_LIGHT1); + if (do_fade || do_blur) { + glEnable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + } +} + +static void +CheckBoxPos(blinkboxstruct *bp, + GLfloat bot_x, GLfloat top_x, GLfloat bot_y, GLfloat top_y) +{ + /*Make sure it's inside of the bounding box*/ + bp->bpos.x = ((bp->bpos.x - bp->bscale.wh) < bot_x) ? bot_x + bp->bscale.wh : bp->bpos.x; + bp->bpos.x = ((bp->bpos.x + bp->bscale.wh) > top_x) ? top_x - bp->bscale.wh : bp->bpos.x; + bp->bpos.y = ((bp->bpos.y - bp->bscale.wh) < bot_y) ? bot_y + bp->bscale.wh : bp->bpos.y; + bp->bpos.y = ((bp->bpos.y + bp->bscale.wh) > top_y) ? top_y - bp->bscale.wh : bp->bpos.y; +} + +ENTRYPOINT void +draw_ball (ModeInfo *mi) +{ + blinkboxstruct *bp = &blinkbox[MI_SCREEN(mi)]; + + Display *dpy = MI_DISPLAY(mi); + Window window = MI_WINDOW(mi); + int i = 0; + + if (! bp->glx_context) + return; + mi->polygon_count = 0; + glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(bp->glx_context)); + + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + hit_top_bottom(bp); + hit_front_back(bp); + hit_side(bp); + + glRotated(0.25,0,0,1); + glRotated(0.25,0,1,0); + glRotated(0.25,1,0,0); + + + glPushMatrix(); + glScalef(0.5,0.5,0.5); + + glColor3f(1,1,1); + glPushMatrix(); + + if (!do_blur || MI_IS_WIREFRAME(mi)) { + glTranslatef(bp->ball.x += bp->mo.x, + bp->ball.y += bp->mo.y, + bp->ball.z += bp->mo.z); + + glScalef(2,2,2); + glCallList(bp->ballList); + mi->polygon_count += SPHERE_SLICES*SPHERE_STACKS; + + } else { + +# define blur_detail 24.0 + float ball_alpha = 1 / blur_detail; + + glBlendFunc(GL_SRC_ALPHA,GL_ONE); + glTranslatef(bp->ball.x, bp->ball.y, bp->ball.z); + + for (i = 0; i < blur_detail; ++i) { + glTranslatef(bp->mo.x / blur_detail, + bp->mo.y / blur_detail, + bp->mo.z / blur_detail); + + /* comment the following line for quick but boring linear blur */ + ball_alpha = sin((M_PI / blur_detail) * i) / blur_detail; + + glColor4f(1, 1, 1, ball_alpha); + + glScalef(2, 2, 2); + glCallList(bp->ballList); + mi->polygon_count += SPHERE_SLICES*SPHERE_STACKS; + glScalef(.5, .5, .5); + } + i = 0; + + bp->ball.x += bp->mo.x; + bp->ball.y += bp->mo.y; + bp->ball.z += bp->mo.z; + } + + glPopMatrix(); + + while(i < 6){ + switch(i){ + case 0:{ + bp->sp = &bp->lside; + bp->bpos.x = bp->lside.pos.z*-1; + bp->bpos.y = bp->lside.pos.y; + bp->bpos.z = bbox.bottom.x - bp->bscale.d; + if (bp->sp->hit) + CheckBoxPos(bp, bbox.bottom.z,bbox.top.z,bbox.bottom.y,bbox.top.y); + break; + } + case 1:{ + bp->sp = &bp->rside; + bp->bpos.x = bp->rside.pos.z*-1; + bp->bpos.y = bp->rside.pos.y; + bp->bpos.z = bbox.top.x + bp->bscale.d; + if (bp->sp->hit) + CheckBoxPos(bp, bbox.bottom.z,bbox.top.z,bbox.bottom.y,bbox.top.y); + break; + } + case 2:{ + bp->sp = &bp->tside; + bp->bpos.x = bp->tside.pos.x; + bp->bpos.y = bp->tside.pos.z; + bp->bpos.z = bbox.bottom.y - bp->bscale.d; + if (bp->sp->hit) + CheckBoxPos(bp, bbox.bottom.x,bbox.top.x,bbox.bottom.z,bbox.top.z); + break; + } + case 3:{ + bp->sp = &bp->bside; + bp->bpos.x = bp->bside.pos.x; + bp->bpos.y = bp->bside.pos.z; + bp->bpos.z = bbox.top.y + bp->bscale.d; + if (bp->sp->hit) + CheckBoxPos(bp, bbox.bottom.x,bbox.top.x,bbox.bottom.z,bbox.top.z); + break; + } + case 4:{ + bp->sp = &bp->fside; + bp->bpos.x = bp->fside.pos.y; + bp->bpos.y = bp->fside.pos.x*-1; + bp->bpos.z = bbox.top.z + bp->bscale.d; + if (bp->sp->hit) + CheckBoxPos(bp, bbox.bottom.y,bbox.top.y,bbox.bottom.x,bbox.top.x); + break; + } + case 5:{ + bp->sp = &bp->aside; + bp->bpos.x = bp->aside.pos.y; + bp->bpos.y = bp->aside.pos.x*-1; + bp->bpos.z = bbox.bottom.z + bp->bscale.d; + if (bp->sp->hit) + CheckBoxPos(bp, bbox.bottom.y,bbox.top.y,bbox.bottom.x,bbox.top.x); + break; + } + } + if(bp->sp->hit){ + if(do_fade){ + glColor4f(bp->sp->color[0],bp->sp->color[1],bp->sp->color[2],1-(ALPHA_AMT * bp->sp->alpha_count)); + }else{ + glColor3fv(bp->sp->color); + } + glBlendFunc(GL_SRC_ALPHA,GL_ONE); + glPushMatrix(); + glRotatef(bp->sp->rot[0],bp->sp->rot[1],bp->sp->rot[2],bp->sp->rot[3]); + glTranslatef(bp->bpos.x,bp->bpos.y,bp->bpos.z); + if (do_dissolve) { + glScalef(bp->bscale.wh-(bp->des_amt*bp->sp->des_count),bp->bscale.wh-(bp->des_amt*bp->sp->des_count),bp->bscale.d); + }else{ + glScalef(bp->bscale.wh,bp->bscale.wh,bp->bscale.d); + } + glCallList(bp->boxList); + mi->polygon_count += 6; + glPopMatrix(); + bp->sp->counter--; + bp->sp->des_count++; + bp->sp->alpha_count++; + if(!bp->sp->counter) + { + bp->sp->hit = 0; + } + } + i++; + } + + + glPopMatrix(); + if (mi->fps_p) do_fps (mi); + glFinish(); + glXSwapBuffers(dpy, window); + +} + +XSCREENSAVER_MODULE_2 ("BlinkBox", blinkbox, ball) + +#endif /* USE_GL */ -- cgit v1.2.3-55-g7522