~ubuntu-branches/ubuntu/dapper/xscreensaver/dapper

« back to all changes in this revision

Viewing changes to hacks/glx/circuit.c

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Grawert
  • Date: 2005-10-11 21:00:42 UTC
  • mfrom: (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20051011210042-u7q6zslgevdxspr3
Tags: 4.21-4ubuntu17
updated pt_BR again, fixed to UTF-8 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * circuit - Random electronic components floating around
3
3
 *
4
 
 * version 1.3
 
4
 * version 1.4
5
5
 *
6
6
 * Since version 1.1: added to-220 transistor, added fuse
7
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
 
10
 * Since version 1.4: Added RCA connector, 3.5mm connector, slide switch,
 
11
 *                    surface mount, to-92 markings. Fixed ~5min crash.
 
12
 *                    Better LED illumination. Other minor changes.
8
13
 *
9
 
 * Copyright (C) 2001 Ben Buxton (bb@cactii.net)
 
14
 * Copyright (C) 2001,2002 Ben Buxton (bb@cactii.net)
10
15
 *
11
16
 * Permission to use, copy, modify, distribute, and sell this software and its
12
17
 * documentation for any purpose is hereby granted without fee, provided that
41
46
#define DEF_SEVEN       "False"
42
47
#define DEF_PARTS       "10"
43
48
 
44
 
 
45
 
#define DEFAULTS        "*parts:      " DEF_PARTS " \n" \
46
 
                        "*spin:       " DEF_SPIN   "\n" \
47
 
                        "*delay:       20000       \n" \
48
 
                        "*showFPS:       False       \n" \
49
 
                        "*seven:      " DEF_SEVEN  "\n" \
50
 
                        "*light:      True  \n" \
51
 
                        "*rotate:      False\n" \
52
 
                        "*rotatespeed:      1\n" \
 
49
#define DEFAULTS        "*delay:   20000 \n" \
 
50
                        "*showFPS: False \n"
53
51
 
54
52
# include "xlockmore.h"                         /* from the xscreensaver distribution */
55
53
#else  /* !STANDALONE */
64
62
#ifdef USE_GL
65
63
 
66
64
#include <GL/glu.h>
 
65
#include "font-ximage.h"
67
66
 
 
67
#undef countof
 
68
#define countof(x) (sizeof((x))/sizeof((*x)))
68
69
 
69
70
static int maxparts;
70
71
static int spin;
72
73
static int rotate;
73
74
static int rotatespeed;
74
75
static int uselight;
 
76
static char *font;
75
77
int def_parts = 10;
76
78
 
77
79
#undef countof
79
81
 
80
82
static XrmOptionDescRec opts[] = {
81
83
  {"-parts", ".circuit.parts", XrmoptionSepArg, "10" },
 
84
  {"-font", ".circuit.font", XrmoptionSepArg, "fixed" },
82
85
  {"-rotate-speed", ".circuit.rotatespeed", XrmoptionSepArg, "1" },
83
 
  {"+spin", ".circuit.spin", XrmoptionNoArg, (caddr_t) "false" },
84
 
  {"-spin", ".circuit.spin", XrmoptionNoArg, (caddr_t) "true" },
85
 
  {"+light", ".circuit.light", XrmoptionNoArg, (caddr_t) "false" },
86
 
  {"-light", ".circuit.light", XrmoptionNoArg, (caddr_t) "true" },
87
 
  {"+seven", ".circuit.seven", XrmoptionNoArg, (caddr_t) "false" },
88
 
  {"-seven", ".circuit.seven", XrmoptionNoArg, (caddr_t) "true" },
89
 
  {"+rotate", ".circuit.rotate", XrmoptionNoArg, (caddr_t) "false" },
90
 
  {"-rotate", ".circuit.rotate", XrmoptionNoArg, (caddr_t) "true" },
 
86
  {"+spin", ".circuit.spin", XrmoptionNoArg, "false" },
 
87
  {"-spin", ".circuit.spin", XrmoptionNoArg, "true" },
 
88
  {"+light", ".circuit.light", XrmoptionNoArg, "false" },
 
89
  {"-light", ".circuit.light", XrmoptionNoArg, "true" },
 
90
  {"+seven", ".circuit.seven", XrmoptionNoArg, "false" },
 
91
  {"-seven", ".circuit.seven", XrmoptionNoArg, "true" },
 
92
  {"+rotate", ".circuit.rotate", XrmoptionNoArg, "false" },
 
93
  {"-rotate", ".circuit.rotate", XrmoptionNoArg, "true" },
91
94
};
92
95
 
93
96
static argtype vars[] = {
94
 
  {(caddr_t *) &maxparts, "parts", "Parts", DEF_PARTS, t_Int},
95
 
  {(caddr_t *) &rotatespeed, "rotatespeed", "Rotatespeed", "1", t_Int},
96
 
  {(caddr_t *) &spin, "spin", "Spin", DEF_SPIN, t_Bool},
97
 
  {(caddr_t *) &rotate, "rotate", "Rotate", "False", t_Bool},
98
 
  {(caddr_t *) &uselight, "light", "Light", "True", t_Bool},
99
 
  {(caddr_t *) &seven, "seven", "Seven", DEF_SEVEN, t_Bool},
 
97
  {&maxparts, "parts", "Parts", DEF_PARTS, t_Int},
 
98
  {&font, "font", "Font", "fixed", t_String},
 
99
  {&rotatespeed, "rotatespeed", "Rotatespeed", "1", t_Int},
 
100
  {&spin, "spin", "Spin", DEF_SPIN, t_Bool},
 
101
  {&rotate, "rotate", "Rotate", "False", t_Bool},
 
102
  {&uselight, "light", "Light", "True", t_Bool},
 
103
  {&seven, "seven", "Seven", DEF_SEVEN, t_Bool},
100
104
};
101
105
 
102
106
ModeSpecOpt circuit_opts = {countof(opts), opts, countof(vars), vars, NULL};
133
137
/* width and height of viewport */
134
138
 
135
139
#define XMAX 30
136
 
#define YMAX 30
 
140
static int YMAX = 30;
137
141
 
138
142
#define MAX_COMPONENTS 30
139
143
 
140
 
#define MOVE_MULT 0.05
 
144
#define MOVE_MULT 0.02
141
145
 
142
146
static float f_rand(void) {
143
147
   return ((float)RAND(10000)/(float)10000);
149
153
int light = 0;
150
154
int lighton = 0;
151
155
 
 
156
/* stores refs to textures */
 
157
static int s_refs[50];
 
158
 
152
159
static GLfloat viewer[] = {0.0, 0.0, 14.0};
153
160
static GLfloat lightpos[] = {7.0, 7.0, 15, 1.0};
154
161
 
156
163
float cos_table[720];
157
164
float tan_table[720];
158
165
 
 
166
ModeInfo *modeinfo;
 
167
 
 
168
/* used for allocating font textures */
 
169
typedef struct {
 
170
  int num; /* index number */
 
171
  int w;   /* width */
 
172
  int h;   /* height */
 
173
} TexNum;
159
174
 
160
175
/* Represents a band on a resistor/diode/etc */
161
176
typedef struct {
174
189
  GLfloat r, g, b; /* body colour */
175
190
} Diode;
176
191
 
 
192
static const char * transistortypes[] = {
 
193
  "TIP2955",
 
194
  "TIP32C",
 
195
  "LM 350T",
 
196
  "IRF730",
 
197
  "ULN2577",
 
198
  "7805T",
 
199
  "7912T",
 
200
  "TIP120",
 
201
  "2N6401",
 
202
  "BD239",
 
203
  "2SC1590",
 
204
  "MRF485",
 
205
  "SC141D"
 
206
};
 
207
 
 
208
static const char * to92types[] = {
 
209
  "C\n548",
 
210
  "C\n848",
 
211
  "74\nL05",
 
212
  "C\n858",
 
213
  "BC\n212L",
 
214
  "BC\n640",
 
215
  "BC\n337",
 
216
  "BC\n338",
 
217
  "S817",
 
218
  "78\nL12",
 
219
  "TL\n431",
 
220
  "LM\n35DZ",
 
221
};
 
222
 
 
223
static const char * smctypes[] = {
 
224
  "1M-",
 
225
  "1K",
 
226
  "1F",
 
227
  "B10",
 
228
  "S14",
 
229
  "Q3",
 
230
  "4A"
 
231
};
 
232
 
177
233
typedef struct {
178
234
  int type; /* package type. 0 = to-92, 1 = to-220 */
 
235
  GLfloat tw, th; /* texture dimensions */
 
236
  GLuint tnum; /* texture binding */
179
237
} Transistor;
180
238
 
181
239
typedef struct {
189
247
  float length; /* length of an electro */
190
248
} Capacitor;
191
249
 
 
250
/* 3.5 mm plug */
 
251
typedef struct {
 
252
  int blah;
 
253
} ThreeFive;
 
254
 
 
255
/* slide switch */
 
256
typedef struct {
 
257
  int position;
 
258
} Switch;
 
259
 
 
260
typedef struct {
 
261
  int pins;
 
262
  const char *val;
 
263
} ICTypes;
 
264
 
 
265
static const ICTypes ictypes[] = {
 
266
  {8, "NE 555"},
 
267
  {8, "LM 386N"},
 
268
  {8, "ADC0831"},
 
269
  {8, "LM 383T"},
 
270
  {8, "TL071"},
 
271
  {8, "LM 311"},
 
272
  {8, "LM393"},
 
273
  {8, "LM 3909"},
 
274
 
 
275
  {14, "LM 380N"},
 
276
  {14, "NE 556"},
 
277
  {14, "TL074"},
 
278
  {14, "LM324"},
 
279
  {14, "LM339"},
 
280
  {14, "MC1488"},
 
281
  {14, "MC1489"},
 
282
  {14, "LM1877-9"},
 
283
  {14, "4011"},
 
284
  {14, "4017"},
 
285
  {14, "4013"},
 
286
  {14, "4024"},
 
287
  {14, "4066"},
 
288
 
 
289
  {16, "4076"},
 
290
  {16, "4049"},
 
291
  {16, "4094"},
 
292
  {16, "4043"},
 
293
  {16, "4510"},
 
294
  {16, "4511"},
 
295
  {16, "4035"},
 
296
  {16, "RS232"},
 
297
  {16, "MC1800"},
 
298
  {16, "ULN2081"},
 
299
  {16, "UDN2953"},
 
300
 
 
301
  {24, "ISD1416P"},
 
302
  {24, "4515"},
 
303
  {24, "TMS6264L"},
 
304
  {24, "MC146818"}
 
305
};
 
306
 
192
307
typedef struct {
193
308
  int type; /* 0 = DIL, 1 = flat square */
194
309
  int pins; 
 
310
  float tw, th; /* texture dimensions for markings */
 
311
  int tnum; /* texture number */
195
312
} IC;
196
313
 
197
314
/* 7 segment display */
205
322
} Fuse;
206
323
 
207
324
typedef struct {
 
325
  GLfloat l, w;
 
326
  int col;
 
327
} RCA;
 
328
 
 
329
typedef struct {
208
330
  GLfloat x, y, z; /* current co-ordinates */
209
331
  GLfloat dx, dy, dz; /* current direction */
210
332
  GLfloat rotx, roty, rotz; /* rotation vector */
258
380
void DrawCapacitor(Capacitor *);
259
381
void DrawDisp(Disp *);
260
382
void DrawFuse(Fuse *);
 
383
void DrawRCA(RCA *);
 
384
void DrawThreeFive(ThreeFive *);
 
385
void DrawSwitch(Switch *);
261
386
 
 
387
void freetexture(GLuint);
262
388
void reorder(Component *[]);
263
389
void circle(float, int,int);
264
390
void bandedCylinder(float, float , GLfloat, GLfloat , GLfloat,  Band **, int);
 
391
TexNum *fonttexturealloc(const char *, float *, float *);
 
392
void Rect(GLfloat , GLfloat , GLfloat, GLfloat , GLfloat ,GLfloat);
 
393
void ICLeg(GLfloat, GLfloat, GLfloat, int);
 
394
void HoledRectangle(GLfloat, GLfloat, GLfloat, GLfloat, int);
265
395
Resistor *NewResistor(void);
266
396
Diode *NewDiode(void);
267
397
Transistor *NewTransistor(void);
270
400
IC* NewIC(void);
271
401
Disp* NewDisp(void);
272
402
Fuse *NewFuse(void);
 
403
RCA *NewRCA(void);
 
404
ThreeFive *NewThreeFive(void);
 
405
Switch *NewSwitch(void);
273
406
 
274
407
/* we use trig tables to speed things up - 200 calls to sin()
275
408
 in one frame can be a bit harsh..
292
425
}
293
426
 
294
427
 
295
 
void createCylinder (float length, float radius, int endcaps, int half) {
296
 
int a; /* current angle around cylinder */
297
 
int angle, norm;
298
 
float z1, y1, z2, y2, ex;
299
 
int nsegs;
 
428
void createCylinder (float length, float radius, int endcaps, int half) 
 
429
{
 
430
  int a; /* current angle around cylinder */
 
431
  int angle, norm;
 
432
  float z1, y1, z2, y2,ex;
 
433
  int step;
 
434
  int nsegs;
300
435
 
301
436
  glPushMatrix();
302
 
  nsegs = radius*MAX(win_w, win_h)/10;
303
 
  nsegs = MAX(nsegs, 6);
 
437
  nsegs = radius*MAX(win_w, win_h)/20;
 
438
  nsegs = MAX(nsegs, 4);
304
439
  if (nsegs % 2)
305
440
     nsegs += 1;
306
441
  angle = (half) ? (180 - 90/nsegs) : 374;
 
442
  step = angle/nsegs;
307
443
  z1 = radius; y1 = 0;
308
444
  glBegin(GL_QUADS);
309
445
  for (a = 0 ; a <= angle ; a+= angle/nsegs) {
312
448
      glNormal3f(0, y1, z1);
313
449
      glVertex3f(0,y1,z1);
314
450
      glVertex3f(length,y1,z1);
 
451
      glNormal3f(0, y2, z2);
315
452
      glVertex3f(length,y2,z2);
316
453
      glVertex3f(0,y2,z2);
317
454
    z1=z2;
331
468
    for(ex = 0 ; ex <= length ; ex += length) {
332
469
      z1 = radius; y1 = 0;
333
470
      norm = (ex == length) ? 1 : -1;
 
471
      glBegin(GL_TRIANGLES);
 
472
      glNormal3f(norm, 0, 0);
334
473
      for (a = 0 ; a <= angle ; a+= angle/nsegs) {
335
474
        y2=radius*(float)sin_table[(int)a];
336
475
        z2=radius*(float)cos_table[(int)a];
337
 
        glBegin(GL_TRIANGLES);
338
 
          glNormal3f(norm, 0, 0);
339
476
          glVertex3f(ex,0, 0);
340
477
          glVertex3f(ex,y1,z1);
341
478
          glVertex3f(ex,y2,z2);
342
 
        glEnd();
343
479
        z1=z2;
344
480
        y1=y2;
345
481
      }
 
482
      glEnd();
346
483
    }
347
484
  }
348
485
  glPopMatrix();
349
486
}
350
487
 
351
 
void circle(float radius, int segments, int half) {
352
 
float x1 = 0, x2 = 0;
353
 
float y1 = 0, y2 = 0;
354
 
int i, t, s;
 
488
void circle(float radius, int segments, int half)
 
489
{
 
490
  float x1 = 0, x2 = 0;
 
491
  float y1 = 0, y2 = 0;
 
492
  int i, t, s;
355
493
 
356
494
  if (half) {
357
495
    t = 270; s = 90;
375
513
  glEnd();
376
514
}
377
515
 
378
 
void wire(float len) {
379
 
static GLfloat col[] = {0.3, 0.3, 0.3, 1.0};
380
 
static GLfloat spec[] = {0.9, 0.9, 0.9, 1.0};
381
 
static GLfloat nospec[] = {0.4, 0.4, 0.4, 1.0};
382
 
GLfloat shin = 30;
383
 
int n;
 
516
void wire(float len)
 
517
{
 
518
  static GLfloat col[] = {0.3, 0.3, 0.3, 1.0};
 
519
  static GLfloat spec[] = {0.9, 0.9, 0.9, 1.0};
 
520
  static GLfloat nospec[] = {0.4, 0.4, 0.4, 1.0};
 
521
  GLfloat shin = 30;
 
522
  int n;
384
523
 
385
524
  glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
386
525
  glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
392
531
  glMaterialfv(GL_FRONT, GL_SPECULAR, nospec);
393
532
}
394
533
 
395
 
void ring(GLfloat inner, GLfloat outer, int nsegs) {
396
 
GLfloat z1, z2, y1, y2;
397
 
GLfloat Z1, Z2, Y1, Y2;
398
 
int i;
 
534
void ring(GLfloat inner, GLfloat outer, int nsegs)
 
535
{
 
536
  GLfloat z1, z2, y1, y2;
 
537
  GLfloat Z1, Z2, Y1, Y2;
 
538
  int i;
399
539
 
400
540
  z1 = inner; y1 = 0;
401
541
  Z1 = outer; Y1 = 0;
422
562
 
423
563
void sphere(GLfloat r, float stacks, float slices,
424
564
             int startstack, int endstack, int startslice,
425
 
             int endslice) {
426
 
GLfloat d, d1, dr, dr1, Dr, Dr1, D, D1, z1, z2, y1, y2, Y1, Z1, Y2, Z2;
427
 
int a, a1, b, b1, c, c1;
428
 
GLfloat step, sstep;
 
565
             int endslice)
 
566
{
 
567
  GLfloat d, d1, dr, dr1, Dr, Dr1, D, D1, z1, z2, y1, y2, Y1, Z1, Y2, Z2;
 
568
  int a, a1, b, b1, c, c1;
 
569
  GLfloat step, sstep;
429
570
 
430
 
      step = 180/stacks;
431
 
      sstep = 360/slices;
432
 
      a1 = startstack * step;
433
 
      b1 = startslice * sstep;
434
 
      y1 = z1 = Y1 = Z1 = 0;
435
 
      c = (endslice / slices) * 360;
436
 
      c1 = (endstack/stacks)*180;
437
 
      glBegin(GL_QUADS);
438
 
      for (a = startstack * step ; a <= c1 ; a+= step) {
439
 
        d=sin_table[a];
440
 
        d1=sin_table[a1];
441
 
        D=cos_table[a];
442
 
        D1=cos_table[a1];
443
 
        dr = d * r;
444
 
        dr1 = d1 * r;
445
 
        Dr = D * r;
446
 
        Dr1 = D1 * r;
447
 
        for (b = b1 ; b <= c ; b+= sstep) {
448
 
          y2=dr*sin_table[b];
449
 
          z2=dr*cos_table[b];
450
 
          Y2=dr1*sin_table[b];
451
 
          Z2=dr1*cos_table[b];
452
 
            glNormal3f(D, y1, z1);
453
 
            glVertex3f(Dr,y1,z1);
454
 
            glVertex3f(Dr,y2,z2);
455
 
            glVertex3f(Dr1,Y2,Z2);
456
 
            glVertex3f(Dr1,Y1,Z1);
457
 
          z1=z2;
458
 
          y1=y2;
459
 
          Z1=Z2;
460
 
          Y1=Y2;
461
 
        }
462
 
        a1 = a;
463
 
     }
464
 
     glEnd();
 
571
  step = 180/stacks;
 
572
  sstep = 360/slices;
 
573
  a1 = startstack * step;
 
574
  b1 = startslice * sstep;
 
575
  y1 = z1 = Y1 = Z1 = 0;
 
576
  c = (endslice / slices) * 360;
 
577
  c1 = (endstack/stacks)*180;
 
578
  glBegin(GL_QUADS);
 
579
  for (a = startstack * step ; a <= c1 ; a+= step) {
 
580
    d=sin_table[a];
 
581
    d1=sin_table[a1];
 
582
    D=cos_table[a];
 
583
    D1=cos_table[a1];
 
584
    dr = d * r;
 
585
    dr1 = d1 * r;
 
586
    Dr = D * r;
 
587
    Dr1 = D1 * r;
 
588
    for (b = b1 ; b <= c ; b+= sstep) {
 
589
      y2=dr*sin_table[b];
 
590
      z2=dr*cos_table[b];
 
591
      Y2=dr1*sin_table[b];
 
592
      Z2=dr1*cos_table[b];
 
593
        glNormal3f(Dr, y1, z1);
 
594
        glVertex3f(Dr,y1,z1);
 
595
        glNormal3f(Dr, y2, z2);
 
596
        glVertex3f(Dr,y2,z2);
 
597
        glNormal3f(Dr1, Y2, Z2);
 
598
        glVertex3f(Dr1,Y2,Z2);
 
599
        glNormal3f(Dr1, Y1, Z1);
 
600
        glVertex3f(Dr1,Y1,Z1);
 
601
      z1=z2;
 
602
      y1=y2;
 
603
      Z1=Z2;
 
604
      Y1=Y2;
 
605
    }
 
606
    a1 = a;
 
607
  }
 
608
  glEnd();
465
609
}
466
610
 
467
 
int DrawComponent(Component *c) {
468
 
int ret = 0; /* return 1 if component is freed */
 
611
int DrawComponent(Component *c)
 
612
{
 
613
  int ret = 0; /* return 1 if component is freed */
469
614
 
470
615
   glPushMatrix();
471
616
   glTranslatef(c->x, c->y, c->z);
472
617
     if (c->angle > 0) {
473
 
        glRotatef(c->angle, 0, 0, 1);
 
618
        glRotatef(c->angle, c->rotx, c->roty, c->rotz);
474
619
     }
475
620
   if (spin) {
476
621
     glRotatef(c->rdeg, c->rotx, c->roty, c->rotz);
504
649
     DrawDisp(c->c);
505
650
   } else if (c->type == 7) {
506
651
     DrawFuse(c->c);
 
652
   } else if (c->type == 8) {
 
653
     DrawRCA(c->c);
 
654
   } else if (c->type == 9) {
 
655
     DrawThreeFive(c->c);
 
656
   } else if (c->type == 10) {
 
657
     DrawSwitch(c->c);
507
658
   }
508
659
   c->x += c->dx * MOVE_MULT;
509
660
   c->y += c->dy * MOVE_MULT;
513
664
          glDisable(GL_LIGHT1);
514
665
          light = 0; lighton = 0;
515
666
        }
 
667
        if (c->type == 5) {
 
668
          if (((IC *)c->c)->tnum)
 
669
            freetexture(((IC *)c->c)->tnum);
 
670
        }
 
671
        if (c->type == 2) {
 
672
          if (((Transistor *)c->c)->tnum)
 
673
            freetexture(((Transistor *)c->c)->tnum);
 
674
        }
 
675
        if (c->type == 1)
 
676
          free(((Diode *)c->c)->band); /* remember to free diode band */
516
677
        free(c->c);
517
678
        ret = 1;
518
679
   }
521
682
   glDisable(GL_NORMALIZE);
522
683
   return ret;
523
684
}
 
685
 
524
686
/* draw a resistor */
525
687
 
526
 
void DrawResistor(Resistor *r) {
527
 
int i;
528
 
GLfloat col[] = {0.74, 0.62, 0.46, 1.0};
529
 
GLfloat spec[] = {0.8, 0.8, 0.8, 1.0};
530
 
GLfloat shine = 30;
 
688
void DrawResistor(Resistor *r)
 
689
{
 
690
  int i;
 
691
  GLfloat col[] = {0.74, 0.62, 0.46, 1.0};
 
692
  GLfloat spec[] = {0.8, 0.8, 0.8, 1.0};
 
693
  GLfloat shine = 30;
531
694
 
532
695
   glTranslatef(-4, 0, 0);
533
696
   wire(3);
546
709
   wire(3);
547
710
}
548
711
 
549
 
void DrawFuse(Fuse *f) {
550
 
static GLfloat col[] = {0.5, 0.5, 0.5, 1.0}; /* endcaps */
551
 
static GLfloat glass[] = {0.4, 0.4, 0.4, 0.3}; /* glass */
552
 
static GLfloat spec[] = {1, 1, 1, 1}; /* glass */
553
 
 
554
 
   glPushMatrix();
 
712
void DrawRCA(RCA *rca)
 
713
{
 
714
  static GLfloat col[] = {0.6, 0.6, 0.6, 1.0}; /* metal */
 
715
  static GLfloat red[] = {1.0, 0.0, 0.0, 1.0}; /* red */
 
716
  static GLfloat white[] = {1.0, 1.0, 1.0, 1.0}; /* white */
 
717
  static GLfloat spec[] = {1, 1, 1, 1}; /* glass */
 
718
 
 
719
   glPushMatrix();
 
720
   glTranslatef(0.3, 0, 0);
 
721
   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
 
722
   glMateriali(GL_FRONT, GL_SHININESS, 40);
 
723
   glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
 
724
   createCylinder(0.7, 0.45, 0, 0);
 
725
   glTranslatef(0.4, 0, 0);
 
726
   createCylinder(0.9, 0.15, 1, 0);
 
727
   glTranslatef(-1.9, 0, 0);
 
728
   glMateriali(GL_FRONT, GL_SHININESS, 20);
 
729
   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, rca->col ? white : red);
 
730
   createCylinder(1.5, 0.6, 1, 0);
 
731
   glTranslatef(-0.9, 0, 0);
 
732
   createCylinder(0.9, 0.25, 0, 0);
 
733
   glTranslatef(0.1, 0, 0);
 
734
   createCylinder(0.2, 0.3, 0, 0);
 
735
   glTranslatef(0.3, 0, 0);
 
736
   createCylinder(0.2, 0.3, 1, 0);
 
737
   glTranslatef(0.3, 0, 0);
 
738
   createCylinder(0.2, 0.3, 1, 0);
 
739
   glPopMatrix();
 
740
}
 
741
 
 
742
void DrawSwitch(Switch *f)
 
743
{
 
744
  static GLfloat col[] = {0.6, 0.6, 0.6, 0}; /* metal */
 
745
  static GLfloat dark[] = {0.1, 0.1, 0.1, 1.0}; /* dark */
 
746
  static GLfloat brown[] = {0.69, 0.32, 0, 1.0}; /* brown */
 
747
  static GLfloat spec[] = {0.9, 0.9, 0.9, 1}; /* shiny */
 
748
 
 
749
   glPushMatrix();
 
750
   glMaterialfv(GL_FRONT, GL_DIFFUSE, col);
 
751
   glMaterialfv(GL_FRONT, GL_AMBIENT, dark);
 
752
   glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
 
753
   glMateriali(GL_FRONT, GL_SHININESS, 90);
 
754
   Rect(-0.25, 0, 0, 1.5, 0.5, 0.75);
 
755
/* Rect(-0.5, 0.5, 0, 2, 0.1, 0.75); */
 
756
   glPushMatrix();
 
757
   glRotatef(90, 1, 0, 0);
 
758
   glTranslatef(-0.5, -0.4, -0.4);
 
759
   HoledRectangle(0.5, 0.75, 0.1, 0.15, 8);
 
760
   glTranslatef(2, 0, 0);
 
761
   HoledRectangle(0.5, 0.75, 0.1, 0.15, 8);
 
762
   glPopMatrix();
 
763
   Rect(0.1, -0.4, -0.25, 0.1, 0.4, 0.05);
 
764
   Rect(0.5, -0.4, -0.25, 0.1, 0.4, 0.05);
 
765
   Rect(0.9, -0.4, -0.25, 0.1, 0.4, 0.05);
 
766
   Rect(0.1, -0.4, -0.5, 0.1, 0.4, 0.05);
 
767
   Rect(0.5, -0.4, -0.5, 0.1, 0.4, 0.05);
 
768
   Rect(0.9, -0.4, -0.5, 0.1, 0.4, 0.05);
 
769
   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, dark);
 
770
   glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
 
771
   Rect(0, 0.5, -0.1, 1, 0.05, 0.5);
 
772
   Rect(0, 0.6, -0.1, 0.5, 0.6, 0.5);
 
773
   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, brown);
 
774
   Rect(-0.2, -0.01, -0.1, 1.4, 0.1, 0.55);
 
775
   glPopMatrix();
 
776
}
 
777
 
 
778
 
 
779
void DrawFuse(Fuse *f)
 
780
{
 
781
  static GLfloat col[] = {0.5, 0.5, 0.5, 1.0}; /* endcaps */
 
782
  static GLfloat glass[] = {0.4, 0.4, 0.4, 0.3}; /* glass */
 
783
  static GLfloat spec[] = {1, 1, 1, 1}; /* glass */
 
784
 
 
785
   glPushMatrix();
 
786
   glTranslatef(-1.8, 0, 0);
555
787
   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
556
788
   glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
557
789
   glMateriali(GL_FRONT, GL_SHININESS, 40);
559
791
   glTranslatef(0.8, 0, 0);
560
792
   glEnable(GL_BLEND);
561
793
   glDepthMask(GL_FALSE);
562
 
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
563
794
   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, glass);
564
795
   glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 40);
565
796
   createCylinder(2, 0.4, 0, 0);
578
809
}
579
810
 
580
811
 
581
 
void DrawCapacitor(Capacitor *c) {
582
 
static GLfloat col[] = {0, 0, 0, 0};
583
 
static GLfloat spec[] = {0.8, 0.8, 0.8, 0};
584
 
GLfloat brown[] = {0.84, 0.5, 0};
585
 
static GLfloat shine = 40;
 
812
void DrawCapacitor(Capacitor *c)
 
813
{
 
814
  static GLfloat col[] = {0, 0, 0, 0};
 
815
  static GLfloat spec[] = {0.8, 0.8, 0.8, 0};
 
816
  GLfloat brown[] = {0.84, 0.5, 0};
 
817
  static GLfloat shine = 40;
586
818
 
587
819
  glPushMatrix();
588
820
  if (c->type) {
589
821
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, brown);
590
 
    sphere(c->width, 20, 20, 0, 5 ,0, 20);
591
 
    glTranslatef(1.45*c->width, 0, 0);
592
 
    sphere(c->width, 20, 20, 15, 20, 0, 20);
 
822
    sphere(c->width, 15, 15, 0, 4 ,0, 15);
 
823
    glTranslatef(1.35*c->width, 0, 0);
 
824
    sphere(c->width, 15, 15, 11, 15, 0, 15);
593
825
    glRotatef(90, 0, 0, 1);
594
826
    glTranslatef(0, 0.7*c->width, 0.3*c->width);
595
827
    wire(3*c->width);
596
828
    glTranslatef(0, 0, -0.6*c->width);
597
829
    wire(3*c->width);
598
830
  } else {
 
831
    glTranslatef(0-c->length*2, 0, 0);
599
832
    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col);
600
833
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
601
834
    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &shine);
605
838
     glVertex3f(3*c->length, 0.82*c->width, 0.1);
606
839
     glVertex3f(0, 0.82*c->width, 0.1);
607
840
    glEnd();
608
 
    col[0] = 0.7;
609
 
    col[1] = 0.7;
610
 
    col[2] = 0.7;
611
 
    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col);
612
 
    circle(0.6*c->width, 30, 0);
613
841
    col[0] = 0.0;
614
842
    col[1] = 0.2;
615
843
    col[2] = 0.9;
616
844
    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col);
617
 
    ring(0.6*c->width, 0.8*c->width, 30);
618
 
    glTranslatef(0.01, 0.0, 0);
 
845
    glEnable(GL_POLYGON_OFFSET_FILL);
 
846
    glPolygonOffset(1.0, 1.0);
619
847
    createCylinder(3.0*c->length, 0.8*c->width, 1, 0);
 
848
    glDisable(GL_POLYGON_OFFSET_FILL);
 
849
    col[0] = 0.7;
 
850
    col[1] = 0.7;
 
851
    col[2] = 0.7;
 
852
    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col);
 
