X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fglx%2Fengine.c;h=0f39b8da7af640d7308a7fb42ba032085832053d;hb=39809ded547bdbb08207d3e514950425215b4410;hp=aadc1a265f8c3b640d41d34775a45326991d9e0c;hpb=6b1c86cf395f59389e4ece4ea8f4bea2c332745b;p=xscreensaver diff --git a/hacks/glx/engine.c b/hacks/glx/engine.c index aadc1a26..0f39b8da 100644 --- a/hacks/glx/engine.c +++ b/hacks/glx/engine.c @@ -24,15 +24,17 @@ #ifdef STANDALONE #define DEFAULTS "*delay: 30000 \n" \ "*showFPS: False \n" \ - "*titleFont: -*-times-bold-r-normal-*-180-*\n" \ + "*suppressRotationAnimation: True\n" \ + "*titleFont: -*-helvetica-medium-r-normal-*-*-180-*-*-*-*-*-*\n" \ -# define refresh_engine 0 +# define free_engine 0 +# define release_engine 0 # include "xlockmore.h" /* from the xscreensaver distribution */ #else /* !STANDALONE */ # include "xlock.h" /* from the xlockmore distribution */ #endif /* !STANDALONE */ -#include "glxfonts.h" +#include "texfont.h" #include "rotator.h" #include "gltrackball.h" @@ -46,7 +48,7 @@ #define DEF_ENGINE "(none)" #define DEF_TITLES "False" #define DEF_SPIN "True" -#define DEF_WANDER "True" +#define DEF_MOVE "True" #undef countof #define countof(x) (sizeof((x))/sizeof((*x))) @@ -68,7 +70,7 @@ static XrmOptionDescRec opts[] = { static argtype vars[] = { {&which_engine, "engine", "Engine", DEF_ENGINE, t_String}, - {&move, "move", "Move", DEF_WANDER, t_Bool}, + {&move, "move", "Move", DEF_MOVE, t_Bool}, {&spin, "spin", "Spin", DEF_SPIN, t_Bool}, {&do_titles, "titles", "Titles", DEF_TITLES, t_Bool}, }; @@ -77,7 +79,7 @@ ENTRYPOINT ModeSpecOpt engine_opts = {countof(opts), opts, countof(vars), vars, #ifdef USE_MODULES ModStruct engine_description = -{"engine", "init_engine", "draw_engine", "release_engine", +{"engine", "init_engine", "draw_engine", NULL, "draw_engine", "init_engine", NULL, &engine_opts, 1000, 1, 2, 1, 4, 1.0, "", "A four stroke engine", 0, NULL}; @@ -109,8 +111,7 @@ typedef struct { rotator *rot; trackball_state *trackball; Bool button_down_p; - XFontStruct *xfont; - GLuint font_dlist; + texture_font_data *font_data; char *engine_name; int engineType; int movepaused; @@ -136,6 +137,9 @@ typedef struct { int ln_init; int lastPlug; + GLuint shaft_list, piston_list; + int shaft_polys, piston_polys; + } Engine; static Engine *engine = NULL; @@ -277,13 +281,13 @@ static void make_tables(Engine *e) float f; f = ONEREV / (M_PI * 2); - for (i = 0 ; i <= TWOREV ; i++) { + for (i = 0 ; i < TWOREV ; i++) { e->sin_table[i] = sin(i/f); } - for (i = 0 ; i <= TWOREV ; i++) { + for (i = 0 ; i < TWOREV ; i++) { e->cos_table[i] = cos(i/f); } - for (i = 0 ; i <= TWOREV ; i++) { + for (i = 0 ; i < TWOREV ; i++) { e->tan_table[i] = tan(i/f); } } @@ -292,17 +296,16 @@ static void make_tables(Engine *e) /* for a tube, endcaps is 0 (none), 1 (left), 2 (right) or 3(both) */ /* angle is how far around the axis to go (up to 360) */ -static void cylinder (Engine *e, GLfloat x, GLfloat y, GLfloat z, +static int cylinder (Engine *e, GLfloat x, GLfloat y, GLfloat z, float length, float outer, float inner, int endcaps, int sang, int eang) { + int polys = 0; int a; /* current angle around cylinder */ int b = 0; /* previous */ int angle, norm, step, sangle; float z1, y1, z2, y2, ex=0; - float y3, z3; - float Z1, Y1, Z2, Y2, xl, Y3, Z3; + float Z1, Y1, Z2, Y2, xl; GLfloat y2c[TWOREV], z2c[TWOREV]; - GLfloat ony, onz; /* previous normals */ int nsegs, tube = 0; glPushMatrix(); @@ -313,7 +316,6 @@ static void cylinder (Engine *e, GLfloat x, GLfloat y, GLfloat z, nsegs += 1; sangle = sang; angle = eang; - ony = onz = 0; z1 = e->cos_table[sangle]*outer+z; y1 = e->sin_table[sangle] * outer+y; Z1 = e->cos_table[sangle] * inner+z; Y1 = e->sin_table[sangle]*inner+y ; Z2 = z; @@ -326,15 +328,13 @@ static void cylinder (Engine *e, GLfloat x, GLfloat y, GLfloat z, for (a = sangle ; a <= angle || b <= angle ; a+= step) { y2=outer*(float)e->sin_table[a]+y; z2=outer*(float)e->cos_table[a]+z; - y3=outer*(float)e->sin_table[a+step]+y; - z3=outer*(float)e->cos_table[a+step]+z; - if (endcaps) - y2c[a] = y2; z2c[a] = z2; /* cache for later */ + if (endcaps) { + y2c[a] = y2; + z2c[a] = z2; /* cache for later */ + } if (tube) { Y2=inner*(float)e->sin_table[a]+y; Z2=inner*(float)e->cos_table[a]+z; - Y3=inner*(float)e->sin_table[a+step]+y; - Z3=inner*(float)e->cos_table[a+step]+z; } glNormal3f(0, y1, z1); glVertex3f(x,y1,z1); @@ -342,6 +342,7 @@ static void cylinder (Engine *e, GLfloat x, GLfloat y, GLfloat z, glNormal3f(0, y2, z2); glVertex3f(xl,y2,z2); glVertex3f(x,y2,z2); + polys++; if (a == sangle && angle - sangle < ONEREV) { if (tube) glVertex3f(x, Y1, Z1); @@ -353,6 +354,7 @@ static void cylinder (Engine *e, GLfloat x, GLfloat y, GLfloat z, glVertex3f(xl, Z1, Z1); else glVertex3f(xl, y, z); + polys++; } if (tube) { if (endcaps != 1) { @@ -361,6 +363,7 @@ static void cylinder (Engine *e, GLfloat x, GLfloat y, GLfloat z, glVertex3f(x, y2, z2); glVertex3f(x, Y2, Z2); glVertex3f(x, Y1, Z1); + polys++; } glNormal3f(0, -Y1, -Z1); /* inner surface */ @@ -369,6 +372,7 @@ static void cylinder (Engine *e, GLfloat x, GLfloat y, GLfloat z, glNormal3f(0, -Y2, -Z2); glVertex3f(xl, Y2, Z2); glVertex3f(x, Y2, Z2); + polys++; if (endcaps != 2) { glNormal3f(1, 0, 0); /* right end */ @@ -376,6 +380,7 @@ static void cylinder (Engine *e, GLfloat x, GLfloat y, GLfloat z, glVertex3f(xl, y2, z2); glVertex3f(xl, Y2, Z2); glVertex3f(xl, Y1, Z1); + polys++; } } @@ -398,6 +403,7 @@ static void cylinder (Engine *e, GLfloat x, GLfloat y, GLfloat z, glVertex3f(x, y1, z1); glVertex3f(xl, y1, z1); glVertex3f(xl, y, z); + polys++; glEnd(); } if (endcaps) { @@ -429,6 +435,7 @@ static void cylinder (Engine *e, GLfloat x, GLfloat y, GLfloat z, glVertex3f(x+ex,y, z); glVertex3f(x+ex,y1,z1); glVertex3f(x+ex,y2c[a],z2c[a]); + polys++; y1 = y2c[a]; z1 = z2c[a]; b = a; } @@ -437,12 +444,13 @@ static void cylinder (Engine *e, GLfloat x, GLfloat y, GLfloat z, } } glPopMatrix(); + return polys; } /* this is just a convenience function to make a solid rod */ -static void rod (Engine *e, GLfloat x, GLfloat y, GLfloat z, float length, float diameter) +static int rod (Engine *e, GLfloat x, GLfloat y, GLfloat z, float length, float diameter) { - cylinder(e, x, y, z, length, diameter, diameter, 3, 0, ONEREV); + return cylinder(e, x, y, z, length, diameter, diameter, 3, 0, ONEREV); } static GLvoid normal(GLfloat v1[], GLfloat v2[], GLfloat v3[], @@ -465,9 +473,10 @@ static GLvoid normal(GLfloat v1[], GLfloat v2[], GLfloat v3[], -static void Rect(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h, +static int Rect(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h, GLfloat t) { + int polys = 0; GLfloat yh; GLfloat xw; GLfloat zt; @@ -480,66 +489,78 @@ static void Rect(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h, glVertex3f(x, yh, z); glVertex3f(xw, yh, z); glVertex3f(xw, y, z); + polys++; /* back */ glNormal3f(0, 0, -1); glVertex3f(x, y, zt); glVertex3f(x, yh, zt); glVertex3f(xw, yh, zt); glVertex3f(xw, y, zt); + polys++; /* top */ glNormal3f(0, 1, 0); glVertex3f(x, yh, z); glVertex3f(x, yh, zt); glVertex3f(xw, yh, zt); glVertex3f(xw, yh, z); + polys++; /* bottom */ glNormal3f(0, -1, 0); glVertex3f(x, y, z); glVertex3f(x, y, zt); glVertex3f(xw, y, zt); glVertex3f(xw, y, z); + polys++; /* left */ glNormal3f(-1, 0, 0); glVertex3f(x, y, z); glVertex3f(x, y, zt); glVertex3f(x, yh, zt); glVertex3f(x, yh, z); + polys++; /* right */ glNormal3f(1, 0, 0); glVertex3f(xw, y, z); glVertex3f(xw, y, zt); glVertex3f(xw, yh, zt); glVertex3f(xw, yh, z); + polys++; glEnd(); + return polys; } -static void makepiston(Engine *e) +static int makepiston(Engine *e) { + int polys = 0; GLfloat colour[] = {0.6, 0.6, 0.6, 1.0}; - int i; - i = glGenLists(1); - glNewList(i, GL_COMPILE); + /* if (e->piston_list) glDeleteLists(1, e->piston_list); */ + if (! e->piston_list) e->piston_list = glGenLists(1); + glNewList(e->piston_list, GL_COMPILE); glRotatef(90, 0, 0, 1); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, colour); glMaterialfv(GL_FRONT, GL_SPECULAR, colour); glMateriali(GL_FRONT, GL_SHININESS, 20); - cylinder(e, 0, 0, 0, 2, 1, 0.7, 2, 0, ONEREV); /* body */ + polys += cylinder(e, 0, 0, 0, 2, 1, 0.7, 2, 0, ONEREV); /* body */ colour[0] = colour[1] = colour[2] = 0.2; glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, colour); - cylinder(e, 1.6, 0, 0, 0.1, 1.05, 1.05, 0, 0, ONEREV); /* ring */ - cylinder(e, 1.8, 0, 0, 0.1, 1.05, 1.05, 0, 0, ONEREV); /* ring */ + polys += cylinder(e, 1.6, 0, 0, 0.1, 1.05, 1.05, 0, 0, ONEREV); /* ring */ + polys += cylinder(e, 1.8, 0, 0, 0.1, 1.05, 1.05, 0, 0, ONEREV); /* ring */ glEndList(); + return polys; } -static void CrankBit(Engine *e, GLfloat x) +static int CrankBit(Engine *e, GLfloat x) { - Rect(x, -1.4, 0.5, 0.2, 1.8, 1); - cylinder(e, x, -0.5, 0, 0.2, 2, 2, 1, 60, 120); + int polys = 0; + polys += Rect(x, -1.4, 0.5, 0.2, 1.8, 1); + polys += cylinder(e, x, -0.5, 0, 0.2, 2, 2, 1, 60, 120); + return polys; } -static void boom(Engine *e, GLfloat x, GLfloat y, int s) +static int boom(Engine *e, GLfloat x, GLfloat y, int s) { + int polys = 0; int flameOut = 720/ENG.speed/ENG.cylinders; if (e->boom_time == 0 && s) { @@ -548,7 +569,7 @@ static void boom(Engine *e, GLfloat x, GLfloat y, int s) e->boom_time++; glEnable(GL_LIGHT1); } else if (e->boom_time == 0 && !s) { - return; + return polys; } else if (e->boom_time >= 8 && e->boom_time < flameOut && !s) { e->boom_time++; e->boom_red[0] -= 0.2; e->boom_red[1] -= 0.1; @@ -556,7 +577,7 @@ static void boom(Engine *e, GLfloat x, GLfloat y, int s) } else if (e->boom_time >= flameOut) { e->boom_time = 0; glDisable(GL_LIGHT1); - return; + return polys; } else { e->boom_red[0] += 0.2; e->boom_red[1] += 0.1; e->boom_d += 0.04; @@ -566,7 +587,7 @@ static void boom(Engine *e, GLfloat x, GLfloat y, int s) glLightfv(GL_LIGHT1, GL_POSITION, e->boom_lpos); glLightfv(GL_LIGHT1, GL_DIFFUSE, e->boom_red); glLightfv(GL_LIGHT1, GL_SPECULAR, e->boom_red); - glLighti(GL_LIGHT1, GL_LINEAR_ATTENUATION, 1.3); + glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 1.3); glLighti(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 0); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, e->boom_red); @@ -575,13 +596,16 @@ static void boom(Engine *e, GLfloat x, GLfloat y, int s) glEnable(GL_BLEND); glDepthMask(GL_FALSE); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - rod(e, x, y, 0, e->boom_d, e->boom_wd); + polys += rod(e, x, y, 0, e->boom_d, e->boom_wd); glDepthMask(GL_TRUE); glDisable(GL_BLEND); + return polys; } -static void display(Engine *e) +static int display(ModeInfo *mi) { + Engine *e = &engine[MI_SCREEN(mi)]; + int polys = 0; GLfloat zb, yb; float rightSide; int half; @@ -595,6 +619,16 @@ static void display(Engine *e) e->lookat[0], e->lookat[1], e->lookat[2], 0.0, 1.0, 0.0); glPushMatrix(); + +# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */ + { + GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi); + int o = (int) current_device_rotation(); + if (o != 0 && o != 180 && o != -180) + glScalef (1/h, 1/h, 1/h); + } +# endif + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); glLightfv(GL_LIGHT0, GL_SPECULAR, light_sp); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_sp); @@ -604,9 +638,12 @@ static void display(Engine *e) get_position (e->rot, &x, &y, &z, !e->button_down_p); glTranslatef(x*16-9, y*14-7, z*16-10); } + if (spin) { double x, y, z; + gltrackball_rotate (e->trackball); + get_rotation(e->rot, &x, &y, &z, !e->button_down_p); glRotatef(x*ONEREV, 1.0, 0.0, 0.0); glRotatef(y*ONEREV, 0.0, 1.0, 0.0); @@ -619,12 +656,13 @@ static void display(Engine *e) /* crankshaft */ glPushMatrix(); glRotatef(e->display_a, 1, 0, 0); - glCallList(1); + glCallList(e->shaft_list); + polys += e->shaft_polys; glPopMatrix(); /* init the ln[] matrix for speed */ if (e->ln_init == 0) { - for (e->ln_init = 0 ; e->ln_init < 730 ; e->ln_init++) { + for (e->ln_init = 0 ; e->ln_init < countof(e->sin_table) ; e->ln_init++) { zb = e->sin_table[e->ln_init]; yb = e->cos_table[e->ln_init]; /* y ordinate of piston */ @@ -648,7 +686,8 @@ static void display(Engine *e) b = (e->display_a + ENG.pistonAngle[j+half]) % ONEREV; glPushMatrix(); glTranslatef(e->crankWidth/2 + e->crankOffset*(j+half), e->yp[b]-0.3, 0); - glCallList(2); + glCallList(e->piston_list); + polys += e->piston_polys; glPopMatrix(); } /* spark plugs */ @@ -657,14 +696,14 @@ static void display(Engine *e) glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red); for (j = 0; j < ENG.cylinders; j += sides) { - cylinder(e, 8.5, -e->crankWidth/2-e->crankOffset*(j+half), 0, + polys += cylinder(e, 8.5, -e->crankWidth/2-e->crankOffset*(j+half), 0, 0.5, 0.4, 0.3, 1, 0, ONEREV); } glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white); for (j = 0; j < ENG.cylinders; j += sides) { - rod(e, 8, -e->crankWidth/2-e->crankOffset*(j+half), 0, 0.5, 0.2); - rod(e, 9, -e->crankWidth/2-e->crankOffset*(j+half), 0, 1, 0.15); + polys += rod(e, 8, -e->crankWidth/2-e->crankOffset*(j+half), 0, 0.5, 0.2); + polys += rod(e, 9, -e->crankWidth/2-e->crankOffset*(j+half), 0, 1, 0.15); } /* rod */ @@ -674,7 +713,7 @@ static void display(Engine *e) b = (e->display_a+HALFREV+ENG.pistonAngle[j+half]) % TWOREV; glPushMatrix(); glRotatef(e->ang[b], 0, 1, 0); - rod(e, + polys += rod(e, -e->cos_table[b], -e->crankWidth/2-e->crankOffset*(j+half), -e->sin_table[b], @@ -690,21 +729,21 @@ static void display(Engine *e) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); rightSide = (sides > 1) ? 0 : 1.6; /* left plate */ - Rect(-e->crankWidth/2, -0.5, 1, 0.2, 9, 2); + polys += Rect(-e->crankWidth/2, -0.5, 1, 0.2, 9, 2); /* right plate */ - Rect(0.3+e->crankOffset*ENG.cylinders-rightSide, -0.5, 1, 0.2, 9, 2); + polys += Rect(0.3+e->crankOffset*ENG.cylinders-rightSide, -0.5, 1, 0.2, 9, 2); /* head plate */ - Rect(-e->crankWidth/2+0.2, 8.3, 1, + polys += Rect(-e->crankWidth/2+0.2, 8.3, 1, e->crankWidth/2+0.1+e->crankOffset*ENG.cylinders-rightSide, 0.2, 2); /* front rail */ - Rect(-e->crankWidth/2+0.2, 3, 1, + polys += Rect(-e->crankWidth/2+0.2, 3, 1, e->crankWidth/2+0.1+e->crankOffset*ENG.cylinders-rightSide, 0.2, 0.2); /* back rail */ - Rect(-e->crankWidth/2+0.2, 3, -1+0.2, + polys += Rect(-e->crankWidth/2+0.2, 3, -1+0.2, e->crankWidth/2+0.1+e->crankOffset*ENG.cylinders-rightSide, 0.2, 0.2); /* plates between cylinders */ for (j=0; j < ENG.cylinders - (sides == 1); j += sides) - Rect(0.4+e->crankWidth+e->crankOffset*(j-half), 3, 1, 1, 5.3, 2); + polys += Rect(0.4+e->crankWidth+e->crankOffset*(j-half), 3, 1, 1, 5.3, 2); glDepthMask(GL_TRUE); } glPopMatrix(); @@ -718,7 +757,7 @@ static void display(Engine *e) if (j & 1) glRotatef(ENG.includedAngle,1,0,0); glRotatef(90, 0, 0, 1); - boom(e, 8, -e->crankWidth/2-e->crankOffset*j, 1); + polys += boom(e, 8, -e->crankWidth/2-e->crankOffset*j, 1); e->lastPlug = j; glPopMatrix(); } @@ -730,7 +769,7 @@ static void display(Engine *e) if (e->lastPlug & 1) glRotatef(ENG.includedAngle, 1, 0, 0); glRotatef(90, 0, 0, 1); - boom(e, 8, -e->crankWidth/2-e->crankOffset*e->lastPlug, 0); + polys += boom(e, 8, -e->crankWidth/2-e->crankOffset*e->lastPlug, 0); } glDisable(GL_BLEND); @@ -739,29 +778,31 @@ static void display(Engine *e) e->display_a = 0; glPopMatrix(); glFlush(); + return polys; } -static void makeshaft (Engine *e) +static int makeshaft (Engine *e) { - int i; + int polys = 0; int j; float crankThick = 0.2; float crankDiam = 0.3; - i = glGenLists(1); - glNewList(i, GL_COMPILE); + /* if (e->shaft_list) glDeleteLists(1, e->shaft_list); */ + if (! e->shaft_list) e->shaft_list = glGenLists(1); + glNewList(e->shaft_list, GL_COMPILE); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue); /* draw the flywheel */ - cylinder(e, -2.5, 0, 0, 1, 3, 2.5, 0, 0, ONEREV); - Rect(-2, -0.3, 2.8, 0.5, 0.6, 5.6); - Rect(-2, -2.8, 0.3, 0.5, 5.6, 0.6); + polys += cylinder(e, -2.5, 0, 0, 1, 3, 2.5, 0, 0, ONEREV); + polys += Rect(-2, -0.3, 2.8, 0.5, 0.6, 5.6); + polys += Rect(-2, -2.8, 0.3, 0.5, 5.6, 0.6); /* now make each of the shaft bits between the cranks, * starting from the flywheel end which is at X-coord 0. * the first cranskhaft bit is always 2 units long */ - rod(e, -2, 0, 0, 2, crankDiam); + polys += rod(e, -2, 0, 0, 2, crankDiam); /* Each crank is crankWidth units wide and the total width of a * cylinder assembly is 3.3 units. For inline engines, there is just @@ -774,11 +815,11 @@ static void makeshaft (Engine *e) if (ENG.includedAngle != 0) e->crankOffset /= 2; for (j = 0; j < ENG.cylinders - 1; j++) - rod(e, + polys += rod(e, e->crankWidth - crankThick + e->crankOffset*j, 0, 0, e->crankOffset - e->crankWidth + 2 * crankThick, crankDiam); /* the last bit connects to the engine wall on the non-flywheel end */ - rod(e, e->crankWidth - crankThick + e->crankOffset*j, 0, 0, 0.9, crankDiam); + polys += rod(e, e->crankWidth - crankThick + e->crankOffset*j, 0, 0, 0.9, crankDiam); for (j = 0; j < ENG.cylinders; j++) @@ -790,25 +831,35 @@ static void makeshaft (Engine *e) glRotatef(HALFREV+ENG.pistonAngle[j],1,0,0); /* draw wrist pin */ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue); - rod(e, e->crankOffset*j, -1.0, 0.0, e->crankWidth, crankDiam); + polys += rod(e, e->crankOffset*j, -1.0, 0.0, e->crankWidth, crankDiam); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green); /* draw right part of crank */ - CrankBit(e, e->crankOffset*j); + polys += CrankBit(e, e->crankOffset*j); /* draw left part of crank */ - CrankBit(e, e->crankWidth-crankThick+e->crankOffset*j); + polys += CrankBit(e, e->crankWidth-crankThick+e->crankOffset*j); glPopMatrix(); } glEndList(); + return polys; } ENTRYPOINT void reshape_engine(ModeInfo *mi, int width, int height) { Engine *e = &engine[MI_SCREEN(mi)]; - glViewport(0,0,(GLint)width, (GLint) height); + double 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, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); - glFrustum(-1.0,1.0,-1.0,1.0,1.5,70.0); + gluPerspective(40, 1/h, 1.5, 70.0); glMatrixMode(GL_MODELVIEW); e->win_h = height; e->win_w = width; @@ -820,11 +871,7 @@ ENTRYPOINT void init_engine(ModeInfo *mi) int screen = MI_SCREEN(mi); Engine *e; - if (engine == NULL) { - if ((engine = (Engine *) calloc(MI_NUM_SCREENS(mi), - sizeof(Engine))) == NULL) - return; - } + MI_INIT(mi, engine); e = &engine[screen]; e->window = MI_WINDOW(mi); @@ -864,15 +911,15 @@ ENTRYPOINT void init_engine(ModeInfo *mi) move ? wander_speed : 0, True); - e->trackball = gltrackball_init (); + e->trackball = gltrackball_init (True); } - if ((e->glx_context = init_GL(mi)) != NULL) { + if (!e->glx_context && /* re-initting breaks print_texture_label */ + (e->glx_context = init_GL(mi)) != NULL) { reshape_engine(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); } else { MI_CLEARWINDOW(mi); } - glClearColor(0.0,0.0,0.0,0.0); glShadeModel(GL_SMOOTH); glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); glEnable(GL_DEPTH_TEST); @@ -882,7 +929,8 @@ ENTRYPOINT void init_engine(ModeInfo *mi) make_tables(e); e->engineType = find_engine(which_engine); - e->engine_name = malloc(200); + if (!e->engine_name) + e->engine_name = malloc(200); sprintf (e->engine_name, "%s\n%s%d%s", engines[e->engineType].engineName, @@ -892,9 +940,11 @@ ENTRYPOINT void init_engine(ModeInfo *mi) (engines[e->engineType].includedAngle == 0 ? " Cylinder" : "") ); - makeshaft(e); - makepiston(e); - load_font (mi->dpy, "titleFont", &e->xfont, &e->font_dlist); + e->shaft_polys = makeshaft(e); + e->piston_polys = makepiston(e); + + if (!e->font_data) + e->font_data = load_texture_font (mi->dpy, "titleFont"); } ENTRYPOINT Bool @@ -905,36 +955,24 @@ engine_handle_event (ModeInfo *mi, XEvent *event) if (event->xany.type == ButtonPress && event->xbutton.button == Button1) { - e->button_down_p = True; - gltrackball_start (e->trackball, - event->xbutton.x, event->xbutton.y, - MI_WIDTH (mi), MI_HEIGHT (mi)); - e->movepaused = 1; return True; } else if (event->xany.type == ButtonRelease && event->xbutton.button == Button1) { - e->button_down_p = False; e->movepaused = 0; - return True; } - else if (event->xany.type == ButtonPress && - (event->xbutton.button == Button4 || - event->xbutton.button == Button5 || - event->xbutton.button == Button6 || - event->xbutton.button == Button7)) + + if (gltrackball_event_handler (event, e->trackball, + MI_WIDTH (mi), MI_HEIGHT (mi), + &e->button_down_p)) + return True; + else if (screenhack_event_helper (MI_DISPLAY(mi), MI_WINDOW(mi), event)) { - gltrackball_mousewheel (e->trackball, event->xbutton.button, 10, - !!event->xbutton.state); + which_engine = NULL; /* randomize */ + init_engine(mi); return True; } - else if (event->xany.type == MotionNotify && - e->button_down_p) { - gltrackball_track (e->trackball, - event->xmotion.x, event->xmotion.y, - MI_WIDTH (mi), MI_HEIGHT (mi)); - return True; - } + return False; } @@ -950,29 +988,19 @@ ENTRYPOINT void draw_engine(ModeInfo *mi) glXMakeCurrent(disp, w, *(e->glx_context)); - display(e); + mi->polygon_count = display(mi); + glColor3f (1, 1, 0); if (do_titles) - print_gl_string (mi->dpy, e->xfont, e->font_dlist, - mi->xgwa.width, mi->xgwa.height, - 10, mi->xgwa.height - 10, - e->engine_name); + print_texture_label (mi->dpy, e->font_data, + mi->xgwa.width, mi->xgwa.height, + 1, e->engine_name); if(mi->fps_p) do_fps(mi); glFinish(); glXSwapBuffers(disp, w); } -ENTRYPOINT void -release_engine(ModeInfo *mi) -{ - if (engine != NULL) { - (void) free((void *) engine); - engine = NULL; - } - FreeAllGL(mi); -} - XSCREENSAVER_MODULE ("Engine", engine) #endif