2 * circuit - Random electronic components floating around
6 * Since version 1.1: added to-220 transistor, added fuse
7 * Since version 1.2: random display digits, LED improvements (flickering)
8 * Since version 1.3: ICs look better, font textures, improved normals to
9 * eliminate segmenting on curved surfaces, speedups
11 * Copyright (C) 2001 Ben Buxton (bb@cactii.net)
13 * Permission to use, copy, modify, distribute, and sell this software and its
14 * documentation for any purpose is hereby granted without fee, provided that
15 * the above copyright notice appear in all copies and that both that
16 * copyright notice and this permission notice appear in supporting
17 * documentation. No representations are made about the suitability of this
18 * software for any purpose. It is provided "as is" without express or
22 /* Written over a few days in a (successful) bid to learn GL coding
24 * -seven option is dedicated to all the Slarkeners
26 * try "-rotate -rotate-speed 0"
28 * This hack uses lookup tables for sin, cos and tan - it can do a lot
32 #include <X11/Intrinsic.h>
35 # define PROGCLASS "Circuit"
36 # define HACK_INIT init_circuit
37 # define HACK_DRAW draw_circuit
38 # define HACK_RESHAPE reshape_circuit
39 # define circuit_opts xlockmore_opts
40 /* insert defaults here */
42 #define DEF_SPIN "True"
43 #define DEF_SEVEN "False"
44 #define DEF_PARTS "10"
47 #define DEFAULTS "*parts: " DEF_PARTS " \n" \
48 "*spin: " DEF_SPIN "\n" \
50 "*showFPS: False \n" \
51 "*seven: " DEF_SEVEN "\n" \
57 # include "xlockmore.h" /* from the xscreensaver distribution */
58 #else /* !STANDALONE */
59 # include "xlock.h" /* from the xlockmore distribution */
60 #endif /* !STANDALONE */
62 /* lifted from lament.c */
63 #define RAND(n) ((long) ((random() & 0x7fffffff) % ((long) (n))))
64 #define RANDSIGN() ((random() & 1) ? 1 : -1)
70 #include "font-ximage.h"
73 #define countof(x) (sizeof((x))/sizeof((*x)))
79 static int rotatespeed;
85 #define countof(x) (sizeof((x))/sizeof((*x)))
87 static XrmOptionDescRec opts[] = {
88 {"-parts", ".circuit.parts", XrmoptionSepArg, "10" },
89 {"-font", ".circuit.font", XrmoptionSepArg, "fixed" },
90 {"-rotate-speed", ".circuit.rotatespeed", XrmoptionSepArg, "1" },
91 {"+spin", ".circuit.spin", XrmoptionNoArg, (caddr_t) "false" },
92 {"-spin", ".circuit.spin", XrmoptionNoArg, (caddr_t) "true" },
93 {"+light", ".circuit.light", XrmoptionNoArg, (caddr_t) "false" },
94 {"-light", ".circuit.light", XrmoptionNoArg, (caddr_t) "true" },
95 {"+seven", ".circuit.seven", XrmoptionNoArg, (caddr_t) "false" },
96 {"-seven", ".circuit.seven", XrmoptionNoArg, (caddr_t) "true" },
97 {"+rotate", ".circuit.rotate", XrmoptionNoArg, (caddr_t) "false" },
98 {"-rotate", ".circuit.rotate", XrmoptionNoArg, (caddr_t) "true" },
101 static argtype vars[] = {
102 {(caddr_t *) &maxparts, "parts", "Parts", DEF_PARTS, t_Int},
103 {(caddr_t *) &font, "font", "Font", "fixed", t_String},
104 {(caddr_t *) &rotatespeed, "rotatespeed", "Rotatespeed", "1", t_Int},
105 {(caddr_t *) &spin, "spin", "Spin", DEF_SPIN, t_Bool},
106 {(caddr_t *) &rotate, "rotate", "Rotate", "False", t_Bool},
107 {(caddr_t *) &uselight, "light", "Light", "True", t_Bool},
108 {(caddr_t *) &seven, "seven", "Seven", DEF_SEVEN, t_Bool},
111 ModeSpecOpt circuit_opts = {countof(opts), opts, countof(vars), vars, NULL};
114 ModStruct circuit_description =
115 {"circuit", "init_circuit", "draw_circuit", "release_circuit",
116 "draw_circuit", "init_circuit", NULL, &circuit_opts,
117 1000, 1, 2, 1, 4, 1.0, "",
118 "Flying electronic components", 0, NULL};
124 GLXContext *glx_context;
128 static Circuit *circuit = NULL;
131 #include <sys/time.h>
136 #define M_PI 3.14159265
139 /* window width, height */
142 /* width and height of viewport */
147 #define MAX_COMPONENTS 30
149 #define MOVE_MULT 0.05
151 static float f_rand(void) {
152 return ((float)RAND(10000)/(float)10000);
155 #define RAND_RANGE(min, max) ((min) + (max - min) * f_rand())
157 /* one lucky led gets to be a light source , unless -no-light*/
161 static GLfloat viewer[] = {0.0, 0.0, 14.0};
162 static GLfloat lightpos[] = {7.0, 7.0, 15, 1.0};
164 float sin_table[720];
165 float cos_table[720];
166 float tan_table[720];
170 /* used for allocating font textures */
172 int num; /* index number */
177 /* Represents a band on a resistor/diode/etc */
179 float pos; /* relative position from start/previous band */
180 GLfloat r, g, b; /* colour of the band */
181 float len; /* length as a fraction of total length */
185 Band *b1, *b2, *b3, *b4; /* bands */
191 GLfloat r, g, b; /* body colour */
194 static const char * transistortypes[] = {
211 int type; /* package type. 0 = to-92, 1 = to-220 */
212 GLfloat tw, th; /* texture dimensions */
213 int tnum; /* texture binding */
217 GLfloat r,g,b; /* LED colour */
218 int light; /* are we the light source? */
222 int type; /* 0 = electro, 1 = ceramic */
223 float width; /* width of an electro/ceramic */
224 float length; /* length of an electro */
232 static const ICTypes ictypes[] = {
275 int type; /* 0 = DIL, 1 = flat square */
277 float tw, th; /* texture dimensions for markings */
278 int tnum; /* texture number */
281 /* 7 segment display */
284 int value; /* displayed number */
292 GLfloat x, y, z; /* current co-ordinates */
293 GLfloat dx, dy, dz; /* current direction */
294 GLfloat rotx, roty, rotz; /* rotation vector */
295 GLfloat drot; /* rotation velocity (degrees per frame) */
296 int norm; /* Normalize this component (for shine) */
297 int rdeg; /* current rotation degrees */
298 int angle; /* angle about the z axis */
299 int alpha; /* 0 if not a transparent component */
300 int type; /* 0 = resistor, 1 = diode, 2 = transistor, 3 = LED, 4 = cap, 5=IC,
302 void * c; /* pointer to the component */
305 static int band_list[12];
307 /* standard colour codes */
309 static GLfloat colorcodes [12][3] = {
310 {0.0,0.0,0.0}, /* black 0 */
311 {0.49,0.25,0.08}, /* brown 1 */
312 {1.0,0.0,0.0}, /* red 2 */
313 {1.0,0.5,0.0}, /* orange 3 */
314 {1.0,1.0,0.0}, /* yellow 4 */
315 {0.0,1.0,0.0}, /* green 5 */
316 {0.0,0.5,1.0}, /* blue 6 */
317 {0.7,0.2,1.0}, /* violet 7 */
318 {0.5,0.5,0.5}, /* grey 8 */
319 {1.0,1.0,1.0}, /* white 9 */
320 {0.66,0.56,0.2}, /* gold 10 */
321 {0.8,0.8,0.8}, /* silver 11 */
324 /* base values for components - we can multiply by 0 - 1M */
325 static int values [9][2] = {
337 void DrawResistor(Resistor *);
338 void DrawDiode(Diode *);
339 void DrawTransistor(Transistor *);
342 void DrawCapacitor(Capacitor *);
343 void DrawDisp(Disp *);
344 void DrawFuse(Fuse *);
346 void reorder(Component *[]);
347 void circle(float, int,int);
348 void bandedCylinder(float, float , GLfloat, GLfloat , GLfloat, Band **, int);
349 TexNum *fonttexturealloc(const char *, float *, float *);
350 Resistor *NewResistor(void);
351 Diode *NewDiode(void);
352 Transistor *NewTransistor(void);
354 Capacitor *NewCapacitor(void);
359 /* we use trig tables to speed things up - 200 calls to sin()
360 in one frame can be a bit harsh..
363 void make_tables(void) {
367 f = 360 / (M_PI * 2);
368 for (i = 0 ; i < 720 ; i++) {
369 sin_table[i] = sin(i/f);
371 for (i = 0 ; i < 720 ; i++) {
372 cos_table[i] = cos(i/f);
374 for (i = 0 ; i < 720 ; i++) {
375 tan_table[i] = tan(i/f);
380 void createCylinder (float length, float radius, int endcaps, int half)
382 int a; /* current angle around cylinder */
384 float z1, y1, z2, y2,ex;
389 nsegs = radius*MAX(win_w, win_h)/20;
390 nsegs = MAX(nsegs, 4);
393 angle = (half) ? (180 - 90/nsegs) : 374;
397 for (a = 0 ; a <= angle ; a+= angle/nsegs) {
398 y2=radius*(float)sin_table[(int)a];
399 z2=radius*(float)cos_table[(int)a];
400 glNormal3f(0, y1, z1);
402 glVertex3f(length,y1,z1);
403 glNormal3f(0, y2, z2);
404 glVertex3f(length,y2,z2);
413 glVertex3f(0, 0, radius);
414 glVertex3f(length, 0, radius);
415 glVertex3f(length, 0, 0 - radius);
416 glVertex3f(0, 0, 0 - radius);
420 for(ex = 0 ; ex <= length ; ex += length) {
422 norm = (ex == length) ? 1 : -1;
423 glBegin(GL_TRIANGLES);
424 glNormal3f(norm, 0, 0);
425 for (a = 0 ; a <= angle ; a+= angle/nsegs) {
426 y2=radius*(float)sin_table[(int)a];
427 z2=radius*(float)cos_table[(int)a];
429 glVertex3f(ex,y1,z1);
430 glVertex3f(ex,y2,z2);
440 void circle(float radius, int segments, int half)
442 float x1 = 0, x2 = 0;
443 float y1 = 0, y2 = 0;
452 glBegin(GL_TRIANGLES);
457 x2=radius*(float)cos_table[(int)angle];
458 y2=radius*(float)sin_table[(int)angle];
470 static GLfloat col[] = {0.3, 0.3, 0.3, 1.0};
471 static GLfloat spec[] = {0.9, 0.9, 0.9, 1.0};
472 static GLfloat nospec[] = {0.4, 0.4, 0.4, 1.0};
476 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
477 glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
478 glMaterialfv(GL_FRONT, GL_SHININESS, &shin);
479 n = glIsEnabled(GL_NORMALIZE);
480 if (!n) glEnable(GL_NORMALIZE);
481 createCylinder(len, 0.05, 1, 0);
482 if (!n) glDisable(GL_NORMALIZE);
483 glMaterialfv(GL_FRONT, GL_SPECULAR, nospec);
486 void ring(GLfloat inner, GLfloat outer, int nsegs)
488 GLfloat z1, z2, y1, y2;
489 GLfloat Z1, Z2, Y1, Y2;
496 for(i=0; i <=360 ; i+= 360/nsegs)
499 z2=inner*(float)sin_table[(int)angle];
500 y2=inner*(float)cos_table[(int)angle];
501 Z2=outer*(float)sin_table[(int)angle];
502 Y2=outer*(float)cos_table[(int)angle];
503 glVertex3f(0, Y1, Z1);
504 glVertex3f(0, y1, z1);
505 glVertex3f(0, y2, z2);
506 glVertex3f(0, Y2, Z2);
515 void sphere(GLfloat r, float stacks, float slices,
516 int startstack, int endstack, int startslice,
519 GLfloat d, d1, dr, dr1, Dr, Dr1, D, D1, z1, z2, y1, y2, Y1, Z1, Y2, Z2;
520 int a, a1, b, b1, c, c1;
525 a1 = startstack * step;
526 b1 = startslice * sstep;
527 y1 = z1 = Y1 = Z1 = 0;
528 c = (endslice / slices) * 360;
529 c1 = (endstack/stacks)*180;
531 for (a = startstack * step ; a <= c1 ; a+= step) {
540 for (b = b1 ; b <= c ; b+= sstep) {
545 glNormal3f(Dr, y1, z1);
546 glVertex3f(Dr,y1,z1);
547 glNormal3f(Dr, y2, z2);
548 glVertex3f(Dr,y2,z2);
549 glNormal3f(Dr1, Y2, Z2);
550 glVertex3f(Dr1,Y2,Z2);
551 glNormal3f(Dr1, Y1, Z1);
552 glVertex3f(Dr1,Y1,Z1);
563 int DrawComponent(Component *c)
565 int ret = 0; /* return 1 if component is freed */
568 glTranslatef(c->x, c->y, c->z);
570 glRotatef(c->angle, c->rotx, c->roty, c->rotz);
573 glRotatef(c->rdeg, c->rotx, c->roty, c->rotz);
578 glEnable(GL_NORMALIZE);
580 glDisable(GL_NORMALIZE);
582 /* call object draw routine here */
585 } else if (c->type == 1) {
587 } else if (c->type == 2) {
588 DrawTransistor(c->c);
589 } else if (c->type == 3) {
590 if (((LED *)c->c)->light && light) {
591 GLfloat lp[] = {0.1, 0, 0, 1};
593 glLightfv(GL_LIGHT1, GL_POSITION, lp);
596 } else if (c->type == 4) {
598 } else if (c->type == 5) {
600 } else if (c->type == 6) {
602 } else if (c->type == 7) {
605 c->x += c->dx * MOVE_MULT;
606 c->y += c->dy * MOVE_MULT;
607 if (c->x > XMAX/2 || c->x < 0 - XMAX/2 ||
608 c->y > YMAX/2 || c->y < 0 - YMAX/2) {
609 if (c->type == 3 && ((LED *)c->c)->light && light) {
610 glDisable(GL_LIGHT1);
611 light = 0; lighton = 0;
614 free(((Diode *)c->c)->band); /* remember to free diode band */
620 glDisable(GL_NORMALIZE);
624 /* draw a resistor */
626 void DrawResistor(Resistor *r)
629 GLfloat col[] = {0.74, 0.62, 0.46, 1.0};
630 GLfloat spec[] = {0.8, 0.8, 0.8, 1.0};
633 glTranslatef(-4, 0, 0);
635 glTranslatef(3, 0, 0);
636 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
637 glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
638 glMaterialfv(GL_FRONT, GL_SHININESS, &shine);
639 createCylinder(1.8, 0.4, 1, 0);
641 for (i = 0 ; i < 4 ; i++) {
642 glTranslatef(0.35, 0, 0);
643 glCallList(band_list[r->b[i]]);
646 glTranslatef(1.8, 0, 0);
650 void DrawFuse(Fuse *f)
652 static GLfloat col[] = {0.5, 0.5, 0.5, 1.0}; /* endcaps */
653 static GLfloat glass[] = {0.4, 0.4, 0.4, 0.3}; /* glass */
654 static GLfloat spec[] = {1, 1, 1, 1}; /* glass */
657 glTranslatef(-1.8, 0, 0);
658 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
659 glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
660 glMateriali(GL_FRONT, GL_SHININESS, 40);
661 createCylinder(0.8, 0.45, 1, 0);
662 glTranslatef(0.8, 0, 0);
664 glDepthMask(GL_FALSE);
665 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, glass);
666 glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 40);
667 createCylinder(2, 0.4, 0, 0);
668 createCylinder(2, 0.3, 0, 0);
670 glDepthMask(GL_TRUE);
671 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
672 glMateriali(GL_FRONT, GL_SHININESS, 40);
675 glVertex3f(2, 0. ,0);
677 glTranslatef(2, 0, 0);
678 createCylinder(0.8, 0.45, 1, 0);
683 void DrawCapacitor(Capacitor *c)
685 static GLfloat col[] = {0, 0, 0, 0};
686 static GLfloat spec[] = {0.8, 0.8, 0.8, 0};
687 GLfloat brown[] = {0.84, 0.5, 0};
688 static GLfloat shine = 40;
692 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, brown);
693 sphere(c->width, 15, 15, 0, 4 ,0, 15);
694 glTranslatef(1.35*c->width, 0, 0);
695 sphere(c->width, 15, 15, 11, 15, 0, 15);
696 glRotatef(90, 0, 0, 1);
697 glTranslatef(0, 0.7*c->width, 0.3*c->width);
699 glTranslatef(0, 0, -0.6*c->width);
702 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col);
703 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
704 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &shine);
706 glVertex3f(0, 0.82*c->width, -0.1);
707 glVertex3f(3*c->length, 0.82*c->width, -0.1);
708 glVertex3f(3*c->length, 0.82*c->width, 0.1);
709 glVertex3f(0, 0.82*c->width, 0.1);
714 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col);
715 circle(0.6*c->width, 30, 0);
719 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col);
720 ring(0.6*c->width, 0.8*c->width, 30);
721 glTranslatef(0.01, 0.0, 0);
722 createCylinder(3.0*c->length, 0.8*c->width, 1, 0);
726 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col);
727 glTranslatef(3.01*c->length, 0.0, 0);
728 circle(0.6*c->width, 30, 0);
729 glTranslatef(0, 0.4*c->width, 0);
731 glTranslatef(0.0, -0.8*c->width, 0);
739 GLfloat col[] = {0, 0, 0, 0.6};
741 col[0] = l->r; col[1] = l->g; col[2] = l->b;
742 if (l->light && light) {
743 GLfloat dir[] = {-1, 0, 0};
744 glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, dir);
746 glLightfv(GL_LIGHT1, GL_SPECULAR, col);
747 glLightfv(GL_LIGHT1, GL_AMBIENT, col);
748 glLightfv(GL_LIGHT1, GL_DIFFUSE, col);
749 glLighti(GL_LIGHT1, GL_SPOT_CUTOFF, (GLint) 90);
750 glLighti(GL_LIGHT1, GL_CONSTANT_ATTENUATION, (GLfloat)1);
751 glLighti(GL_LIGHT1, GL_LINEAR_ATTENUATION, (GLfloat)0);
752 glLighti(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, (GLfloat)0);
753 glLighti(GL_LIGHT1, GL_SPOT_EXPONENT, (GLint) 20);
757 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col);
758 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col);
759 /* no transparency when LED is lit */
762 glDepthMask(GL_FALSE);
763 glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
765 createCylinder(1.2, 0.3, 0, 0);
766 if (l->light && light) {
767 glDisable(GL_LIGHTING);
770 sphere(0.3, 7, 7, 3, 7, 0, 7);
771 if (l->light && light) {
772 glEnable(GL_LIGHTING);
774 glDepthMask(GL_TRUE);
778 glTranslatef(1.2, 0, 0);
779 createCylinder(0.1, 0.38, 1, 0);
780 glTranslatef(-0.3, 0.15, 0);
782 glTranslatef(0, -0.3, 0);
784 if (random() % 50 == 25) {
786 l->light = 0; light = 0; lighton = 0;
787 glDisable(GL_LIGHT1);
789 l->light = 1; light = 1;
796 void DrawDiode(Diode *d)
799 GLfloat col[] = {0.3, 0.3, 0.3, 0};
800 GLfloat spec[] = {0.7, 0.7, 0.7, 0};
803 glMaterialfv(GL_FRONT, GL_SHININESS, &shine);
804 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
805 glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
806 glTranslatef(-4, 0, 0);
808 glTranslatef(3, 0, 0);
809 bandedCylinder(0.3, 1.5, d->r, d->g, d->b, &(d->band), 1);
810 glTranslatef(1.5, 0, 0);
815 void Rect(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h,
822 yh = y+h; xw = x+w; zt = z - t;
824 glBegin(GL_QUADS); /* front */
827 glVertex3f(x, yh, z);
828 glVertex3f(xw, yh, z);
829 glVertex3f(xw, y, z);
831 glNormal3f(0, 0, -1);
832 glVertex3f(x, y, zt);
833 glVertex3f(x, yh, zt);
834 glVertex3f(xw, yh, zt);
835 glVertex3f(xw, y, zt);
838 glVertex3f(x, yh, z);
839 glVertex3f(x, yh, zt);
840 glVertex3f(xw, yh, zt);
841 glVertex3f(xw, yh, z);
843 glNormal3f(0, -1, 0);
845 glVertex3f(x, y, zt);
846 glVertex3f(xw, y, zt);
847 glVertex3f(xw, y, z);
849 glNormal3f(-1, 0, 0);
851 glVertex3f(x, y, zt);
852 glVertex3f(x, yh, zt);
853 glVertex3f(x, yh, z);
856 glVertex3f(xw, y, z);
857 glVertex3f(xw, y, zt);
858 glVertex3f(xw, yh, zt);
859 glVertex3f(xw, yh, z);
865 void ICLeg(GLfloat x, GLfloat y, GLfloat z, int dir)
868 Rect(x-0.1, y, z, 0.1, 0.1, 0.02);
869 Rect(x-0.1, y, z, 0.02, 0.1, 0.1);
870 Rect(x-0.1, y+0.03, z-0.1, 0.02, 0.05, 0.3);
872 Rect(x, y, z, 0.1, 0.1, 0.02);
873 Rect(x+0.8*0.1, y, z, 0.02, 0.1, 0.1);
874 Rect(x+0.8*0.1, y+0.03, z-0.1, 0.02, 0.05, 0.3);
884 GLfloat col[] = {0.1, 0.1, 0.1, 0};
885 GLfloat col2[] = {0.2, 0.2, 0.2, 0};
886 GLfloat spec[] = {0.6, 0.6, 0.6, 0};
888 GLfloat lspec[] = {0.6, 0.6, 0.6, 0};
889 GLfloat lcol[] = {0.4, 0.4, 0.4, 0};
891 float mult, th, size;
894 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
895 glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
896 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
897 glMaterialfv(GL_FRONT, GL_SHININESS, &shine);
916 glVertex3f(w, h, 0.1);
917 glVertex3f(w, -h, 0.1);
918 glVertex3f(-w, -h, 0.1);
919 glVertex3f(-w, h, 0.1);
920 glNormal3f(0, 0, -1);
921 glVertex3f(w, h, -0.1);
922 glVertex3f(w, -h, -0.1);
923 glVertex3f(-w, -h, -0.1);
924 glVertex3f(-w, h, -0.1);
926 glVertex3f(w, h, -0.1);
927 glVertex3f(w, -h, -0.1);
928 glVertex3f(w, -h, 0.1);
929 glVertex3f(w, h, 0.1);
930 glNormal3f(0, -1, 0);
931 glVertex3f(w, -h, -0.1);
932 glVertex3f(w, -h, 0.1);
933 glVertex3f(-w, -h, 0.1);
934 glVertex3f(-w, -h, -0.1);
935 glNormal3f(-1, 0, 0);
936 glVertex3f(-w, h, -0.1);
937 glVertex3f(-w, h, 0.1);
938 glVertex3f(-w, -h, 0.1);
939 glVertex3f(-w, -h, -0.1);
940 glNormal3f(0, -1, 0);
941 glVertex3f(-w, h, -0.1);
942 glVertex3f(w, h, -0.1);
943 glVertex3f(w, h, 0.1);
944 glVertex3f(-w, h, 0.1);
946 glBindTexture(GL_TEXTURE_2D, c->tnum);
947 glEnable(GL_TEXTURE_2D);
949 glDepthMask(GL_FALSE);
955 mult = size*c->tw / c->th;
957 glBegin(GL_QUADS); /* text markings */
960 glVertex3f(th, mult, 0.11);
962 glVertex3f(th, -mult, 0.11);
964 glVertex3f(-th, -mult, 0.11);
966 glVertex3f(-th, mult, 0.11);
968 glDisable(GL_TEXTURE_2D);
970 glDepthMask(GL_TRUE);
971 d = (h*2-0.1) / c->pins;
973 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, lcol);
974 glMaterialfv(GL_FRONT, GL_SPECULAR, lspec);
975 glMaterialfv(GL_FRONT, GL_SHININESS, &lshine);
976 for (z = 0 ; z < c->pins/2 ; z++) {
977 ICLeg(w, -h + z*d + d/2, 0, 0);
979 for (z = 0 ; z < c->pins/2 ; z++) {
980 ICLeg(-w, -h + z*d + d/2, 0, 1);
982 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col2);
983 glTranslatef(-w+0.3, h-0.3, 0.11);
984 glRotatef(90, 0, 1, 0);
989 void DrawDisp(Disp *d)
991 GLfloat col[] = {0.8, 0.8, 0.8, 1.0}; /* body colour */
992 GLfloat front[] = {0.2, 0.2, 0.2, 1.0}; /* front colour */
993 GLfloat on[] = {0.9, 0, 0, 1}; /* 'on' segment */
994 GLfloat off[] = {0.3, 0, 0, 1}; /* 'off' segment */
996 GLfloat x, y; /* for the pins */
997 GLfloat spec[] = {0.6, 0.6, 0.6, 0};
998 GLfloat lcol[] = {0.4, 0.4, 0.4, 0};
1000 static GLfloat vdata_h[6][2] = {
1008 static GLfloat vdata_v[6][2] = {
1017 static GLfloat seg_start[7][2] = {
1027 static int nums[10][7] = {
1028 {1, 1, 1, 1, 1, 1, 0}, /* 0 */
1029 {0, 1, 1, 0, 0, 0, 0}, /* 1 */
1030 {1, 1, 0, 1, 1, 0, 1}, /* 2 */
1031 {1, 1, 1, 1, 0, 0, 1}, /* 3 */
1032 {0, 1, 1, 0, 0, 1, 1}, /* 4 */
1033 {1, 0, 1, 1, 0, 1, 1}, /* 5 */
1034 {1, 0, 1, 1, 1, 1, 1}, /* 6 */
1035 {1, 1, 1, 0, 0, 0, 0}, /* 7 */
1036 {1, 1, 1, 1, 1, 1, 1}, /* 8 */
1037 {1, 1, 1, 0, 0, 1, 1} /* 9 */
1040 glTranslatef(-0.9, -1.8, 0);
1041 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
1042 Rect(0, 0, -0.01, 1.8, 2.6, 0.7);
1043 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, front);
1045 glVertex2f(-0.05, -0.05);
1046 glVertex2f(-0.05, 2.65);
1047 glVertex2f(1.85, 2.65);
1048 glVertex2f(1.85, -0.05);
1050 glDisable(GL_LIGHTING); /* lit segments dont need light */
1051 if (!seven && (random() % 30) == 19) { /* randomly change value */
1052 d->value = random() % 10;
1054 for (j = 0 ; j < 7 ; j++) { /* draw the segments */
1055 GLfloat xx[6], yy[6];
1056 if (nums[d->value][j])
1060 for (k = 0 ; k < 6 ; k++) {
1061 if (j == 0 || j == 3 || j == 6) {
1062 xx[k] = seg_start[j][0] + vdata_h[k][0];
1063 yy[k] = seg_start[j][1] + vdata_h[k][1];
1065 xx[k] = seg_start[j][0] + vdata_v[k][0];
1066 yy[k] = seg_start[j][1] + vdata_v[k][1];
1069 glBegin(GL_POLYGON);
1070 for(i = 0 ; i < 6 ; i++) {
1071 glVertex3f(xx[i], yy[i], 0.01);
1078 glVertex3f(1.5, 0.2, 0.01);
1080 glEnable(GL_LIGHTING);
1081 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, lcol);
1082 glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
1083 glMaterialfv(GL_FRONT, GL_SHININESS, &shine);
1084 for (x = 0.35 ; x <= 1.5 ; x+= 1.15) {
1085 for ( y = 0.2 ; y <= 2.4 ; y += 0.3) {
1086 ICLeg(x, y, -0.7, 1);
1091 void HoledRectangle(GLfloat w, GLfloat h, GLfloat d, GLfloat radius, int p)
1094 GLfloat x1, y1, x2, y2;
1095 GLfloat yr, yr1, xr, xr1, side, side1;
1099 x1 = radius; y1 = 0;
1104 for (a = 0 ; a <= 360 ; a+= step) {
1105 y2=radius*(float)sin_table[(int)a];
1106 x2=radius*(float)cos_table[(int)a];
1108 if (a < 45 || a > 315) {
1110 yr = side1 * tan_table[a];
1112 } else if (a <= 135 || a >= 225) {
1113 xr = side/tan_table[a];
1124 yr = -side1 * tan_table[a];
1128 glNormal3f(-x1, -y1, 0); /* cylinder */
1129 glVertex3f(x1,y1,0);
1130 glVertex3f(x1,y1,-d);
1131 glVertex3f(x2,y2,-d);
1132 glVertex3f(x2,y2,0);
1134 glNormal3f(0, 0, 1); /* front face */
1135 glVertex3f(x1,y1,0);
1136 glVertex3f(xr1, yr1, 0);
1137 glVertex3f(xr, yr, 0);
1138 glVertex3f(x2, y2, 0);
1140 glNormal3f(nx, ny, 0); /* side */
1141 glVertex3f(xr, yr, 0);
1142 glVertex3f(xr, yr, -d);
1143 glVertex3f(xr1, yr1, -d);
1144 glVertex3f(xr1, yr1, 0);
1146 glNormal3f(0, 0, -1); /* back */
1147 glVertex3f(xr, yr, -d);
1148 glVertex3f(x2, y2, -d);
1149 glVertex3f(x1, y1, -d);
1150 glVertex3f(xr1, yr1, -d);
1159 void DrawTransistor(Transistor *t)
1161 static GLfloat col[] = {0.3, 0.3, 0.3, 1.0};
1162 static GLfloat spec[] = {0.9, 0.9, 0.9, 1.0};
1163 static GLfloat nospec[] = {0.4, 0.4, 0.4, 1.0};
1167 glMaterialfv(GL_FRONT, GL_SHININESS, &shin);
1168 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col);
1169 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1171 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col);
1172 glRotatef(90, 0, 1, 0);
1173 glRotatef(90, 0, 0, 1);
1174 createCylinder(1.0, 0.4, 1, 1);
1175 Rect(0, -0.2, 0.4, 1, 0.2, 0.8);
1176 glTranslatef(-2, 0, -0.2);
1178 glTranslatef(0, 0, 0.2);
1180 glTranslatef(0, 0, 0.2);
1184 mult = 1.5*t->th/t->tw;
1187 Rect(0, 0, 0, 1.5, 1.5, 0.5);
1188 glEnable(GL_TEXTURE_2D);
1189 glBindTexture(GL_TEXTURE_2D, t->tnum);
1191 glDepthMask(GL_FALSE);
1193 glNormal3f(0, 0, 1);
1195 glVertex3f(0, y1, 0.01);
1197 glVertex3f(1.5, y1, 0.01);
1199 glVertex3f(1.5, y2, 0.01);
1201 glVertex3f(0, y2, 0.01);
1203 glDisable(GL_TEXTURE_2D);
1204 glDisable(GL_BLEND);
1205 glDepthMask(GL_TRUE);
1206 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
1207 glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
1208 glMaterialfv(GL_FRONT, GL_SHININESS, &shin);
1209 Rect(0, 0, -0.5, 1.5, 1.5, 0.30);
1210 if (!glIsEnabled(GL_NORMALIZE)) glEnable(GL_NORMALIZE);
1211 glTranslatef(0.75, 1.875, -0.55);
1212 HoledRectangle(1.5, 0.75, 0.25, 0.2, 8);
1213 glMaterialfv(GL_FRONT, GL_SPECULAR, nospec);
1214 glTranslatef(-0.375, -1.875, 0);
1215 glRotatef(90, 0, 0, -1);
1217 glTranslatef(0, 0.375, 0);
1219 glTranslatef(0, 0.375, 0);
1225 Component * NewComponent(void)
1230 c = malloc(sizeof(Component));
1231 c->angle = RAND_RANGE(0,360);
1233 if (rnd < 0.25) { /* come from the top */
1235 c->x = RAND_RANGE(0, XMAX) - XMAX/2;
1237 c->dx = 0 - RAND_RANGE(0.5, 2);
1239 c->dx = RAND_RANGE(0.5, 2);
1240 c->dy = 0 - RAND_RANGE(0.5, 2);
1241 } else if (rnd < 0.5) { /* come from the bottom */
1243 c->x = RAND_RANGE(0, XMAX) - XMAX/2;
1245 c->dx = 0 - RAND_RANGE(0.5, 2);
1247 c->dx = RAND_RANGE(0.5, 2);
1248 c->dy = RAND_RANGE(0.5, 2);
1249 } else if (rnd < 0.75) { /* come from the left */
1251 c->y = RAND_RANGE(0, YMAX) - YMAX/2;
1252 c->dx = RAND_RANGE(0.5, 2);
1254 c->dy = 0 - RAND_RANGE(0.5, 2);
1256 c->dy = RAND_RANGE(0.5, 2);
1257 } else { /* come from the right */
1259 c->y = RAND_RANGE(0, YMAX) - YMAX/2;
1260 c->dx = 0 - RAND_RANGE(0.5, 2);
1262 c->dy = 0 - RAND_RANGE(0.5, 2);
1264 c->dy = RAND_RANGE(0.5, 2);
1266 c->z = RAND_RANGE(0, 7) - 9;
1270 c->drot = f_rand() * 7;
1272 c->dz = f_rand()*2 - 1;
1274 c->alpha = 0; /* explicitly set to 1 later */
1277 c->c = NewResistor();
1280 c->norm = 1; /* some resistors shine */
1281 } else if (rnd < 0.2) {
1284 c->norm = 1; /* some diodes shine */
1286 } else if (rnd < 0.3) {
1287 c->c = NewTransistor();
1290 } else if (rnd < 0.4) {
1291 c->c = NewCapacitor();
1294 } else if (rnd < 0.6) {
1298 } else if (rnd < 0.7) {
1303 } else if (rnd < 0.8) {
1315 Transistor *NewTransistor(void)
1318 float texfg[] = {0.7, 0.7, 0.7, 1.0};
1319 float texbg[] = {0.3, 0.3, 0.3, 0.1};
1323 t = malloc(sizeof(Transistor));
1324 t->type = (f_rand() < 0.5);
1326 val = transistortypes[random() % countof(transistortypes)];
1327 tn = fonttexturealloc(val, texfg, texbg);
1329 fprintf(stderr, "Error getting a texture for a string!\n");
1332 t->tw = tn->w; t->th = tn->h;
1339 Capacitor *NewCapacitor(void)
1343 c = malloc(sizeof(Capacitor));
1344 c->type = (f_rand() < 0.5);
1346 c->length = RAND_RANGE(0.5, 1);
1347 c->width = RAND_RANGE(0.5, 1);
1349 c->width = RAND_RANGE(0.3, 1);
1354 /* 7 segment display */
1360 d = malloc(sizeof(Disp));
1364 d->value = RAND_RANGE(0, 10);
1374 float texfg[] = {0.7, 0.7, 0.7, 1.0};
1375 float texbg[] = {0.1, 0.1, 0.1, 0};
1377 int types[countof(ictypes)], i, n = 0;
1379 c = malloc(sizeof(IC));
1381 switch((int)RAND_RANGE(0,4)) {
1396 for (i = 0 ; i < countof(ictypes) ; i++) {
1397 if (ictypes[i].pins == pins) {
1403 if (n > countof(types)) abort();
1404 val = ictypes[types[random() % n]].val;
1405 tn = fonttexturealloc(val, texfg, texbg);
1407 fprintf(stderr, "Error allocating font texture for '%s'\n", val);
1409 c->tw = tn->w; c->th = tn->h;
1422 l = malloc(sizeof(LED));
1425 if (!light && (f_rand() < 0.4)) {
1430 l->r = 0.9; l->g = 0; l->b = 0;
1431 } else if (r < 0.4) {
1432 l->r = 0.3; l->g = 0.9; l->b = 0;
1433 } else if (r < 0.6) {
1434 l->r = 0.8; l->g = 0.9; l->b = 0;
1435 } else if (r < 0.8) {
1436 l->r = 0.0; l->g = 0.2; l->b = 0.8;
1438 l->r = 0.9, l->g = 0.55, l->b = 0;
1447 f = malloc(sizeof(Fuse));
1451 Diode *NewDiode(void)
1456 ret = malloc(sizeof(Diode));
1457 b = malloc(sizeof(Band));
1460 if (f_rand() < 0.5) {
1464 ret->r = 0.7; ret->g = 0.1 ; ret->b = 0.1;
1469 ret->r = 0.2; ret->g = 0.2 ; ret->b = 0.2;
1476 Resistor * NewResistor(void)
1478 int v, m, t; /* value, multiplier, tolerance */
1483 t = (RAND(10) < 5) ? 10 : 11;
1484 ret = malloc(sizeof(Resistor));
1487 ret->b[0] = ret->b[1] = ret->b[2] = 7;
1489 ret->b[0] = values[v][0];
1490 ret->b[1] = values[v][1];
1498 void makebandlist(void)
1501 GLfloat col[] = {0,0,0,0};
1502 GLfloat spec[] = {0.8,0.8,0.8,0};
1505 for (i = 0 ; i < 12 ; i++) {
1506 band_list[i] = glGenLists(i);
1507 glNewList(band_list[i], GL_COMPILE);
1508 col[0] = colorcodes[i][0];
1509 col[1] = colorcodes[i][1];
1510 col[2] = colorcodes[i][2];
1511 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col);
1512 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
1513 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &shine);
1514 createCylinder(0.1, 0.42, 0, 0);
1520 void bandedCylinder(float radius, float l, GLfloat r, GLfloat g, GLfloat bl,
1521 Band **b, int nbands)
1523 int n; /* band number */
1524 int p = 0; /* prev number + 1; */
1525 GLfloat col[] = {0,0,0,0};
1527 col[0] = r; col[1] = g; col[2] = bl;
1528 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
1529 createCylinder(l, radius, 1, 0); /* body */
1530 for (n = 0 ; n < nbands ; n++) {
1532 glTranslatef(b[n]->pos*l, 0, 0);
1533 col[0] = b[n]->r; col[1] = b[n]->g; col[2] = b[n]->b;
1534 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
1535 createCylinder(b[n]->len*l, radius*1.05, 0, 0); /* band */
1544 static GLfloat col[] = {0, 0.25, 0.05};
1545 static GLfloat col2[] = {0, 0.125, 0.05};
1546 GLfloat col3[] = {0, 0.8, 0};
1547 static GLfloat sx, sy; /* bright spot co-ords */
1548 static int sdir; /* 0 = left-right, 1 = right-left, 2 = up->dn, 3 = dn->up */
1549 static int s = 0; /* if spot is enabled */
1550 static float ds; /* speed of spot */
1553 if (f_rand() < ((rotate) ? 0.05 : 0.01)) {
1554 sdir = RAND_RANGE(0, 4);
1555 ds = RAND_RANGE(0.4, 0.8);
1559 sy = ((int)RAND_RANGE(0, YMAX/2))*2 - YMAX/2;
1563 sy = ((int)RAND_RANGE(0, YMAX/2))*2 - YMAX/2;
1567 sx = ((int)RAND_RANGE(0, XMAX/2))*2 - XMAX/2;
1571 sx = ((int)RAND_RANGE(0, XMAX/2))*2 - XMAX/2;
1576 } else if (!rotate) {
1577 if (col[1] < 0.25) {
1578 col[1] += 0.025; col[2] += 0.005;
1579 col2[1] += 0.015 ; col2[2] += 0.005;
1583 glDisable(GL_LIGHTING);
1587 glTranslatef(sx, sy, -10);
1588 sphere(0.1, 10, 10, 0, 10, 0, 10);
1590 glTranslatef(-ds, 0, 0);
1592 glTranslatef(ds, 0, 0);
1594 glTranslatef(0, ds, 0);
1596 glTranslatef(0, -ds, 0);
1597 sphere(0.05, 10, 10, 0, 10, 0, 10);
1619 } else if (!rotate) {
1621 col[1] -= 0.0025; col[2] -= 0.0005;
1622 col2[1] -= 0.0015 ; col2[2] -= 0.0005;
1625 for (x = -XMAX/2 ; x <= XMAX/2 ; x+= 2) {
1628 glVertex3f(x, YMAX/2, -10);
1629 glVertex3f(x, -YMAX/2, -10);
1631 glVertex3f(x-0.02, YMAX/2, -10);
1632 glVertex3f(x-0.02, -YMAX/2, -10);
1633 glVertex3f(x+0.02, YMAX/2, -10);
1634 glVertex3f(x+0.02, -YMAX/2, -10);
1637 for (y = -YMAX/2 ; y <= YMAX/2 ; y+= 2) {
1640 glVertex3f(-XMAX/2, y, -10);
1641 glVertex3f(XMAX/2, y, -10);
1643 glVertex3f(-XMAX/2, y-0.02, -10);
1644 glVertex3f(XMAX/2, y-0.02, -10);
1645 glVertex3f(-XMAX/2, y+0.02, -10);
1646 glVertex3f(XMAX/2, y+0.02, -10);
1649 glEnable(GL_LIGHTING);
1654 static Component *c[MAX_COMPONENTS];
1656 GLfloat light_sp[] = {0.8, 0.8, 0.8, 1.0};
1657 GLfloat black[] = {0, 0, 0, 1.0};
1658 static GLfloat rotate_angle = 0; /* when 'rotate' is enabled */
1662 for (i = 0 ; i < maxparts ; i++) {
1666 glEnable(GL_LIGHTING);
1667 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
1669 gluLookAt(viewer[0], viewer[1], viewer[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
1672 glRotatef(rotate_angle, 0, 0, 1);
1673 rotate_angle += 0.01 * (float)rotatespeed;
1674 if (rotate_angle >= 360) rotate_angle = 0;
1676 glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
1677 glLightfv(GL_LIGHT0, GL_SPECULAR, light_sp);
1678 glLightfv(GL_LIGHT0, GL_DIFFUSE, light_sp);
1679 glLighti(GL_LIGHT0, GL_CONSTANT_ATTENUATION, (GLfloat)1);
1680 glLighti(GL_LIGHT0, GL_LINEAR_ATTENUATION, (GLfloat)0.5);
1681 glLighti(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, (GLfloat)0);
1683 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, light_sp);
1684 if (f_rand() < 0.05) {
1685 for (j = 0 ; j < maxparts ; j++) {
1687 c[j] = NewComponent();
1693 for (j = 0 ; j < maxparts ; j++) {
1694 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, black);
1695 glMaterialfv(GL_FRONT, GL_EMISSION, black);
1696 glMaterialfv(GL_FRONT, GL_SPECULAR, black);
1698 if (DrawComponent(c[j])) {
1699 free(c[j]); c[j] = NULL;
1707 TexNum * fonttexturealloc (const char *str, float *fg, float *bg)
1709 static char *strings[50]; /* max of 40 textures */
1710 static int w[50], h[50];
1718 for (i = 1 ; i < 50 ; i++) {
1724 for (i = 1 ; i < 50 ; i++) {
1725 if (strings[i] && !strcmp(str, strings[i])) { /* if one matches */
1726 t = malloc(sizeof(TexNum));
1727 t->w = w[i]; t->h = h[i];
1732 /* at this point we need to make the new texture */
1733 ximage = text_to_ximage (modeinfo->xgwa.screen,
1734 modeinfo->xgwa.visual,
1737 for (i = 1 ; strings[i] != NULL ; i++); /* set i to the next unused value */
1738 glBindTexture(GL_TEXTURE_2D, i);
1739 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1740 gluBuild2DMipmaps(GL_TEXTURE_2D, 4, ximage->width, ximage->height, GL_RGBA,
1741 GL_UNSIGNED_BYTE, ximage->data);
1742 t = malloc(sizeof(TexNum));
1743 t->w = ximage->width;
1744 t->h = ximage->height;
1745 w[i] = t->w; h[i] = t->h;
1749 c = malloc(strlen(str)+1);
1750 strncpy(c, str, strlen(str)+1);
1756 /* ensure transparent components are at the end */
1757 void reorder(Component *c[])
1760 Component *c1[MAX_COMPONENTS];
1761 Component *c2[MAX_COMPONENTS];
1764 for (i = 0 ; i < maxparts ; i++) { /* clear old matrix */
1768 for (i = 0 ; i < maxparts ; i++) {
1769 if (c[i] == NULL) continue;
1770 if (c[i]->alpha) { /* transparent parts go to c1 */
1773 } else { /* opaque parts go to c2 */
1777 for (i = 0 ; i < maxparts ; i++) { /* clear old matrix */
1781 for (i = 0 ; i < maxparts ; i++) { /* insert opaque part */
1782 if (c2[i] != NULL) {
1787 for (i = 0 ; i < j ; i++) { /* insert transparent parts */
1793 void reshape_circuit(ModeInfo *mi, int width, int height)
1795 glViewport(0,0,(GLint)width, (GLint) height);
1796 glMatrixMode(GL_PROJECTION);
1798 glFrustum(-1.0,1.0,-1.0,1.0,1.5,35.0);
1799 glMatrixMode(GL_MODELVIEW);
1800 win_h = height; win_w = width;
1804 void init_circuit(ModeInfo *mi)
1806 int screen = MI_SCREEN(mi);
1809 if (circuit == NULL) {
1810 if ((circuit = (Circuit *) calloc(MI_NUM_SCREENS(mi),
1811 sizeof(Circuit))) == NULL)
1814 c = &circuit[screen];
1815 c->window = MI_WINDOW(mi);
1818 if ((c->glx_context = init_GL(mi)) != NULL) {
1819 reshape_circuit(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
1825 glClearColor(0.0,0.0,0.0,0.0);
1826 glShadeModel(GL_SMOOTH);
1827 glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
1828 glEnable(GL_DEPTH_TEST);
1829 glEnable(GL_LIGHTING);
1830 glEnable(GL_LIGHT0);
1831 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1837 void draw_circuit(ModeInfo *mi)
1839 Circuit *c = &circuit[MI_SCREEN(mi)];
1840 Window w = MI_WINDOW(mi);
1841 Display *disp = MI_DISPLAY(mi);
1843 if (!c->glx_context)
1847 glXMakeCurrent(disp, w, *(c->glx_context));
1851 if(mi->fps_p) do_fps(mi);
1853 glXSwapBuffers(disp, w);
1856 void release_circuit(ModeInfo *mi)
1858 if (circuit != NULL) {
1859 (void) free((void *) circuit);