853
    circle(0.6*c->width, 30, 0);
620
854
    col[0] = 0;
621
855
    col[1] = 0;
622
856
    col[2] = 0;
623
857
    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col);
624
 
    glTranslatef(3.01*c->length, 0.0, 0);
 
858
    glTranslatef(3.0*c->length, 0.0, 0);
625
859
    circle(0.6*c->width, 30, 0);
626
860
    glTranslatef(0, 0.4*c->width, 0);
627
861
    wire(3*c->length);
631
865
  glPopMatrix();
632
866
}
633
867
 
634
 
void DrawLED(LED *l) {
635
 
GLfloat col[] = {0, 0, 0, 0.6};
 
868
void DrawLED(LED *l)
 
869
{
 
870
  GLfloat col[] = {0, 0, 0, 0.6};
 
871
  GLfloat black[] = {0, 0, 0, 0.6};
636
872
 
637
873
  col[0] = l->r; col[1] = l->g; col[2] = l->b;
638
874
  if (l->light && light) {
640
876
    glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, dir);
641
877
    if (!lighton) {
642
878
      glLightfv(GL_LIGHT1, GL_SPECULAR, col);
643
 
      glLightfv(GL_LIGHT1, GL_AMBIENT, col);
 
879
      glLightfv(GL_LIGHT1, GL_AMBIENT, black);
 
880
      col[0] /= 1.5; col[1] /= 1.5; col[2] /= 1.5;
644
881
      glLightfv(GL_LIGHT1, GL_DIFFUSE, col);
645
882
      glLighti(GL_LIGHT1, GL_SPOT_CUTOFF, (GLint) 90);
646
883
      glLighti(GL_LIGHT1, GL_CONSTANT_ATTENUATION, (GLfloat)1); 
658
895
    glDepthMask(GL_FALSE);
659
896
    glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
660
897
  }
 
898
  glTranslatef(-0.9, 0, 0);
661
899
  createCylinder(1.2, 0.3, 0, 0);
662
900
  if (l->light && light) {
663
901
    glDisable(GL_LIGHTING);
664
902
    glColor3fv(col);
665
903
  }
666
 
  sphere(0.3, 10, 10, 5, 10, 0, 10);
 
904
  sphere(0.3, 7, 7, 3, 7, 0, 7);
667
905
  if (l->light && light) {
668
906
    glEnable(GL_LIGHTING);
669
907
  } else {
686
924
    }
687
925
  }
688
926
}
 
