/*
* circuit - Random electronic components floating around
*
- * version 1.3
+ * 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 Ben Buxton (bb@cactii.net)
+ * Copyright (C) 2001,2002 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
#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" \
- "*rotatespeed: 1\n" \
+#define DEFAULTS "*delay: 20000 \n" \
+ "*showFPS: False \n"
# include "xlockmore.h" /* from the xscreensaver distribution */
#else /* !STANDALONE */
#ifdef USE_GL
#include <GL/glu.h>
+#include "font-ximage.h"
+#undef countof
+#define countof(x) (sizeof((x))/sizeof((*x)))
static int maxparts;
static int spin;
static int rotate;
static int rotatespeed;
static int uselight;
+static char *font;
int def_parts = 10;
#undef countof
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" },
+ {"+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" },
+ {"+rotate", ".circuit.rotate", XrmoptionNoArg, "false" },
+ {"-rotate", ".circuit.rotate", XrmoptionNoArg, "true" },
};
static argtype vars[] = {
- {(caddr_t *) &maxparts, "parts", "Parts", DEF_PARTS, t_Int},
- {(caddr_t *) &rotatespeed, "rotatespeed", "Rotatespeed", "1", t_Int},
- {(caddr_t *) &spin, "spin", "Spin", DEF_SPIN, t_Bool},
- {(caddr_t *) &rotate, "rotate", "Rotate", "False", t_Bool},
- {(caddr_t *) &uselight, "light", "Light", "True", t_Bool},
- {(caddr_t *) &seven, "seven", "Seven", DEF_SEVEN, t_Bool},
+ {&maxparts, "parts", "Parts", DEF_PARTS, t_Int},
+ {&font, "font", "Font", "fixed", t_String},
+ {&rotatespeed, "rotatespeed", "Rotatespeed", "1", t_Int},
+ {&spin, "spin", "Spin", DEF_SPIN, t_Bool},
+ {&rotate, "rotate", "Rotate", "False", t_Bool},
+ {&uselight, "light", "Light", "True", t_Bool},
+ {&seven, "seven", "Seven", DEF_SEVEN, t_Bool},
};
ModeSpecOpt circuit_opts = {countof(opts), opts, countof(vars), vars, NULL};
/* width and height of viewport */
#define XMAX 30
-#define YMAX 30
+static int YMAX = 30;
#define MAX_COMPONENTS 30
-#define MOVE_MULT 0.05
+#define MOVE_MULT 0.02
static float f_rand(void) {
return ((float)RAND(10000)/(float)10000);
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 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 {
GLfloat r, g, b; /* body colour */
} Diode;
+static const char * transistortypes[] = {
+ "TIP2955",
+ "TIP32C",
+ "LM 350T",
+ "IRF730",
+ "ULN2577",
+ "7805T",
+ "7912T",
+ "TIP120",
+ "2N6401",
+ "BD239",
+ "2SC1590",
+ "MRF485",
+ "SC141D"
+};
+
+static const char * 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 * smctypes[] = {
+ "1M-",
+ "1K",
+ "1F",
+ "B10",
+ "S14",
+ "Q3",
+ "4A"
+};
+
typedef struct {
int type; /* package type. 0 = to-92, 1 = to-220 */
+ GLfloat tw, th; /* texture dimensions */
+ GLuint tnum; /* texture binding */
} Transistor;
typedef struct {
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;
+ float tw, th; /* texture dimensions for markings */
+ int tnum; /* texture number */
} IC;
/* 7 segment display */
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 */
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);
IC* NewIC(void);
Disp* NewDisp(void);
Fuse *NewFuse(void);
+RCA *NewRCA(void);
+ThreeFive *NewThreeFive(void);
+Switch *NewSwitch(void);
/* we use trig tables to speed things up - 200 calls to sin()
in one frame can be a bit harsh..
}
-void createCylinder (float length, float radius, int endcaps, int half) {
-int a; /* current angle around cylinder */
-int angle, norm;
-float z1, y1, z2, y2, ex;
-int nsegs;
+void createCylinder (float length, float radius, int endcaps, int half)
+{
+ 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)/10;
- nsegs = MAX(nsegs, 6);
+ nsegs = radius*MAX(win_w, 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) {
glNormal3f(0, y1, z1);
glVertex3f(0,y1,z1);
glVertex3f(length,y1,z1);
+ glNormal3f(0, y2, z2);
glVertex3f(length,y2,z2);
glVertex3f(0,y2,z2);
z1=z2;
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)sin_table[(int)a];
z2=radius*(float)cos_table[(int)a];
- glBegin(GL_TRIANGLES);
- glNormal3f(norm, 0, 0);
glVertex3f(ex,0, 0);
glVertex3f(ex,y1,z1);
glVertex3f(ex,y2,z2);
- glEnd();
z1=z2;
y1=y2;
}
+ glEnd();
}
}
glPopMatrix();
}
-void circle(float radius, int segments, int half) {
-float x1 = 0, x2 = 0;
-float y1 = 0, y2 = 0;
-int i, t, s;
+void circle(float radius, int segments, int half)
+{
+ float x1 = 0, x2 = 0;
+ float y1 = 0, y2 = 0;
+ int i, t, s;
if (half) {
t = 270; s = 90;
glEnd();
}
-void wire(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};
-GLfloat shin = 30;
-int n;
+void wire(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};
+ GLfloat shin = 30;
+ int n;
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
glMaterialfv(GL_FRONT, GL_SPECULAR, nospec);
}
-void ring(GLfloat inner, GLfloat outer, int nsegs) {
-GLfloat z1, z2, y1, y2;
-GLfloat Z1, Z2, Y1, Y2;
-int i;
+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;
void sphere(GLfloat r, float stacks, float slices,
int startstack, int endstack, int startslice,
- int endslice) {
-GLfloat d, d1, dr, dr1, Dr, Dr1, D, D1, z1, z2, y1, y2, Y1, Z1, Y2, Z2;
-int a, a1, b, b1, c, c1;
-GLfloat step, sstep;
-
- step = 180/stacks;
- sstep = 360/slices;
- a1 = startstack * step;
- b1 = startslice * sstep;
- y1 = z1 = Y1 = Z1 = 0;
- c = (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];
- 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];
- glNormal3f(D, y1, z1);
- glVertex3f(Dr,y1,z1);
- glVertex3f(Dr,y2,z2);
- glVertex3f(Dr1,Y2,Z2);
- glVertex3f(Dr1,Y1,Z1);
- z1=z2;
- y1=y2;
- Z1=Z2;
- Y1=Y2;
- }
- a1 = a;
- }
- glEnd();
+ int endslice)
+{
+ GLfloat d, d1, dr, dr1, Dr, Dr1, D, D1, z1, z2, y1, y2, Y1, Z1, Y2, Z2;
+ int a, a1, b, b1, c, c1;
+ GLfloat step, sstep;
+
+ step = 180/stacks;
+ sstep = 360/slices;
+ a1 = startstack * step;
+ b1 = startslice * sstep;
+ y1 = z1 = Y1 = Z1 = 0;
+ c = (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];
+ 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];
+ 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);
+ z1=z2;
+ y1=y2;
+ Z1=Z2;
+ Y1=Y2;
+ }
+ a1 = a;
+ }
+ glEnd();
}
-int DrawComponent(Component *c) {
-int ret = 0; /* return 1 if component is freed */
+int DrawComponent(Component *c)
+{
+ int ret = 0; /* return 1 if component is freed */
glPushMatrix();
glTranslatef(c->x, c->y, c->z);
if (c->angle > 0) {
- glRotatef(c->angle, 0, 0, 1);
+ glRotatef(c->angle, c->rotx, c->roty, c->rotz);
}
if (spin) {
glRotatef(c->rdeg, c->rotx, c->roty, c->rotz);
DrawDisp(c->c);
} else if (c->type == 7) {
DrawFuse(c->c);
+ } else if (c->type == 8) {
+ DrawRCA(c->c);
+ } else if (c->type == 9) {
+ DrawThreeFive(c->c);
+ } else if (c->type == 10) {
+ DrawSwitch(c->c);
}
c->x += c->dx * MOVE_MULT;
c->y += c->dy * MOVE_MULT;
glDisable(GL_LIGHT1);
light = 0; 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);
ret = 1;
}
glDisable(GL_NORMALIZE);
return ret;
}
+
/* draw a resistor */
-void DrawResistor(Resistor *r) {
-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;
+void DrawResistor(Resistor *r)
+{
+ 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);
wire(3);
}
-void DrawFuse(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 */
+void DrawRCA(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 */
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);
+ glTranslatef(0.4, 0, 0);
+ createCylinder(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);
+ glTranslatef(-0.9, 0, 0);
+ createCylinder(0.9, 0.25, 0, 0);
+ glTranslatef(0.1, 0, 0);
+ createCylinder(0.2, 0.3, 0, 0);
+ glTranslatef(0.3, 0, 0);
+ createCylinder(0.2, 0.3, 1, 0);
+ glTranslatef(0.3, 0, 0);
+ createCylinder(0.2, 0.3, 1, 0);
+ glPopMatrix();
+}
+
+void DrawSwitch(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 */
+
+ 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); */
+ glPushMatrix();
+ glRotatef(90, 1, 0, 0);
+ glTranslatef(-0.5, -0.4, -0.4);
+ HoledRectangle(0.5, 0.75, 0.1, 0.15, 8);
+ glTranslatef(2, 0, 0);
+ HoledRectangle(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);
+ 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);
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, brown);
+ Rect(-0.2, -0.01, -0.1, 1.4, 0.1, 0.55);
+ glPopMatrix();
+}
+
+
+void DrawFuse(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 */
+
+ 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);
glTranslatef(0.8, 0, 0);
glEnable(GL_BLEND);
glDepthMask(GL_FALSE);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, glass);
glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 40);
createCylinder(2, 0.4, 0, 0);
}
-void DrawCapacitor(Capacitor *c) {
-static GLfloat col[] = {0, 0, 0, 0};
-static GLfloat spec[] = {0.8, 0.8, 0.8, 0};
-GLfloat brown[] = {0.84, 0.5, 0};
-static GLfloat shine = 40;
+void DrawCapacitor(Capacitor *c)
+{
+ static GLfloat col[] = {0, 0, 0, 0};
+ static GLfloat spec[] = {0.8, 0.8, 0.8, 0};
+ GLfloat brown[] = {0.84, 0.5, 0};
+ static GLfloat shine = 40;
glPushMatrix();
if (c->type) {
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, brown);
- sphere(c->width, 20, 20, 0, 5 ,0, 20);
- glTranslatef(1.45*c->width, 0, 0);
- sphere(c->width, 20, 20, 15, 20, 0, 20);
+ sphere(c->width, 15, 15, 0, 4 ,0, 15);
+ glTranslatef(1.35*c->width, 0, 0);
+ sphere(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);
glTranslatef(0, 0, -0.6*c->width);
wire(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);
glVertex3f(3*c->length, 0.82*c->width, 0.1);
glVertex3f(0, 0.82*c->width, 0.1);
glEnd();
- 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);
col[0] = 0.0;
col[1] = 0.2;
col[2] = 0.9;
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col);
- ring(0.6*c->width, 0.8*c->width, 30);
- glTranslatef(0.01, 0.0, 0);
+ glEnable(GL_POLYGON_OFFSET_FILL);
+ glPolygonOffset(1.0, 1.0);
createCylinder(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);
col[0] = 0;
col[1] = 0;
col[2] = 0;
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col);
- glTranslatef(3.01*c->length, 0.0, 0);
+ glTranslatef(3.0*c->length, 0.0, 0);
circle(0.6*c->width, 30, 0);
glTranslatef(0, 0.4*c->width, 0);
wire(3*c->length);
glPopMatrix();
}
-void DrawLED(LED *l) {
-GLfloat col[] = {0, 0, 0, 0.6};
+void DrawLED(LED *l)
+{
+ 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) {
glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, dir);
if (!lighton) {
glLightfv(GL_LIGHT1, GL_SPECULAR, col);
- glLightfv(GL_LIGHT1, GL_AMBIENT, 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);
glDepthMask(GL_FALSE);
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) {
glDisable(GL_LIGHTING);
glColor3fv(col);
}
- sphere(0.3, 10, 10, 5, 10, 0, 10);
+ sphere(0.3, 7, 7, 3, 7, 0, 7);
if (l->light && light) {
glEnable(GL_LIGHTING);
} else {
}
}
}
+
+
+void DrawThreeFive(ThreeFive *d)
+{
+ 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};
+
+ 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);
+ createCylinder(0.7, 0.2, 0, 0);
+ glTranslatef(0.7, 0, 0);
+ createCylinder(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);
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, dark);
+ glTranslatef(0.65, 0, 0);
+ createCylinder(0.15, 0.21, 0, 0);
+ glTranslatef(0.3, 0, 0);
+ createCylinder(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);
+ glPopMatrix();
+}
-void DrawDiode(Diode *d) {
-GLfloat shine = 40;
-GLfloat col[] = {0.3, 0.3, 0.3, 0};
-GLfloat spec[] = {0.7, 0.7, 0.7, 0};
+void DrawDiode(Diode *d)
+{
+ 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);
}
void Rect(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h,
- GLfloat t) {
-GLfloat yh;
-GLfloat xw;
-GLfloat zt;
+ GLfloat t)
+{
+ GLfloat yh;
+ GLfloat xw;
+ GLfloat zt;
yh = y+h; xw = x+w; zt = z - t;
/* IC pins */
-void ICLeg(GLfloat x, GLfloat y, GLfloat z, int dir) {
-
-
+void ICLeg(GLfloat x, GLfloat y, GLfloat z, int dir)
+{
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);
}
-void DrawIC(IC *c) {
-GLfloat w, h, d;
-int z;
-GLfloat col[] = {0.1, 0.1, 0.1, 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;
+void DrawIC(IC *c)
+{
+ 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;
+ float mult, th, size;
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:
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);
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();
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
d = (h*2-0.1) / c->pins;
d*=2;
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, lcol);
for (z = 0 ; z < c->pins/2 ; z++) {
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);
glPopMatrix();
}
-void DrawDisp(Disp *d) {
-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 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 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 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 int nums[10][7] =
+void DrawDisp(Disp *d)
{
- {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 */
-};
-
+ 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 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 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 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 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);
Rect(0, 0, -0.01, 1.8, 2.6, 0.7);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, front);
}
}
-void HoledRectangle(GLfloat w, GLfloat h, GLfloat d, GLfloat radius, int p) {
-int step, a;
-GLfloat x1, y1, x2, y2;
-GLfloat yr, yr1, xr, xr1, side, side1;
-GLfloat nx, ny;
+void HoledRectangle(GLfloat w, GLfloat h, GLfloat d, GLfloat radius, int p)
+{
+ 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;
glEnd();
}
-void DrawTransistor(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};
-GLfloat shin = 30;
+void DrawTransistor(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};
+ GLfloat shin = 30;
glPushMatrix();
glMaterialfv(GL_FRONT, GL_SHININESS, &shin);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col);
- if (t->type == 1) {
+ 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);
+/* 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();
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+ glDepthMask(GL_TRUE);
glTranslatef(-2, 0, -0.2);
wire(2);
glTranslatef(0, 0, 0.2);
wire(2);
glTranslatef(0, 0, 0.2);
wire(2);
- } else {
- Rect(0, 0, 0, 1.5, 1.5, 0.75);
- glTranslatef(0.75, 1.875, -0.5);
+ } 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();
+ 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);
- if (glIsEnabled(GL_NORMALIZE)) glEnable(GL_NORMALIZE);
+ 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);
glMaterialfv(GL_FRONT, GL_SPECULAR, nospec);
glTranslatef(-0.375, -1.875, 0);
wire(2);
glTranslatef(0, 0.375, 0);
wire(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);
+/* 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(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);
+ 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);
+ 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);
}
glPopMatrix();
}
-Component * NewComponent(void) {
-Component *c;
-float rnd;
+Component * NewComponent(void)
+{
+ Component *c;
+ float rnd;
c = malloc(sizeof(Component));
c->angle = RAND_RANGE(0,360);
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;
c->alpha = 0; /* explicitly set to 1 later */
- rnd = f_rand();
- if (rnd < 0.1) {
+ 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 < 0.2) {
+ } else if (rnd < 2) {
c->c = NewDiode();
if (f_rand() < 0.4)
c->norm = 1; /* some diodes shine */
c->type = 1;
- } else if (rnd < 0.3) {
+ } else if (rnd < 3) {
c->c = NewTransistor();
c->norm = 1;
c->type = 2;
- } else if (rnd < 0.4) {
+ } else if (rnd < 4) {
c->c = NewCapacitor();
- if (f_rand() < 0.4)
- c->norm = 1; /* some capacitors shine */
+ c->norm = 1;
c->type = 4;
- } else if (rnd < 0.6) {
+ } else if (rnd < 5) {
c->c = NewIC();
c->type = 5;
- } else if (rnd < 0.7) {
+ c->norm = 1;
+ } else if (rnd < 6) {
c->c = NewLED();
c->type = 3;
c->norm = 1;
c->alpha = 1;
- } else if (rnd < 0.8) {
+ } else if (rnd < 7) {
c->c = NewFuse();
c->norm = 1;
c->type = 7;
c->alpha = 1;
+ } else if (rnd < 8) {
+ c->c = NewRCA();
+ c->norm = 1;
+ c->type = 8;
+ } else if (rnd < 9) {
+ c->c = NewThreeFive();
+ c->norm = 1;
+ c->type = 9;
+ } else if (rnd < 10) {
+ c->c = NewSwitch();
+ c->norm = 1;
+ c->type = 10;
} else {
c->c = NewDisp();
c->type = 6;
return c;
}
-Transistor *NewTransistor(void) {
-Transistor *t;
+Transistor *NewTransistor(void)
+{
+ 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 = (f_rand() < 0.5);
+ 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);
+ }
+ } 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);
+ }
+ } 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);
+ }
+ }
+
return t;
}
-Capacitor *NewCapacitor(void) {
-Capacitor *c;
+Capacitor *NewCapacitor(void)
+{
+ Capacitor *c;
c = malloc(sizeof(Capacitor));
c->type = (f_rand() < 0.5);
c->length = RAND_RANGE(0.5, 1);
c->width = RAND_RANGE(0.5, 1);
} else {
- c->width = RAND_RANGE(1, 2);
+ c->width = RAND_RANGE(0.3, 1);
}
return c;
}
/* 7 segment display */
-Disp *NewDisp(void) {
-Disp *d;
+Disp *NewDisp(void)
+{
+ Disp *d;
d = malloc(sizeof(Disp));
if (seven)
}
-IC *NewIC(void) {
-IC *c;
-int pins;
+IC *NewIC(void)
+{
+ 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));
c->type = 0;
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;
+ 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);
+ }
c->pins = pins;
return c;
}
-LED *NewLED(void) {
-LED *l;
-float r;
+LED *NewLED(void)
+{
+ LED *l;
+ float r;
l = malloc(sizeof(LED));
r = f_rand();
return l;
}
-Fuse *NewFuse(void) {
-Fuse *f;
+Fuse *NewFuse(void)
+{
+ Fuse *f;
f = malloc(sizeof(Fuse));
return f;
}
-Diode *NewDiode(void) {
-Band *b;
-Diode *ret;
+RCA *NewRCA(void)
+{
+ RCA *r;
+
+ r = malloc(sizeof(RCA));
+ r->col = (random() % 10 < 5);
+ return r;
+}
+
+ThreeFive *NewThreeFive(void)
+{
+ ThreeFive *r;
+
+ r = malloc(sizeof(ThreeFive));
+ return r;
+}
+
+Switch *NewSwitch(void)
+{
+ Switch *s;
+
+ s = malloc(sizeof(Switch));
+ s->position = 0;
+ return s;
+}
+
+Diode *NewDiode(void)
+{
+ Band *b;
+ Diode *ret;
ret = malloc(sizeof(Diode));
b = malloc(sizeof(Band));
}
-Resistor * NewResistor(void) {
-int v, m, t; /* value, multiplier, tolerance */
-Resistor *ret;
+Resistor * NewResistor(void)
+{
+ int v, m, t; /* value, multiplier, tolerance */
+ Resistor *ret;
v = RAND(9);
m = RAND(5);
return ret;
}
-void makebandlist(void) {
-int i;
-GLfloat col[] = {0,0,0,0};
-GLfloat spec[] = {0.8,0.8,0.8,0};
-GLfloat shine = 40;
+void makebandlist(void)
+{
+ 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++) {
band_list[i] = glGenLists(i);
void bandedCylinder(float radius, float l, GLfloat r, GLfloat g, GLfloat bl,
- Band **b, int nbands) {
-int n; /* band number */
-int p = 0; /* prev number + 1; */
-GLfloat col[] = {0,0,0,0};
+ Band **b, int nbands)
+{
+ 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);
}
}
-void drawgrid(void) {
-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 */
+void drawgrid(void)
+{
+ 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)) {
glEnable(GL_LIGHTING);
}
-void display(void) {
-static Component *c[MAX_COMPONENTS];
-static int i = 0;
-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;
+void display(void)
+{
+ static Component *c[MAX_COMPONENTS];
+ static int i = 0;
+ 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++) {
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[]) {
-int i, j, k;
-Component *c1[MAX_COMPONENTS];
-Component *c2[MAX_COMPONENTS];
+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 */
void reshape_circuit(ModeInfo *mi, int width, int height)
{
-
+ GLfloat h = (GLfloat) height / (GLfloat) width;
glViewport(0,0,(GLint)width, (GLint) height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
- glFrustum(-1.0,1.0,-1.0,1.0,1.5,35.0);
+ glFrustum(-1.0,1.0,-h,h,1.5,35.0);
glMatrixMode(GL_MODELVIEW);
win_h = height; win_w = width;
+ YMAX = XMAX * h;
}
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
make_tables();
makebandlist();
}
-void draw_circuit(ModeInfo *mi) {
-Circuit *c = &circuit[MI_SCREEN(mi)];
-Window w = MI_WINDOW(mi);
-Display *disp = MI_DISPLAY(mi);
+void draw_circuit(ModeInfo *mi)
+{
+ Circuit *c = &circuit[MI_SCREEN(mi)];
+ Window w = MI_WINDOW(mi);
+ Display *disp = MI_DISPLAY(mi);
if (!c->glx_context)
return;
+ modeinfo = mi;
glXMakeCurrent(disp, w, *(c->glx_context));
glXSwapBuffers(disp, w);
}
-void release_circuit(ModeInfo *mi) {
-
+void release_circuit(ModeInfo *mi)
+{
if (circuit != NULL) {
(void) free((void *) circuit);
circuit = NULL;