summaryrefslogtreecommitdiffstats
path: root/hacks/glx/circuit.c
diff options
context:
space:
mode:
Diffstat (limited to 'hacks/glx/circuit.c')
-rw-r--r--hacks/glx/circuit.c2105
1 files changed, 0 insertions, 2105 deletions
diff --git a/hacks/glx/circuit.c b/hacks/glx/circuit.c
deleted file mode 100644
index 00e88c8..0000000
--- a/hacks/glx/circuit.c
+++ /dev/null
@@ -1,2105 +0,0 @@
-/*
- * circuit - Random electronic components floating around
- *
- * version 1.4
- *
- * Since version 1.1: added to-220 transistor, added fuse
- * Since version 1.2: random display digits, LED improvements (flickering)
- * Since version 1.3: ICs look better, font textures, improved normals to
- * eliminate segmenting on curved surfaces, speedups
- * Since version 1.4: Added RCA connector, 3.5mm connector, slide switch,
- * surface mount, to-92 markings. Fixed ~5min crash.
- * Better LED illumination. Other minor changes.
- *
- * 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
- * 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.
- */
-
-/* Written over a few days in a (successful) bid to learn GL coding
- *
- * -seven option is dedicated to all the Slarkeners
- *
- * This hack uses lookup tables for sin, cos and tan - it can do a lot
- */
-
-#ifdef STANDALONE
-#define DEFAULTS "*delay: 20000 \n" \
- "*showFPS: False \n" \
- "*suppressRotationAnimation: True\n" \
- "*componentFont: monospace bold 12" \
-
-# define release_circuit 0
-# define circuit_handle_event xlockmore_no_events
-# 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)
-
-
-#ifdef USE_GL
-
-#include "texfont.h"
-
-static int maxparts;
-static int rotatespeed;
-static int spin;
-static int uselight;
-static int seven;
-
-static XrmOptionDescRec opts[] = {
- {"-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},
- {&rotatespeed, "rotatespeed", "Rotatespeed", DEF_ROTATESPEED, t_Int},
- {&spin, "spin", "Spin", DEF_SPIN, t_Bool},
- {&uselight, "light", "Light", DEF_LIGHT, t_Bool},
- {&seven, "seven", "Seven", DEF_SEVEN, t_Bool},
-};
-
-ENTRYPOINT ModeSpecOpt circuit_opts = {countof(opts), opts, countof(vars), vars, NULL};
-
-#ifdef USE_MODULES
-ModStruct circuit_description =
-{"circuit", "init_circuit", "draw_circuit", NULL,
- "draw_circuit", "init_circuit", "free_circuit", &circuit_opts,
- 1000, 1, 2, 1, 4, 1.0, "",
- "Flying electronic components", 0, NULL};
-
-#endif
-
-#define MAX_COMPONENTS 400
-#define MOVE_MULT 0.02
-
-static float f_rand(void)
-{
- return ((float)RAND(10000)/(float)10000);
-}
-
-#define RAND_RANGE(min, max) ((min) + (max - min) * f_rand())
-
-/* Represents a band on a resistor/diode/etc */
-typedef struct {
- float pos; /* relative position from start/previous band */
- GLfloat r, g, b; /* colour of the band */
- float len; /* length as a fraction of total length */
-} Band;
-
-typedef struct {
- Band *b1, *b2, *b3, *b4; /* bands */
- int b[4];
-} Resistor;
-
-typedef struct {
- Band *band;
- GLfloat r, g, b; /* body colour */
-} Diode;
-
-static const char * const transistortypes[] = {
- "TIP2955",
- "TIP32C",
- "LM 350T",
- "IRF730",
- "ULN2577",
- "7805T",
- "7912T",
- "TIP120",
- "2N6401",
- "BD239",
- "2SC1590",
- "MRF485",
- "SC141D"
-};
-
-static const char * const to92types[] = {
- "C\n548",
- "C\n848",
- "74\nL05",
- "C\n858",
- "BC\n212L",
- "BC\n640",
- "BC\n337",
- "BC\n338",
- "S817",
- "78\nL12",
- "TL\n431",
- "LM\n35DZ",
-};
-
-static const char * const smctypes[] = {
- "1M-",
- "1K",
- "1F",
- "B10",
- "S14",
- "Q3",
- "4A"
-};
-
-typedef struct {
- int type; /* package type. 0 = to-92, 1 = to-220 */
- const char *text;
-} Transistor;
-
-typedef struct {
- GLfloat r,g,b; /* LED colour */
- int light; /* are we the light source? */
-} LED;
-
-typedef struct {
- int type; /* 0 = electro, 1 = ceramic */
- float width; /* width of an electro/ceramic */
- float length; /* length of an electro */
-} Capacitor;
-
-/* 3.5 mm plug */
-typedef struct {
- int blah;
-} ThreeFive;
-
-/* slide switch */
-typedef struct {
- int position;
-} Switch;
-
-typedef struct {
- int pins;
- const char *val;
-} ICTypes;
-
-static const ICTypes ictypes[] = {
- {8, "NE 555"},
- {8, "LM 386N"},
- {8, "ADC0831"},
- {8, "LM 383T"},
- {8, "TL071"},
- {8, "LM 311"},
- {8, "LM393"},
- {8, "LM 3909"},
-
- {14, "LM 380N"},
- {14, "NE 556"},
- {14, "TL074"},
- {14, "LM324"},
- {14, "LM339"},
- {14, "MC1488"},
- {14, "MC1489"},
- {14, "LM1877-9"},
- {14, "4011"},
- {14, "4017"},
- {14, "4013"},
- {14, "4024"},
- {14, "4066"},
-
- {16, "4076"},
- {16, "4049"},
- {16, "4094"},
- {16, "4043"},
- {16, "4510"},
- {16, "4511"},
- {16, "4035"},
- {16, "RS232"},
- {16, "MC1800"},
- {16, "ULN2081"},
- {16, "UDN2953"},
-
- {24, "ISD1416P"},
- {24, "4515"},
- {24, "TMS6264L"},
- {24, "MC146818"}
-};
-
-typedef struct {
- int type; /* 0 = DIL, 1 = flat square */
- int pins;
- char text[100];
-} IC;
-
-/* 7 segment display */
-
-typedef struct {
- int value; /* displayed number */
-} Disp;
-
-typedef struct {
- GLfloat l, w;
-} Fuse;
-
-typedef struct {
- GLfloat l, w;
- int col;
-} RCA;
-
-typedef struct {
- GLfloat x, y, z; /* current co-ordinates */
- GLfloat dx, dy, dz; /* current direction */
- GLfloat rotx, roty, rotz; /* rotation vector */
- GLfloat drot; /* rotation velocity (degrees per frame) */
- int norm; /* Normalize this component (for shine) */
- int rdeg; /* current rotation degrees */
- int angle; /* angle about the z axis */
- int alpha; /* 0 if not a transparent component */
- int type; /* 0 = resistor, 1 = diode, 2 = transistor, 3 = LED, 4 = cap, 5=IC,
- 6 = 7 seg disp */
- void * c; /* pointer to the component */
-} Component;
-
-/* standard colour codes */
-
-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 */
- {1.0,0.5,0.0}, /* orange 3 */
- {1.0,1.0,0.0}, /* yellow 4 */
- {0.0,1.0,0.0}, /* green 5 */
- {0.0,0.5,1.0}, /* blue 6 */
- {0.7,0.2,1.0}, /* violet 7 */
- {0.5,0.5,0.5}, /* grey 8 */
- {1.0,1.0,1.0}, /* white 9 */
- {0.66,0.56,0.2}, /* gold 10 */
- {0.8,0.8,0.8}, /* silver 11 */
-};
-
-/* base values for components - we can multiply by 0 - 1M */
-static const int values [9][2] = {
- {1,0},
- {2,2},
- {3,3},
- {4,7},
- {5,6},
- {6,8},
- {7,5},
- {8,2},
- {9,1}
-};
-
-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..
-*/
-
-static void make_tables(Circuit *ci)
-{
-int i;
-float f;
-
- f = 360 / (M_PI * 2);
- for (i = 0 ; i < 720 ; i++) {
- ci->sin_table[i] = sin(i/f);
- }
- for (i = 0 ; i < 720 ; i++) {
- ci->cos_table[i] = cos(i/f);
- }
- for (i = 0 ; i < 720 ; i++) {
- ci->tan_table[i] = tan(i/f);
- }
-}
-
-
-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 nsegs;
-
- glPushMatrix();
- 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;
- z1 = radius; y1 = 0;
- glBegin(GL_QUADS);
- for (a = 0 ; a <= angle ; a+= angle/nsegs) {
- 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;
- }
- glEnd();
- if (half) {
- glBegin(GL_POLYGON);
- glNormal3f(0, 1, 0);
- glVertex3f(0, 0, radius);
- glVertex3f(length, 0, radius);
- glVertex3f(length, 0, 0 - radius);
- glVertex3f(0, 0, 0 - radius);
- polys++;
- glEnd();
- }
- if (endcaps) {
- for(ex = 0 ; ex <= length ; ex += length) {
- z1 = radius; y1 = 0;
- norm = (ex == length) ? 1 : -1;
- glBegin(GL_TRIANGLES);
- glNormal3f(norm, 0, 0);
- for (a = 0 ; a <= angle ; a+= angle/nsegs) {
- 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;
- }
- glEnd();
- }
- }
- glPopMatrix();
- return polys;
-}
-
-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;
-
- if (half) {
- t = 270; s = 90;
- x1 = radius, y1 = 0;
- } else {
- t = 360, s = 0;
- }
- glBegin(GL_TRIANGLES);
- glNormal3f(1, 0, 0);
- for(i=s;i<=t;i+=10)
- {
- float angle=i;
- 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;
-}
-
-static int wire(Circuit *ci, float len)
-{
- 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;
-
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
- glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
- glMaterialfv(GL_FRONT, GL_SHININESS, &shin);
- n = glIsEnabled(GL_NORMALIZE);
- if (!n) glEnable(GL_NORMALIZE);
- polys += createCylinder(ci, len, 0.05, 1, 0);
- if (!n) glDisable(GL_NORMALIZE);
- glMaterialfv(GL_FRONT, GL_SPECULAR, nospec);
- return polys;
-}
-
-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, c0, c1;
- GLfloat step, sstep;
-
- step = 180/stacks;
- sstep = 360/slices;
- a1 = startstack * step;
- b1 = startslice * sstep;
- y1 = z1 = Y1 = Z1 = 0;
- c0 = (endslice / slices) * 360;
- c1 = (endstack/stacks)*180;
- glBegin(GL_QUADS);
- for (a = startstack * step ; a <= c1 ; a+= step) {
- 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 <= 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);
- glVertex3f(Dr,y2,z2);
- glNormal3f(Dr1, Y2, Z2);
- glVertex3f(Dr1,Y2,Z2);
- glNormal3f(Dr1, Y1, Z1);
- glVertex3f(Dr1,Y1,Z1);
- polys++;
- z1=z2;
- y1=y2;
- Z1=Z2;
- Y1=Y2;
- }
- a1 = a;
- }
- glEnd();
- return polys;
-}
-
-static int DrawComponent(Circuit *ci, Component *c, unsigned long *polysP)
-{
- int polys = *polysP;
- int ret = 0; /* return 1 if component is freed */
-
- glPushMatrix();
- glTranslatef(c->x, c->y, c->z);
- if (c->angle > 0) {
- glRotatef(c->angle, c->rotx, c->roty, c->rotz);
- }
- if (spin) {
- glRotatef(c->rdeg, c->rotx, c->roty, c->rotz);
- c->rdeg += c->drot;
- }
-
- if (c->norm)
- glEnable(GL_NORMALIZE);
- else
- glDisable(GL_NORMALIZE);
-
- /* call object draw routine here */
- if (c->type == 0) {
- polys += DrawResistor(ci, c->c);
- } else if (c->type == 1) {
- polys += DrawDiode(ci, c->c);
- } else if (c->type == 2) {
- polys += DrawTransistor(ci, c->c);
- } else if (c->type == 3) {
- if (((LED *)c->c)->light && ci->light) {
- GLfloat lp[] = {0.1, 0, 0, 1};
- glEnable(GL_LIGHT1);
- glLightfv(GL_LIGHT1, GL_POSITION, lp);
- }
- polys += DrawLED(ci, c->c);
- } else if (c->type == 4) {
- polys += DrawCapacitor(ci, c->c);
- } else if (c->type == 5) {
- polys += DrawIC(ci, c->c);
- } else if (c->type == 6) {
- polys += DrawDisp(ci, c->c);
- } else if (c->type == 7) {
- polys += DrawFuse(ci, c->c);
- } else if (c->type == 8) {
- polys += DrawRCA(ci, c->c);
- } else if (c->type == 9) {
- polys += DrawThreeFive(ci, c->c);
- } else if (c->type == 10) {
- polys += DrawSwitch(ci, c->c);
- }
- c->x += c->dx * MOVE_MULT;
- c->y += c->dy * MOVE_MULT;
- 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);
- ci->light = 0; ci->lighton = 0;
- }
- if (c->type == 1)
- free(((Diode *)c->c)->band); /* remember to free diode band */
- free(c->c);
- ret = 1;
- }
-
- glPopMatrix();
- glDisable(GL_NORMALIZE);
- *polysP = polys;
- return ret;
-}
-
-/* draw a resistor */
-
-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);
- 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);
- polys += createCylinder(ci, 1.8, 0.4, 1, 0);
- glPushMatrix();
- for (i = 0 ; i < 4 ; i++) {
- glTranslatef(0.35, 0, 0);
- glCallList(ci->band_list[r->b[i]]);
- polys += ci->band_list_polys[r->b[i]];
- }
- glPopMatrix();
- glTranslatef(1.8, 0, 0);
- polys += wire(ci, 3);
- return polys;
-}
-
-static int DrawRCA(Circuit *ci, RCA *rca)
-{
- 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);
- polys += createCylinder(ci, 0.7, 0.45, 0, 0);
- glTranslatef(0.4, 0, 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);
- polys += createCylinder(ci, 1.5, 0.6, 1, 0);
- glTranslatef(-0.9, 0, 0);
- polys += createCylinder(ci, 0.9, 0.25, 0, 0);
- glTranslatef(0.1, 0, 0);
- polys += createCylinder(ci, 0.2, 0.3, 0, 0);
- glTranslatef(0.3, 0, 0);
- polys += createCylinder(ci, 0.2, 0.3, 1, 0);
- glTranslatef(0.3, 0, 0);
- polys += createCylinder(ci, 0.2, 0.3, 1, 0);
- glPopMatrix();
- return polys;
-}
-
-static int DrawSwitch(Circuit *ci, Switch *f)
-{
- 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);
- 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);
- polys += HoledRectangle(ci, 0.5, 0.75, 0.1, 0.15, 8);
- glTranslatef(2, 0, 0);
- polys += HoledRectangle(ci, 0.5, 0.75, 0.1, 0.15, 8);
- glPopMatrix();
- 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);
- 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);
- polys += Rect(-0.2, -0.01, -0.1, 1.4, 0.1, 0.55);
- glPopMatrix();
- return polys;
-}
-
-
-static int DrawFuse(Circuit *ci, Fuse *f)
-{
- 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);
- 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);
- 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);
- glMateriali(GL_FRONT, GL_SHININESS, 40);
- glBegin(GL_LINES);
- glVertex3f(0, 0, 0);
- glVertex3f(2, 0. ,0);
- glEnd();
- glTranslatef(2, 0, 0);
- polys += createCylinder(ci, 0.8, 0.45, 1, 0);
- glPopMatrix();
- return polys;
-}
-
-
-static int DrawCapacitor(Circuit *ci, Capacitor *c)
-{
- 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};
- GLfloat shine = 40;
-
- glPushMatrix();
- if (c->type) {
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, brown);
- polys += sphere(ci, c->width, 15, 15, 0, 4 ,0, 15);
- glTranslatef(1.35*c->width, 0, 0);
- 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);
- polys += wire(ci, 3*c->width);
- glTranslatef(0, 0, -0.6*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);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &shine);
- glBegin(GL_POLYGON);
- glVertex3f(0, 0.82*c->width, -0.1);
- glVertex3f(3*c->length, 0.82*c->width, -0.1);
- glVertex3f(3*c->length, 0.82*c->width, 0.1);
- glVertex3f(0, 0.82*c->width, 0.1);
- glEnd();
- col[0] = 0.0;
- col[1] = 0.2;
- col[2] = 0.9;
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col);
- glEnable(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(1.0, 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);
- 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);
- polys += circle(ci, 0.6*c->width, 30, 0);
- glTranslatef(0, 0.4*c->width, 0);
- polys += wire(ci, 3*c->length);
- glTranslatef(0.0, -0.8*c->width, 0);
- polys += wire(ci, 3.3*c->length);
- }
- glPopMatrix();
- return polys;
-}
-
-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 && ci->light) {
- GLfloat dir[] = {-1, 0, 0};
- glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, dir);
- 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;
- glLightfv(GL_LIGHT1, GL_DIFFUSE, col);
- glLighti(GL_LIGHT1, GL_SPOT_CUTOFF, (GLint) 90);
- glLighti(GL_LIGHT1, GL_CONSTANT_ATTENUATION, (GLfloat)1);
- glLighti(GL_LIGHT1, GL_LINEAR_ATTENUATION, (GLfloat)0);
- glLighti(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, (GLfloat)0);
- glLighti(GL_LIGHT1, GL_SPOT_EXPONENT, (GLint) 20);
- ci->lighton = 1;
- }
- }
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col);
- /* no transparency when LED is lit */
- if (!l->light) {
- glEnable(GL_BLEND);
- glDepthMask(GL_FALSE);
- glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
- }
- glTranslatef(-0.9, 0, 0);
- polys += createCylinder(ci, 1.2, 0.3, 0, 0);
- if (l->light && ci->light) {
- glDisable(GL_LIGHTING);
- glColor3fv(col);
- }
- polys += sphere(ci, 0.3, 7, 7, 3, 7, 0, 7);
- if (l->light && ci->light) {
- glEnable(GL_LIGHTING);
- } else {
- glDepthMask(GL_TRUE);
- glDisable(GL_BLEND);
- }
-
- glTranslatef(1.2, 0, 0);
- polys += createCylinder(ci, 0.1, 0.38, 1, 0);
- glTranslatef(-0.3, 0.15, 0);
- polys += wire(ci, 3);
- glTranslatef(0, -0.3, 0);
- polys += wire(ci, 3.3);
- if (random() % 50 == 25) {
- if (l->light) {
- l->light = 0; ci->light = 0; ci->lighton = 0;
- glDisable(GL_LIGHT1);
- } else if (!ci->light) {
- l->light = 1;
- ci->light = 1;
- }
- }
- return polys;
-}
-
-
-static int DrawThreeFive(Circuit *ci, ThreeFive *d)
-{
- int polys = 0;
- GLfloat shine = 40;
- 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);
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cream);
- glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
-
- glTranslatef(-2.0, 0, 0);
- polys += createCylinder(ci, 0.7, 0.2, 0, 0);
- glTranslatef(0.7, 0, 0);
- polys += createCylinder(ci, 1.3, 0.4, 1, 0);
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, light);
- glTranslatef(1.3, 0, 0);
- polys += createCylinder(ci, 1.3, 0.2, 0, 0);
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, dark);
- glTranslatef(0.65, 0, 0);
- polys += createCylinder(ci, 0.15, 0.21, 0, 0);
- glTranslatef(0.3, 0, 0);
- polys += createCylinder(ci, 0.15, 0.21, 0, 0);
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, light);
- glTranslatef(0.4, 0, 0);
- polys += sphere(ci, 0.23, 7, 7, 0, 5, 0, 7);
-
- glPopMatrix();
- return polys;
-}
-
-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};
-
- glPushMatrix();
- glMaterialfv(GL_FRONT, GL_SHININESS, &shine);
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
- glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
- glTranslatef(-4, 0, 0);
- polys += wire(ci, 3);
- glTranslatef(3, 0, 0);
- polys += bandedCylinder(ci, 0.3, 1.5, d->r, d->g, d->b, &(d->band), 1);
- glTranslatef(1.5, 0, 0);
- polys += wire(ci, 3);
- glPopMatrix();
- return polys;
-}
-
-static int Rect(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h,
- GLfloat t)
-{
- int polys = 0;
- GLfloat yh;
- GLfloat xw;
- GLfloat zt;
-
- yh = y+h; xw = x+w; zt = z - t;
-
- glBegin(GL_QUADS); /* front */
- glNormal3f(0, 0, 1);
- glVertex3f(x, y, z);
- 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 */
-
-static int ICLeg(GLfloat x, GLfloat y, GLfloat z, int dir)
-{
- int polys = 0;
- if (dir) {
- 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 {
- 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;
-}
-
-
-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};
- GLfloat col2[] = {0.2, 0.2, 0.2, 0};
- GLfloat spec[] = {0.6, 0.6, 0.6, 0};
- GLfloat shine = 40;
- GLfloat lspec[] = {0.6, 0.6, 0.6, 0};
- GLfloat lcol[] = {0.4, 0.4, 0.4, 0};
- GLfloat lshine = 40;
-
- glPushMatrix();
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
- glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glMaterialfv(GL_FRONT, GL_SHININESS, &shine);
- switch(c->pins) {
- case 8:
- w = 1.0; h = 1.5;
- break;
- case 14:
- w = 1.0; h = 3;
- break;
- case 16:
- w = 1.0; h = 3;
- break;
- case 24:
- default:
- w = 1.5; h = 3.5;
- break;
- }
- w = w/2; h = h/2;
- glEnable(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(1.0, 1.0);
- glBegin(GL_QUADS);
- 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(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);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
-
- {
- 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);
- glEnable(GL_LIGHTING);
- glPopMatrix();
- }
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
- d = (h*2-0.1) / c->pins;
- d*=2;
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, lcol);
- glMaterialfv(GL_FRONT, GL_SPECULAR, lspec);
- glMaterialfv(GL_FRONT, GL_SHININESS, &lshine);
- for (z = 0 ; z < c->pins/2 ; z++) {
- polys += ICLeg(w, -h + z*d + d/2, 0, 0);
- }
- for (z = 0 ; z < c->pins/2 ; z++) {
- 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);
- polys += circle(ci, 0.1, 7, 0);
- glPopMatrix();
- return polys;
-}
-
-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 */
- GLfloat off[] = {0.3, 0, 0, 1}; /* 'off' segment */
- int i, j, k;
- GLfloat x, y; /* for the pins */
- GLfloat spec[] = {0.6, 0.6, 0.6, 0};
- GLfloat lcol[] = {0.4, 0.4, 0.4, 0};
- GLfloat shine = 40;
- static const GLfloat vdata_h[6][2] = {
- {0, 0},
- {0.1, 0.1},
- {0.9, 0.1},
- {1, 0},
- {0.9, -0.1},
- {0.1, -0.1}
- };
- static const GLfloat vdata_v[6][2] = {
- {0.27, 0},
- {0.35, -0.1},
- {0.2, -0.9},
- {0.1, -1},
- {0, -0.9},
- {0.15, -0.15}
- };
-
- static const GLfloat seg_start[7][2] = {
- {0.55, 2.26},
- {1.35, 2.26},
- {1.2, 1.27},
- {0.25, 0.25},
- {0.06, 1.25},
- {0.25, 2.25},
- {0.39, 1.24}
- };
-
- 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 */
- {1, 1, 1, 1, 0, 0, 1}, /* 3 */
- {0, 1, 1, 0, 0, 1, 1}, /* 4 */
- {1, 0, 1, 1, 0, 1, 1}, /* 5 */
- {1, 0, 1, 1, 1, 1, 1}, /* 6 */
- {1, 1, 1, 0, 0, 0, 0}, /* 7 */
- {1, 1, 1, 1, 1, 1, 1}, /* 8 */
- {1, 1, 1, 0, 0, 1, 1} /* 9 */
- };
-
- glTranslatef(-0.9, -1.8, 0);
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
- 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 */
- d->value = random() % 10;
- }
- for (j = 0 ; j < 7 ; j++) { /* draw the segments */
- GLfloat xx[6], yy[6];
- if (nums[d->value][j])
- glColor3fv(on);
- else
- glColor3fv(off);
- for (k = 0 ; k < 6 ; k++) {
- if (j == 0 || j == 3 || j == 6) {
- xx[k] = seg_start[j][0] + vdata_h[k][0];
- yy[k] = seg_start[j][1] + vdata_h[k][1];
- } else {
- xx[k] = seg_start[j][0] + vdata_v[k][0];
- yy[k] = seg_start[j][1] + vdata_v[k][1];
- }
- }
- glBegin(GL_POLYGON);
- 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);
- glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
- 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) {
- polys += ICLeg(x, y, -0.7, 1);
- }
- }
- return polys;
-}
-
-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;
- GLfloat nx, ny;
-
- step = 360 / p;
- x1 = radius; y1 = 0;
- xr1 = w/2; yr1 = 0;
- side = w/2;
- side1 = h/2;
- glBegin(GL_QUADS);
- for (a = 0 ; a <= 360 ; a+= step) {
- 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 * ci->tan_table[a];
- nx = 1; ny = 0;
- } else if (a <= 135 || a >= 225) {
- xr = side/ci->tan_table[a];
- if (a >= 225) {
- yr = -side1;
- xr = 0 - xr;
- nx = 0; ny = -1;
- } else {
- yr = side1;
- nx = 0; ny = 1;
- }
- } else {
- xr = -side;
- yr = -side1 * ci->tan_table[a];
- nx = -1; ny = 0;
- }
-
- glNormal3f(-x1, -y1, 0); /* cylinder */
- glVertex3f(x1,y1,0);
- 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;
-}
-
-static int DrawTransistor(Circuit *ci, Transistor *t)
-{
- 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();
- glMaterialfv(GL_FRONT, GL_SHININESS, &shin);
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- if (t->type == 1) { /* TO-92 style */
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col);
- glRotatef(90, 0, 1, 0);
- glRotatef(90, 0, 0, 1);
- polys += createCylinder(ci, 1.0, 0.4, 1, 1);
- polys += Rect(0, -0.2, 0.4, 1, 0.2, 0.8);
-/* Draw the markings */
-
- {
- 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);
- glEnable (GL_LIGHTING);
- glPopMatrix();
- }
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
- glDepthMask(GL_TRUE);
- glTranslatef(-2, 0, -0.2);
- polys += wire(ci, 2);
- glTranslatef(0, 0, 0.2);
- polys += wire(ci, 2);
- glTranslatef(0, 0, 0.2);
- polys += wire(ci, 2);
- } else if (t->type == 0) { /* TO-220 Style */
- 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);
- glEnable (GL_LIGHTING);
- 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);
- 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);
- 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);
- polys += wire(ci, 2);
- glTranslatef(0, 0.375, 0);
- polys += wire(ci, 2);
- glTranslatef(0, 0.375, 0);
- 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);
- polys += Rect(0, 0, 0, 1, 0.5, 0.2);
-/* Draw the markings */
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glDepthMask(GL_FALSE);
- glBegin (GL_QUADS);
- glNormal3f(0, 0, 1);
- glTexCoord2f(0, 1);
- glVertex3f(0.2, 0, 0.01);
- glTexCoord2f(1, 1);
- glVertex3f(0.8, 0, 0.01);
- glTexCoord2f(1, 0);
- 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);
- glDepthMask(GL_TRUE);
-/* Now draw the legs */
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
- glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
- glMaterialfv(GL_FRONT, GL_SHININESS, &shin);
- 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;
-}
-
-static Component * NewComponent(ModeInfo *mi)
-{
- Circuit *ci = &circuit[MI_SCREEN(mi)];
- Component *c;
- float rnd;
-
- c = malloc(sizeof(Component));
- c->angle = RAND_RANGE(0,360);
- rnd = f_rand();
- if (rnd < 0.25) { /* come from the top */
- 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 - 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 - 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 = 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);
- else
- c->dy = RAND_RANGE(0.5, 2);
- }
- c->z = RAND_RANGE(0, 7) - 9;
- c->rotx = f_rand();
- c->roty = f_rand();
- c->rotz = f_rand();
- c->drot = f_rand() * 3;
- c->rdeg = 0;
- c->dz = f_rand()*2 - 1;
- c->norm = 0;
- c->alpha = 0; /* explicitly set to 1 later */
- rnd = random() % 11;
- if (rnd < 1) {
- c->c = NewResistor();
- c->type = 0;
- if (f_rand() < 0.4)
- c->norm = 1; /* some resistors shine */
- } else if (rnd < 2) {
- c->c = NewDiode();
- if (f_rand() < 0.4)
- c->norm = 1; /* some diodes shine */
- c->type = 1;
- } else if (rnd < 3) {
- c->c = NewTransistor(mi);
- c->norm = 1;
- c->type = 2;
- } else if (rnd < 4) {
- c->c = NewCapacitor(ci);
- c->norm = 1;
- c->type = 4;
- } else if (rnd < 5) {
- c->c = NewIC(mi);
- c->type = 5;
- c->norm = 1;
- } else if (rnd < 6) {
- c->c = NewLED(ci);
- c->type = 3;
- c->norm = 1;
- c->alpha = 1;
- } else if (rnd < 7) {
- c->c = NewFuse(ci);
- c->norm = 1;
- c->type = 7;
- c->alpha = 1;
- } else if (rnd < 8) {
- c->c = NewRCA(ci);
- c->norm = 1;
- c->type = 8;
- } else if (rnd < 9) {
- c->c = NewThreeFive(ci);
- c->norm = 1;
- c->type = 9;
- } else if (rnd < 10) {
- c->c = NewSwitch(ci);
- c->norm = 1;
- c->type = 10;
- } else {
- c->c = NewDisp(ci);
- c->type = 6;
- }
- return c;
-}
-
-static Transistor *NewTransistor(ModeInfo *mi)
-{
- Transistor *t;
-
- t = malloc(sizeof(Transistor));
- t->type = (random() % 3);
- if (t->type == 0) {
- t->text = transistortypes[random() % countof(transistortypes)];
- } else if (t->type == 2) {
- t->text = smctypes[random() % countof(smctypes)];
- } else if (t->type == 1) {
- t->text = to92types[random() % countof(to92types)];
- }
- return t;
-}
-
-static Capacitor *NewCapacitor(Circuit *ci)
-{
- Capacitor *c;
-
- c = malloc(sizeof(Capacitor));
- c->type = (f_rand() < 0.5);
- if (!c->type) {
- c->length = RAND_RANGE(0.5, 1);
- c->width = RAND_RANGE(0.5, 1);
- } else {
- c->width = RAND_RANGE(0.3, 1);
- }
- return c;
-}
-
-/* 7 segment display */
-
-static Disp *NewDisp(Circuit *ci)
-{
- Disp *d;
-
- d = malloc(sizeof(Disp));
- if (seven)
- d->value = 7;
- else
- d->value = RAND_RANGE(0, 10);
- return d;
-}
-
-
-static IC *NewIC(ModeInfo *mi)
-{
- IC *c;
- int pins;
- const char *val;
- int types[countof(ictypes)], i, n = 0;
-
- c = malloc(sizeof(IC));
- c->type = 0;
- switch((int)RAND_RANGE(0,4)) {
- case 0:
- pins = 8;
- break;
- case 1:
- pins = 14;
- break;
- case 2:
- pins = 16;
- break;
- case 3:
- default:
- pins = 24;
- break;
- }
- for (i = 0 ; i < countof(ictypes) ; i++) {
- if (ictypes[i].pins == pins) {
- types[n] = i;
- n++;
- }
- }
-
- if (n > countof(types)) abort();
- val = ictypes[types[random() % n]].val;
- sprintf(c->text, "%s\n%02d%02d", val,
- (int)RAND_RANGE(80, 100), (int)RAND_RANGE(1,53));
- c->pins = pins;
- return c;
-}
-
-static LED *NewLED(Circuit *ci)
-{
- LED *l;
- float r;
-
- l = malloc(sizeof(LED));
- r = f_rand();
- l->light = 0;
- if (!ci->light && (f_rand() < 0.4)) {
- ci->light = 1;
- l->light = 1;
- }
- if (r < 0.2) {
- l->r = 0.9; l->g = 0; l->b = 0;
- } else if (r < 0.4) {
- l->r = 0.3; l->g = 0.9; l->b = 0;
- } else if (r < 0.6) {
- l->r = 0.8; l->g = 0.9; l->b = 0;
- } else if (r < 0.8) {
- l->r = 0.0; l->g = 0.2; l->b = 0.8;
- } else {
- l->r = 0.9, l->g = 0.55, l->b = 0;
- }
- return l;
-}
-
-static Fuse *NewFuse(Circuit *ci)
-{
- Fuse *f;
-
- f = malloc(sizeof(Fuse));
- return f;
-}
-
-static RCA *NewRCA(Circuit *ci)
-{
- RCA *r;
-
- r = malloc(sizeof(RCA));
- r->col = (random() % 10 < 5);
- return r;
-}
-
-static ThreeFive *NewThreeFive(Circuit *ci)
-{
- ThreeFive *r;
-
- r = malloc(sizeof(ThreeFive));
- return r;
-}
-
-static Switch *NewSwitch(Circuit *ci)
-{
- Switch *s;
-
- s = malloc(sizeof(Switch));
- s->position = 0;
- return s;
-}
-
-static Diode *NewDiode(void)
-{
- Band *b;
- Diode *ret;
-
- ret = malloc(sizeof(Diode));
- b = malloc(sizeof(Band));
- b->pos = 0.8;
- b->len = 0.1;
- if (f_rand() < 0.5) {
- b->r = 1;
- b->g = 1;
- b->b = 1;
- ret->r = 0.7; ret->g = 0.1 ; ret->b = 0.1;
- } else {
- b->r = 1;
- b->g = 1;
- b->b = 1;
- ret->r = 0.2; ret->g = 0.2 ; ret->b = 0.2;
- }
- ret->band = b;
- return ret;
-}
-
-
-static Resistor * NewResistor(void)
-{
- int v, m, t; /* value, multiplier, tolerance */
- Resistor *ret;
-
- v = RAND(9);
- m = RAND(5);
- t = (RAND(10) < 5) ? 10 : 11;
- ret = malloc(sizeof(Resistor));
-
- if (seven) {
- ret->b[0] = ret->b[1] = ret->b[2] = 7;
- } else {
- ret->b[0] = values[v][0];
- ret->b[1] = values[v][1];
- ret->b[2] = m;
- }
- ret->b[3] = t;
-
- return ret;
-}
-
-static void makebandlist(Circuit *ci)
-{
- int i;
- GLfloat col[] = {0,0,0,0};
- GLfloat spec[] = {0.8,0.8,0.8,0};
- GLfloat shine = 40;
-
- for (i = 0 ; i < 12 ; i++) {
- 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);
- ci->band_list_polys[i] = createCylinder(ci, 0.1, 0.42, 0, 0);
- glEndList();
- }
-}
-
-
-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 */
- GLfloat col[] = {0,0,0,0};
-
- col[0] = r; col[1] = g; col[2] = bl;
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
- 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);
- polys += createCylinder(ci, b[n]->len*l, radius*1.05, 0, 0); /* band */
- glPopMatrix();
- }
- return polys;
-}
-
-static int drawgrid(Circuit *ci)
-{
- int polys = 0;
- GLfloat x, y;
- GLfloat col3[] = {0, 0.8, 0};
-
- 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:
- ci->draw_sx = -ci->XMAX/2;
- ci->draw_sy = ((int)RAND_RANGE(0, ci->YMAX/2))*2 - ci->YMAX/2;
- break;
- case 1:
- ci->draw_sx = ci->XMAX/2;
- ci->draw_sy = ((int)RAND_RANGE(0, ci->YMAX/2))*2 - ci->YMAX/2;
- break;
- case 2:
- ci->draw_sy = ci->YMAX/2;
- ci->draw_sx = ((int)RAND_RANGE(0, ci->XMAX/2))*2 - ci->XMAX/2;
- break;
- case 3:
- ci->draw_sy = -ci->YMAX/2;
- ci->draw_sx = ((int)RAND_RANGE(0, ci->XMAX/2))*2 - ci->XMAX/2;
- break;
- }
- ci->draw_s = 1;
- }
- } 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 (ci->draw_s) {
- glColor3fv(col3);
- glPushMatrix();
- 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 (ci->draw_sdir == 0) {
- ci->draw_sx += ci->draw_ds;
- if (ci->draw_sx > ci->XMAX/2)
- ci->draw_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 (ci->draw_sdir == 2) {
- ci->draw_sy -= ci->draw_ds;
- if (ci->draw_sy < ci->YMAX/2)
- ci->draw_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 (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 = -ci->XMAX/2 ; x <= ci->XMAX/2 ; x+= 2) {
- glColor3fv(ci->grid_col);
- glBegin(GL_LINES);
- 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 = -ci->YMAX/2 ; y <= ci->YMAX/2 ; y+= 2) {
- glColor3fv(ci->grid_col);
- glBegin(GL_LINES);
- 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;
-}
-
-static void display(ModeInfo *mi)
-{
- Circuit *ci = &circuit[MI_SCREEN(mi)];
- GLfloat light_sp[] = {0.8, 0.8, 0.8, 1.0};
- GLfloat black[] = {0, 0, 0, 1.0};
- int j;
-
- 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(ci->viewer[0], ci->viewer[1], ci->viewer[2],
- 0.0, 0.0, 0.0,
- 0.0, 1.0, 0.0);
- glPushMatrix();
- 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);
-
-# 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);
- }
-# else
- {
- /* Don't understand why this clause doesn't work on mobile, but it
- doesn't. */
- GLfloat s = (MI_WIDTH(mi) < MI_HEIGHT(mi)
- ? (MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi))
- : 1);
- s = 1/s;
- glScalef (s, s, s);
- }
-# 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 (ci->components[j] == NULL) {
- ci->components[j] = NewComponent(mi);
- j = maxparts;
- }
- }
- 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 (ci->components[j] != NULL) {
- if (DrawComponent(ci, ci->components[j], &mi->polygon_count)) {
- free(ci->components[j]); ci->components[j] = NULL;
- }
- }
- }
- glPopMatrix();
- glFlush();
-}
-
-/* ensure transparent components are at the end */
-static void reorder(Component *c[])
-{
- int i, j, k;
- Component *c1[MAX_COMPONENTS];
- Component *c2[MAX_COMPONENTS];
-
- j = 0;
- for (i = 0 ; i < maxparts ; i++) { /* clear old matrix */
- c1[i] = NULL;
- c2[i] = NULL;
- }
- for (i = 0 ; i < maxparts ; i++) {
- if (c[i] == NULL) continue;
- if (c[i]->alpha) { /* transparent parts go to c1 */
- c1[j] = c[i];
- j++;
- } else { /* opaque parts go to c2 */
- c2[i] = c[i];
- }
- }
- for (i = 0 ; i < maxparts ; i++) { /* clear old matrix */
- c[i] = NULL;
- }
- k = 0;
- for (i = 0 ; i < maxparts ; i++) { /* insert opaque part */
- if (c2[i] != NULL) {
- c[k] = c2[i];
- k++;
- }
- }
- for (i = 0 ; i < j ; i++) { /* insert transparent parts */
- c[k] = c1[i];
- k++;
- }
-}
-
-ENTRYPOINT void reshape_circuit(ModeInfo *mi, int width, int height)
-{
- Circuit *ci = &circuit[MI_SCREEN(mi)];
- int y = 0;
- GLfloat h = (GLfloat) height / (GLfloat) width;
-
- 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();
- glFrustum(-1.0,1.0,-h,h,1.5,35.0);
- glMatrixMode(GL_MODELVIEW);
- ci->win_h = height;
- ci->win_w = width;
- ci->YMAX = ci->XMAX * h;
-}
-
-
-ENTRYPOINT void init_circuit(ModeInfo *mi)
-{
-int screen = MI_SCREEN(mi);
-Circuit *ci;
-
- MI_INIT(mi, 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;
-
- 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)
- 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(ci);
- makebandlist(ci);
-
-}
-
-ENTRYPOINT void draw_circuit(ModeInfo *mi)
-{
- Circuit *ci = &circuit[MI_SCREEN(mi)];
- Window w = MI_WINDOW(mi);
- Display *disp = MI_DISPLAY(mi);
-
- if (!ci->glx_context)
- return;
-
- glXMakeCurrent(disp, w, *ci->glx_context);
-
- display(mi);
-
- if(mi->fps_p) do_fps(mi);
- glFinish();
- glXSwapBuffers(disp, w);
-}
-
-ENTRYPOINT void free_circuit(ModeInfo *mi)
-{
- Circuit *ci = &circuit[MI_SCREEN(mi)];
- int i;
- if (!ci->glx_context) return;
- glXMakeCurrent (MI_DISPLAY(mi), MI_WINDOW(mi), *ci->glx_context);
- if (ci->font) free_texture_font (ci->font);
- for (i = 0 ; i < 12 ; i++)
- if (glIsList(ci->band_list[i])) glDeleteLists(ci->band_list[i], 1);
- FreeAllGL(mi);
-}
-
-XSCREENSAVER_MODULE ("Circuit", circuit)
-
-#endif