927
 
 
928
 
 
929
void DrawThreeFive(ThreeFive *d)
 
930
{
 
931
  GLfloat shine = 40;
 
932
  GLfloat dark[] = {0.3, 0.3, 0.3, 0};
 
933
  GLfloat light[] = {0.6, 0.6, 0.6, 0};
 
934
  GLfloat cream[] = {0.8, 0.8, 0.6, 0};
 
935
  GLfloat spec[] = {0.7, 0.7, 0.7, 0};
 
936
 
 
937
   glPushMatrix();
 
938
   glMaterialfv(GL_FRONT, GL_SHININESS, &shine);
 
939
   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cream);
 
940
   glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
689
941
   
690
 
 
691
 
 
692
 
void DrawDiode(Diode *d) {
693
 
GLfloat shine = 40;
694
 
GLfloat col[] = {0.3, 0.3, 0.3, 0};
695
 
GLfloat spec[] = {0.7, 0.7, 0.7, 0};
 
942
   glTranslatef(-2.0, 0, 0);
 
943
   createCylinder(0.7, 0.2, 0, 0);
 
944
   glTranslatef(0.7, 0, 0);
 
945
   createCylinder(1.3, 0.4, 1, 0);
 
946
   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, light);
 
947
   glTranslatef(1.3, 0, 0);
 
