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