X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fglx%2Fcircuit.c;h=e5723d5aec417f2c6e387d157ef6312e1fdfa93a;hp=e7ee382b80daae3fb04d1771578bf2c1e03b1c82;hb=4361b69d3178d7fc98d0388f9a223af6c2651aba;hpb=e4fa2ac140f7bc56571373a7b7eb585fa4500e38 diff --git a/hacks/glx/circuit.c b/hacks/glx/circuit.c index e7ee382b..e5723d5a 100644 --- a/hacks/glx/circuit.c +++ b/hacks/glx/circuit.c @@ -11,7 +11,7 @@ * surface mount, to-92 markings. Fixed ~5min crash. * Better LED illumination. Other minor changes. * - * Copyright (C) 2001,2002 Ben Buxton (bb@cactii.net) + * Copyright (C) 2001-2015 Ben Buxton (bb@cactii.net) * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -26,42 +26,29 @@ * * -seven option is dedicated to all the Slarkeners * - * try "-rotate -rotate-speed 0" - * * This hack uses lookup tables for sin, cos and tan - it can do a lot */ - -#include - #ifdef STANDALONE -# define PROGCLASS "Circuit" -# define HACK_INIT init_circuit -# define HACK_DRAW draw_circuit -# define HACK_RESHAPE reshape_circuit -# define circuit_opts xlockmore_opts -/* insert defaults here */ - -#define DEF_SPIN "True" -#define DEF_SEVEN "False" -#define DEF_PARTS "10" - - -#define DEFAULTS "*parts: " DEF_PARTS " \n" \ - "*spin: " DEF_SPIN "\n" \ - "*delay: 20000 \n" \ - "*showFPS: False \n" \ - "*seven: " DEF_SEVEN "\n" \ - "*light: True \n" \ - "*rotate: False\n" \ - "*font: fixed\n" \ - "*rotatespeed: 1\n" \ - +#define DEFAULTS "*delay: 20000 \n" \ + "*showFPS: False \n" \ + "*suppressRotationAnimation: True\n" \ + "*componentFont: -*-courier-bold-r-normal-*-*-140-*-*-*-*-*-*" + +# define refresh_circuit 0 +# define release_circuit 0 +# define circuit_handle_event 0 # include "xlockmore.h" /* from the xscreensaver distribution */ #else /* !STANDALONE */ # include "xlock.h" /* from the xlockmore distribution */ #endif /* !STANDALONE */ +#define DEF_SPIN "True" +#define DEF_SEVEN "False" +#define DEF_PARTS "10" +#define DEF_ROTATESPEED "1" +#define DEF_LIGHT "True" + /* lifted from lament.c */ #define RAND(n) ((long) ((random() & 0x7fffffff) % ((long) (n)))) #define RANDSIGN() ((random() & 1) ? 1 : -1) @@ -69,117 +56,60 @@ #ifdef USE_GL -#include -#include "font-ximage.h" +#include "texfont.h" #undef countof #define countof(x) (sizeof((x))/sizeof((*x))) static int maxparts; -static int spin; -static int seven; -static int rotate; static int rotatespeed; +static int spin; static int uselight; -static char *font; -int def_parts = 10; +static int seven; #undef countof #define countof(x) (sizeof((x))/sizeof((*x))) static XrmOptionDescRec opts[] = { - {"-parts", ".circuit.parts", XrmoptionSepArg, "10" }, - {"-font", ".circuit.font", XrmoptionSepArg, "fixed" }, - {"-rotate-speed", ".circuit.rotatespeed", XrmoptionSepArg, "1" }, - {"+spin", ".circuit.spin", XrmoptionNoArg, (caddr_t) "false" }, - {"-spin", ".circuit.spin", XrmoptionNoArg, (caddr_t) "true" }, - {"+light", ".circuit.light", XrmoptionNoArg, (caddr_t) "false" }, - {"-light", ".circuit.light", XrmoptionNoArg, (caddr_t) "true" }, - {"+seven", ".circuit.seven", XrmoptionNoArg, (caddr_t) "false" }, - {"-seven", ".circuit.seven", XrmoptionNoArg, (caddr_t) "true" }, - {"+rotate", ".circuit.rotate", XrmoptionNoArg, (caddr_t) "false" }, - {"-rotate", ".circuit.rotate", XrmoptionNoArg, (caddr_t) "true" }, + {"-parts", ".circuit.parts", XrmoptionSepArg, 0 }, + {"-rotate-speed", ".circuit.rotatespeed", XrmoptionSepArg, 0 }, + {"+spin", ".circuit.spin", XrmoptionNoArg, "false" }, + {"-spin", ".circuit.spin", XrmoptionNoArg, "true" }, + {"+light", ".circuit.light", XrmoptionNoArg, "false" }, + {"-light", ".circuit.light", XrmoptionNoArg, "true" }, + {"+seven", ".circuit.seven", XrmoptionNoArg, "false" }, + {"-seven", ".circuit.seven", XrmoptionNoArg, "true" }, }; static argtype vars[] = { {&maxparts, "parts", "Parts", DEF_PARTS, t_Int}, - {&font, "font", "Font", "fixed", t_String}, - {&rotatespeed, "rotatespeed", "Rotatespeed", "1", t_Int}, + {&rotatespeed, "rotatespeed", "Rotatespeed", DEF_ROTATESPEED, t_Int}, {&spin, "spin", "Spin", DEF_SPIN, t_Bool}, - {&rotate, "rotate", "Rotate", "False", t_Bool}, - {&uselight, "light", "Light", "True", t_Bool}, + {&uselight, "light", "Light", DEF_LIGHT, t_Bool}, {&seven, "seven", "Seven", DEF_SEVEN, t_Bool}, }; -ModeSpecOpt circuit_opts = {countof(opts), opts, countof(vars), vars, NULL}; +ENTRYPOINT ModeSpecOpt circuit_opts = {countof(opts), opts, countof(vars), vars, NULL}; #ifdef USE_MODULES ModStruct circuit_description = -{"circuit", "init_circuit", "draw_circuit", "release_circuit", +{"circuit", "init_circuit", "draw_circuit", NULL, "draw_circuit", "init_circuit", NULL, &circuit_opts, 1000, 1, 2, 1, 4, 1.0, "", "Flying electronic components", 0, NULL}; #endif +#define MAX_COMPONENTS 400 +#define MOVE_MULT 0.02 -typedef struct { - GLXContext *glx_context; - Window window; -} Circuit; - -static Circuit *circuit = NULL; - -#include -#include -#include -#include - -#ifndef M_PI -#define M_PI 3.14159265 -#endif - -/* window width, height */ -int win_w, win_h; - -/* width and height of viewport */ - -#define XMAX 30 -static int YMAX = 30; - -#define MAX_COMPONENTS 30 - -#define MOVE_MULT 0.05 - -static float f_rand(void) { +static float f_rand(void) +{ return ((float)RAND(10000)/(float)10000); } #define RAND_RANGE(min, max) ((min) + (max - min) * f_rand()) -/* one lucky led gets to be a light source , unless -no-light*/ -int light = 0; -int lighton = 0; - -/* stores refs to textures */ -static int s_refs[50]; - -static GLfloat viewer[] = {0.0, 0.0, 14.0}; -static GLfloat lightpos[] = {7.0, 7.0, 15, 1.0}; - -float sin_table[720]; -float cos_table[720]; -float tan_table[720]; - -ModeInfo *modeinfo; - -/* used for allocating font textures */ -typedef struct { - int num; /* index number */ - int w; /* width */ - int h; /* height */ -} TexNum; - /* Represents a band on a resistor/diode/etc */ typedef struct { float pos; /* relative position from start/previous band */ @@ -197,7 +127,7 @@ typedef struct { GLfloat r, g, b; /* body colour */ } Diode; -static const char * transistortypes[] = { +static const char * const transistortypes[] = { "TIP2955", "TIP32C", "LM 350T", @@ -213,7 +143,7 @@ static const char * transistortypes[] = { "SC141D" }; -static const char * to92types[] = { +static const char * const to92types[] = { "C\n548", "C\n848", "74\nL05", @@ -228,7 +158,7 @@ static const char * to92types[] = { "LM\n35DZ", }; -static const char * smctypes[] = { +static const char * const smctypes[] = { "1M-", "1K", "1F", @@ -240,8 +170,7 @@ static const char * smctypes[] = { typedef struct { int type; /* package type. 0 = to-92, 1 = to-220 */ - GLfloat tw, th; /* texture dimensions */ - GLuint tnum; /* texture binding */ + const char *text; } Transistor; typedef struct { @@ -315,8 +244,7 @@ static const ICTypes ictypes[] = { typedef struct { int type; /* 0 = DIL, 1 = flat square */ int pins; - float tw, th; /* texture dimensions for markings */ - int tnum; /* texture number */ + char text[100]; } IC; /* 7 segment display */ @@ -348,11 +276,9 @@ typedef struct { void * c; /* pointer to the component */ } Component; -static int band_list[12]; - /* standard colour codes */ -static GLfloat colorcodes [12][3] = { +static const GLfloat colorcodes [12][3] = { {0.0,0.0,0.0}, /* black 0 */ {0.49,0.25,0.08}, /* brown 1 */ {1.0,0.0,0.0}, /* red 2 */ @@ -368,7 +294,7 @@ static GLfloat colorcodes [12][3] = { }; /* base values for components - we can multiply by 0 - 1M */ -static int values [9][2] = { +static const int values [9][2] = { {1,0}, {2,2}, {3,3}, @@ -380,85 +306,133 @@ static int values [9][2] = { {9,1} }; -void DrawResistor(Resistor *); -void DrawDiode(Diode *); -void DrawTransistor(Transistor *); -void DrawLED(LED *); -void DrawIC(IC *); -void DrawCapacitor(Capacitor *); -void DrawDisp(Disp *); -void DrawFuse(Fuse *); -void DrawRCA(RCA *); -void DrawThreeFive(ThreeFive *); -void DrawSwitch(Switch *); - -void freetexture(GLuint); -void reorder(Component *[]); -void circle(float, int,int); -void bandedCylinder(float, float , GLfloat, GLfloat , GLfloat, Band **, int); -TexNum *fonttexturealloc(const char *, float *, float *); -void Rect(GLfloat , GLfloat , GLfloat, GLfloat , GLfloat ,GLfloat); -void ICLeg(GLfloat, GLfloat, GLfloat, int); -void HoledRectangle(GLfloat, GLfloat, GLfloat, GLfloat, int); -Resistor *NewResistor(void); -Diode *NewDiode(void); -Transistor *NewTransistor(void); -LED * NewLED(void); -Capacitor *NewCapacitor(void); -IC* NewIC(void); -Disp* NewDisp(void); -Fuse *NewFuse(void); -RCA *NewRCA(void); -ThreeFive *NewThreeFive(void); -Switch *NewSwitch(void); +typedef struct { + GLXContext *glx_context; + Window window; + + int XMAX, YMAX; + int win_w, win_h; + + /* one lucky led gets to be a light source , unless -no-light*/ + int light; + int lighton; + + /* stores refs to textures */ + int s_refs[50]; + + GLfloat viewer[3]; + GLfloat lightpos[4]; + + float sin_table[720]; + float cos_table[720]; + float tan_table[720]; + + Component *components[MAX_COMPONENTS]; + int band_list[12]; + int band_list_polys[12]; + + GLfloat grid_col[3], grid_col2[3]; + + int display_i; + GLfloat rotate_angle; + + texture_font_data *font; + char *font_strings[50]; /* max of 40 textures */ + int font_w[50], font_h[50]; + int font_init; + + GLfloat draw_sx, draw_sy; /* bright spot co-ords */ + int draw_sdir; /* 0 = left-right, 1 = right-left, 2 = up->dn, 3 = dn->up */ + int draw_s; /* if spot is enabled */ + float draw_ds; /* speed of spot */ + +} Circuit; + +static Circuit *circuit = NULL; + + +static int DrawResistor(Circuit *, Resistor *); +static int DrawDiode(Circuit *, Diode *); +static int DrawTransistor(Circuit *, Transistor *); +static int DrawLED(Circuit *, LED *); +static int DrawIC(Circuit *, IC *); +static int DrawCapacitor(Circuit *, Capacitor *); +static int DrawDisp(Circuit *, Disp *); +static int DrawFuse(Circuit *, Fuse *); +static int DrawRCA(Circuit *, RCA *); +static int DrawThreeFive(Circuit *, ThreeFive *); +static int DrawSwitch(Circuit *, Switch *); + +static void reorder(Component *[]); +static int circle(Circuit *, float, int,int); +static int bandedCylinder(Circuit *, + float, float , GLfloat, GLfloat , GLfloat, + Band **, int); +static int Rect(GLfloat , GLfloat , GLfloat, GLfloat , GLfloat ,GLfloat); +static int ICLeg(GLfloat, GLfloat, GLfloat, int); +static int HoledRectangle(Circuit *ci, + GLfloat, GLfloat, GLfloat, GLfloat, int); +static Resistor *NewResistor(void); +static Diode *NewDiode(void); +static Transistor *NewTransistor(ModeInfo *); +static LED * NewLED(Circuit *); +static Capacitor *NewCapacitor(Circuit *); +static IC* NewIC(ModeInfo *); +static Disp* NewDisp(Circuit *); +static Fuse *NewFuse(Circuit *); +static RCA *NewRCA(Circuit *); +static ThreeFive *NewThreeFive(Circuit *); +static Switch *NewSwitch(Circuit *); /* we use trig tables to speed things up - 200 calls to sin() in one frame can be a bit harsh.. */ -void make_tables(void) { +static void make_tables(Circuit *ci) +{ int i; float f; f = 360 / (M_PI * 2); for (i = 0 ; i < 720 ; i++) { - sin_table[i] = sin(i/f); + ci->sin_table[i] = sin(i/f); } for (i = 0 ; i < 720 ; i++) { - cos_table[i] = cos(i/f); + ci->cos_table[i] = cos(i/f); } for (i = 0 ; i < 720 ; i++) { - tan_table[i] = tan(i/f); + ci->tan_table[i] = tan(i/f); } } -void createCylinder (float length, float radius, int endcaps, int half) +static int createCylinder (Circuit *ci, + float length, float radius, int endcaps, int half) { + int polys = 0; int a; /* current angle around cylinder */ int angle, norm; float z1, y1, z2, y2,ex; - int step; int nsegs; glPushMatrix(); - nsegs = radius*MAX(win_w, win_h)/20; + nsegs = radius*MAX(ci->win_w, ci->win_h)/20; nsegs = MAX(nsegs, 4); if (nsegs % 2) nsegs += 1; angle = (half) ? (180 - 90/nsegs) : 374; - step = angle/nsegs; z1 = radius; y1 = 0; glBegin(GL_QUADS); for (a = 0 ; a <= angle ; a+= angle/nsegs) { - y2=radius*(float)sin_table[(int)a]; - z2=radius*(float)cos_table[(int)a]; + y2=radius*(float)ci->sin_table[(int)a]; + z2=radius*(float)ci->cos_table[(int)a]; glNormal3f(0, y1, z1); glVertex3f(0,y1,z1); glVertex3f(length,y1,z1); glNormal3f(0, y2, z2); glVertex3f(length,y2,z2); glVertex3f(0,y2,z2); + polys++; z1=z2; y1=y2; } @@ -470,6 +444,7 @@ void createCylinder (float length, float radius, int endcaps, int half) glVertex3f(length, 0, radius); glVertex3f(length, 0, 0 - radius); glVertex3f(0, 0, 0 - radius); + polys++; glEnd(); } if (endcaps) { @@ -479,11 +454,12 @@ void createCylinder (float length, float radius, int endcaps, int half) glBegin(GL_TRIANGLES); glNormal3f(norm, 0, 0); for (a = 0 ; a <= angle ; a+= angle/nsegs) { - y2=radius*(float)sin_table[(int)a]; - z2=radius*(float)cos_table[(int)a]; + y2=radius*(float)ci->sin_table[(int)a]; + z2=radius*(float)ci->cos_table[(int)a]; glVertex3f(ex,0, 0); glVertex3f(ex,y1,z1); glVertex3f(ex,y2,z2); + polys++; z1=z2; y1=y2; } @@ -491,10 +467,12 @@ void createCylinder (float length, float radius, int endcaps, int half) } } glPopMatrix(); + return polys; } -void circle(float radius, int segments, int half) +static int circle(Circuit *ci, float radius, int segments, int half) { + int polys = 0; float x1 = 0, x2 = 0; float y1 = 0, y2 = 0; int i, t, s; @@ -510,22 +488,25 @@ void circle(float radius, int segments, int half) for(i=s;i<=t;i+=10) { float angle=i; - x2=radius*(float)cos_table[(int)angle]; - y2=radius*(float)sin_table[(int)angle]; + x2=radius*(float)ci->cos_table[(int)angle]; + y2=radius*(float)ci->sin_table[(int)angle]; glVertex3f(0,0,0); glVertex3f(0,y1,x1); glVertex3f(0,y2,x2); + polys++; x1=x2; y1=y2; } glEnd(); + return polys; } -void wire(float len) +static int wire(Circuit *ci, float len) { - static GLfloat col[] = {0.3, 0.3, 0.3, 1.0}; - static GLfloat spec[] = {0.9, 0.9, 0.9, 1.0}; - static GLfloat nospec[] = {0.4, 0.4, 0.4, 1.0}; + int polys = 0; + GLfloat col[] = {0.3, 0.3, 0.3, 1.0}; + GLfloat spec[] = {0.9, 0.9, 0.9, 1.0}; + GLfloat nospec[] = {0.4, 0.4, 0.4, 1.0}; GLfloat shin = 30; int n; @@ -534,46 +515,19 @@ void wire(float len) glMaterialfv(GL_FRONT, GL_SHININESS, &shin); n = glIsEnabled(GL_NORMALIZE); if (!n) glEnable(GL_NORMALIZE); - createCylinder(len, 0.05, 1, 0); + polys += createCylinder(ci, len, 0.05, 1, 0); if (!n) glDisable(GL_NORMALIZE); glMaterialfv(GL_FRONT, GL_SPECULAR, nospec); + return polys; } -void ring(GLfloat inner, GLfloat outer, int nsegs) -{ - GLfloat z1, z2, y1, y2; - GLfloat Z1, Z2, Y1, Y2; - int i; - - z1 = inner; y1 = 0; - Z1 = outer; Y1 = 0; - glBegin(GL_QUADS); - glNormal3f(1, 0, 0); - for(i=0; i <=360 ; i+= 360/nsegs) - { - float angle=i; - z2=inner*(float)sin_table[(int)angle]; - y2=inner*(float)cos_table[(int)angle]; - Z2=outer*(float)sin_table[(int)angle]; - Y2=outer*(float)cos_table[(int)angle]; - glVertex3f(0, Y1, Z1); - glVertex3f(0, y1, z1); - glVertex3f(0, y2, z2); - glVertex3f(0, Y2, Z2); - z1=z2; - y1=y2; - Z1=Z2; - Y1=Y2; - } - glEnd(); -} - -void sphere(GLfloat r, float stacks, float slices, +static int sphere(Circuit *ci, GLfloat r, float stacks, float slices, int startstack, int endstack, int startslice, int endslice) { + int polys = 0; GLfloat d, d1, dr, dr1, Dr, Dr1, D, D1, z1, z2, y1, y2, Y1, Z1, Y2, Z2; - int a, a1, b, b1, c, c1; + int a, a1, b, b1, c0, c1; GLfloat step, sstep; step = 180/stacks; @@ -581,23 +535,23 @@ void sphere(GLfloat r, float stacks, float slices, a1 = startstack * step; b1 = startslice * sstep; y1 = z1 = Y1 = Z1 = 0; - c = (endslice / slices) * 360; + c0 = (endslice / slices) * 360; c1 = (endstack/stacks)*180; glBegin(GL_QUADS); for (a = startstack * step ; a <= c1 ; a+= step) { - d=sin_table[a]; - d1=sin_table[a1]; - D=cos_table[a]; - D1=cos_table[a1]; + d=ci->sin_table[a]; + d1=ci->sin_table[a1]; + D=ci->cos_table[a]; + D1=ci->cos_table[a1]; dr = d * r; dr1 = d1 * r; Dr = D * r; Dr1 = D1 * r; - for (b = b1 ; b <= c ; b+= sstep) { - y2=dr*sin_table[b]; - z2=dr*cos_table[b]; - Y2=dr1*sin_table[b]; - Z2=dr1*cos_table[b]; + for (b = b1 ; b <= c0 ; b+= sstep) { + y2=dr*ci->sin_table[b]; + z2=dr*ci->cos_table[b]; + Y2=dr1*ci->sin_table[b]; + Z2=dr1*ci->cos_table[b]; glNormal3f(Dr, y1, z1); glVertex3f(Dr,y1,z1); glNormal3f(Dr, y2, z2); @@ -606,6 +560,7 @@ void sphere(GLfloat r, float stacks, float slices, glVertex3f(Dr1,Y2,Z2); glNormal3f(Dr1, Y1, Z1); glVertex3f(Dr1,Y1,Z1); + polys++; z1=z2; y1=y2; Z1=Z2; @@ -614,10 +569,12 @@ void sphere(GLfloat r, float stacks, float slices, a1 = a; } glEnd(); + return polys; } -int DrawComponent(Component *c) +static int DrawComponent(Circuit *ci, Component *c, unsigned long *polysP) { + int polys = *polysP; int ret = 0; /* return 1 if component is freed */ glPushMatrix(); @@ -637,49 +594,41 @@ int DrawComponent(Component *c) /* call object draw routine here */ if (c->type == 0) { - DrawResistor(c->c); + polys += DrawResistor(ci, c->c); } else if (c->type == 1) { - DrawDiode(c->c); + polys += DrawDiode(ci, c->c); } else if (c->type == 2) { - DrawTransistor(c->c); + polys += DrawTransistor(ci, c->c); } else if (c->type == 3) { - if (((LED *)c->c)->light && light) { + if (((LED *)c->c)->light && ci->light) { GLfloat lp[] = {0.1, 0, 0, 1}; glEnable(GL_LIGHT1); glLightfv(GL_LIGHT1, GL_POSITION, lp); } - DrawLED(c->c); + polys += DrawLED(ci, c->c); } else if (c->type == 4) { - DrawCapacitor(c->c); + polys += DrawCapacitor(ci, c->c); } else if (c->type == 5) { - DrawIC(c->c); + polys += DrawIC(ci, c->c); } else if (c->type == 6) { - DrawDisp(c->c); + polys += DrawDisp(ci, c->c); } else if (c->type == 7) { - DrawFuse(c->c); + polys += DrawFuse(ci, c->c); } else if (c->type == 8) { - DrawRCA(c->c); + polys += DrawRCA(ci, c->c); } else if (c->type == 9) { - DrawThreeFive(c->c); + polys += DrawThreeFive(ci, c->c); } else if (c->type == 10) { - DrawSwitch(c->c); + polys += DrawSwitch(ci, c->c); } c->x += c->dx * MOVE_MULT; c->y += c->dy * MOVE_MULT; - if (c->x > XMAX/2 || c->x < 0 - XMAX/2 || - c->y > YMAX/2 || c->y < 0 - YMAX/2) { - if (c->type == 3 && ((LED *)c->c)->light && light) { + if (c->x > ci->XMAX/2 || c->x < 0 - ci->XMAX/2 || + c->y > ci->YMAX/2 || c->y < 0 - ci->YMAX/2) { + if (c->type == 3 && ((LED *)c->c)->light && ci->light) { glDisable(GL_LIGHT1); - light = 0; lighton = 0; + ci->light = 0; ci->lighton = 0; } - if (c->type == 5) { - if (((IC *)c->c)->tnum) - freetexture(((IC *)c->c)->tnum); - } - if (c->type == 2) { - if (((Transistor *)c->c)->tnum) - freetexture(((Transistor *)c->c)->tnum); - } if (c->type == 1) free(((Diode *)c->c)->band); /* remember to free diode band */ free(c->c); @@ -688,121 +637,130 @@ int DrawComponent(Component *c) glPopMatrix(); glDisable(GL_NORMALIZE); + *polysP = polys; return ret; } /* draw a resistor */ -void DrawResistor(Resistor *r) +static int DrawResistor(Circuit *ci, Resistor *r) { + int polys = 0; int i; GLfloat col[] = {0.74, 0.62, 0.46, 1.0}; GLfloat spec[] = {0.8, 0.8, 0.8, 1.0}; GLfloat shine = 30; glTranslatef(-4, 0, 0); - wire(3); + polys += wire(ci, 3); glTranslatef(3, 0, 0); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col); glMaterialfv(GL_FRONT, GL_SPECULAR, spec); glMaterialfv(GL_FRONT, GL_SHININESS, &shine); - createCylinder(1.8, 0.4, 1, 0); + polys += createCylinder(ci, 1.8, 0.4, 1, 0); glPushMatrix(); for (i = 0 ; i < 4 ; i++) { glTranslatef(0.35, 0, 0); - glCallList(band_list[r->b[i]]); + glCallList(ci->band_list[r->b[i]]); + polys += ci->band_list_polys[r->b[i]]; } glPopMatrix(); glTranslatef(1.8, 0, 0); - wire(3); + polys += wire(ci, 3); + return polys; } -void DrawRCA(RCA *rca) +static int DrawRCA(Circuit *ci, RCA *rca) { - static GLfloat col[] = {0.6, 0.6, 0.6, 1.0}; /* metal */ - static GLfloat red[] = {1.0, 0.0, 0.0, 1.0}; /* red */ - static GLfloat white[] = {1.0, 1.0, 1.0, 1.0}; /* white */ - static GLfloat spec[] = {1, 1, 1, 1}; /* glass */ + int polys = 0; + GLfloat col[] = {0.6, 0.6, 0.6, 1.0}; /* metal */ + GLfloat red[] = {1.0, 0.0, 0.0, 1.0}; /* red */ + GLfloat white[] = {1.0, 1.0, 1.0, 1.0}; /* white */ + GLfloat spec[] = {1, 1, 1, 1}; /* glass */ glPushMatrix(); glTranslatef(0.3, 0, 0); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col); glMateriali(GL_FRONT, GL_SHININESS, 40); glMaterialfv(GL_FRONT, GL_SPECULAR, spec); - createCylinder(0.7, 0.45, 0, 0); + polys += createCylinder(ci, 0.7, 0.45, 0, 0); glTranslatef(0.4, 0, 0); - createCylinder(0.9, 0.15, 1, 0); + polys += createCylinder(ci, 0.9, 0.15, 1, 0); glTranslatef(-1.9, 0, 0); glMateriali(GL_FRONT, GL_SHININESS, 20); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, rca->col ? white : red); - createCylinder(1.5, 0.6, 1, 0); + polys += createCylinder(ci, 1.5, 0.6, 1, 0); glTranslatef(-0.9, 0, 0); - createCylinder(0.9, 0.25, 0, 0); + polys += createCylinder(ci, 0.9, 0.25, 0, 0); glTranslatef(0.1, 0, 0); - createCylinder(0.2, 0.3, 0, 0); + polys += createCylinder(ci, 0.2, 0.3, 0, 0); glTranslatef(0.3, 0, 0); - createCylinder(0.2, 0.3, 1, 0); + polys += createCylinder(ci, 0.2, 0.3, 1, 0); glTranslatef(0.3, 0, 0); - createCylinder(0.2, 0.3, 1, 0); + polys += createCylinder(ci, 0.2, 0.3, 1, 0); glPopMatrix(); + return polys; } -void DrawSwitch(Switch *f) +static int DrawSwitch(Circuit *ci, Switch *f) { - static GLfloat col[] = {0.6, 0.6, 0.6, 0}; /* metal */ - static GLfloat dark[] = {0.1, 0.1, 0.1, 1.0}; /* dark */ - static GLfloat brown[] = {0.69, 0.32, 0, 1.0}; /* brown */ - static GLfloat spec[] = {0.9, 0.9, 0.9, 1}; /* shiny */ + int polys = 0; + GLfloat col[] = {0.6, 0.6, 0.6, 0}; /* metal */ + GLfloat dark[] = {0.1, 0.1, 0.1, 1.0}; /* dark */ + GLfloat brown[] = {0.69, 0.32, 0, 1.0}; /* brown */ + GLfloat spec[] = {0.9, 0.9, 0.9, 1}; /* shiny */ glPushMatrix(); glMaterialfv(GL_FRONT, GL_DIFFUSE, col); glMaterialfv(GL_FRONT, GL_AMBIENT, dark); glMaterialfv(GL_FRONT, GL_SPECULAR, spec); glMateriali(GL_FRONT, GL_SHININESS, 90); - Rect(-0.25, 0, 0, 1.5, 0.5, 0.75); -/* Rect(-0.5, 0.5, 0, 2, 0.1, 0.75); */ + polys += Rect(-0.25, 0, 0, 1.5, 0.5, 0.75); +/* polys += Rect(-0.5, 0.5, 0, 2, 0.1, 0.75); */ glPushMatrix(); glRotatef(90, 1, 0, 0); glTranslatef(-0.5, -0.4, -0.4); - HoledRectangle(0.5, 0.75, 0.1, 0.15, 8); + polys += HoledRectangle(ci, 0.5, 0.75, 0.1, 0.15, 8); glTranslatef(2, 0, 0); - HoledRectangle(0.5, 0.75, 0.1, 0.15, 8); + polys += HoledRectangle(ci, 0.5, 0.75, 0.1, 0.15, 8); glPopMatrix(); - Rect(0.1, -0.4, -0.25, 0.1, 0.4, 0.05); - Rect(0.5, -0.4, -0.25, 0.1, 0.4, 0.05); - Rect(0.9, -0.4, -0.25, 0.1, 0.4, 0.05); - Rect(0.1, -0.4, -0.5, 0.1, 0.4, 0.05); - Rect(0.5, -0.4, -0.5, 0.1, 0.4, 0.05); - Rect(0.9, -0.4, -0.5, 0.1, 0.4, 0.05); + polys += Rect(0.1, -0.4, -0.25, 0.1, 0.4, 0.05); + polys += Rect(0.5, -0.4, -0.25, 0.1, 0.4, 0.05); + polys += Rect(0.9, -0.4, -0.25, 0.1, 0.4, 0.05); + polys += Rect(0.1, -0.4, -0.5, 0.1, 0.4, 0.05); + polys += Rect(0.5, -0.4, -0.5, 0.1, 0.4, 0.05); + polys += Rect(0.9, -0.4, -0.5, 0.1, 0.4, 0.05); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, dark); glMaterialfv(GL_FRONT, GL_SPECULAR, spec); - Rect(0, 0.5, -0.1, 1, 0.05, 0.5); - Rect(0, 0.6, -0.1, 0.5, 0.6, 0.5); + polys += Rect(0, 0.5, -0.1, 1, 0.05, 0.5); + polys += Rect(0, 0.6, -0.1, 0.5, 0.6, 0.5); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, brown); - Rect(-0.2, -0.01, -0.1, 1.4, 0.1, 0.55); + polys += Rect(-0.2, -0.01, -0.1, 1.4, 0.1, 0.55); glPopMatrix(); + return polys; } -void DrawFuse(Fuse *f) +static int DrawFuse(Circuit *ci, Fuse *f) { - static GLfloat col[] = {0.5, 0.5, 0.5, 1.0}; /* endcaps */ - static GLfloat glass[] = {0.4, 0.4, 0.4, 0.3}; /* glass */ - static GLfloat spec[] = {1, 1, 1, 1}; /* glass */ + int polys = 0; + GLfloat col[] = {0.5, 0.5, 0.5, 1.0}; /* endcaps */ + GLfloat glass[] = {0.4, 0.4, 0.4, 0.3}; /* glass */ + GLfloat spec[] = {1, 1, 1, 1}; /* glass */ glPushMatrix(); glTranslatef(-1.8, 0, 0); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col); glMaterialfv(GL_FRONT, GL_SPECULAR, spec); glMateriali(GL_FRONT, GL_SHININESS, 40); - createCylinder(0.8, 0.45, 1, 0); + polys += createCylinder(ci, 0.8, 0.45, 1, 0); glTranslatef(0.8, 0, 0); glEnable(GL_BLEND); glDepthMask(GL_FALSE); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, glass); glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 40); - createCylinder(2, 0.4, 0, 0); - createCylinder(2, 0.3, 0, 0); + polys += createCylinder(ci, 2, 0.4, 0, 0); + polys += createCylinder(ci, 2, 0.3, 0, 0); glDisable(GL_BLEND); glDepthMask(GL_TRUE); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col); @@ -812,29 +770,31 @@ void DrawFuse(Fuse *f) glVertex3f(2, 0. ,0); glEnd(); glTranslatef(2, 0, 0); - createCylinder(0.8, 0.45, 1, 0); + polys += createCylinder(ci, 0.8, 0.45, 1, 0); glPopMatrix(); + return polys; } -void DrawCapacitor(Capacitor *c) +static int DrawCapacitor(Circuit *ci, Capacitor *c) { - static GLfloat col[] = {0, 0, 0, 0}; - static GLfloat spec[] = {0.8, 0.8, 0.8, 0}; + int polys = 0; + GLfloat col[] = {0, 0, 0, 0}; + GLfloat spec[] = {0.8, 0.8, 0.8, 0}; GLfloat brown[] = {0.84, 0.5, 0}; - static GLfloat shine = 40; + GLfloat shine = 40; glPushMatrix(); if (c->type) { glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, brown); - sphere(c->width, 15, 15, 0, 4 ,0, 15); + polys += sphere(ci, c->width, 15, 15, 0, 4 ,0, 15); glTranslatef(1.35*c->width, 0, 0); - sphere(c->width, 15, 15, 11, 15, 0, 15); + polys += sphere(ci, c->width, 15, 15, 11, 15, 0, 15); glRotatef(90, 0, 0, 1); glTranslatef(0, 0.7*c->width, 0.3*c->width); - wire(3*c->width); + polys += wire(ci, 3*c->width); glTranslatef(0, 0, -0.6*c->width); - wire(3*c->width); + polys += wire(ci, 3*c->width); } else { glTranslatef(0-c->length*2, 0, 0); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col); @@ -852,37 +812,39 @@ void DrawCapacitor(Capacitor *c) glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(1.0, 1.0); - createCylinder(3.0*c->length, 0.8*c->width, 1, 0); + polys += createCylinder(ci, 3.0*c->length, 0.8*c->width, 1, 0); glDisable(GL_POLYGON_OFFSET_FILL); col[0] = 0.7; col[1] = 0.7; col[2] = 0.7; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col); - circle(0.6*c->width, 30, 0); + polys += circle(ci, 0.6*c->width, 30, 0); col[0] = 0; col[1] = 0; col[2] = 0; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col); glTranslatef(3.0*c->length, 0.0, 0); - circle(0.6*c->width, 30, 0); + polys += circle(ci, 0.6*c->width, 30, 0); glTranslatef(0, 0.4*c->width, 0); - wire(3*c->length); + polys += wire(ci, 3*c->length); glTranslatef(0.0, -0.8*c->width, 0); - wire(3.3*c->length); + polys += wire(ci, 3.3*c->length); } glPopMatrix(); + return polys; } -void DrawLED(LED *l) +static int DrawLED(Circuit *ci, LED *l) { + int polys = 0; GLfloat col[] = {0, 0, 0, 0.6}; GLfloat black[] = {0, 0, 0, 0.6}; col[0] = l->r; col[1] = l->g; col[2] = l->b; - if (l->light && light) { + if (l->light && ci->light) { GLfloat dir[] = {-1, 0, 0}; glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, dir); - if (!lighton) { + if (!ci->lighton) { glLightfv(GL_LIGHT1, GL_SPECULAR, col); glLightfv(GL_LIGHT1, GL_AMBIENT, black); col[0] /= 1.5; col[1] /= 1.5; col[2] /= 1.5; @@ -892,7 +854,7 @@ void DrawLED(LED *l) glLighti(GL_LIGHT1, GL_LINEAR_ATTENUATION, (GLfloat)0); glLighti(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, (GLfloat)0); glLighti(GL_LIGHT1, GL_SPOT_EXPONENT, (GLint) 20); - lighton = 1; + ci->lighton = 1; } } glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col); @@ -904,13 +866,13 @@ void DrawLED(LED *l) glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); } glTranslatef(-0.9, 0, 0); - createCylinder(1.2, 0.3, 0, 0); - if (l->light && light) { + polys += createCylinder(ci, 1.2, 0.3, 0, 0); + if (l->light && ci->light) { glDisable(GL_LIGHTING); glColor3fv(col); } - sphere(0.3, 7, 7, 3, 7, 0, 7); - if (l->light && light) { + polys += sphere(ci, 0.3, 7, 7, 3, 7, 0, 7); + if (l->light && ci->light) { glEnable(GL_LIGHTING); } else { glDepthMask(GL_TRUE); @@ -918,29 +880,32 @@ void DrawLED(LED *l) } glTranslatef(1.2, 0, 0); - createCylinder(0.1, 0.38, 1, 0); + polys += createCylinder(ci, 0.1, 0.38, 1, 0); glTranslatef(-0.3, 0.15, 0); - wire(3); + polys += wire(ci, 3); glTranslatef(0, -0.3, 0); - wire(3.3); + polys += wire(ci, 3.3); if (random() % 50 == 25) { if (l->light) { - l->light = 0; light = 0; lighton = 0; + l->light = 0; ci->light = 0; ci->lighton = 0; glDisable(GL_LIGHT1); - } else if (!light) { - l->light = 1; light = 1; + } else if (!ci->light) { + l->light = 1; + ci->light = 1; } } + return polys; } -void DrawThreeFive(ThreeFive *d) +static int DrawThreeFive(Circuit *ci, ThreeFive *d) { + int polys = 0; GLfloat shine = 40; - GLfloat dark[] = {0.3, 0.3, 0.3, 0}; - GLfloat light[] = {0.6, 0.6, 0.6, 0}; - GLfloat cream[] = {0.8, 0.8, 0.6, 0}; - GLfloat spec[] = {0.7, 0.7, 0.7, 0}; + GLfloat const dark[] = {0.3, 0.3, 0.3, 0}; + GLfloat const light[] = {0.6, 0.6, 0.6, 0}; + GLfloat const cream[] = {0.8, 0.8, 0.6, 0}; + GLfloat const spec[] = {0.7, 0.7, 0.7, 0}; glPushMatrix(); glMaterialfv(GL_FRONT, GL_SHININESS, &shine); @@ -948,26 +913,28 @@ void DrawThreeFive(ThreeFive *d) glMaterialfv(GL_FRONT, GL_SPECULAR, spec); glTranslatef(-2.0, 0, 0); - createCylinder(0.7, 0.2, 0, 0); + polys += createCylinder(ci, 0.7, 0.2, 0, 0); glTranslatef(0.7, 0, 0); - createCylinder(1.3, 0.4, 1, 0); + polys += createCylinder(ci, 1.3, 0.4, 1, 0); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, light); glTranslatef(1.3, 0, 0); - createCylinder(1.3, 0.2, 0, 0); + polys += createCylinder(ci, 1.3, 0.2, 0, 0); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, dark); glTranslatef(0.65, 0, 0); - createCylinder(0.15, 0.21, 0, 0); + polys += createCylinder(ci, 0.15, 0.21, 0, 0); glTranslatef(0.3, 0, 0); - createCylinder(0.15, 0.21, 0, 0); + polys += createCylinder(ci, 0.15, 0.21, 0, 0); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, light); glTranslatef(0.4, 0, 0); - sphere(0.23, 7, 7, 0, 5, 0, 7); + polys += sphere(ci, 0.23, 7, 7, 0, 5, 0, 7); glPopMatrix(); + return polys; } -void DrawDiode(Diode *d) +static int DrawDiode(Circuit *ci, Diode *d) { + int polys = 0; GLfloat shine = 40; GLfloat col[] = {0.3, 0.3, 0.3, 0}; GLfloat spec[] = {0.7, 0.7, 0.7, 0}; @@ -977,17 +944,19 @@ void DrawDiode(Diode *d) glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col); glMaterialfv(GL_FRONT, GL_SPECULAR, spec); glTranslatef(-4, 0, 0); - wire(3); + polys += wire(ci, 3); glTranslatef(3, 0, 0); - bandedCylinder(0.3, 1.5, d->r, d->g, d->b, &(d->band), 1); + polys += bandedCylinder(ci, 0.3, 1.5, d->r, d->g, d->b, &(d->band), 1); glTranslatef(1.5, 0, 0); - wire(3); + polys += wire(ci, 3); glPopMatrix(); + return polys; } -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; @@ -1000,58 +969,67 @@ 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; } /* IC pins */ -void ICLeg(GLfloat x, GLfloat y, GLfloat z, int dir) +static int ICLeg(GLfloat x, GLfloat y, GLfloat z, int dir) { + int polys = 0; if (dir) { - Rect(x-0.1, y, z, 0.1, 0.1, 0.02); - Rect(x-0.1, y, z, 0.02, 0.1, 0.1); - Rect(x-0.1, y+0.03, z-0.1, 0.02, 0.05, 0.3); + polys += Rect(x-0.1, y, z, 0.1, 0.1, 0.02); + polys += Rect(x-0.1, y, z, 0.02, 0.1, 0.1); + polys += Rect(x-0.1, y+0.03, z-0.1, 0.02, 0.05, 0.3); } else { - Rect(x, y, z, 0.1, 0.1, 0.02); - Rect(x+0.8*0.1, y, z, 0.02, 0.1, 0.1); - Rect(x+0.8*0.1, y+0.03, z-0.1, 0.02, 0.05, 0.3); + polys += Rect(x, y, z, 0.1, 0.1, 0.02); + polys += Rect(x+0.8*0.1, y, z, 0.02, 0.1, 0.1); + polys += Rect(x+0.8*0.1, y+0.03, z-0.1, 0.02, 0.05, 0.3); } - + return polys; } -void DrawIC(IC *c) +static int DrawIC(Circuit *ci, IC *c) { + int polys = 0; GLfloat w, h, d; int z; GLfloat col[] = {0.1, 0.1, 0.1, 0}; @@ -1061,7 +1039,6 @@ void DrawIC(IC *c) GLfloat lspec[] = {0.6, 0.6, 0.6, 0}; GLfloat lcol[] = {0.4, 0.4, 0.4, 0}; GLfloat lshine = 40; - float mult, th, size; glPushMatrix(); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col); @@ -1092,54 +1069,58 @@ void DrawIC(IC *c) glVertex3f(w, -h, 0.1); glVertex3f(-w, -h, 0.1); glVertex3f(-w, h, 0.1); + polys++; glNormal3f(0, 0, -1); glVertex3f(w, h, -0.1); glVertex3f(w, -h, -0.1); glVertex3f(-w, -h, -0.1); glVertex3f(-w, h, -0.1); + polys++; glNormal3f(1, 0, 0); glVertex3f(w, h, -0.1); glVertex3f(w, -h, -0.1); glVertex3f(w, -h, 0.1); glVertex3f(w, h, 0.1); + polys++; glNormal3f(0, -1, 0); glVertex3f(w, -h, -0.1); glVertex3f(w, -h, 0.1); glVertex3f(-w, -h, 0.1); glVertex3f(-w, -h, -0.1); + polys++; glNormal3f(-1, 0, 0); glVertex3f(-w, h, -0.1); glVertex3f(-w, h, 0.1); glVertex3f(-w, -h, 0.1); glVertex3f(-w, -h, -0.1); + polys++; glNormal3f(0, -1, 0); glVertex3f(-w, h, -0.1); glVertex3f(w, h, -0.1); glVertex3f(w, h, 0.1); glVertex3f(-w, h, 0.1); + polys++; glEnd(); glDisable(GL_POLYGON_OFFSET_FILL); - if (c->tnum) glBindTexture(GL_TEXTURE_2D, c->tnum); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); - if (c->pins == 8) - size = 0.4; - else - size = 0.6; - th = size*2/3; - mult = size*c->tw / c->th; - mult /= 2; - glBegin(GL_QUADS); /* text markings */ - glNormal3f(0, 0, 1); - glTexCoord2f(0, 1); - glVertex3f(th, mult, 0.1); - glTexCoord2f(1, 1); - glVertex3f(th, -mult, 0.1); - glTexCoord2f(1, 0); - glVertex3f(-th, -mult, 0.1); - glTexCoord2f(0, 0); - glVertex3f(-th, mult, 0.1); - glEnd(); + + { + GLfloat texfg[] = {0.7, 0.7, 0.7, 1.0}; + GLfloat s = 0.015; + XCharStruct e; + texture_string_metrics (ci->font, c->text, &e, 0, 0); + + glPushMatrix(); + glTranslatef (0, 0, 0.1); + glRotatef (90, 0, 0, 1); + glScalef (s, s, s); + glTranslatef (-w/2, 0, 0); + glColor4fv (texfg); + print_texture_string (ci->font, c->text); + glPopMatrix(); + } + glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); d = (h*2-0.1) / c->pins; @@ -1148,20 +1129,22 @@ void DrawIC(IC *c) glMaterialfv(GL_FRONT, GL_SPECULAR, lspec); glMaterialfv(GL_FRONT, GL_SHININESS, &lshine); for (z = 0 ; z < c->pins/2 ; z++) { - ICLeg(w, -h + z*d + d/2, 0, 0); + polys += ICLeg(w, -h + z*d + d/2, 0, 0); } for (z = 0 ; z < c->pins/2 ; z++) { - ICLeg(-w, -h + z*d + d/2, 0, 1); + polys += ICLeg(-w, -h + z*d + d/2, 0, 1); } glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col2); glTranslatef(-w+0.3, h-0.3, 0.1); glRotatef(90, 0, 1, 0); - circle(0.1, 7, 0); + polys += circle(ci, 0.1, 7, 0); glPopMatrix(); + return polys; } -void DrawDisp(Disp *d) +static int DrawDisp(Circuit *ci, Disp *d) { + int polys = 0; GLfloat col[] = {0.8, 0.8, 0.8, 1.0}; /* body colour */ GLfloat front[] = {0.2, 0.2, 0.2, 1.0}; /* front colour */ GLfloat on[] = {0.9, 0, 0, 1}; /* 'on' segment */ @@ -1171,7 +1154,7 @@ void DrawDisp(Disp *d) GLfloat spec[] = {0.6, 0.6, 0.6, 0}; GLfloat lcol[] = {0.4, 0.4, 0.4, 0}; GLfloat shine = 40; - static GLfloat vdata_h[6][2] = { + static const GLfloat vdata_h[6][2] = { {0, 0}, {0.1, 0.1}, {0.9, 0.1}, @@ -1179,7 +1162,7 @@ void DrawDisp(Disp *d) {0.9, -0.1}, {0.1, -0.1} }; - static GLfloat vdata_v[6][2] = { + static const GLfloat vdata_v[6][2] = { {0.27, 0}, {0.35, -0.1}, {0.2, -0.9}, @@ -1188,7 +1171,7 @@ void DrawDisp(Disp *d) {0.15, -0.15} }; - static GLfloat seg_start[7][2] = { + static const GLfloat seg_start[7][2] = { {0.55, 2.26}, {1.35, 2.26}, {1.2, 1.27}, @@ -1198,7 +1181,7 @@ void DrawDisp(Disp *d) {0.39, 1.24} }; - static int nums[10][7] = { + static const int nums[10][7] = { {1, 1, 1, 1, 1, 1, 0}, /* 0 */ {0, 1, 1, 0, 0, 0, 0}, /* 1 */ {1, 1, 0, 1, 1, 0, 1}, /* 2 */ @@ -1213,13 +1196,14 @@ void DrawDisp(Disp *d) glTranslatef(-0.9, -1.8, 0); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col); - Rect(0, 0, -0.01, 1.8, 2.6, 0.7); + polys += Rect(0, 0, -0.01, 1.8, 2.6, 0.7); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, front); glBegin(GL_QUADS); glVertex2f(-0.05, -0.05); glVertex2f(-0.05, 2.65); glVertex2f(1.85, 2.65); glVertex2f(1.85, -0.05); + polys++; glEnd(); glDisable(GL_LIGHTING); /* lit segments dont need light */ if (!seven && (random() % 30) == 19) { /* randomly change value */ @@ -1244,12 +1228,14 @@ void DrawDisp(Disp *d) for(i = 0 ; i < 6 ; i++) { glVertex3f(xx[i], yy[i], 0.01); } + polys++; glEnd(); } glColor3fv(on); glPointSize(4); glBegin(GL_POINTS); glVertex3f(1.5, 0.2, 0.01); + polys++; glEnd(); glEnable(GL_LIGHTING); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, lcol); @@ -1257,13 +1243,17 @@ void DrawDisp(Disp *d) glMaterialfv(GL_FRONT, GL_SHININESS, &shine); for (x = 0.35 ; x <= 1.5 ; x+= 1.15) { for ( y = 0.2 ; y <= 2.4 ; y += 0.3) { - ICLeg(x, y, -0.7, 1); + polys += ICLeg(x, y, -0.7, 1); } } + return polys; } -void HoledRectangle(GLfloat w, GLfloat h, GLfloat d, GLfloat radius, int p) +static int HoledRectangle(Circuit *ci, + GLfloat w, GLfloat h, GLfloat d, GLfloat radius, + int p) { + int polys = 0; int step, a; GLfloat x1, y1, x2, y2; GLfloat yr, yr1, xr, xr1, side, side1; @@ -1276,15 +1266,15 @@ void HoledRectangle(GLfloat w, GLfloat h, GLfloat d, GLfloat radius, int p) side1 = h/2; glBegin(GL_QUADS); for (a = 0 ; a <= 360 ; a+= step) { - y2=radius*(float)sin_table[(int)a]; - x2=radius*(float)cos_table[(int)a]; + y2=radius*(float)ci->sin_table[(int)a]; + x2=radius*(float)ci->cos_table[(int)a]; if (a < 45 || a > 315) { xr = side; - yr = side1 * tan_table[a]; + yr = side1 * ci->tan_table[a]; nx = 1; ny = 0; } else if (a <= 135 || a >= 225) { - xr = side/tan_table[a]; + xr = side/ci->tan_table[a]; if (a >= 225) { yr = -side1; xr = 0 - xr; @@ -1295,7 +1285,7 @@ void HoledRectangle(GLfloat w, GLfloat h, GLfloat d, GLfloat radius, int p) } } else { xr = -side; - yr = -side1 * tan_table[a]; + yr = -side1 * ci->tan_table[a]; nx = -1; ny = 0; } @@ -1304,37 +1294,43 @@ void HoledRectangle(GLfloat w, GLfloat h, GLfloat d, GLfloat radius, int p) glVertex3f(x1,y1,-d); glVertex3f(x2,y2,-d); glVertex3f(x2,y2,0); + polys++; glNormal3f(0, 0, 1); /* front face */ glVertex3f(x1,y1,0); glVertex3f(xr1, yr1, 0); glVertex3f(xr, yr, 0); glVertex3f(x2, y2, 0); + polys++; glNormal3f(nx, ny, 0); /* side */ glVertex3f(xr, yr, 0); glVertex3f(xr, yr, -d); glVertex3f(xr1, yr1, -d); glVertex3f(xr1, yr1, 0); + polys++; glNormal3f(0, 0, -1); /* back */ glVertex3f(xr, yr, -d); glVertex3f(x2, y2, -d); glVertex3f(x1, y1, -d); glVertex3f(xr1, yr1, -d); + polys++; x1=x2; y1=y2; xr1 = xr; yr1 = yr; } glEnd(); + return polys; } -void DrawTransistor(Transistor *t) +static int DrawTransistor(Circuit *ci, Transistor *t) { - static GLfloat col[] = {0.3, 0.3, 0.3, 1.0}; - static GLfloat spec[] = {0.9, 0.9, 0.9, 1.0}; - static GLfloat nospec[] = {0.4, 0.4, 0.4, 1.0}; + int polys = 0; + GLfloat col[] = {0.3, 0.3, 0.3, 1.0}; + GLfloat spec[] = {0.9, 0.9, 0.9, 1.0}; + GLfloat nospec[] = {0.4, 0.4, 0.4, 1.0}; GLfloat shin = 30; glPushMatrix(); @@ -1342,87 +1338,81 @@ void DrawTransistor(Transistor *t) glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if (t->type == 1) { /* TO-92 style */ - float mult, y1, y2; - mult = 1.5*t->th/t->tw; - y1 = 0.2+mult/2; - y2 = 0.8-mult/2; glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col); glRotatef(90, 0, 1, 0); glRotatef(90, 0, 0, 1); - createCylinder(1.0, 0.4, 1, 1); - Rect(0, -0.2, 0.4, 1, 0.2, 0.8); + polys += createCylinder(ci, 1.0, 0.4, 1, 1); + polys += Rect(0, -0.2, 0.4, 1, 0.2, 0.8); /* Draw the markings */ - glEnable(GL_TEXTURE_2D); - if (t->tnum) glBindTexture(GL_TEXTURE_2D, t->tnum); - glEnable(GL_BLEND); - glDepthMask(GL_FALSE); - glBegin (GL_QUADS); - glNormal3f(0, 0, 1); - glTexCoord2f(0, 1); - glVertex3f(y1, -0.21, 0.3); - glTexCoord2f(1, 1); - glVertex3f(y1, -0.21, -0.3); - glTexCoord2f(1, 0); - glVertex3f(y2, -0.21, -0.3); - glTexCoord2f(0, 0); - glVertex3f(y2, -0.21, 0.3); - glEnd(); + + { + GLfloat texfg[] = {0.7, 0.7, 0.7, 1.0}; + GLfloat s = 0.015; + XCharStruct e; + int w; + texture_string_metrics (ci->font, t->text, &e, 0, 0); + w = e.width; + glPushMatrix(); + glRotatef (90, 1, 0, 0); + glTranslatef (0.5, -0.05, 0.21); + glScalef (s, s, s); + glTranslatef (-w/2, 0, 0); + glColor4fv (texfg); + print_texture_string (ci->font, t->text); + glPopMatrix(); + } + glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); glDepthMask(GL_TRUE); glTranslatef(-2, 0, -0.2); - wire(2); + polys += wire(ci, 2); glTranslatef(0, 0, 0.2); - wire(2); + polys += wire(ci, 2); glTranslatef(0, 0, 0.2); - wire(2); + polys += wire(ci, 2); } else if (t->type == 0) { /* TO-220 Style */ - float mult, y1, y2; - mult = 1.5*t->th/t->tw; - y1 = 0.75+mult/2; - y2 = 0.75-mult/2; - Rect(0, 0, 0, 1.5, 1.5, 0.5); - glEnable(GL_TEXTURE_2D); - if (t->tnum) glBindTexture(GL_TEXTURE_2D, t->tnum); - glEnable(GL_BLEND); - glDepthMask(GL_FALSE); - glBegin (GL_QUADS); - glNormal3f(0, 0, 1); - glTexCoord2f(0, 1); - glVertex3f(0, y1, 0.01); - glTexCoord2f(1, 1); - glVertex3f(1.5, y1, 0.01); - glTexCoord2f(1, 0); - glVertex3f(1.5, y2, 0.01); - glTexCoord2f(0, 0); - glVertex3f(0, y2, 0.01); - glEnd(); + polys += Rect(0, 0, 0, 1.5, 1.5, 0.5); + { + GLfloat texfg[] = {0.7, 0.7, 0.7, 1.0}; + GLfloat s = 0.015; + XCharStruct e; + int w; + texture_string_metrics (ci->font, t->text, &e, 0, 0); + w = e.width; + glPushMatrix(); + glTranslatef (0.75, 0.75, 0.01); + glScalef (s, s, s); + glTranslatef (-w/2, 0, 0); + glColor4fv (texfg); + print_texture_string (ci->font, t->text); + glPopMatrix(); + } glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); glDepthMask(GL_TRUE); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col); glMaterialfv(GL_FRONT, GL_SPECULAR, spec); glMaterialfv(GL_FRONT, GL_SHININESS, &shin); - Rect(0, 0, -0.5, 1.5, 1.5, 0.30); + polys += Rect(0, 0, -0.5, 1.5, 1.5, 0.30); if (!glIsEnabled(GL_NORMALIZE)) glEnable(GL_NORMALIZE); glTranslatef(0.75, 1.875, -0.55); - HoledRectangle(1.5, 0.75, 0.25, 0.2, 8); + polys += HoledRectangle(ci, 1.5, 0.75, 0.25, 0.2, 8); glMaterialfv(GL_FRONT, GL_SPECULAR, nospec); glTranslatef(-0.375, -1.875, 0); glRotatef(90, 0, 0, -1); - wire(2); + polys += wire(ci, 2); glTranslatef(0, 0.375, 0); - wire(2); + polys += wire(ci, 2); glTranslatef(0, 0.375, 0); - wire(2); + polys += wire(ci, 2); } else { /* SMC transistor */ /* Draw the body */ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col); glTranslatef(-0.5, -0.25, 0.1); - Rect(0, 0, 0, 1, 0.5, 0.2); + polys += Rect(0, 0, 0, 1, 0.5, 0.2); /* Draw the markings */ glEnable(GL_TEXTURE_2D); - if (t->tnum) glBindTexture(GL_TEXTURE_2D, t->tnum); glEnable(GL_BLEND); glDepthMask(GL_FALSE); glBegin (GL_QUADS); @@ -1435,6 +1425,7 @@ void DrawTransistor(Transistor *t) glVertex3f(0.8, 0.5, 0.01); glTexCoord2f(0, 0); glVertex3f(0.2, 0.5, 0.01); + polys++; glEnd(); glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); @@ -1443,18 +1434,20 @@ void DrawTransistor(Transistor *t) glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col); glMaterialfv(GL_FRONT, GL_SPECULAR, spec); glMaterialfv(GL_FRONT, GL_SHININESS, &shin); - Rect(0.25, -0.1, -0.05, 0.1, 0.1, 0.2); - Rect(0.75, -0.1, -0.05, 0.1, 0.1, 0.2); - Rect(0.5, 0.5, -0.05, 0.1, 0.1, 0.2); - Rect(0.25, -0.2, -0.2, 0.1, 0.15, 0.1); - Rect(0.75, -0.2, -0.2, 0.1, 0.15, 0.1); - Rect(0.5, 0.5, -0.2, 0.1, 0.15, 0.1); + polys += Rect(0.25, -0.1, -0.05, 0.1, 0.1, 0.2); + polys += Rect(0.75, -0.1, -0.05, 0.1, 0.1, 0.2); + polys += Rect(0.5, 0.5, -0.05, 0.1, 0.1, 0.2); + polys += Rect(0.25, -0.2, -0.2, 0.1, 0.15, 0.1); + polys += Rect(0.75, -0.2, -0.2, 0.1, 0.15, 0.1); + polys += Rect(0.5, 0.5, -0.2, 0.1, 0.15, 0.1); } glPopMatrix(); + return polys; } -Component * NewComponent(void) +static Component * NewComponent(ModeInfo *mi) { + Circuit *ci = &circuit[MI_SCREEN(mi)]; Component *c; float rnd; @@ -1462,32 +1455,32 @@ Component * NewComponent(void) c->angle = RAND_RANGE(0,360); rnd = f_rand(); if (rnd < 0.25) { /* come from the top */ - c->y = YMAX/2; - c->x = RAND_RANGE(0, XMAX) - XMAX/2; + c->y = ci->YMAX/2; + c->x = RAND_RANGE(0, ci->XMAX) - ci->XMAX/2; if (c->x > 0) c->dx = 0 - RAND_RANGE(0.5, 2); else c->dx = RAND_RANGE(0.5, 2); c->dy = 0 - RAND_RANGE(0.5, 2); } else if (rnd < 0.5) { /* come from the bottom */ - c->y = 0 - YMAX/2; - c->x = RAND_RANGE(0, XMAX) - XMAX/2; + c->y = 0 - ci->YMAX/2; + c->x = RAND_RANGE(0, ci->XMAX) - ci->XMAX/2; if (c->x > 0) c->dx = 0 - RAND_RANGE(0.5, 2); else c->dx = RAND_RANGE(0.5, 2); c->dy = RAND_RANGE(0.5, 2); } else if (rnd < 0.75) { /* come from the left */ - c->x = 0 - XMAX/2; - c->y = RAND_RANGE(0, YMAX) - YMAX/2; + c->x = 0 - ci->XMAX/2; + c->y = RAND_RANGE(0, ci->YMAX) - ci->YMAX/2; c->dx = RAND_RANGE(0.5, 2); if (c->y > 0) c->dy = 0 - RAND_RANGE(0.5, 2); else c->dy = RAND_RANGE(0.5, 2); } else { /* come from the right */ - c->x = XMAX/2; - c->y = RAND_RANGE(0, YMAX) - YMAX/2; + c->x = ci->XMAX/2; + c->y = RAND_RANGE(0, ci->YMAX) - ci->YMAX/2; c->dx = 0 - RAND_RANGE(0.5, 2); if (c->y > 0) c->dy = 0 - RAND_RANGE(0.5, 2); @@ -1498,7 +1491,7 @@ Component * NewComponent(void) c->rotx = f_rand(); c->roty = f_rand(); c->rotz = f_rand(); - c->drot = f_rand() * 7; + c->drot = f_rand() * 3; c->rdeg = 0; c->dz = f_rand()*2 - 1; c->norm = 0; @@ -1515,95 +1508,63 @@ Component * NewComponent(void) c->norm = 1; /* some diodes shine */ c->type = 1; } else if (rnd < 3) { - c->c = NewTransistor(); + c->c = NewTransistor(mi); c->norm = 1; c->type = 2; } else if (rnd < 4) { - c->c = NewCapacitor(); + c->c = NewCapacitor(ci); c->norm = 1; c->type = 4; } else if (rnd < 5) { - c->c = NewIC(); + c->c = NewIC(mi); c->type = 5; c->norm = 1; } else if (rnd < 6) { - c->c = NewLED(); + c->c = NewLED(ci); c->type = 3; c->norm = 1; c->alpha = 1; } else if (rnd < 7) { - c->c = NewFuse(); + c->c = NewFuse(ci); c->norm = 1; c->type = 7; c->alpha = 1; } else if (rnd < 8) { - c->c = NewRCA(); + c->c = NewRCA(ci); c->norm = 1; c->type = 8; } else if (rnd < 9) { - c->c = NewThreeFive(); + c->c = NewThreeFive(ci); c->norm = 1; c->type = 9; } else if (rnd < 10) { - c->c = NewSwitch(); + c->c = NewSwitch(ci); c->norm = 1; c->type = 10; } else { - c->c = NewDisp(); + c->c = NewDisp(ci); c->type = 6; } return c; } -Transistor *NewTransistor(void) +static Transistor *NewTransistor(ModeInfo *mi) { Transistor *t; - float texfg[] = {0.7, 0.7, 0.7, 1.0}; - float texbg[] = {0.3, 0.3, 0.3, 0.1}; - TexNum *tn; - const char *val; t = malloc(sizeof(Transistor)); t->type = (random() % 3); if (t->type == 0) { - val = transistortypes[random() % countof(transistortypes)]; - tn = fonttexturealloc(val, texfg, texbg); - if (tn == NULL) { - fprintf(stderr, "Error getting a texture for a string!\n"); - t->tnum = 0; - } else { - t->tnum = tn->num; - t->tw = tn->w; t->th = tn->h; - free(tn); - } + t->text = transistortypes[random() % countof(transistortypes)]; } else if (t->type == 2) { - val = smctypes[random() % countof(smctypes)]; - tn = fonttexturealloc(val, texfg, texbg); - if (tn == NULL) { - fprintf(stderr, "Error getting a texture for a string!\n"); - t->tnum = 0; - } else { - t->tnum = tn->num; - t->tw = tn->w; t->th = tn->h; - free(tn); - } + t->text = smctypes[random() % countof(smctypes)]; } else if (t->type == 1) { - val = to92types[random() % countof(to92types)]; - tn = fonttexturealloc(val, texfg, texbg); - if (tn == NULL) { - fprintf(stderr, "Error getting a texture for a string!\n"); - t->tnum = 0; - } else { - t->tnum = tn->num; - t->tw = tn->w; t->th = tn->h; - free(tn); - } + t->text = to92types[random() % countof(to92types)]; } - return t; } -Capacitor *NewCapacitor(void) +static Capacitor *NewCapacitor(Circuit *ci) { Capacitor *c; @@ -1620,7 +1581,7 @@ Capacitor *NewCapacitor(void) /* 7 segment display */ -Disp *NewDisp(void) +static Disp *NewDisp(Circuit *ci) { Disp *d; @@ -1633,15 +1594,11 @@ Disp *NewDisp(void) } -IC *NewIC(void) +static IC *NewIC(ModeInfo *mi) { IC *c; int pins; - TexNum *tn; - float texfg[] = {0.7, 0.7, 0.7, 1.0}; - float texbg[] = {0.1, 0.1, 0.1, 0}; const char *val; - char *str; int types[countof(ictypes)], i, n = 0; c = malloc(sizeof(IC)); @@ -1670,23 +1627,13 @@ IC *NewIC(void) if (n > countof(types)) abort(); val = ictypes[types[random() % n]].val; - str = malloc(strlen(val) + 1 + 4 + 1); /* add space for production date */ - sprintf(str, "%s\n%02d%02d", val, (int)RAND_RANGE(80, 100), (int)RAND_RANGE(1,53)); - tn = fonttexturealloc(str, texfg, texbg); - free(str); - if (tn == NULL) { - fprintf(stderr, "Error allocating font texture for '%s'\n", val); - c->tnum = 0; - } else { - c->tw = tn->w; c->th = tn->h; - c->tnum = tn->num; - free(tn); - } + sprintf(c->text, "%s\n%02d%02d", val, + (int)RAND_RANGE(80, 100), (int)RAND_RANGE(1,53)); c->pins = pins; return c; } -LED *NewLED(void) +static LED *NewLED(Circuit *ci) { LED *l; float r; @@ -1694,8 +1641,8 @@ LED *NewLED(void) l = malloc(sizeof(LED)); r = f_rand(); l->light = 0; - if (!light && (f_rand() < 0.4)) { - light = 1; + if (!ci->light && (f_rand() < 0.4)) { + ci->light = 1; l->light = 1; } if (r < 0.2) { @@ -1712,7 +1659,7 @@ LED *NewLED(void) return l; } -Fuse *NewFuse(void) +static Fuse *NewFuse(Circuit *ci) { Fuse *f; @@ -1720,7 +1667,7 @@ Fuse *NewFuse(void) return f; } -RCA *NewRCA(void) +static RCA *NewRCA(Circuit *ci) { RCA *r; @@ -1729,7 +1676,7 @@ RCA *NewRCA(void) return r; } -ThreeFive *NewThreeFive(void) +static ThreeFive *NewThreeFive(Circuit *ci) { ThreeFive *r; @@ -1737,7 +1684,7 @@ ThreeFive *NewThreeFive(void) return r; } -Switch *NewSwitch(void) +static Switch *NewSwitch(Circuit *ci) { Switch *s; @@ -1746,7 +1693,7 @@ Switch *NewSwitch(void) return s; } -Diode *NewDiode(void) +static Diode *NewDiode(void) { Band *b; Diode *ret; @@ -1771,7 +1718,7 @@ Diode *NewDiode(void) } -Resistor * NewResistor(void) +static Resistor * NewResistor(void) { int v, m, t; /* value, multiplier, tolerance */ Resistor *ret; @@ -1793,7 +1740,7 @@ Resistor * NewResistor(void) return ret; } -void makebandlist(void) +static void makebandlist(Circuit *ci) { int i; GLfloat col[] = {0,0,0,0}; @@ -1801,200 +1748,211 @@ void makebandlist(void) GLfloat shine = 40; for (i = 0 ; i < 12 ; i++) { - band_list[i] = glGenLists(i); - glNewList(band_list[i], GL_COMPILE); + ci->band_list[i] = glGenLists(1); + glNewList(ci->band_list[i], GL_COMPILE); col[0] = colorcodes[i][0]; col[1] = colorcodes[i][1]; col[2] = colorcodes[i][2]; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec); glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &shine); - createCylinder(0.1, 0.42, 0, 0); + ci->band_list_polys[i] = createCylinder(ci, 0.1, 0.42, 0, 0); glEndList(); } } -void bandedCylinder(float radius, float l, GLfloat r, GLfloat g, GLfloat bl, - Band **b, int nbands) +static int bandedCylinder(Circuit *ci, + float radius, float l, + GLfloat r, GLfloat g, GLfloat bl, + Band **b, int nbands) { + int polys = 0; int n; /* band number */ - int p = 0; /* prev number + 1; */ GLfloat col[] = {0,0,0,0}; col[0] = r; col[1] = g; col[2] = bl; glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col); - createCylinder(l, radius, 1, 0); /* body */ + polys += createCylinder(ci, l, radius, 1, 0); /* body */ for (n = 0 ; n < nbands ; n++) { glPushMatrix(); glTranslatef(b[n]->pos*l, 0, 0); col[0] = b[n]->r; col[1] = b[n]->g; col[2] = b[n]->b; glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col); - createCylinder(b[n]->len*l, radius*1.05, 0, 0); /* band */ + polys += createCylinder(ci, b[n]->len*l, radius*1.05, 0, 0); /* band */ glPopMatrix(); - p = n+1; } + return polys; } -void drawgrid(void) +static int drawgrid(Circuit *ci) { + int polys = 0; GLfloat x, y; - static GLfloat col[] = {0, 0.25, 0.05}; - static GLfloat col2[] = {0, 0.125, 0.05}; GLfloat col3[] = {0, 0.8, 0}; - static GLfloat sx, sy; /* bright spot co-ords */ - static int sdir; /* 0 = left-right, 1 = right-left, 2 = up->dn, 3 = dn->up */ - static int s = 0; /* if spot is enabled */ - static float ds; /* speed of spot */ - - if (!s) { - if (f_rand() < ((rotate) ? 0.05 : 0.01)) { - sdir = RAND_RANGE(0, 4); - ds = RAND_RANGE(0.4, 0.8); - switch (sdir) { + + if (!ci->draw_s) { + if (f_rand() < ((rotatespeed > 0) ? 0.05 : 0.01)) { + ci->draw_sdir = RAND_RANGE(0, 4); + ci->draw_ds = RAND_RANGE(0.4, 0.8); + switch (ci->draw_sdir) { case 0: - sx = -XMAX/2; - sy = ((int)RAND_RANGE(0, YMAX/2))*2 - YMAX/2; + ci->draw_sx = -ci->XMAX/2; + ci->draw_sy = ((int)RAND_RANGE(0, ci->YMAX/2))*2 - ci->YMAX/2; break; case 1: - sx = XMAX/2; - sy = ((int)RAND_RANGE(0, YMAX/2))*2 - YMAX/2; + ci->draw_sx = ci->XMAX/2; + ci->draw_sy = ((int)RAND_RANGE(0, ci->YMAX/2))*2 - ci->YMAX/2; break; case 2: - sy = YMAX/2; - sx = ((int)RAND_RANGE(0, XMAX/2))*2 - XMAX/2; + ci->draw_sy = ci->YMAX/2; + ci->draw_sx = ((int)RAND_RANGE(0, ci->XMAX/2))*2 - ci->XMAX/2; break; case 3: - sy = -YMAX/2; - sx = ((int)RAND_RANGE(0, XMAX/2))*2 - XMAX/2; + ci->draw_sy = -ci->YMAX/2; + ci->draw_sx = ((int)RAND_RANGE(0, ci->XMAX/2))*2 - ci->XMAX/2; break; } - s = 1; + ci->draw_s = 1; } - } else if (!rotate) { - if (col[1] < 0.25) { - col[1] += 0.025; col[2] += 0.005; - col2[1] += 0.015 ; col2[2] += 0.005; + } else if (rotatespeed <= 0) { + if (ci->grid_col[1] < 0.25) { + ci->grid_col[1] += 0.025; ci->grid_col[2] += 0.005; + ci->grid_col2[1] += 0.015 ; ci->grid_col2[2] += 0.005; } } glDisable(GL_LIGHTING); - if (s) { + if (ci->draw_s) { glColor3fv(col3); glPushMatrix(); - glTranslatef(sx, sy, -10); - sphere(0.1, 10, 10, 0, 10, 0, 10); - if (sdir == 0) - glTranslatef(-ds, 0, 0); - if (sdir == 1) - glTranslatef(ds, 0, 0); - if (sdir == 2) - glTranslatef(0, ds, 0); - if (sdir == 3) - glTranslatef(0, -ds, 0); - sphere(0.05, 10, 10, 0, 10, 0, 10); + glTranslatef(ci->draw_sx, ci->draw_sy, -10); + polys += sphere(ci, 0.1, 10, 10, 0, 10, 0, 10); + if (ci->draw_sdir == 0) + glTranslatef(-ci->draw_ds, 0, 0); + if (ci->draw_sdir == 1) + glTranslatef(ci->draw_ds, 0, 0); + if (ci->draw_sdir == 2) + glTranslatef(0, ci->draw_ds, 0); + if (ci->draw_sdir == 3) + glTranslatef(0, -ci->draw_ds, 0); + polys += sphere(ci, 0.05, 10, 10, 0, 10, 0, 10); glPopMatrix(); - if (sdir == 0) { - sx += ds; - if (sx > XMAX/2) - s = 0; + if (ci->draw_sdir == 0) { + ci->draw_sx += ci->draw_ds; + if (ci->draw_sx > ci->XMAX/2) + ci->draw_s = 0; } - if (sdir == 1) { - sx -= ds; - if (sx < -XMAX/2) - s = 0; + if (ci->draw_sdir == 1) { + ci->draw_sx -= ci->draw_ds; + if (ci->draw_sx < -ci->XMAX/2) + ci->draw_s = 0; } - if (sdir == 2) { - sy -= ds; - if (sy < YMAX/2) - s = 0; + if (ci->draw_sdir == 2) { + ci->draw_sy -= ci->draw_ds; + if (ci->draw_sy < ci->YMAX/2) + ci->draw_s = 0; } - if (sdir == 3) { - sy += ds; - if (sy > YMAX/2) - s = 0; + if (ci->draw_sdir == 3) { + ci->draw_sy += ci->draw_ds; + if (ci->draw_sy > ci->YMAX/2) + ci->draw_s = 0; } - } else if (!rotate) { - if (col[1] > 0) { - col[1] -= 0.0025; col[2] -= 0.0005; - col2[1] -= 0.0015 ; col2[2] -= 0.0005; + } else if (rotatespeed <= 0) { + if (ci->grid_col[1] > 0) { + ci->grid_col[1] -= 0.0025; ci->grid_col[2] -= 0.0005; + ci->grid_col2[1] -= 0.0015 ; ci->grid_col2[2] -= 0.0005; } } - for (x = -XMAX/2 ; x <= XMAX/2 ; x+= 2) { - glColor3fv(col); + for (x = -ci->XMAX/2 ; x <= ci->XMAX/2 ; x+= 2) { + glColor3fv(ci->grid_col); glBegin(GL_LINES); - glVertex3f(x, YMAX/2, -10); - glVertex3f(x, -YMAX/2, -10); - glColor3fv(col2); - glVertex3f(x-0.02, YMAX/2, -10); - glVertex3f(x-0.02, -YMAX/2, -10); - glVertex3f(x+0.02, YMAX/2, -10); - glVertex3f(x+0.02, -YMAX/2, -10); + glVertex3f(x, ci->YMAX/2, -10); + glVertex3f(x, -ci->YMAX/2, -10); + glColor3fv(ci->grid_col2); + glVertex3f(x-0.02, ci->YMAX/2, -10); + glVertex3f(x-0.02, -ci->YMAX/2, -10); + glVertex3f(x+0.02, ci->YMAX/2, -10); + glVertex3f(x+0.02, -ci->YMAX/2, -10); glEnd(); } - for (y = -YMAX/2 ; y <= YMAX/2 ; y+= 2) { - glColor3fv(col); + for (y = -ci->YMAX/2 ; y <= ci->YMAX/2 ; y+= 2) { + glColor3fv(ci->grid_col); glBegin(GL_LINES); - glVertex3f(-XMAX/2, y, -10); - glVertex3f(XMAX/2, y, -10); - glColor3fv(col2); - glVertex3f(-XMAX/2, y-0.02, -10); - glVertex3f(XMAX/2, y-0.02, -10); - glVertex3f(-XMAX/2, y+0.02, -10); - glVertex3f(XMAX/2, y+0.02, -10); + glVertex3f(-ci->XMAX/2, y, -10); + glVertex3f(ci->XMAX/2, y, -10); + glColor3fv(ci->grid_col2); + glVertex3f(-ci->XMAX/2, y-0.02, -10); + glVertex3f(ci->XMAX/2, y-0.02, -10); + glVertex3f(-ci->XMAX/2, y+0.02, -10); + glVertex3f(ci->XMAX/2, y+0.02, -10); glEnd(); } glEnable(GL_LIGHTING); + return polys; } -void display(void) +static void display(ModeInfo *mi) { - static Component *c[MAX_COMPONENTS]; - static int i = 0; + Circuit *ci = &circuit[MI_SCREEN(mi)]; GLfloat light_sp[] = {0.8, 0.8, 0.8, 1.0}; GLfloat black[] = {0, 0, 0, 1.0}; - static GLfloat rotate_angle = 0; /* when 'rotate' is enabled */ int j; - if (i == 0) { - for (i = 0 ; i < maxparts ; i++) { - c[i] = NULL; + mi->polygon_count = 0; + + if (ci->display_i == 0) { + for (ci->display_i = 0 ; ci->display_i < maxparts ; ci->display_i++) { + ci->components[ci->display_i] = NULL; } } glEnable(GL_LIGHTING); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glLoadIdentity(); - gluLookAt(viewer[0], viewer[1], viewer[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); + gluLookAt(ci->viewer[0], ci->viewer[1], ci->viewer[2], + 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0); glPushMatrix(); - if (rotate) { - glRotatef(rotate_angle, 0, 0, 1); - rotate_angle += 0.01 * (float)rotatespeed; - if (rotate_angle >= 360) rotate_angle = 0; - } - glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + glRotatef(ci->rotate_angle, 0, 0, 1); + ci->rotate_angle += 0.01 * (float)rotatespeed; + if (ci->rotate_angle >= 360) ci->rotate_angle = 0; + + glLightfv(GL_LIGHT0, GL_POSITION, ci->lightpos); glLightfv(GL_LIGHT0, GL_SPECULAR, light_sp); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_sp); glLighti(GL_LIGHT0, GL_CONSTANT_ATTENUATION, (GLfloat)1); glLighti(GL_LIGHT0, GL_LINEAR_ATTENUATION, (GLfloat)0.5); glLighti(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, (GLfloat)0); - drawgrid(); + +# 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 (h, h, h); + h = 2; + glScalef (h, h, h); + } +# endif + + mi->polygon_count += drawgrid(ci); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, light_sp); if (f_rand() < 0.05) { for (j = 0 ; j < maxparts ; j++) { - if (c[j] == NULL) { - c[j] = NewComponent(); + if (ci->components[j] == NULL) { + ci->components[j] = NewComponent(mi); j = maxparts; } } - reorder(&c[0]); + reorder(&ci->components[0]); } for (j = 0 ; j < maxparts ; j++) { glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, black); glMaterialfv(GL_FRONT, GL_EMISSION, black); glMaterialfv(GL_FRONT, GL_SPECULAR, black); - if (c[j] != NULL) { - if (DrawComponent(c[j])) { - free(c[j]); c[j] = NULL; + if (ci->components[j] != NULL) { + if (DrawComponent(ci, ci->components[j], &mi->polygon_count)) { + free(ci->components[j]); ci->components[j] = NULL; } } } @@ -2002,93 +1960,8 @@ void display(void) glFlush(); } -void freetexture (GLuint texture) { - s_refs[texture]--; - if (s_refs[texture] < 1) { - glDeleteTextures(1, &texture); - } -} - -TexNum * fonttexturealloc (const char *str, float *fg, float *bg) -{ - static char *strings[50]; /* max of 40 textures */ - static int w[50], h[50]; - int i, status; - static int init; - XImage *ximage; - char *c; - TexNum *t; - - if (init == 0) { - for (i = 0 ; i < 50 ; i++) { - strings[i] = NULL; - s_refs[i] = 0; - w[i] = 0; h[i] = 0; - } - init++; - } - for (i = 0 ; i < 50 ; i++) { - if (!s_refs[i] && strings[i]) { - free (strings[i]); - strings[i] = NULL; - } - if (strings[i] && !strcmp(str, strings[i])) { /* if one matches */ - t = malloc(sizeof(TexNum)); - t->w = w[i]; t->h = h[i]; - t->num = i; - s_refs[i]++; - return t; - } - } - /* at this point we need to make the new texture */ - ximage = text_to_ximage (modeinfo->xgwa.screen, - modeinfo->xgwa.visual, - font, str, - fg, bg); - for (i = 0 ; strings[i] != NULL ; i++) { /* set i to the next unused value */ - if (i > 49) { - fprintf(stderr, "Texture cache full!\n"); - free(ximage->data); - ximage->data = 0; - XFree (ximage); - return NULL; - } - } - glBindTexture(GL_TEXTURE_2D, i); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - clear_gl_error(); - status = gluBuild2DMipmaps(GL_TEXTURE_2D, 4, ximage->width, ximage->height, - GL_RGBA, GL_UNSIGNED_BYTE, ximage->data); - if (status) - { - const char *s = (char *) gluErrorString (status); - fprintf (stderr, "%s: error mipmapping %dx%d texture: %s\n", - progname, ximage->width, ximage->height, - (s ? s : "(unknown)")); - exit (1); - } - check_gl_error("mipmapping"); - - t = malloc(sizeof(TexNum)); - t->w = ximage->width; - t->h = ximage->height; - w[i] = t->w; h[i] = t->h; - free(ximage->data); - ximage->data = 0; - XFree (ximage); - c = malloc(strlen(str)+1); - strncpy(c, str, strlen(str)+1); - strings[i] = c; - s_refs[i]++; - t->num = i; - return t; -} - /* ensure transparent components are at the end */ -void reorder(Component *c[]) +static void reorder(Component *c[]) { int i, j, k; Component *c1[MAX_COMPONENTS]; @@ -2124,78 +1997,93 @@ void reorder(Component *c[]) } } -void reshape_circuit(ModeInfo *mi, int width, int height) +ENTRYPOINT void reshape_circuit(ModeInfo *mi, int width, int height) { + Circuit *ci = &circuit[MI_SCREEN(mi)]; GLfloat h = (GLfloat) height / (GLfloat) width; glViewport(0,0,(GLint)width, (GLint) height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-1.0,1.0,-h,h,1.5,35.0); glMatrixMode(GL_MODELVIEW); - win_h = height; win_w = width; - YMAX = XMAX * h; + ci->win_h = height; + ci->win_w = width; + ci->YMAX = ci->XMAX * h; } -void init_circuit(ModeInfo *mi) +static void free_circuit(ModeInfo *mi); + +ENTRYPOINT void init_circuit(ModeInfo *mi) { int screen = MI_SCREEN(mi); -Circuit *c; +Circuit *ci; - if (circuit == NULL) { - if ((circuit = (Circuit *) calloc(MI_NUM_SCREENS(mi), - sizeof(Circuit))) == NULL) - return; - } - c = &circuit[screen]; - c->window = MI_WINDOW(mi); + MI_INIT(mi, circuit, free_circuit); + ci = &circuit[screen]; + ci->window = MI_WINDOW(mi); + + ci->XMAX = ci->YMAX = 50; + ci->viewer[2] = 14; + ci->lightpos[0] = 7; + ci->lightpos[1] = 7; + ci->lightpos[2] = 15; + ci->lightpos[3] = 1; + ci->grid_col[1] = 0.25; + ci->grid_col[2] = 0.05; + ci->grid_col2[1] = 0.125; + ci->grid_col2[2] = 0.05; - if ((c->glx_context = init_GL(mi)) != NULL) { + ci->font = load_texture_font (MI_DISPLAY(mi), "componentFont"); + + if (maxparts >= MAX_COMPONENTS) + maxparts = MAX_COMPONENTS-1; + + if ((ci->glx_context = init_GL(mi)) != NULL) { reshape_circuit(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); } else { MI_CLEARWINDOW(mi); } if (uselight == 0) - light = 1; - glClearColor(0.0,0.0,0.0,0.0); + ci->light = 1; glShadeModel(GL_SMOOTH); glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - make_tables(); - makebandlist(); + make_tables(ci); + makebandlist(ci); } -void draw_circuit(ModeInfo *mi) +ENTRYPOINT void draw_circuit(ModeInfo *mi) { - Circuit *c = &circuit[MI_SCREEN(mi)]; + Circuit *ci = &circuit[MI_SCREEN(mi)]; Window w = MI_WINDOW(mi); Display *disp = MI_DISPLAY(mi); - if (!c->glx_context) + if (!ci->glx_context) return; - modeinfo = mi; - glXMakeCurrent(disp, w, *(c->glx_context)); + glXMakeCurrent(disp, w, *(ci->glx_context)); - display(); + display(mi); if(mi->fps_p) do_fps(mi); glFinish(); glXSwapBuffers(disp, w); } -void release_circuit(ModeInfo *mi) +static void free_circuit(ModeInfo *mi) { - if (circuit != NULL) { - (void) free((void *) circuit); - circuit = NULL; - } - FreeAllGL(MI); + Circuit *ci = &circuit[MI_SCREEN(mi)]; + if (ci->font) + free_texture_font (ci->font); + FreeAllGL(mi); } +XSCREENSAVER_MODULE ("Circuit", circuit) + #endif