948
   createCylinder(1.3, 0.2, 0, 0);
 
949
   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, dark);
 
950
   glTranslatef(0.65, 0, 0);
 
951
   createCylinder(0.15, 0.21, 0, 0);
 
952
   glTranslatef(0.3, 0, 0);
 
953
   createCylinder(0.15, 0.21, 0, 0);
 
954
   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, light);
 
955
   glTranslatef(0.4, 0, 0);
 
956
   sphere(0.23, 7, 7, 0, 5, 0, 7);
 
957
 
 
958
   glPopMatrix();
 
959
}
 
960
 
 
961
void DrawDiode(Diode *d)
 
962
{
 
963
  GLfloat shine = 40;
 
964
  GLfloat col[] = {0.3, 0.3, 0.3, 0};
 
965
  GLfloat spec[] = {0.7, 0.7, 0.7, 0};
696
966
 
697
967
   glPushMatrix();
698
968
   glMaterialfv(GL_FRONT, GL_SHININESS, &shine);
708
978
}
709
979
 
710
980
void Rect(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h,
711
 
            GLfloat t) {
712
 
GLfloat yh;
713
 
GLfloat xw;
714
 
GLfloat zt;
 
981
            GLfloat t)
 
982
{
 
983
  GLfloat yh;
 
984
  GLfloat xw;
 
985
  GLfloat zt;
715
986
 
716
987
  yh = y+h; xw = x+w; zt = z - t;
717
988
 
756
1027
 
757
1028
/* IC pins */
758
1029
 
759
 
void ICLeg(GLfloat x, GLfloat y, GLfloat z, int dir) {
760
 
 
761
 
 
 
1030
void ICLeg(GLfloat x, GLfloat y, GLfloat z, int dir)
 
1031
{
762
1032
  if (dir) {
763
1033
    Rect(x-0.1, y, z, 0.1, 0.1, 0.02);
764
1034
    Rect(x-0.1, y, z, 0.02, 0.1, 0.1);
772
1042
}
773
1043
 
774
1044
 
775
 
void DrawIC(IC *c) {
776
 
GLfloat w, h, d;
777
 
int z;
778
 
GLfloat col[] = {0.1, 0.1, 0.1, 0};
779
 
GLfloat spec[] = {0.6, 0.6, 0.6, 0};
780
 
GLfloat shine = 40;
781
 
GLfloat lspec[] = {0.6, 0.6, 0.6, 0};
782
 
GLfloat lcol[] = {0.4, 0.4, 0.4, 0};
783
 
GLfloat lshine = 40;
 
1045
void DrawIC(IC *c)
 
1046
{
 
1047
  GLfloat w, h, d;
 
1048
  int z;
 
1049
  GLfloat col[] = {0.1, 0.1, 0.1, 0};
 
1050
  GLfloat col2[] = {0.2, 0.2, 0.2, 0};
 
1051
  GLfloat spec[] = {0.6, 0.6, 0.6, 0};
 
1052
  GLfloat shine = 40;
 
1053
  GLfloat lspec[] = {0.6, 0.6, 0.6, 0};
 
1054
  GLfloat lcol[] = {0.4, 0.4, 0.4, 0};
 
1055
  GLfloat lshine = 40;
 
1056
  float mult, th, size;
784
1057
 
785
1058
  glPushMatrix();
786
1059
  glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
787
1060
  glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
 
1061
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
788
1062
  glMaterialfv(GL_FRONT, GL_SHININESS, &shine);
789
1063
  switch(c->pins) {
790
1064
    case 8:
802
1076
      break;
803
1077
  }
804
1078
  w = w/2; h = h/2;
 
1079
    glEnable(GL_POLYGON_OFFSET_FILL);
 
1080
    glPolygonOffset(1.0, 1.0);
805
1081
    glBegin(GL_QUADS);
806
1082
      glNormal3f(0, 0, 1);
807
1083
      glVertex3f(w, h, 0.1);
834
1110
      glVertex3f(w, h, 0.1);
835
1111
      glVertex3f(-w, h, 0.1);
836
1112
    glEnd();
 
1113
    glDisable(GL_POLYGON_OFFSET_FILL);
 
1114
    if (c->tnum) glBindTexture(GL_TEXTURE_2D, c->tnum);
 
1115
    glEnable(GL_TEXTURE_2D);
 
1116
    glEnable(GL_BLEND);
 
1117
    if (c->pins == 8)
 
1118
      size = 0.4;
 
1119
    else
 
1120
      size = 0.6;
 
1121
    th = size*2/3;
 
1122
    mult = size*c->tw / c->th;
 
1123
    mult /= 2;
 
1124
    glBegin(GL_QUADS); /* text markings */
 
1125
     glNormal3f(0, 0, 1);
 
1126
     glTexCoord2f(0, 1);
 
1127
     glVertex3f(th, mult, 0.1);
 
1128
     glTexCoord2f(1, 1);
 
1129
     glVertex3f(th, -mult, 0.1);
 
1130
     glTexCoord2f(1, 0);
 
1131
     glVertex3f(-th, -mult, 0.1);
 
1132
     glTexCoord2f(0, 0);
 
1133
     glVertex3f(-th, mult, 0.1);
 
1134
    glEnd();
 
1135
    glDisable(GL_TEXTURE_2D);
 
1136
    glDisable(GL_BLEND);
837
1137
    d = (h*2-0.1) / c->pins;
838
1138
    d*=2;
839
1139
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, lcol);
845
1145
    for (z = 0 ; z < c->pins/2 ; z++) {
846
1146
      ICLeg(-w, -h + z*d + d/2, 0, 1);
847
1147
    }
 
1148
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col2);
 
1149
    glTranslatef(-w+0.3, h-0.3, 0.1);
 
1150
    glRotatef(90, 0, 1, 0);
 
1151
    circle(0.1, 7, 0);
848
1152
    glPopMatrix();
849
1153
}
850
1154
 
851
 
void DrawDisp(Disp *d) {
852
 
GLfloat col[] = {0.8, 0.8, 0.8, 1.0}; /* body colour */
853
 
GLfloat front[] = {0.2, 0.2, 0.2, 1.0}; /* front colour */
854
 
GLfloat on[] = {0.9, 0, 0, 1}; /* 'on' segment */
855
 
GLfloat off[] = {0.3, 0, 0, 1}; /* 'off' segment */
856
 
int i, j, k;
857
 
GLfloat x, y; /* for the pins */
858
 
GLfloat spec[] = {0.6, 0.6, 0.6, 0};
859
 
GLfloat lcol[] = {0.4, 0.4, 0.4, 0};
860
 
GLfloat shine = 40;
861
 
static GLfloat vdata_h[6][2] = 
862
 
{
863
 
  {0, 0},
864
 
  {0.1, 0.1},
865
 
  {0.9, 0.1},
866
 
  {1, 0},
867
 
  {0.9, -0.1},
868
 
  {0.1, -0.1}
869
 
};
870
 
static GLfloat vdata_v[6][2] =
871
 
{
872
 
  {0.27, 0},
873
 
  {0.35, -0.1},
874
 
  {0.2, -0.9},
875
 
  {0.1, -1},
876
 
  {0, -0.9},
877
 
  {0.15, -0.15}
878
 
};
879
 
 
880
 
static GLfloat seg_start[7][2] = 
881
 
{
882
 
 
883
 
  {0.55, 2.26},
884
 
  {1.35, 2.26},
885
 
  {1.2, 1.27},
886
 
  {0.25, 0.25},
887
 
  {0.06, 1.25},
888
 
  {0.25, 2.25},
889
 
  {0.39, 1.24}
890
 
};
891
 
 
892
 
static int nums[10][7] =
893
 
{
894
 
  {1, 1, 1, 1, 1, 1, 0}, /* 0 */
895
 
  {0, 1, 1, 0, 0, 0, 0}, /* 1 */
896
 
  {1, 1, 0, 1, 1, 0, 1}, /* 2 */
897
 
  {1, 1, 1, 1, 0, 0, 1}, /* 3 */
898
 
  {0, 1, 1, 0, 0, 1, 1}, /* 4 */
899
 
  {1, 0, 1, 1, 0, 1, 1}, /* 5 */
900
 
  {1, 0, 1, 1, 1, 1, 1}, /* 6 */
901
 
  {1, 1, 1, 0, 0, 0, 0}, /* 7 */
902
 
  {1, 1, 1, 1, 1, 1, 1}, /* 8 */
903
 
  {1, 1, 1, 0, 0, 1, 1}  /* 9 */
904
 
};
905
 
  
 
1155
void DrawDisp(Disp *d)
 
1156
{
 
1157
  GLfloat col[] = {0.8, 0.8, 0.8, 1.0}; /* body colour */
 
1158
  GLfloat front[] = {0.2, 0.2, 0.2, 1.0}; /* front colour */
 
1159
  GLfloat on[] = {0.9, 0, 0, 1}; /* 'on' segment */
 
1160
  GLfloat off[] = {0.3, 0, 0, 1}; /* 'off' segment */
 
1161
  int i, j, k;
 
1162
  GLfloat x, y; /* for the pins */
 
1163
  GLfloat spec[] = {0.6, 0.6, 0.6, 0};
 
1164
  GLfloat lcol[] = {0.4, 0.4, 0.4, 0};
 
1165
  GLfloat shine = 40;
 
1166
  static GLfloat vdata_h[6][2] = {
 
1167
    {0, 0},
 
1168
    {0.1, 0.1},
 
1169
    {0.9, 0.1},
 
1170
    {1, 0},
 
1171
    {0.9, -0.1},
 
1172
    {0.1, -0.1}
 
1173
  };
 
1174
  static GLfloat vdata_v[6][2] = {
 
1175
    {0.27, 0},
 
1176
    {0.35, -0.1},
 
1177
    {0.2, -0.9},
 
1178
    {0.1, -1},
 
1179
    {0, -0.9},
 
1180
    {0.15, -0.15}
 
1181
  };
 
1182
 
 
1183
  static GLfloat seg_start[7][2] = {
 
1184
    {0.55, 2.26},
 
1185
    {1.35, 2.26},
 
1186
    {1.2, 1.27},
 
1187
    {0.25, 0.25},
 
1188
    {0.06, 1.25},
 
1189
    {0.25, 2.25},
 
1190
    {0.39, 1.24}
 
1191
  };
 
1192
 
 
1193
  static int nums[10][7] = {
 
1194
    {1, 1, 1, 1, 1, 1, 0}, /* 0 */
 
1195
    {0, 1, 1, 0, 0, 0, 0}, /* 1 */
 
1196
    {1, 1, 0, 1, 1, 0, 1}, /* 2 */
 
1197
    {1, 1, 1, 1, 0, 0, 1}, /* 3 */
 
1198
    {0, 1, 1, 0, 0, 1, 1}, /* 4 */
 
1199
    {1, 0, 1, 1, 0, 1, 1}, /* 5 */
 
1200
    {1, 0, 1, 1, 1, 1, 1}, /* 6 */
 
1201
    {1, 1, 1, 0, 0, 0, 0}, /* 7 */
 
1202
    {1, 1, 1, 1, 1, 1, 1}, /* 8 */
 
1203
    {1, 1, 1, 0, 0, 1, 1}  /* 9 */
 
1204
  };
 
1205
 
 
1206
   glTranslatef(-0.9, -1.8, 0);
906
1207
   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
907
1208
   Rect(0, 0, -0.01, 1.8, 2.6, 0.7);
908
1209
   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, front);
953
1254
   }
954
1255
}
955
1256
 
956
 
void HoledRectangle(GLfloat w, GLfloat h, GLfloat d, GLfloat radius, int p) {
957
 
int step, a;
958
 
GLfloat x1, y1, x2, y2;
959
 
GLfloat yr, yr1, xr, xr1, side, side1;
960
 
GLfloat nx, ny;
 
1257
void HoledRectangle(GLfloat w, GLfloat h, GLfloat d, GLfloat radius, int p)
 
1258
{
 
1259
  int step, a;
 
1260
  GLfloat x1, y1, x2, y2;
 
1261
  GLfloat yr, yr1, xr, xr1, side, side1;
 
1262
  GLfloat nx, ny;
961
1263
 
962
1264
  step = 360 / p;
963
1265
  x1 = radius; y1 = 0;
1020
1322
  glEnd();
1021
1323
}
1022
1324
 
1023
 
void DrawTransistor(Transistor *t) {
1024
 
static GLfloat col[] = {0.3, 0.3, 0.3, 1.0};
1025
 
static GLfloat spec[] = {0.9, 0.9, 0.9, 1.0};
1026
 
static GLfloat nospec[] = {0.4, 0.4, 0.4, 1.0};
1027
 
GLfloat shin = 30;
 
1325
void DrawTransistor(Transistor *t)
 
1326
{
 
1327
  static GLfloat col[] = {0.3, 0.3, 0.3, 1.0};
 
1328
  static GLfloat spec[] = {0.9, 0.9, 0.9, 1.0};
 
1329
  static GLfloat nospec[] = {0.4, 0.4, 0.4, 1.0};
 
1330
  GLfloat shin = 30;
1028
1331
 
1029
1332
  glPushMatrix();
1030
1333
  glMaterialfv(GL_FRONT, GL_SHININESS, &shin);
1031
1334
  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col);
1032
 
  if (t->type == 1) {
 
1335
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
1336
  if (t->type == 1) { /* TO-92 style */
 
1337
    float mult, y1, y2;
 
1338
    mult = 1.5*t->th/t->tw;
 
1339
    y1 = 0.2+mult/2;
 
1340
    y2 = 0.8-mult/2;
 
1341
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col);
1033
1342
    glRotatef(90, 0, 1, 0);
1034
1343
    glRotatef(90, 0, 0, 1);
1035
1344
    createCylinder(1.0, 0.4, 1, 1);
1036
1345
    Rect(0, -0.2, 0.4, 1, 0.2, 0.8);
 
1346
/* Draw the markings */
 
1347
    glEnable(GL_TEXTURE_2D);
 
1348
    if (t->tnum) glBindTexture(GL_TEXTURE_2D, t->tnum);
 
1349
    glEnable(GL_BLEND);
 
1350
    glDepthMask(GL_FALSE);
 
1351
    glBegin (GL_QUADS);
 
1352
     glNormal3f(0, 0, 1);
 
1353
     glTexCoord2f(0, 1);
 
1354
     glVertex3f(y1, -0.21, 0.3);
 
1355
     glTexCoord2f(1, 1);
 
1356
     glVertex3f(y1, -0.21, -0.3);
 
1357
     glTexCoord2f(1, 0);
 
1358
     glVertex3f(y2, -0.21, -0.3);
 
1359
     glTexCoord2f(0, 0);
 
1360
     glVertex3f(y2, -0.21, 0.3);
 
1361
    glEnd();
 
1362
    glDisable(GL_TEXTURE_2D);
 
1363
    glDisable(GL_BLEND);
 
1364
    glDepthMask(GL_TRUE);
1037
1365
    glTranslatef(-2, 0, -0.2);
1038
1366
    wire(2);
1039
1367
    glTranslatef(0, 0, 0.2);
1040
1368
    wire(2);
1041
1369
    glTranslatef(0, 0, 0.2);
1042
1370
    wire(2);
1043
 
  } else {
1044
 
    Rect(0, 0, 0, 1.5, 1.5, 0.75);
1045
 
    glTranslatef(0.75, 1.875, -0.5);
 
1371
  } else if (t->type == 0) { /* TO-220 Style */
 
1372
    float mult, y1, y2;
 
1373
    mult = 1.5*t->th/t->tw;
 
1374
    y1 = 0.75+mult/2;
 
1375
    y2 = 0.75-mult/2;
 
1376
    Rect(0, 0, 0, 1.5, 1.5, 0.5);
 
1377
    glEnable(GL_TEXTURE_2D);
 
1378
    if (t->tnum) glBindTexture(GL_TEXTURE_2D, t->tnum);
 
1379
    glEnable(GL_BLEND);
 
1380
    glDepthMask(GL_FALSE);
 
1381
    glBegin (GL_QUADS);
 
1382
     glNormal3f(0, 0, 1);
 
1383
     glTexCoord2f(0, 1);
 
1384
     glVertex3f(0, y1, 0.01);
 
1385
     glTexCoord2f(1, 1);
 
1386
     glVertex3f(1.5, y1, 0.01);
 
1387
     glTexCoord2f(1, 0);
 
1388
     glVertex3f(1.5, y2, 0.01);
 
1389
     glTexCoord2f(0, 0);
 
1390
     glVertex3f(0, y2, 0.01);
 
1391
    glEnd();
 
1392
    glDisable(GL_TEXTURE_2D);
 
1393
    glDisable(GL_BLEND);
 
1394
    glDepthMask(GL_TRUE);
1046
1395
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
1047
1396
    glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
1048
1397
    glMaterialfv(GL_FRONT, GL_SHININESS, &shin);
1049
 
    if (glIsEnabled(GL_NORMALIZE)) glEnable(GL_NORMALIZE);
 
1398
    Rect(0, 0, -0.5, 1.5, 1.5, 0.30);
 
1399
    if (!glIsEnabled(GL_NORMALIZE)) glEnable(GL_NORMALIZE);
 
1400
    glTranslatef(0.75, 1.875, -0.55);
1050
1401
    HoledRectangle(1.5, 0.75, 0.25, 0.2, 8);
1051
1402
    glMaterialfv(GL_FRONT, GL_SPECULAR, nospec);
1052
1403
    glTranslatef(-0.375, -1.875, 0);
1056
1407
    wire(2);
1057
1408
    glTranslatef(0, 0.375, 0);
1058
1409
    wire(2);
 
1410
  } else {              /* SMC transistor */
 
1411
/* Draw the body */
 
1412
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col);
 
1413
    glTranslatef(-0.5, -0.25, 0.1);
 
1414
    Rect(0, 0, 0, 1, 0.5, 0.2);
 
1415
/* Draw the markings */
 
1416
    glEnable(GL_TEXTURE_2D);
 
1417
    if (t->tnum) glBindTexture(GL_TEXTURE_2D, t->tnum);
 
1418
    glEnable(GL_BLEND);
 
1419
    glDepthMask(GL_FALSE);
 
1420
    glBegin (GL_QUADS);
 
1421
     glNormal3f(0, 0, 1);
 
1422
     glTexCoord2f(0, 1);
 
1423
     glVertex3f(0.2, 0, 0.01);
 
1424
     glTexCoord2f(1, 1);
 
1425
     glVertex3f(0.8, 0, 0.01);
 
1426
     glTexCoord2f(1, 0);
 
1427
     glVertex3f(0.8, 0.5, 0.01);
 
1428
     glTexCoord2f(0, 0);
 
1429
     glVertex3f(0.2, 0.5, 0.01);
 
1430
    glEnd();
 
1431
    glDisable(GL_TEXTURE_2D);
 
1432
    glDisable(GL_BLEND);
 
1433
    glDepthMask(GL_TRUE);
 
1434
/* Now draw the legs */
 
1435
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
 
1436
    glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
 
1437
    glMaterialfv(GL_FRONT, GL_SHININESS, &shin);
 
1438
    Rect(0.25, -0.1, -0.05, 0.1, 0.1, 0.2);
 
1439
    Rect(0.75, -0.1, -0.05, 0.1, 0.1, 0.2);
 
1440
    Rect(0.5, 0.5, -0.05, 0.1, 0.1, 0.2);
 
1441
    Rect(0.25, -0.2, -0.2, 0.1, 0.15, 0.1);
 
1442
    Rect(0.75, -0.2, -0.2, 0.1, 0.15, 0.1);
 
1443
    Rect(0.5, 0.5, -0.2, 0.1, 0.15, 0.1);
1059
1444
  }
1060
1445
  glPopMatrix();
1061
1446
}
1062
1447
 
1063
 
Component * NewComponent(void) {
1064
 
Component *c;
1065
 
float rnd;
 
1448
Component * NewComponent(void)
 
1449
{
 
1450
  Component *c;
 
1451
  float rnd;
1066
1452
 
1067
1453
  c = malloc(sizeof(Component));
1068
1454
  c->angle = RAND_RANGE(0,360);
1104
1490
  c->rotx = f_rand();
1105
1491
  c->roty = f_rand();
1106
1492
  c->rotz = f_rand();
1107
 
  c->drot = f_rand() * 7;
 
1493
  c->drot = f_rand() * 3;
1108
1494
  c->rdeg = 0;
1109
1495
  c->dz = f_rand()*2 - 1;
1110
1496
  c->norm = 0;
1111
1497
  c->alpha = 0; /* explicitly set to 1 later */
1112
 
  rnd = f_rand();
1113
 
  if (rnd < 0.1) {
 
1498
  rnd = random() % 11;
 
1499
  if (rnd < 1) {
1114
1500
    c->c = NewResistor();
1115
1501
    c->type = 0;
1116
1502
    if (f_rand() < 0.4)
1117
1503
      c->norm = 1; /* some resistors shine */
1118
 
  } else if (rnd < 0.2) {
 
1504
  } else if (rnd < 2) {
1119
1505
    c->c = NewDiode();
1120
1506
    if (f_rand() < 0.4)
1121
1507
      c->norm = 1; /* some diodes shine */
1122
1508
    c->type = 1;
1123
 
  } else if (rnd < 0.3) {
 
1509
  } else if (rnd < 3) {
1124
1510
    c->c = NewTransistor();
1125
1511
    c->norm = 1;
1126
1512
    c->type = 2;
1127
 
  } else if (rnd < 0.4) {
 
1513
  } else if (rnd < 4) {
1128
1514
    c->c = NewCapacitor();
1129
 
    if (f_rand() < 0.4)
1130
 
      c->norm = 1; /* some capacitors shine */
 
1515
    c->norm = 1;
1131
1516
    c->type = 4;
1132
 
  } else if (rnd < 0.6) {
 
1517
  } else if (rnd < 5) {
1133
1518
    c->c = NewIC();
1134
1519
    c->type = 5;
1135
 
  } else if (rnd < 0.7) {
 
1520
    c->norm = 1;
 
1521
  } else if (rnd < 6) {
1136
1522
    c->c = NewLED();
1137
1523
    c->type = 3;
1138
1524
    c->norm = 1;
1139
1525
    c->alpha = 1;
1140
 
  } else if (rnd < 0.8) {
 
1526
  } else if (rnd < 7) {
1141
1527
    c->c = NewFuse();
1142
1528
    c->norm = 1;
1143
1529
    c->type = 7;
1144
1530
    c->alpha = 1;
 
1531
  } else if (rnd < 8) {
 
1532
    c->c = NewRCA();
 
1533
    c->norm = 1;
 
1534
    c->type = 8;
 
1535
  } else if (rnd < 9) {
 
1536
    c->c = NewThreeFive();
 
1537
    c->norm = 1;
 
1538
    c->type = 9;
 
1539
  } else if (rnd < 10) {
 
1540
    c->c = NewSwitch();
 
1541
    c->norm = 1;
 
1542
    c->type = 10;
1145
1543
  } else {
1146
1544
    c->c = NewDisp();
1147
1545
    c->type = 6;
1149
1547
  return c;
1150
1548
}
1151
1549
 
1152
 
Transistor *NewTransistor(void) {
1153
 
Transistor *t;
 
1550
Transistor *NewTransistor(void)
 
1551
{
 
1552
  Transistor *t;
 
1553
  float texfg[] = {0.7, 0.7, 0.7, 1.0};
 
1554
  float texbg[] = {0.3, 0.3, 0.3, 0.1};
 
1555
  TexNum *tn;
 
1556
  const char *val;
1154
1557
 
1155
1558
  t = malloc(sizeof(Transistor));
1156
 
  t->type = (f_rand() < 0.5);
 
1559
  t->type = (random() % 3);
 
1560
  if (t->type == 0) {
 
1561
    val = transistortypes[random() % countof(transistortypes)];
 
1562
    tn = fonttexturealloc(val, texfg, texbg);
 
1563
    if (tn == NULL) {
 
1564
      fprintf(stderr, "Error getting a texture for a string!\n");
 
1565
      t->tnum = 0;
 
1566
    } else {
 
1567
      t->tnum = tn->num;
 
1568
      t->tw = tn->w; t->th = tn->h;
 
1569
      free(tn);
 
1570
    }
 
1571
  } else if (t->type == 2) {
 
1572
    val = smctypes[random() % countof(smctypes)];
 
1573
    tn = fonttexturealloc(val, texfg, texbg);
 
1574
    if (tn == NULL) {
 
1575
      fprintf(stderr, "Error getting a texture for a string!\n");
 
1576
      t->tnum = 0;
 
1577
    } else {
 
1578
      t->tnum = tn->num;
 
1579
      t->tw = tn->w; t->th = tn->h;
 
1580
      free(tn);
 
1581
    }
 
1582
  } else if (t->type == 1) {
 
1583
    val = to92types[random() % countof(to92types)];
 
1584
    tn = fonttexturealloc(val, texfg, texbg);
 
1585
    if (tn == NULL) {
 
1586
      fprintf(stderr, "Error getting a texture for a string!\n");
 
1587
      t->tnum = 0;
 
1588
    } else {
 
1589
      t->tnum = tn->num;
 
1590
      t->tw = tn->w; t->th = tn->h;
 
1591
      free(tn);
 
1592
    }
 
1593
  }
 
1594
 
1157
1595
  return t;
1158
1596
}
1159
1597
 
1160
 
Capacitor *NewCapacitor(void) {
1161
 
Capacitor *c;
 
1598
Capacitor *NewCapacitor(void)
 
1599
{
 
1600
  Capacitor *c;
1162
1601
 
1163
1602
  c = malloc(sizeof(Capacitor));
1164
1603
  c->type = (f_rand() < 0.5);
1166
1605
    c->length = RAND_RANGE(0.5, 1);
1167
1606
    c->width = RAND_RANGE(0.5, 1);
1168
1607
  } else {
1169
 
    c->width = RAND_RANGE(1, 2);
 
1608
    c->width = RAND_RANGE(0.3, 1);
1170
1609
  }
1171
1610
  return c;
1172
1611
}
1173
1612
 
1174
1613
/* 7 segment display */
1175
1614
 
1176
 
Disp *NewDisp(void) {
1177
 
Disp *d;
 
1615
Disp *NewDisp(void)
 
1616
{
 
1617
  Disp *d;
1178
1618
 
1179
1619
  d = malloc(sizeof(Disp));
1180
1620
  if (seven)
1185
1625
}
1186
1626
 
1187
1627
 
1188
 
IC *NewIC(void) {
1189
 
IC *c;
1190
 
int pins;
 
1628
IC *NewIC(void)
 
1629
{
 
1630
  IC *c;
 
1631
  int pins;
 
1632
  TexNum *tn;
 
1633
  float texfg[] = {0.7, 0.7, 0.7, 1.0};
 
1634
  float texbg[] = {0.1, 0.1, 0.1, 0};
 
1635
  const char *val;
 
1636
  char *str;
 
1637
  int types[countof(ictypes)], i, n = 0;
1191
1638
 
1192
1639
  c = malloc(sizeof(IC));
1193
1640
  c->type = 0;
1206
1653
      pins = 24;
1207
1654
      break;
1208
1655
  }
 
1656
  for (i = 0 ; i < countof(ictypes) ; i++) {
 
1657
    if (ictypes[i].pins == pins) {
 
1658
       types[n] = i;
 
1659
       n++;
 
1660
    }
 
1661
  }
 
1662
 
 
1663
  if (n > countof(types)) abort();
 
1664
  val = ictypes[types[random() % n]].val;
 
1665
  str = malloc(strlen(val) + 1 + 4 + 1); /* add space for production date */
 
1666
  sprintf(str, "%s\n%02d%02d", val, (int)RAND_RANGE(80, 100), (int)RAND_RANGE(1,53));
 
1667
  tn = fonttexturealloc(str, texfg, texbg);
 
1668
  free(str);
 
1669
  if (tn == NULL) {
 
1670
    fprintf(stderr, "Error allocating font texture for '%s'\n", val);
 
1671
    c->tnum = 0;
 
1672
  } else {
 
1673
    c->tw = tn->w; c->th = tn->h;
 
1674
    c->tnum = tn->num;
 
1675
    free(tn);
 
1676
  }
1209
1677
  c->pins = pins;
1210
1678
  return c;
1211
1679
}
1212
1680
 
1213
 
LED *NewLED(void) {
1214
 
LED *l;
1215
 
float r;
 
1681
LED *NewLED(void)
 
1682
{
 
1683
  LED *l;
 
1684
  float r;
1216
1685
 
1217
1686
  l = malloc(sizeof(LED));
1218
1687
  r = f_rand();
1235
1704
  return l;
1236
1705
}
1237
1706
 
1238
 
Fuse *NewFuse(void) {
1239
 
Fuse *f;
 
1707
Fuse *NewFuse(void)
 
1708
{
 
1709
  Fuse *f;
1240
1710
 
1241
1711
  f = malloc(sizeof(Fuse));
1242
1712
  return f;
1243
1713
}
1244
1714
 
1245
 
Diode *NewDiode(void) {
1246
 
Band *b;
1247
 
Diode *ret;
 
1715
RCA *NewRCA(void)
 
1716
{
 
1717
  RCA *r;
 
1718
 
 
1719
  r = malloc(sizeof(RCA));
 
1720
  r->col = (random() % 10 < 5);
 
1721
  return r;
 
1722
}
 
1723
 
 
1724
ThreeFive *NewThreeFive(void)
 
1725
{
 
1726
  ThreeFive *r;
 
1727
 
 
1728
  r = malloc(sizeof(ThreeFive));
 
1729
  return r;
 
1730
}
 
1731
 
 
1732
Switch *NewSwitch(void)
 
1733
{
 
1734
  Switch *s;
 
1735
 
 
1736
  s = malloc(sizeof(Switch));
 
1737
  s->position = 0;
 
1738
  return s;
 
1739
}
 
1740
 
 
1741
Diode *NewDiode(void)
 
1742
{
 
1743
  Band *b;
 
1744
  Diode *ret;
1248
1745
 
1249
1746
  ret = malloc(sizeof(Diode));
1250
1747
  b = malloc(sizeof(Band));
1266
1763
}
1267
1764
 
1268
1765
 
1269
 
Resistor  * NewResistor(void) {
1270
 
int v, m, t; /* value, multiplier, tolerance */
1271
 
Resistor *ret;
 
1766
Resistor  * NewResistor(void)
 
1767
{
 
1768
  int v, m, t; /* value, multiplier, tolerance */
 
1769
  Resistor *ret;
1272
1770
 
1273
1771
  v = RAND(9);
1274
1772
  m = RAND(5);
1287
1785
  return ret;
1288
1786
}
1289
1787
 
1290
 
void makebandlist(void) {
1291
 
int i;
1292
 
GLfloat col[] = {0,0,0,0};
1293
 
GLfloat spec[] = {0.8,0.8,0.8,0};
1294
 
GLfloat shine = 40;
 
1788
void makebandlist(void)
 
1789
{
 
1790
  int i;
 
1791
  GLfloat col[] = {0,0,0,0};
 
1792
  GLfloat spec[] = {0.8,0.8,0.8,0};
 
1793
  GLfloat shine = 40;
1295
1794
 
1296
1795
   for (i = 0 ; i < 12 ; i++) {
1297
1796
     band_list[i] = glGenLists(i);
1309
1808
  
1310
1809
 
1311
1810
void bandedCylinder(float radius, float l, GLfloat r, GLfloat g, GLfloat bl, 
1312
 
                        Band **b, int nbands) {
1313
 
int n; /* band number */
1314
 
int p = 0; /* prev number + 1; */
1315
 
GLfloat col[] = {0,0,0,0};
 
1811
                        Band **b, int nbands)
 
1812
{
 
1813
  int n; /* band number */
 
1814
  int p = 0; /* prev number + 1; */
 
1815
  GLfloat col[] = {0,0,0,0};
1316
1816
 
1317
1817
   col[0] = r; col[1] = g; col[2] = bl;
1318
1818
   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, col);
1328
1828
   }
1329
1829
}
1330
1830
 
1331
 
void drawgrid(void) {
1332
 
GLfloat x, y;
1333
 
static GLfloat col[] = {0, 0.25, 0.05};
1334
 
static GLfloat col2[] = {0, 0.125, 0.05};
1335
 
GLfloat col3[] = {0, 0.8, 0};
1336
 
static GLfloat sx, sy; /* bright spot co-ords */
1337
 
static int sdir; /* 0 = left-right, 1 = right-left, 2 = up->dn, 3 = dn->up */
1338
 
static int s = 0; /* if spot is enabled */
1339
 
static float ds; /* speed of spot */
 
1831
void drawgrid(void)
 
1832
{
 
1833
  GLfloat x, y;
 
1834
  static GLfloat col[] = {0, 0.25, 0.05};
 
1835
  static GLfloat col2[] = {0, 0.125, 0.05};
 
1836
  GLfloat col3[] = {0, 0.8, 0};
 
1837
  static GLfloat sx, sy; /* bright spot co-ords */
 
1838
  static int sdir; /* 0 = left-right, 1 = right-left, 2 = up->dn, 3 = dn->up */
 
1839
  static int s = 0; /* if spot is enabled */
 
1840
  static float ds; /* speed of spot */
1340
1841
 
1341
1842
  if (!s) {
1342
1843
     if (f_rand() < ((rotate) ? 0.05 : 0.01)) {
1438
1939
  glEnable(GL_LIGHTING);
1439
1940
}
1440
1941
 
1441
 
void display(void) {
1442
 
static Component *c[MAX_COMPONENTS];
1443
 
static int i = 0;
1444
 
GLfloat light_sp[] = {0.8, 0.8, 0.8, 1.0};
1445
 
GLfloat black[] = {0, 0, 0, 1.0};
1446
 
static GLfloat rotate_angle = 0; /*  when 'rotate' is enabled */
1447
 
int j;
 
1942
void display(void)
 
1943
{
 
1944
  static Component *c[MAX_COMPONENTS];
 
1945
  static int i = 0;
 
1946
  GLfloat light_sp[] = {0.8, 0.8, 0.8, 1.0};
 
1947
  GLfloat black[] = {0, 0, 0, 1.0};
 
1948
  static GLfloat rotate_angle = 0; /*  when 'rotate' is enabled */
 
1949
  int j;
1448
1950
 
1449
1951
  if (i == 0) {
1450
1952
    for (i = 0 ; i < maxparts ; i++) {
1492
1994
  glFlush();
1493
1995
}
1494
1996
 
 
1997
void freetexture (GLuint texture) {
 
1998
  s_refs[texture]--;
 
1999
  if (s_refs[texture] < 1) {
 
2000
    glDeleteTextures(1, &texture);
 
2001
  }
 
2002
}
 
2003
 
 
2004
TexNum * fonttexturealloc (const char *str, float *fg, float *bg)
 
2005
{
 
2006
  static char *strings[50]; /* max of 40 textures */
 
2007
  static int w[50], h[50];
 
2008
  int i, status;
 
2009
  static int init;
 
2010
  XImage *ximage;
 
2011
  char *c;
 
2012
  TexNum *t;
 
2013
 
 
2014
  if (init == 0) {
 
2015
    for (i = 0 ; i < 50 ; i++) {
 
2016
      strings[i] = NULL;
 
2017
      s_refs[i] = 0;
 
2018
      w[i] = 0; h[i] = 0;
 
2019
    }
 
2020
    init++;
 
2021
  }
 
2022
  for (i = 0 ; i < 50 ; i++) {
 
2023
    if (!s_refs[i] && strings[i]) {
 
2024
      free (strings[i]);
 
2025
      strings[i] = NULL;
 
2026
    }
 
2027
    if (strings[i] && !strcmp(str, strings[i])) { /* if one matches */
 
2028
      t = malloc(sizeof(TexNum));
 
2029
      t->w = w[i]; t->h = h[i];
 
2030
      t->num = i;
 
2031
      s_refs[i]++;
 
2032
      return t;
 
2033
    }
 
2034
  }
 
2035
  /* at this point we need to make the new texture */
 
2036
  ximage = text_to_ximage (modeinfo->xgwa.screen,
 
2037
                           modeinfo->xgwa.visual,
 
2038
                           font, str,
 
2039
                           fg, bg);
 
2040
  for (i = 0 ; strings[i] != NULL ; i++) { /* set i to the next unused value */
 
2041
     if (i > 49) {
 
2042
        fprintf(stderr, "Texture cache full!\n");
 
2043
        free(ximage->data);
 
2044
        ximage->data = 0;
 
2045
        XFree (ximage);
 
2046
        return NULL;
 
2047
     }
 
2048
  }
 
2049
  glBindTexture(GL_TEXTURE_2D, i);
 
2050
  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
 
2051
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 
2052
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
2053
 
 
2054
  clear_gl_error();
 
2055
  status = gluBuild2DMipmaps(GL_TEXTURE_2D, 4, ximage->width, ximage->height,
 
2056
                             GL_RGBA, GL_UNSIGNED_BYTE, ximage->data);
 
2057
  if (status)
 
2058
    {
 
2059
      const char *s = (char *) gluErrorString (status);
 
2060
      fprintf (stderr, "%s: error mipmapping %dx%d texture: %s\n",
 
2061
               progname, ximage->width, ximage->height,
 
2062
               (s ? s : "(unknown)"));
 
2063
      exit (1);
 
2064
    }
 
2065
  check_gl_error("mipmapping");
 
2066
 
 
2067
  t = malloc(sizeof(TexNum));
 
2068
  t->w = ximage->width;
 
2069
  t->h = ximage->height;
 
2070
  w[i] = t->w; h[i] = t->h;
 
2071
  free(ximage->data);
 
2072
  ximage->data = 0;
 
2073
  XFree (ximage);
 
2074
  c = malloc(strlen(str)+1);
 
2075
  strncpy(c, str, strlen(str)+1);
 
2076
  strings[i] = c;
 
2077
  s_refs[i]++;
 
2078
  t->num = i;
 
2079
  return t;
 
2080
}
 
2081
 
1495
2082
/* ensure transparent components are at the end */
1496
 
void reorder(Component *c[]) {
1497
 
int i, j, k;
1498
 
Component *c1[MAX_COMPONENTS];
1499
 
Component *c2[MAX_COMPONENTS];
 
2083
void reorder(Component *c[])
 
2084
{
 
2085
  int i, j, k;
 
2086
  Component *c1[MAX_COMPONENTS];
 
2087
  Component *c2[MAX_COMPONENTS];
1500
2088
 
1501
2089
  j = 0;
1502
2090
  for (i = 0 ; i < maxparts ; i++) { /* clear old matrix */
1530
2118
 
1531
2119
void reshape_circuit(ModeInfo *mi, int width, int height)
1532
2120
{
1533
 
 
 
2121
 GLfloat h = (GLfloat) height / (GLfloat) width;
1534
2122
 glViewport(0,0,(GLint)width, (GLint) height);
1535
2123
 glMatrixMode(GL_PROJECTION);
1536
2124
 glLoadIdentity();
1537
 
 glFrustum(-1.0,1.0,-1.0,1.0,1.5,35.0);
 
2125
 glFrustum(-1.0,1.0,-h,h,1.5,35.0);
1538
2126
 glMatrixMode(GL_MODELVIEW);
1539
2127
 win_h = height; win_w = width;
 
2128
 YMAX = XMAX * h;
1540
2129
}
1541
2130
 
1542
2131
 
1567
2156
 glEnable(GL_DEPTH_TEST);
1568
2157
 glEnable(GL_LIGHTING);
1569
2158
 glEnable(GL_LIGHT0);
 
2159
 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1570
2160
 make_tables();
1571
2161
 makebandlist();
1572
2162
 
1573
2163
}
1574
2164
 
1575
 
void draw_circuit(ModeInfo *mi) {
1576
 
Circuit *c = &circuit[MI_SCREEN(mi)];
1577
 
Window w = MI_WINDOW(mi);
1578
 
Display *disp = MI_DISPLAY(mi);
 
2165
void draw_circuit(ModeInfo *mi)
 
2166
{
 
2167
  Circuit *c = &circuit[MI_SCREEN(mi)];
 
2168
  Window w = MI_WINDOW(mi);
 
2169
  Display *disp = MI_DISPLAY(mi);
1579
2170
 
1580
2171
  if (!c->glx_context)
1581
2172
      return;
 
2173
 modeinfo = mi;
1582
2174
 
1583
2175
 glXMakeCurrent(disp, w, *(c->glx_context));
1584
2176
 
1589
2181
  glXSwapBuffers(disp, w);
1590
2182
}
1591
2183
 
1592
 
void release_circuit(ModeInfo *mi) {
1593
 
 
 
2184
void release_circuit(ModeInfo *mi)
 
2185
{
1594
2186
  if (circuit != NULL) {
1595
2187
   (void) free((void *) circuit);
1596
2188
   circuit = NULL;