http://nanonyme.dy.fi/mirrors/hvl/distfiles/xscreensaver/xscreensaver-5.03.tar.gz
authorZygo Blaxell <zblaxell@hungrycats.org>
Mon, 2 Mar 2009 05:43:46 +0000 (00:43 -0500)
committerZygo Blaxell <zblaxell@faye.furryterror.org>
Fri, 8 Feb 2013 17:54:44 +0000 (12:54 -0500)
-rw-r--r-- 1 zblaxell zblaxell 5412089 Mar  1 04:09 xscreensaver-5.03.tar.gz
e283a52faf6148273a82a9e5c9ed70c5722cdcb8  xscreensaver-5.03.tar.gz

41 files changed:
OSX/SaverTester.plist
OSX/XScreenSaver.plist
OSX/bindist.rtf
README
configure
configure.in
driver/Makefile.in
driver/XScreenSaver.ad.in
driver/XScreenSaver_ad.h
driver/lock.c
driver/xscreensaver-getimage-video
driver/xscreensaver.man
hacks/Makefile.in
hacks/asm6502.c [new file with mode: 0644]
hacks/asm6502.h [new file with mode: 0644]
hacks/compile_axp.com
hacks/compile_decc.com
hacks/config/README
hacks/config/cwaves.xml [new file with mode: 0644]
hacks/config/glcells.xml [new file with mode: 0644]
hacks/config/m6502.xml [new file with mode: 0644]
hacks/config/voronoi.xml [new file with mode: 0644]
hacks/cwaves.c [new file with mode: 0644]
hacks/cwaves.man [new file with mode: 0644]
hacks/glx/Makefile.in
hacks/glx/antspotlight.c
hacks/glx/glcells.c [new file with mode: 0644]
hacks/glx/glcells.man [new file with mode: 0644]
hacks/glx/glschool_gl.c
hacks/glx/voronoi.c [new file with mode: 0644]
hacks/glx/voronoi.man [new file with mode: 0644]
hacks/images/osx_10_2.xpm
hacks/images/osx_10_3.xpm
hacks/m6502.c [new file with mode: 0644]
hacks/webcollage
hacks/xmatrix.c
po/POTFILES.in
setup.com
utils/version.h
xscreensaver.spec
xscreensaver.xcodeproj/project.pbxproj

index 141266be8203300938a0b6d4abdf7202660839a0..0b6c514f8be4f4f0e5eda2a00a956e9d3f2e789a 100644 (file)
        <key>CFBundlePackageType</key>
        <string>APPL</string>
        <key>CFBundleShortVersionString</key>
-       <string>5.02</string>
+       <string>5.03</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>5.02</string>
+       <string>5.03</string>
        <key>LSMinimumSystemVersion</key>
        <string>10.4.0</string>
        <key>NSMainNibFile</key>
index 7eaf05dad7ff64ad63a53b8deb74bc6636ff12c9..250279305882079caa41550bb1e971bd4fe80089 100644 (file)
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>5.02</string>
+       <string>5.03</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>5.02</string>
+       <string>5.03</string>
        <key>LSMinimumSystemVersion</key>
        <string>10.4.0</string>
        <key>NSMainNibFile</key>
index 2e04b9290ae8e9d4ce280af18c28c5fe8ab2d557..b9e13eef10ecad1be9ecf45250db5cf1e82e930e 100644 (file)
@@ -15,7 +15,7 @@ XScreenSaver
 \f1\b0 \
 by Jamie Zawinski \uc0\u8232 and many others\
 \
-version 5.02 \uc0\u8232 20-Apr-2007\
+version 5.03 \uc0\u8232 17-Jul-2007\
 \
 {\field{\*\fldinst{HYPERLINK "http://www.jwz.org/xscreensaver/"}}{\fldrslt \cf2 \ul \ulc2 http://www.jwz.org/xscreensaver/}}\
 \pard\pardeftab720\li720
diff --git a/README b/README
index 776ef1287a8ed218c1ee06cd3d5aef361e047a78..5fbf2300eb6bc86a8ff9d6ddd8ddf1e2d64f1196 100644 (file)
--- a/README
+++ b/README
@@ -38,6 +38,11 @@ XScreenSaver has an extensive manual -- please read it!
 
 ===============================================================================
 
+Changes since 5.02:   * New hacks, `cwaves', `glcells', `m6502', and `voronoi'.
+                      * Minor fixes to `bsod'.
+                      * Fixed possible crash with PAM USB-dongle auth.
+                      * Updated `webcollage' to track recent Google Images
+                        and Flickr changes.
 Changes since 5.01:   * Reworked PAM code to support fingerprint readers, etc.
                       * Ported 'webcollage' to OSX.
                       * Added OSX 10.2 and 10.3 kernel panics to `bsod'.
index 18570b3cf7706b1c62246d9d39d837ada9641951..3bbf0ad3db081ebe8e29284d9853a0edfcddfa40 100755 (executable)
--- a/configure
+++ b/configure
@@ -16608,7 +16608,7 @@ esac
 
 have_login_manager=no
 with_login_manager_req=unspecified
-default_login_manager='gdmflexiserver -l'
+default_login_manager='gdmflexiserver -ls'
 
 
 # Check whether --with-login-manager was given.
index fcc8f886c69725142cddb90a3c3f4d556bda348f..adab2635a4b0f2be9c671d4578a04dd3c094d1c1 100644 (file)
@@ -2265,7 +2265,7 @@ esac
 
 have_login_manager=no
 with_login_manager_req=unspecified
-default_login_manager='gdmflexiserver -l'
+default_login_manager='gdmflexiserver -ls'
 
 AC_ARG_WITH(login-manager,
 [  --with-login-manager    Put a "New Login" button on the unlock dialog that
index 2f9fb89f3681a4aff9b0a38fe39bda09ef6ab619..5daf8a26f63ec96c591dceb70bbce64601f2e79c 100644 (file)
@@ -900,9 +900,7 @@ lock.o: $(srcdir)/types.h
 lock.o: $(UTILS_SRC)/resources.h
 lock.o: $(srcdir)/xscreensaver.h
 mlstring.o: $(srcdir)/mlstring.h
-passwd.o: $(srcdir)/auth.h
 passwd.o: ../config.h
-passwd.o: $(srcdir)/types.h
 passwd-pwent.o: ../config.h
 prefs.o: ../config.h
 prefs.o: $(srcdir)/prefs.h
index f7d563e3858fadb4949f7312039f032b627945a2..29f69600daea83b9c5913f872fe5bd5153878eb8 100644 (file)
@@ -4,8 +4,8 @@
 !            a screen saver and locker for the X window system
 !                            by Jamie Zawinski
 !
-!                              version 5.02
-!                              20-Apr-2007
+!                              version 5.03
+!                              17-Jul-2007
 !
 ! See "man xscreensaver" for more info.  The latest version is always
 ! available at http://www.jwz.org/xscreensaver/
@@ -302,6 +302,8 @@ GetViewPortIsFullOfLies: False
                                fiberlamp -root                             \n\
                                boxfit -root                                \n\
                                celtic -root                                \n\
+                               cwaves -root                                \n\
+                               m6502 -root                                 \n\
 - default-n:                   webcollage -root                            \n\
 - default-n:  "WebCollage (whacked)"                                         \
                                webcollage -root -filter                      \
@@ -388,6 +390,8 @@ GetViewPortIsFullOfLies: False
 @GL_KLUDGE@ GL:                        juggler3d -root                             \n\
 @GL_KLUDGE@ GL:                        topblock -root                              \n\
 @GL_KLUDGE@ GL:                        glschool -root                              \n\
+@GL_KLUDGE@ GL:                        glcells -root                               \n\
+@GL_KLUDGE@ GL:                        voronoi -root                               \n\
                                                                              \
 -                              xdaliclock -root -font BUILTIN3             \n\
 -                              xplanet -vroot -wait 1 -timewarp 90000        \
@@ -530,6 +534,7 @@ XScreenSaver.bourneShell:           /bin/sh
 *hacks.glhanoi.name:        GLHanoi
 *hacks.topblock.name:       TopBlock
 *hacks.glschool.name:       GLSchool
+*hacks.glcells.name:        GLCells
 
 ! obsolete, but still used by xscreensaver-demo-Xm.
 *hacks.documentation.isInstalled: True
index 2843bdcc6cbdfbd9ec468d6e38f0f8116cb537b2..2f632ab1604d949f3379c5b106cb49cc9e810851 100644 (file)
                                fiberlamp -root                             \\n\
                                boxfit -root                                \\n\
                                celtic -root                                \\n\
+                               cwaves -root                                \\n\
+                               m6502 -root                                 \\n\
 - default-n:                   webcollage -root                            \\n\
 - default-n:  \"WebCollage (whacked)\"                                       \
                                webcollage -root -filter                      \
           GL:                  juggler3d -root                             \\n\
           GL:                  topblock -root                              \\n\
           GL:                  glschool -root                              \\n\
+          GL:                  glcells -root                               \\n\
+          GL:                  voronoi -root                               \\n\
                                                                              \
 -                              xdaliclock -root -font BUILTIN3             \\n\
 -                              xplanet -vroot -wait 1 -timewarp 90000        \
 "*hacks.glhanoi.name:        GLHanoi",
 "*hacks.topblock.name:       TopBlock",
 "*hacks.glschool.name:       GLSchool",
+"*hacks.glcells.name:        GLCells",
 "*hacks.documentation.isInstalled: True",
index bba326b0be97f10e1e4568ac9e13e0fa9b715bad..e36b5913bb0fa4d6f704761d71d32cba8be71d82 100644 (file)
@@ -1870,7 +1870,6 @@ passwd_event_loop (saver_info *si)
       si->pw_data->i_beam = 0;
       update_passwd_window (si, msg, 0.0);
       XSync (si->dpy, False);
-      sleep (1);
 
       /* Swallow all pending KeyPress/KeyRelease events. */
       {
@@ -2066,7 +2065,8 @@ auth_finished_cb (saver_info *si)
       }
     }
 
-  destroy_passwd_window (si);
+  if (si->pw_data)
+    destroy_passwd_window (si);
 }
 
 
index 468bf3afc1f2615b0c4923792a9c8ae68c13f622..6b9c1408ea87f94a661061caae1ea666ffc0eccb 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/perl -w
-# Copyright Â© 2001, 2002, 2003, 2005 Jamie Zawinski <jwz@jwz.org>.
+# Copyright Â© 2001-2007 Jamie Zawinski <jwz@jwz.org>.
 #
 # Permission to use, copy, modify, distribute, and sell this software and its
 # documentation for any purpose is hereby granted without fee, provided that
@@ -29,12 +29,14 @@ use diagnostics;
 use strict;
 
 my $progname = $0; $progname =~ s@.*/@@g;
-my $version = q{ $Revision: 1.16 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
+my $version  = q{ $Revision: 1.17 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
 
-my $verbose = 0;
+my $tmpdir   = $ENV{TMPDIR} || "/tmp";
+my $tmpfile  = sprintf("%s/xssv.%08x.ppm", $tmpdir, rand(0xFFFFFFFF));
 
-my $tmpdir  = $ENV{TMPDIR} || "/tmp";
-my $tmpfile = sprintf ("%s/xssgv.%08x.ppm", $tmpdir, rand(0xFFFFFFFF));
+my $verbose           = 0;
+my $use_stdout_p      = 0;
+my $return_filename_p = 0;
 
 
 # These are programs that can be used to grab a video frame.  The first one
@@ -70,15 +72,13 @@ my @programs = (
 );
 
 
-sub error {
-  ($_) = @_;
-  print STDERR "$progname: $_\n";
+sub error($) {
+  my ($e) = @_;
+  print STDERR "$progname: $e\n";
   exit 1;
 }
 
-my $displayer = undef;
-
-sub pick_grabber {
+sub pick_grabber() {
   my @names = ();
 
   foreach my $cmd (@programs) {
@@ -89,21 +89,17 @@ sub pick_grabber {
     foreach my $dir (split (/:/, $ENV{PATH})) {
       print STDERR "$progname:   checking $dir/$name\n" if ($verbose > 3);
       if (-x "$dir/$name") {
-        $displayer = $name;
         return $cmd;
       }
     }
   }
 
   $names[$#names] = "or " . $names[$#names];
-  error "none of: " . join (", ", @names) . " were found on \$PATH.";
+  error ("none of: " . join (", ", @names) . " were found on \$PATH.");
 }
 
 
-my $use_stdout_p = 0;
-my $return_filename_p = 0;
-
-sub grab_image {
+sub grab_image() {
   my $cmd = pick_grabber();
   unlink $tmpfile;
 
@@ -113,7 +109,7 @@ sub grab_image {
   if (-z $tmpfile)
     {
       unlink $tmpfile;
-      error "\"$cmd\" produced no data.";
+      error ("\"$cmd\" produced no data.");
     }
 
   if ($return_filename_p) {
@@ -126,13 +122,13 @@ sub grab_image {
     my $reader  = "<$tmpfile";
 
     # horrid kludge for SGIs, since they don't use PPM...
-    if ($displayer eq "vidtomem") {
+    if ($cmd =~ m/^vidtomem\s/) {
       $reader = "sgitopnm $tmpfile";
       $reader .= " 2>/dev/null" if ($verbose <= 1);
       $reader .= " |";
     }
 
-    open(IN, $reader) || error "reading $tmpfile: $!";
+    open(IN, $reader) || error ("reading $tmpfile: $!");
     print STDERR "$progname: reading $tmpfile\n" if ($verbose > 1);
     while (<IN>) { $ppm .= $_; }
     close IN;
@@ -153,12 +149,12 @@ sub grab_image {
 }
 
 
-sub usage {
+sub usage() {
   print STDERR "usage: $progname [--verbose] [--name | --stdout]\n";
   exit 1;
 }
 
-sub main {
+sub main() {
   while ($_ = $ARGV[0]) {
     shift @ARGV;
     if ($_ eq "--verbose") { $verbose++; }
index 9484831f505f3663cb3e4f57c8dd034ae86c8d48..0d2f65fc14f856211ee52aaef769c5080d8be192 100644 (file)
@@ -778,16 +778,16 @@ this is the way you disable it:
 .TP 3
 \fB1: Switch off KDE's screen saver.\fP
 Open the ``\fIControl Center\fP'' and
-select the ``\fILook and Feel / Screensaver\fP'' page.
-Turn off the ``\fIEnable Screensaver\fP'' checkbox.
+select the ``\fIAppearance & Themes -> Screensaver\fP'' page.
+Turn off the ``\fIStart Automatically\fP'' checkbox.
 .TP 3
 \fB2: Find your Autostart directory.\fP
-Open the ``\fILook and Feel / Desktop / Paths\fP'' page,
-and see what your ``Autostart'' directory is set to: it will
-probably be \fI~/.kde3/Autostart/\fP or something similar.
+Open the ``\fISystem Administration -> Paths\fP'' page,
+and see what your ``Autostart path'' is set to: it will
+probably be \fI~/.kde/Autostart/\fP or something similar.
 .TP 3
 \fB3: Make xscreensaver be an Autostart program.\fP
-Create a file in your autostart directory 
+Create a .desktop file in your autostart directory 
 called \fIxscreensaver.desktop\fP that contains the following five lines:
 .EX
 [Desktop Entry]
@@ -798,7 +798,9 @@ X-KDE-StartupNotify=false
 .EE
 .TP 3
 \fB4: Make the various "lock session" buttons call xscreensaver.\fP
-Replace the file \fI/usr/bin/kdesktop_lock\fP with these two lines:
+Replace the file \fI/usr/bin/kdesktop_lock\fP (or 
+possibly \fI/usr/kde/3.5/bin/kdesktop_lock\fP)
+with these two lines:
 .EX
 #!/bin/sh
 xscreensaver-command -lock
index ae934eb05c040309adb1dbe1b861a7a8a2d44bfc..b95f56d3d5e616aa7a7ad3417af59f73b40b2488 100644 (file)
@@ -110,8 +110,9 @@ SRCS                = attraction.c blitspin.c bouboule.c braid.c bubbles.c \
                  mismunch.c pacman.c pacman_ai.c pacman_level.c \
                  fuzzyflakes.c anemotaxis.c memscroller.c substrate.c \
                  intermomentary.c fireworkx.c fireworkx_mmx.S fiberlamp.c \
-                 boxfit.c interaggregate.c celtic.c webcollage-cocoa.m \
-                 webcollage-helper-cocoa.m
+                 boxfit.c interaggregate.c celtic.c cwaves.c m6502.c \
+                 asm6502.c \
+                 webcollage-cocoa.m webcollage-helper-cocoa.m
 SCRIPTS                = vidwhacker webcollage ljlatest
 
 # Programs that are mentioned in XScreenSaver.ad, and that have XML files,
@@ -148,8 +149,8 @@ OBJS                = attraction.o blitspin.o bouboule.o braid.o bubbles.o \
                  mismunch.o pacman.o pacman_ai.o pacman_level.o \
                  fuzzyflakes.o anemotaxis.o memscroller.o substrate.o \
                  intermomentary.o fireworkx.o fiberlamp.o boxfit.o \
-                 interaggregate.o celtic.o webcollage-cocoa.o \
-                 webcollage-helper-cocoa.o
+                 interaggregate.o celtic.o cwaves.o webcollage-cocoa.o \
+                 webcollage-helper-cocoa.o m6502.0 asm6502.o
 
 NEXES          = attraction blitspin bouboule braid bubbles decayscreen deco \
                  drift flag flame forest vines galaxy grav greynetic halo \
@@ -170,7 +171,7 @@ NEXES               = attraction blitspin bouboule braid bubbles decayscreen deco \
                  fontglide apple2 xanalogtv pong  wormhole mismunch \
                  pacman fuzzyflakes anemotaxis memscroller substrate \
                  intermomentary fireworkx fiberlamp boxfit interaggregate \
-                 celtic \
+                 celtic cwaves m6502 \
                  @JPEG_EXES@
 SEXES          = sonar
 JPEG_EXES      = webcollage-helper
@@ -187,7 +188,7 @@ XDBE_OBJS   = $(UTILS_BIN)/xdbe.o
 
 HDRS           = screenhack.h screenhackI.h xlockmore.h xlockmoreI.h \
                  automata.h bubbles.h bumps.h xpm-pixmap.h apple2.h \
-                 analogtv.h pacman.h pacman_ai.h pacman_level.h
+                 analogtv.h pacman.h pacman_ai.h pacman_level.h asm6502.h
 MEN            = anemone.man apollonian.man attraction.man \
                  blaster.man blitspin.man bouboule.man braid.man bsod.man \
                  bubbles.man bumps.man ccurve.man compass.man coral.man \
@@ -218,7 +219,7 @@ MEN         = anemone.man apollonian.man attraction.man \
                  wormhole.man mismunch.man pacman.man fuzzyflakes.man \
                  anemotaxis.man memscroller.man substrate.man \
                  intermomentary.man fireworkx.man fiberlamp.man boxfit.man \
-                 interaggregate.man celtic.man
+                 interaggregate.man celtic.man cwaves.man
 STAR           = *
 EXTRAS         = README Makefile.in xml2man.pl .gdbinit \
                  euler2d.tex \
@@ -761,7 +762,7 @@ xrayswarm:  xrayswarm.o     $(HACK_OBJS)
 hyperball:     hyperball.o     $(HACK_OBJS)
        $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) $(HACK_LIBS)
 
-zoom:  zoom.o  $(HACK_OBJS) $(GRAB)
+zoom:  zoom.o                  $(HACK_OBJS) $(GRAB)
        $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) $(GRAB) $(HACK_LIBS)
 
 whirlwindwarp: whirlwindwarp.o $(HACK_OBJS) $(COL)
@@ -851,6 +852,11 @@ ifs:               ifs.o           $(HACK_OBJS) $(COL)
 celtic:                celtic.o        $(HACK_OBJS) $(COL) $(ERASE)
        $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) $(COL) $(ERASE) $(HACK_LIBS)
 
+cwaves:                cwaves.o        $(HACK_OBJS) $(COL)
+       $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) $(COL) $(HACK_LIBS)
+
+m6502:         m6502.o         asm6502.o $(HACK_OBJS) $(ATV)
+       $(CC_HACK) -o $@ $@.o   asm6502.o $(HACK_OBJS) $(ATV) $(HACK_LIBS)
 
 # The rules for those hacks which follow the `xlockmore' API.
 #
@@ -1069,6 +1075,7 @@ apple2.o: $(UTILS_SRC)/usleep.h
 apple2.o: $(UTILS_SRC)/visual.h
 apple2.o: $(UTILS_SRC)/xshm.h
 apple2.o: $(UTILS_SRC)/yarandom.h
+asm6502.o: $(srcdir)/asm6502.h
 attraction.o: ../config.h
 attraction.o: $(srcdir)/screenhackI.h
 attraction.o: $(srcdir)/screenhack.h
@@ -1316,6 +1323,17 @@ crystal.o: $(UTILS_SRC)/xshm.h
 crystal.o: $(UTILS_SRC)/yarandom.h
 crystal.o: $(srcdir)/xlockmoreI.h
 crystal.o: $(srcdir)/xlockmore.h
+cwaves.o: ../config.h
+cwaves.o: $(srcdir)/screenhackI.h
+cwaves.o: $(srcdir)/screenhack.h
+cwaves.o: $(UTILS_SRC)/colors.h
+cwaves.o: $(UTILS_SRC)/grabscreen.h
+cwaves.o: $(UTILS_SRC)/hsv.h
+cwaves.o: $(UTILS_SRC)/resources.h
+cwaves.o: $(UTILS_SRC)/usleep.h
+cwaves.o: $(UTILS_SRC)/visual.h
+cwaves.o: $(UTILS_SRC)/yarandom.h
+cwaves.o: $(srcdir)/xpm-pixmap.h
 cynosure.o: ../config.h
 cynosure.o: $(srcdir)/screenhackI.h
 cynosure.o: $(srcdir)/screenhack.h
@@ -1843,6 +1861,19 @@ loop.o: $(UTILS_SRC)/xshm.h
 loop.o: $(UTILS_SRC)/yarandom.h
 loop.o: $(srcdir)/xlockmoreI.h
 loop.o: $(srcdir)/xlockmore.h
+m6502.o: $(srcdir)/analogtv.h
+m6502.o: $(srcdir)/asm6502.h
+m6502.o: ../config.h
+m6502.o: $(srcdir)/screenhackI.h
+m6502.o: $(srcdir)/screenhack.h
+m6502.o: $(UTILS_SRC)/colors.h
+m6502.o: $(UTILS_SRC)/grabscreen.h
+m6502.o: $(UTILS_SRC)/hsv.h
+m6502.o: $(UTILS_SRC)/resources.h
+m6502.o: $(UTILS_SRC)/usleep.h
+m6502.o: $(UTILS_SRC)/visual.h
+m6502.o: $(UTILS_SRC)/xshm.h
+m6502.o: $(UTILS_SRC)/yarandom.h
 maze.o: ../config.h
 maze.o: $(srcdir)/screenhackI.h
 maze.o: $(srcdir)/screenhack.h
diff --git a/hacks/asm6502.c b/hacks/asm6502.c
new file mode 100644 (file)
index 0000000..aeda482
--- /dev/null
@@ -0,0 +1,2148 @@
+/* Copyright (C) 2007 Jeremy English <jhe@jeremyenglish.org>
+ * 
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  No representations are made about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or 
+ * implied warranty.
+ * 
+ * Created: 12-April-2007 
+ */ 
+
+/*
+      This is a port of the javascript 6502 assembler, compiler and
+      debugger. The orignal code was copyright 2006 by Stian Soreng -
+      www.6502asm.com
+
+      I changed the structure of the assembler in this version.
+*/
+
+#define NDEBUG  /* Uncomment when done with debugging */
+
+#include <stdlib.h>
+#include <stdio.h>
+/*#include <malloc.h>*/
+#include <string.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+#include <math.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "asm6502.h"
+
+typedef enum{
+  LEFT, RIGHT
+    } Side;
+
+/* 
+
+Bit Flags
+   _  _  _  _  _  _  _  _ 
+  |N||V||F||B||D||I||Z||C|
+   -  -  -  -  -  -  -  - 
+   7  6  5  4  3  2  1  0
+
+*/
+
+typedef enum{
+      CARRY_FL = 0, ZERO_FL = 1, INTERRUPT_FL = 2, 
+       DECIMAL_FL = 3, BREAK_FL = 4, FUTURE_FL = 5,
+       OVERFLOW_FL = 6, NEGATIVE_FL = 7
+       } Flags;
+       
+
+typedef BOOL (*CharTest) (char);
+
+/* A jump function takes a pointer to the current machine and a
+   opcode. The opcode is needed to figure out the memory mode. */
+/*typedef void (*JumpFunc) (machine_6502* AddrMode);*/
+
+typedef struct {
+  AddrMode type;
+  Bit32 value[MAX_PARAM_VALUE];
+  unsigned int vp; /*value pointer, index into the value table.*/
+  char *label;
+  Bit32 lbladdr;
+} Param;
+
+typedef struct {
+  Bit32 addr; /* Address of the label */  
+  char *label; 
+} Label;  
+
+typedef struct AsmLine AsmLine;
+struct AsmLine {
+  BOOL labelDecl; /* Does the line have a label declaration? */
+  Label *label;
+  char *command;
+  Param *param;
+  AsmLine *next; /* in list */
+};
+
+typedef struct {
+  Bit16 addr;
+  Bit16 value;
+} Pointer;
+
+/* eprintf - Taken from "Practice of Programming" by Kernighan and Pike */
+static void eprintf(char *fmt, ...){
+  va_list args;
+  
+  char *progname = "Assembler";
+
+  fflush(stdout);
+  if (progname != NULL)
+    fprintf(stderr, "%s: ", progname);
+
+  va_start(args, fmt);
+  vfprintf(stderr, fmt, args);
+  va_end(args);
+  
+  if (fmt[0] != '\0' && fmt[strlen(fmt) -1] == ':')
+    fprintf(stderr, " %s", strerror(errno));
+  fprintf(stderr, "\n");
+  exit(2); /* conventional value for failed execution */
+}
+
+/* emalloc - Taken from "Practice of Programming" by Kernighan and
+   Pike.  If memory allocatiion fails the program will print a message
+   an exit. */
+static void *emalloc(size_t n) {
+  void *p;
+  
+  p = malloc(n);
+  if (p == NULL)
+    eprintf("malloc of %u bytes failed:", n);
+  return p;
+}
+
+/* ecalloc - Dose the same thing as emalloc just calls calloc instead. */
+static void *ecalloc(uint32_t nelm, size_t nsize){
+  void *p;
+  p = calloc(nelm, nsize);
+  if (p == NULL)
+    eprintf("calloc of %u bytes failed:", nelm * nsize);
+  return p;
+}
+
+/* estrdup() - Allocates memory for a new string a returns a copy of the source sting in it. */
+static char *estrdup(const char *source){
+  int ln = strlen(source) + 1;
+  char *s = ecalloc(ln, sizeof(char));
+  strncpy(s,source,ln);
+  return s;
+}
+
+static void checkAddress(Bit32 address){
+  /* XXX: Do we want to kill the program here? */
+  if (address >= MEM_64K)
+    fprintf(stderr, "Address %d is beyond 64k", address);
+}
+
+/*
+ *  stackPush() - Push byte to stack
+ *
+ */
+
+static void stackPush(machine_6502 *machine, Bit8 value ) {
+  if(machine->regSP >= STACK_BOTTOM){
+    machine->memory[machine->regSP--] = value;
+  }
+  else{
+    fprintf(stderr, "The stack is full: %.4x\n", machine->regSP);
+    machine->codeRunning = FALSE;
+  }
+}
+
+
+/*
+ *  stackPop() - Pop byte from stack
+ *
+ */
+
+static Bit8 stackPop(machine_6502 *machine) {
+  if (machine->regSP < STACK_TOP){
+    Bit8 value =machine->memory[++machine->regSP];
+    return value;
+  }
+  else {
+    /*    fprintf(stderr, "The stack is empty.\n"); xxx */
+    machine->codeRunning = FALSE;
+    return 0;
+  }
+}
+
+static void pushByte(machine_6502 *machine, Bit32 value ) {
+  Bit32 address = 0x600 + machine->codeLen;
+  checkAddress(address);
+  machine->memory[0x600 + machine->codeLen] = value & 0xff;
+  machine->codeLen++;
+}
+
+/*
+ * pushWord() - Push a word using pushByte twice
+ *
+ */
+
+static void pushWord(machine_6502 *machine, Bit16 value ) {
+  pushByte(machine, value & 0xff );
+  pushByte(machine, (value>>8) & 0xff );
+}
+
+/*
+ * popByte( machine_6502 *machine,) - Pops a byte
+ *
+ */
+
+static Bit8 popByte( machine_6502 *machine) {
+  Bit8 value = machine->memory[machine->regPC];
+  machine->regPC++;
+  return value;
+}
+
+/*
+ * popWord() - Pops a word using popByte() twice
+ *
+ */
+
+static int popWord(machine_6502 *machine) {
+  return popByte(machine) + (popByte(machine) << 8);
+}
+
+
+/*
+ * memReadByte() - Peek a byte, don't touch any registers
+ *
+ */
+
+static int memReadByte( machine_6502 *machine, int addr ) {
+  if( addr == 0xfe ) return floor( random()%255 );
+  return machine->memory[addr];
+}
+
+static void updateDisplayPixel(machine_6502 *machine, Bit16 addr){
+  Bit8 idx = memReadByte(machine,addr) & 0x0f;
+  Bit8 x,y;
+  addr -= 0x200;
+  x = addr & 0x1f;
+  y = (addr >> 5);
+  if (machine->plot) {
+    machine->plot(x,y,idx,machine->plotterState);
+  }
+}
+
+/*
+ * memStoreByte() - Poke a byte, don't touch any registers
+ *
+ */
+
+static void memStoreByte( machine_6502 *machine, int addr, int value ) {
+  machine->memory[ addr ] = (value & 0xff);
+  if( (addr >= 0x200) && (addr<=0x5ff) )
+    updateDisplayPixel(machine, addr );
+}
+
+
+\f
+/* EMULATION CODE */
+
+static Bit8 bitOn(Bit8 value,Flags bit){
+  Bit8 mask = 1;
+  mask = mask << bit;
+  return ((value & mask) > 0);
+}
+
+static Bit8 bitOff(Bit8 value, Flags bit){
+  return (! bitOn(value,bit));
+}
+
+static Bit8 setBit(Bit8 value, Flags bit, int on){
+  Bit8 onMask  = 1;
+  Bit8 offMask = 0xff;
+  onMask = onMask << bit;
+  offMask = offMask ^ onMask;
+  return ((on) ? value | onMask : value & offMask);
+}
+
+static Bit8 nibble(Bit8 value, Side side){
+  switch(side){
+  case LEFT:  return value & 0xf0;
+  case RIGHT: return value & 0xf;
+  default:
+    fprintf(stderr,"nibble unknown side\n");
+    return 0;
+  }
+}
+
+
+/* used for tracing. XXX: combined with function getvalue */
+static BOOL peekValue(machine_6502 *machine, AddrMode adm, Pointer *pointer, Bit16 PC){
+  Bit8 zp;
+  pointer->value = 0;
+  pointer->addr = 0;
+  switch(adm){
+  case SINGLE:
+    return FALSE;
+  case IMMEDIATE_LESS:
+  case IMMEDIATE_GREAT:
+  case IMMEDIATE_VALUE:
+    pointer->value = memReadByte(machine, PC);
+    return TRUE;
+  case INDIRECT_X:
+    zp = memReadByte(machine, PC);
+    pointer->addr = memReadByte(machine,zp) + 
+      (memReadByte(machine,zp+1)<<8) + machine->regX;
+    pointer->value = memReadByte(machine, pointer->addr);
+    return TRUE;
+  case INDIRECT_Y:
+    zp = memReadByte(machine, PC);
+    pointer->addr = memReadByte(machine,zp) + 
+      (memReadByte(machine,zp+1)<<8) + machine->regY;
+    pointer->value = memReadByte(machine, pointer->addr);
+    return TRUE;
+  case ZERO:
+    pointer->addr = memReadByte(machine, PC);
+    pointer->value = memReadByte(machine, pointer->addr);
+    return TRUE;
+  case ZERO_X:
+    pointer->addr = memReadByte(machine, PC) + machine->regX;
+    pointer->value = memReadByte(machine, pointer->addr);
+    return TRUE;
+  case ZERO_Y:
+    pointer->addr = memReadByte(machine, PC) + machine->regY;
+    pointer->value = memReadByte(machine, pointer->addr);
+    return TRUE;
+  case ABS_OR_BRANCH:
+    pointer->addr = memReadByte(machine, PC);
+    return TRUE;
+  case ABS_VALUE:
+    pointer->addr = memReadByte(machine, PC) + (memReadByte(machine, PC+1) << 8);
+    pointer->value = memReadByte(machine, pointer->addr);
+    return TRUE;
+  case ABS_LABEL_X:
+  case ABS_X:
+    pointer->addr = (memReadByte(machine, PC) + 
+                    (memReadByte(machine, PC+1) << 8)) + machine->regX;
+    pointer->value = memReadByte(machine, pointer->addr);
+    return TRUE;
+  case ABS_LABEL_Y:
+  case ABS_Y:
+    pointer->addr = (memReadByte(machine, PC) + 
+                    (memReadByte(machine, PC+1) << 8)) + machine->regY;
+    pointer->value = memReadByte(machine, pointer->addr);
+    return TRUE;
+  case DCB_PARAM:
+    /* Handled elsewhere */
+    break;
+  }
+  return FALSE;
+
+}
+
+
+/* Figure out how to get the value from the addrmode and get it.*/
+static BOOL getValue(machine_6502 *machine, AddrMode adm, Pointer *pointer){
+  Bit8 zp;
+  pointer->value = 0;
+  pointer->addr = 0;
+  switch(adm){
+  case SINGLE:
+    return FALSE;
+  case IMMEDIATE_LESS:
+  case IMMEDIATE_GREAT:
+  case IMMEDIATE_VALUE:
+    pointer->value = popByte(machine);
+    return TRUE;
+  case INDIRECT_X:
+    zp = popByte(machine);
+    pointer->addr = memReadByte(machine,zp) + 
+      (memReadByte(machine,zp+1)<<8) + machine->regX;
+    pointer->value = memReadByte(machine, pointer->addr);
+    return TRUE;
+  case INDIRECT_Y:
+    zp = popByte(machine);
+    pointer->addr = memReadByte(machine,zp) + 
+      (memReadByte(machine,zp+1)<<8) + machine->regY;
+    pointer->value = memReadByte(machine, pointer->addr);
+    return TRUE;
+  case ZERO:
+    pointer->addr = popByte(machine);
+    pointer->value = memReadByte(machine, pointer->addr);
+    return TRUE;
+  case ZERO_X:
+    pointer->addr = popByte(machine) + machine->regX;
+    pointer->value = memReadByte(machine, pointer->addr);
+    return TRUE;
+  case ZERO_Y:
+    pointer->addr = popByte(machine) + machine->regY;
+    pointer->value = memReadByte(machine, pointer->addr);
+    return TRUE;
+  case ABS_OR_BRANCH:
+    pointer->addr = popByte(machine);
+    return TRUE;
+  case ABS_VALUE:
+    pointer->addr = popWord(machine);
+    pointer->value = memReadByte(machine, pointer->addr);
+    return TRUE;
+  case ABS_LABEL_X:
+  case ABS_X:
+    pointer->addr = popWord(machine) + machine->regX;
+    pointer->value = memReadByte(machine, pointer->addr);
+    return TRUE;
+  case ABS_LABEL_Y:
+  case ABS_Y:
+    pointer->addr = popWord(machine) + machine->regY;
+    pointer->value = memReadByte(machine, pointer->addr);
+    return TRUE;
+  case DCB_PARAM:
+    /* Handled elsewhere */
+    break;
+  }
+  return FALSE;
+
+}
+
+/* manZeroNeg - Manage the negative and zero flags */
+static void manZeroNeg(machine_6502 *machine, Bit8 value){
+  machine->regP = setBit(machine->regP, ZERO_FL, (value == 0));
+  machine->regP = setBit(machine->regP, NEGATIVE_FL, bitOn(value,NEGATIVE_FL));
+}
+
+static void warnValue(BOOL isValue){
+  if (! isValue){
+    fprintf(stderr,"Invalid Value from getValue.\n");
+  }
+}
+
+static void jmpADC(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  Bit16 tmp;
+  Bit8 c = bitOn(machine->regP, CARRY_FL);
+  BOOL isValue = getValue(machine, adm, &ptr);
+
+  warnValue(isValue);
+  
+  if (bitOn(machine->regA, NEGATIVE_FL) &&
+      bitOn(ptr.value, NEGATIVE_FL))
+    machine->regP = setBit(machine->regP, OVERFLOW_FL, 0);
+  else
+    machine->regP = setBit(machine->regP, OVERFLOW_FL, 1);
+
+  if (bitOn(machine->regP, DECIMAL_FL)) {    
+    tmp = nibble(machine->regA,RIGHT) + nibble(ptr.value,RIGHT ) + c;
+    /* The decimal part is limited to 0 through 9 */
+    if (tmp >= 10){
+      tmp = 0x10 | ((tmp + 6) & 0xf);
+    }
+    tmp += nibble(machine->regA,LEFT) + nibble(ptr.value,LEFT);
+    if (tmp >= 160){
+      machine->regP = setBit(machine->regP,CARRY_FL,1);
+      if (bitOn(machine->regP, OVERFLOW_FL) && tmp >= 0x180)
+       machine->regP = setBit(machine->regP, OVERFLOW_FL, 0);
+      tmp += 0x60;
+    }
+    else {
+      machine->regP = setBit(machine->regP,CARRY_FL,0);
+      if (bitOn(machine->regP, OVERFLOW_FL) && tmp < 0x80)
+       machine->regP = setBit(machine->regP, OVERFLOW_FL, 0);
+    }
+  } /* end decimal */      
+  else {
+    tmp = machine->regA + ptr.value + c;
+    if ( tmp >= 0x100 ){
+      machine->regP = setBit(machine->regP,CARRY_FL,1);
+      if (bitOn(machine->regP, OVERFLOW_FL) && tmp >= 0x180)
+       machine->regP =setBit(machine->regP, OVERFLOW_FL, 0);
+    }
+    else {
+      machine->regP = setBit(machine->regP,CARRY_FL,0);
+      if (bitOn(machine->regP, OVERFLOW_FL) && tmp < 0x80)
+       machine->regP =setBit(machine->regP, OVERFLOW_FL, 0);
+    }
+  }
+
+  machine->regA = tmp;
+  manZeroNeg(machine,machine->regA);
+}
+
+static void jmpAND(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  machine->regA &= ptr.value;
+  manZeroNeg(machine,machine->regA);
+}
+
+static void jmpASL(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  if (isValue){
+      machine->regP = setBit(machine->regP, CARRY_FL, bitOn(ptr.value, NEGATIVE_FL));
+      ptr.value = ptr.value << 1;
+      ptr.value = setBit(ptr.value, CARRY_FL, 0);
+      memStoreByte(machine, ptr.addr, ptr.value);
+      manZeroNeg(machine,ptr.value);
+  }
+  else { /* Accumulator */
+      machine->regP = setBit(machine->regP, CARRY_FL, bitOn(machine->regA, NEGATIVE_FL));
+      machine->regA = machine->regA << 1;
+      machine->regA = setBit(machine->regA, CARRY_FL, 0);
+      manZeroNeg(machine,machine->regA);
+  }  
+  
+}
+
+static void jmpBIT(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  machine->regP = setBit(machine->regP, ZERO_FL, (ptr.value & machine->regA));
+  machine->regP = setBit(machine->regP, OVERFLOW_FL, bitOn(ptr.value, OVERFLOW_FL));
+  machine->regP = setBit(machine->regP, NEGATIVE_FL, bitOn(ptr.value, NEGATIVE_FL));
+  
+}
+
+static void jumpBranch(machine_6502 *machine, Bit16 offset){
+  if ( offset > 0x7f )
+    machine->regPC = machine->regPC - (0x100 - offset);
+  else
+    machine->regPC = machine->regPC + offset;
+}
+
+static void jmpBPL(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  if (bitOff(machine->regP,NEGATIVE_FL))
+    jumpBranch(machine, ptr.addr);
+    
+}
+
+static void jmpBMI(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  if (bitOn(machine->regP,NEGATIVE_FL))
+    jumpBranch(machine, ptr.addr);
+
+}
+
+static void jmpBVC(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  if (bitOff(machine->regP,OVERFLOW_FL))
+    jumpBranch(machine, ptr.addr);
+}
+
+static void jmpBVS(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  if (bitOn(machine->regP,OVERFLOW_FL))
+    jumpBranch(machine, ptr.addr);
+}
+
+static void jmpBCC(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  if (bitOff(machine->regP,CARRY_FL))
+    jumpBranch(machine, ptr.addr);
+}
+
+static void jmpBCS(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  if (bitOn(machine->regP,CARRY_FL))
+    jumpBranch(machine, ptr.addr);
+}
+
+static void jmpBNE(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  if (bitOff(machine->regP, ZERO_FL))
+    jumpBranch(machine, ptr.addr);
+}
+
+static void jmpBEQ(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  if (bitOn(machine->regP, ZERO_FL))
+    jumpBranch(machine, ptr.addr);
+}
+
+static void doCompare(machine_6502 *machine, Bit16 reg, Pointer *ptr){
+  machine->regP = setBit(machine->regP,CARRY_FL, ((reg + ptr->value) > 0xff));
+  manZeroNeg(machine,(reg - ptr->value));
+}
+
+static void jmpCMP(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  doCompare(machine,machine->regA,&ptr);
+}
+
+static void jmpCPX(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  doCompare(machine,machine->regX,&ptr);
+}
+
+static void jmpCPY(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  doCompare(machine,machine->regY,&ptr);
+}
+
+static void jmpDEC(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  if (ptr.value > 0)
+    ptr.value--;
+  else
+    ptr.value = 0xFF;
+  memStoreByte(machine, ptr.addr, ptr.value);
+  manZeroNeg(machine,ptr.value);
+}
+
+static void jmpEOR(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  machine->regA ^= ptr.value;
+  manZeroNeg(machine, machine->regA);
+}
+
+static void jmpCLC(machine_6502 *machine, AddrMode adm){
+  machine->regP = setBit(machine->regP, CARRY_FL, 0);
+}
+
+static void jmpSEC(machine_6502 *machine, AddrMode adm){
+  machine->regP = setBit(machine->regP, CARRY_FL, 1);
+}
+
+static void jmpCLI(machine_6502 *machine, AddrMode adm){
+  machine->regP = setBit(machine->regP, INTERRUPT_FL, 0);
+}
+
+static void jmpSEI(machine_6502 *machine, AddrMode adm){
+  machine->regP = setBit(machine->regP, INTERRUPT_FL, 1);
+}
+
+static void jmpCLV(machine_6502 *machine, AddrMode adm){
+  machine->regP = setBit(machine->regP, OVERFLOW_FL, 0);
+}
+
+static void jmpCLD(machine_6502 *machine, AddrMode adm){
+  machine->regP = setBit(machine->regP, DECIMAL_FL, 0);
+}
+
+static void jmpSED(machine_6502 *machine, AddrMode adm){
+  machine->regP = setBit(machine->regP, DECIMAL_FL, 1);
+}
+
+static void jmpINC(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  ptr.value = (ptr.value + 1) & 0xFF;
+  memStoreByte(machine, ptr.addr, ptr.value);
+  manZeroNeg(machine,ptr.value);
+}
+
+static void jmpJMP(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  machine->regPC = ptr.addr;
+}
+
+static void jmpJSR(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  /* Move past the 2 byte parameter. JSR is always followed by
+     absolute address. */
+  Bit16 currAddr = machine->regPC + 2;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  stackPush(machine, (currAddr >> 8) & 0xff);
+  stackPush(machine, currAddr & 0xff);
+  machine->regPC = ptr.addr;  
+}
+
+static void jmpLDA(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  machine->regA = ptr.value;
+  manZeroNeg(machine, machine->regA);
+}
+
+static void jmpLDX(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  machine->regX = ptr.value;
+  manZeroNeg(machine, machine->regX);
+}
+
+static void jmpLDY(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  machine->regY = ptr.value;
+  manZeroNeg(machine, machine->regY);
+}
+
+static void jmpLSR(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  if (isValue){
+    machine->regP = 
+      setBit(machine->regP, CARRY_FL, 
+            bitOn(ptr.value, CARRY_FL));
+    ptr.value = ptr.value >> 1;
+    ptr.value = setBit(ptr.value,NEGATIVE_FL,0);
+    memStoreByte(machine,ptr.addr,ptr.value);
+    manZeroNeg(machine,ptr.value);
+  }
+  else { /* Accumulator */
+    machine->regP = 
+      setBit(machine->regP, CARRY_FL, 
+            bitOn(machine->regA, CARRY_FL));
+    machine->regA = machine->regA >> 1;
+    machine->regA = setBit(machine->regA,NEGATIVE_FL,0);
+    manZeroNeg(machine,ptr.value);
+  }
+}
+
+static void jmpNOP(machine_6502 *machine, AddrMode adm){
+  /* no operation */
+}
+
+static void jmpORA(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  machine->regA |= ptr.value;
+  manZeroNeg(machine,machine->regA);
+}
+
+static void jmpTAX(machine_6502 *machine, AddrMode adm){
+  machine->regX = machine->regA;
+  manZeroNeg(machine,machine->regX);
+}
+
+static void jmpTXA(machine_6502 *machine, AddrMode adm){
+  machine->regA = machine->regX;
+  manZeroNeg(machine,machine->regA);
+}
+
+static void jmpDEX(machine_6502 *machine, AddrMode adm){
+  if (machine->regX > 0)
+    machine->regX--;
+  else
+    machine->regX = 0xFF;
+  manZeroNeg(machine, machine->regX);
+}
+
+static void jmpINX(machine_6502 *machine, AddrMode adm){
+  Bit16 value = machine->regX + 1;
+  machine->regX = value & 0xFF;
+  manZeroNeg(machine, machine->regX);
+}
+
+static void jmpTAY(machine_6502 *machine, AddrMode adm){
+  machine->regY = machine->regA;
+  manZeroNeg(machine, machine->regY);
+}
+
+static void jmpTYA(machine_6502 *machine, AddrMode adm){
+  machine->regA = machine->regY;
+  manZeroNeg(machine, machine->regA);
+}
+
+static void jmpDEY(machine_6502 *machine, AddrMode adm){
+  if (machine->regY > 0)
+    machine->regY--;
+  else
+    machine->regY = 0xFF;
+  manZeroNeg(machine, machine->regY);
+}
+
+static void jmpINY(machine_6502 *machine, AddrMode adm){
+  Bit16 value = machine->regY + 1;
+  machine->regY = value & 0xff;
+  manZeroNeg(machine, machine->regY);
+}
+
+static void jmpROR(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  Bit8 cf;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  if (isValue) { 
+    cf = bitOn(machine->regP, CARRY_FL);
+    machine->regP = 
+      setBit(machine->regP, CARRY_FL,
+            bitOn(ptr.value, CARRY_FL));
+    ptr.value = ptr.value >> 1;
+    ptr.value = setBit(ptr.value, NEGATIVE_FL, cf);
+    memStoreByte(machine, ptr.addr, ptr.value);
+    manZeroNeg(machine, ptr.value);
+  }
+  else { /* Implied */
+    cf = bitOn(machine->regP, CARRY_FL);
+    machine->regP = 
+      setBit(machine->regP, CARRY_FL,
+            bitOn(machine->regA, CARRY_FL));
+    machine->regA = machine->regA >> 1;
+    machine->regA = setBit(machine->regA, NEGATIVE_FL, cf);
+    manZeroNeg(machine, machine->regA);
+  }
+}
+
+static void jmpROL(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  Bit8 cf;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  if (isValue) { 
+    cf = bitOn(machine->regP, CARRY_FL);
+    machine->regP = 
+      setBit(machine->regP, CARRY_FL,
+            bitOn(ptr.value, NEGATIVE_FL));
+    ptr.value = ptr.value << 1;
+    ptr.value = setBit(ptr.value, CARRY_FL, cf);
+    memStoreByte(machine, ptr.addr, ptr.value);
+    manZeroNeg(machine, ptr.value);
+  }
+  else { /* Implied */
+    cf = bitOn(machine->regP, CARRY_FL);
+    machine->regP = 
+      setBit(machine->regP, CARRY_FL,
+            bitOn(machine->regA,NEGATIVE_FL));
+    machine->regA = machine->regA << 1;
+    machine->regA = setBit(machine->regA, CARRY_FL, cf);
+    manZeroNeg(machine, machine->regA);
+  }
+}
+
+static void jmpRTI(machine_6502 *machine, AddrMode adm){
+  machine->regP = stackPop(machine);
+  machine->regPC = stackPop(machine);
+}
+
+static void jmpRTS(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  Bit16 nr = stackPop(machine);
+  Bit16 nl = stackPop(machine);
+  warnValue(! isValue);
+  machine->regPC = (nl << 8) | nr;
+}
+
+static void jmpSBC(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  Bit8 vflag;
+  Bit8 c = bitOn(machine->regP, CARRY_FL);
+  Bit16 tmp, w;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  vflag = (bitOn(machine->regA,NEGATIVE_FL) &&
+          bitOn(ptr.value, NEGATIVE_FL));
+
+  if (bitOn(machine->regP, DECIMAL_FL)) {
+    Bit8 ar = nibble(machine->regA, RIGHT);
+    Bit8 br = nibble(ptr.value, RIGHT);
+    Bit8 al = nibble(machine->regA, LEFT);
+    Bit8 bl = nibble(machine->regA, LEFT);
+
+    tmp = 0xf + ar - br + c;
+    if ( tmp < 0x10){
+      w = 0;
+      tmp -= 6;
+    }
+    else {
+      w = 0x10;
+      tmp -= 0x10;
+    }
+    w += 0xf0 + al - bl;
+    if ( w < 0x100) {
+      machine->regP = setBit(machine->regP, CARRY_FL, 0);
+      if (bitOn(machine->regP, OVERFLOW_FL) && w < 0x80)
+       machine->regP = setBit(machine->regP, OVERFLOW_FL, 0);
+      w -= 0x60;
+    }
+    else {
+      machine->regP = setBit(machine->regP, CARRY_FL, 1);
+      if (bitOn(machine->regP, OVERFLOW_FL) && w >= 0x180)
+       machine->regP = setBit(machine->regP, OVERFLOW_FL, 0);
+    }
+    w += tmp;
+  } /* end decimal mode */
+  else {
+    w = 0xff + machine->regA - ptr.value + c;
+    if ( w < 0x100 ){
+      machine->regP = setBit(machine->regP, CARRY_FL, 0);
+      if (bitOn(machine->regP, OVERFLOW_FL) && w < 0x80)
+       machine->regP = setBit(machine->regP, OVERFLOW_FL, 0);
+    }
+    else {
+      machine->regP = setBit(machine->regP, CARRY_FL, 1);
+      if (bitOn(machine->regP, OVERFLOW_FL) && w >= 0x180)
+       machine->regP = setBit(machine->regP, OVERFLOW_FL, 0);
+    }
+  }
+  machine->regA = w;
+  manZeroNeg(machine,machine->regA);
+}
+
+static void jmpSTA(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  memStoreByte(machine,ptr.addr,machine->regA);
+}
+
+static void jmpTXS(machine_6502 *machine, AddrMode adm){
+  stackPush(machine,machine->regX);
+}
+
+static void jmpTSX(machine_6502 *machine, AddrMode adm){
+  machine->regX = stackPop(machine);
+  manZeroNeg(machine, machine->regX);
+}
+
+static void jmpPHA(machine_6502 *machine, AddrMode adm){
+  stackPush(machine, machine->regA);
+}
+
+static void jmpPLA(machine_6502 *machine, AddrMode adm){
+  machine->regA = stackPop(machine);
+  manZeroNeg(machine, machine->regA);
+}
+
+static void jmpPHP(machine_6502 *machine, AddrMode adm){
+  stackPush(machine,machine->regP);
+}
+
+static void jmpPLP(machine_6502 *machine, AddrMode adm){
+  machine->regP = stackPop(machine);
+  machine->regP = setBit(machine->regP, FUTURE_FL, 1);
+}
+
+static void jmpSTX(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  memStoreByte(machine,ptr.addr,machine->regX);
+}
+
+static void jmpSTY(machine_6502 *machine, AddrMode adm){
+  Pointer ptr;
+  BOOL isValue = getValue(machine, adm, &ptr);
+  warnValue(isValue);
+  memStoreByte(machine,ptr.addr,machine->regY);
+}
+
+\f
+
+/* OPCODES */
+static void assignOpCodes(Opcodes *opcodes){
+
+ #define SETOP(num, _name, _Imm, _ZP, _ZPX, _ZPY, _ABS, _ABSX, _ABSY, _INDX, _INDY, _SNGL, _BRA, _func) \
+{opcodes[num].name[4] = '\0'; \
+ strncpy(opcodes[num].name, _name, 3); opcodes[num].Imm = _Imm; opcodes[num].ZP = _ZP; \
+ opcodes[num].ZPX = _ZPX; opcodes[num].ZPY = _ZPY; opcodes[num].ABS = _ABS; \
+ opcodes[num].ABSX = _ABSX; opcodes[num].ABSY = _ABSY; opcodes[num].INDX = _INDX; \
+ opcodes[num].INDY = _INDY; opcodes[num].SNGL = _SNGL; opcodes[num].BRA = _BRA; \
+ opcodes[num].func = _func;}
+
+  /*        OPCODE Imm   ZP    ZPX   ZPY   ABS   ABSX  ABSY  INDX  INDY  SGNL  BRA   Jump Function*/ 
+  SETOP( 0, "ADC", 0x69, 0x65, 0x75, 0x00, 0x6d, 0x7d, 0x79, 0x61, 0x71, 0x00, 0x00, jmpADC);
+  SETOP( 1, "AND", 0x29, 0x25, 0x35, 0x31, 0x2d, 0x3d, 0x39, 0x00, 0x00, 0x00, 0x00, jmpAND);
+  SETOP( 2, "ASL", 0x00, 0x06, 0x16, 0x00, 0x0e, 0x1e, 0x00, 0x00, 0x00, 0x0a, 0x00, jmpASL);
+  SETOP( 3, "BIT", 0x00, 0x24, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, jmpBIT);
+  SETOP( 4, "BPL", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, jmpBPL);
+  SETOP( 5, "BMI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, jmpBMI);
+  SETOP( 6, "BVC", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, jmpBVC);
+  SETOP( 7, "BVS", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, jmpBVS);
+  SETOP( 8, "BCC", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, jmpBCC);
+  SETOP( 9, "BCS", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, jmpBCS);
+  SETOP(10, "BNE", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, jmpBNE);
+  SETOP(11, "BEQ", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, jmpBEQ);
+  SETOP(12, "CMP", 0xc9, 0xc5, 0xd5, 0x00, 0xcd, 0xdd, 0xd9, 0xc1, 0xd1, 0x00, 0x00, jmpCMP);
+  SETOP(13, "CPX", 0xe0, 0xe4, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, jmpCPX);
+  SETOP(14, "CPY", 0xc0, 0xc4, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, jmpCPY);
+  SETOP(15, "DEC", 0x00, 0xc6, 0xd6, 0x00, 0xce, 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, jmpDEC);
+  SETOP(16, "EOR", 0x49, 0x45, 0x55, 0x00, 0x4d, 0x5d, 0x59, 0x41, 0x51, 0x00, 0x00, jmpEOR);
+  SETOP(17, "CLC", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, jmpCLC);
+  SETOP(18, "SEC", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, jmpSEC);
+  SETOP(19, "CLI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, jmpCLI);
+  SETOP(20, "SEI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, jmpSEI);
+  SETOP(21, "CLV", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x00, jmpCLV);
+  SETOP(22, "CLD", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x00, jmpCLD);
+  SETOP(23, "SED", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, jmpSED);
+  SETOP(24, "INC", 0x00, 0xe6, 0xf6, 0x00, 0xee, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, jmpINC);
+  SETOP(25, "JMP", 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, jmpJMP);
+  SETOP(26, "JSR", 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, jmpJSR);
+  SETOP(27, "LDA", 0xa9, 0xa5, 0xb5, 0x00, 0xad, 0xbd, 0xb9, 0xa1, 0xb1, 0x00, 0x00, jmpLDA);
+  SETOP(28, "LDX", 0xa2, 0xa6, 0x00, 0xb6, 0xae, 0x00, 0xbe, 0x00, 0x00, 0x00, 0x00, jmpLDX);
+  SETOP(29, "LDY", 0xa0, 0xa4, 0xb4, 0x00, 0xac, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, jmpLDY);
+  SETOP(30, "LSR", 0x00, 0x46, 0x56, 0x00, 0x4e, 0x5e, 0x00, 0x00, 0x00, 0x4a, 0x00, jmpLSR);
+  SETOP(31, "NOP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x00, jmpNOP);
+  SETOP(32, "ORA", 0x09, 0x05, 0x15, 0x00, 0x0d, 0x1d, 0x19, 0x01, 0x11, 0x00, 0x00, jmpORA);
+  SETOP(33, "TAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x00, jmpTAX);
+  SETOP(34, "TXA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x00, jmpTXA);
+  SETOP(35, "DEX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0x00, jmpDEX);
+  SETOP(36, "INX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x00, jmpINX);
+  SETOP(37, "TAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, jmpTAY);
+  SETOP(38, "TYA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, jmpTYA);
+  SETOP(39, "DEY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, jmpDEY);
+  SETOP(40, "INY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00, jmpINY);
+  SETOP(41, "ROR", 0x00, 0x66, 0x76, 0x00, 0x6e, 0x7e, 0x00, 0x00, 0x00, 0x6a, 0x00, jmpROR);
+  SETOP(42, "ROL", 0x00, 0x26, 0x36, 0x00, 0x2e, 0x3e, 0x00, 0x00, 0x00, 0x2a, 0x00, jmpROL);
+  SETOP(43, "RTI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, jmpRTI);
+  SETOP(44, "RTS", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, jmpRTS);
+  SETOP(45, "SBC", 0xe9, 0xe5, 0xf5, 0x00, 0xed, 0xfd, 0xf9, 0xe1, 0xf1, 0x00, 0x00, jmpSBC);
+  SETOP(46, "STA", 0x00, 0x85, 0x95, 0x00, 0x8d, 0x9d, 0x99, 0x81, 0x91, 0x00, 0x00, jmpSTA);
+  SETOP(47, "TXS", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x00, jmpTXS);
+  SETOP(48, "TSX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xba, 0x00, jmpTSX);
+  SETOP(49, "PHA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, jmpPHA);
+  SETOP(50, "PLA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, jmpPLA);
+  SETOP(51, "PHP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, jmpPHP);
+  SETOP(52, "PLP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, jmpPLP);
+  SETOP(53, "STX", 0x00, 0x86, 0x00, 0x96, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, jmpSTX);
+  SETOP(54, "STY", 0x00, 0x84, 0x94, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, jmpSTY);
+  SETOP(55, "---", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, NULL);
+}
+
+static void buildIndexCache(machine_6502 *machine){
+  unsigned int i;
+  for (i = 0; i < NUM_OPCODES; i++) {
+    if (machine->opcodes[i].Imm != 0x00){
+      machine->opcache[machine->opcodes[i].Imm].adm = IMMEDIATE_VALUE;
+      machine->opcache[machine->opcodes[i].Imm].index = i;
+    }
+     if (machine->opcodes[i].ZP != 0x00){
+      machine->opcache[machine->opcodes[i].ZP].adm = ZERO;
+      machine->opcache[machine->opcodes[i].ZP].index = i;
+    }
+     if (machine->opcodes[i].ZPX != 0x00){
+      machine->opcache[machine->opcodes[i].ZPX].adm = ZERO_X;
+      machine->opcache[machine->opcodes[i].ZPX].index = i;;
+    }
+     if (machine->opcodes[i].ZPY != 0x00){
+      machine->opcache[machine->opcodes[i].ZPY].adm = ZERO_Y;
+      machine->opcache[machine->opcodes[i].ZPY].index = i;;
+    }
+     if (machine->opcodes[i].ABS != 0x00){
+      machine->opcache[machine->opcodes[i].ABS].adm = ABS_VALUE;
+      machine->opcache[machine->opcodes[i].ABS].index = i;;
+    }
+     if (machine->opcodes[i].ABSX != 0x00){
+      machine->opcache[machine->opcodes[i].ABSX].adm = ABS_X;
+      machine->opcache[machine->opcodes[i].ABSX].index = i;;
+    }
+     if (machine->opcodes[i].ABSY != 0x00){
+      machine->opcache[machine->opcodes[i].ABSY].adm = ABS_Y;
+      machine->opcache[machine->opcodes[i].ABSY].index = i;;
+    }
+     if (machine->opcodes[i].INDX != 0x00){
+      machine->opcache[machine->opcodes[i].INDX].adm = INDIRECT_X;
+      machine->opcache[machine->opcodes[i].INDX].index = i;;
+    }
+     if (machine->opcodes[i].INDY != 0x00){
+      machine->opcache[machine->opcodes[i].INDY].adm = INDIRECT_Y;
+      machine->opcache[machine->opcodes[i].INDY].index = i;;
+    }
+     if (machine->opcodes[i].SNGL != 0x00){
+      machine->opcache[machine->opcodes[i].SNGL].adm = SINGLE;
+      machine->opcache[machine->opcodes[i].SNGL].index = i;
+    }
+     if (machine->opcodes[i].BRA != 0x00){
+      machine->opcache[machine->opcodes[i].BRA].adm = ABS_OR_BRANCH;
+      machine->opcache[machine->opcodes[i].BRA].index = i;
+    }
+  }   
+}
+
+/* opIndex() - Search the opcode table for a match. If found return
+   the index into the optable and the address mode of the opcode. If
+   the opcode is not found then return -1. */
+static int opIndex(machine_6502 *machine, Bit8 opcode, AddrMode *adm){ 
+  /* XXX could catch errors by setting a addressmode of error or something */
+  *adm = machine->opcache[opcode].adm;
+  return machine->opcache[opcode].index;
+}
+
+\f
+/* Assembly parser */
+
+static Param *newParam(void){
+  Param *newp;
+  int i = 0;
+
+  newp = (Param *) emalloc(sizeof(Param));
+  newp->type = SINGLE;
+  for (i = 0; i < MAX_PARAM_VALUE; i++)
+    newp->value[i] = 0;
+  newp->vp = 0;
+  newp->label = ecalloc(MAX_LABEL_LEN,sizeof(char));
+  newp->lbladdr = 0;
+  return newp;
+}
+
+/* Copy the fields from p2 to p1 */
+static void copyParam(Param *p1, Param *p2){
+  int i = 0;
+  strncpy(p1->label,p2->label,MAX_LABEL_LEN);
+  for(i = 0; i < MAX_PARAM_VALUE; i++)
+    p1->value[i] = p2->value[i];
+  p1->vp = p2->vp;
+  p1->type = p2->type;
+}
+
+static Label *newLabel(void){
+  Label *newp; 
+
+  newp = (Label *) emalloc(sizeof(Label));
+  newp->addr = 0;
+  newp->label = ecalloc(MAX_LABEL_LEN,sizeof(char));
+  
+  return newp;
+}
+
+static AsmLine *newAsmLine(char *cmd, char *label, BOOL decl, Param *param, int lc)
+{
+    AsmLine *newp;
+
+    newp =  (AsmLine *) emalloc(sizeof(AsmLine));
+    newp->labelDecl = decl;
+    newp->label = newLabel();
+    strncpy(newp->label->label,label,MAX_LABEL_LEN);
+    newp->command = estrdup(cmd);
+    newp->param = newParam();
+    copyParam(newp->param, param);
+    newp->next = NULL;
+    return newp;
+}
+
+static AsmLine *addend(AsmLine *listp, AsmLine *newp)
+{
+    AsmLine *p;
+    if(listp == NULL)
+      return newp;
+    for (p =listp; p->next != NULL; p = p->next)
+      ;
+    p->next = newp;
+    return listp;
+}
+
+static BOOL apply(AsmLine *listp, BOOL(*fn)(AsmLine*, void*), void *arg)
+{
+  AsmLine *p;
+  if(listp == NULL)
+    return FALSE;
+  for (p = listp; p != NULL; p = p->next)
+    if (! fn(p,arg) )
+      return FALSE;
+  return TRUE;
+}
+
+static void freeParam(Param *param){
+  free(param->label);
+  free(param);
+}
+
+static void freeLabel(Label *label){
+  free(label->label);
+  free(label);
+}
+
+static void freeallAsmLine(AsmLine *listp)
+{
+    AsmLine *next;
+    for(; listp != NULL; listp = next){
+       next = listp->next;
+       freeParam(listp->param);
+       freeLabel(listp->label);
+       free(listp->command);
+       free(listp);
+    }
+}
+
+static BOOL addvalue(Param *param,Bit32 value){
+  if (0 <= param->vp && param->vp < MAX_PARAM_VALUE) {
+    param->value[param->vp++] = value;
+    return TRUE;
+  }
+  else {
+    fprintf(stderr,"Wrong number of parameters: %d. The limit is %d\n",param->vp+1, MAX_PARAM_VALUE);
+    return FALSE;
+  }
+}
+
+static void parseError(char *s){
+  fprintf(stderr,"6502 Syntax Error: %s\n", s);
+}
+
+/* stoupper() - Destructivley modifies the string making all letters upper case*/
+static void stoupper(char **s){
+  int i = 0;
+  while((*s)[i] != '\0'){
+    (*s)[i] = toupper((*s)[i]);
+    i++;
+  }
+}
+static BOOL isWhite(char c){
+  return (c == '\r' || c == '\t' || c == ' ');
+}
+
+static void skipSpace(char **s){
+  for(; isWhite(**s); (*s)++)
+    ;
+}
+  
+/* nullify() - fills a string with upto sourceLength null characters. */
+static void nullify(char *token, unsigned int sourceLength){
+  unsigned int i = 0;
+  while (i < sourceLength)
+    token[i++] = '\0';
+}
+
+static BOOL isBlank(const char *token){
+  return (token[0] == '\0');
+}
+
+static BOOL isCommand(machine_6502 *machine, const char *token){
+  int i = 0;
+
+  while (i < NUM_OPCODES) {
+    if (strcmp(machine->opcodes[i].name,token) == 0) 
+      return TRUE;
+    i++;
+  }
+  
+  if (strcmp(token, "DCB") == 0) return TRUE;
+  return FALSE;
+}
+
+/* hasChar() - Check to see if the current line has a certain
+   charater */
+static BOOL hasChar(char *s, char c){
+  for(; *s != '\0' && *s != '\n'; s++) {
+    if (*s  == c)
+      return TRUE;
+  }
+  return FALSE;
+}
+
+static BOOL ishexdigit(char c){
+  if (isdigit(c))
+    return TRUE;
+  else {
+    char c1 = toupper(c);
+    return ('A' <= c1 && c1 <= 'F');
+  }
+}
+
+/* command() - parse a command from the source code. We pass along a
+   machine so the opcode can be validated. */
+static BOOL command(machine_6502 *machine, char **s, char **cmd){
+  int i = 0;
+  skipSpace(s);
+  for(;isalpha(**s) && i < MAX_CMD_LEN; (*s)++)
+    (*cmd)[i++] = **s;
+  if (i == 0)
+    return TRUE; /* Could be a blank line. */
+  else
+    return isCommand(machine,*cmd);
+}
+
+static BOOL declareLabel(char **s, char **label){
+  int i = 0;
+  skipSpace(s);
+  for(;**s != ':' && **s != '\n' && **s != '\0'; (*s)++){
+    if (isWhite(**s)) 
+      continue;
+    (*label)[i++] = **s;
+  }
+  if (i == 0)
+    return FALSE; /* Current line has to have a label */
+  else if (**s == ':'){
+    (*s)++; /* Skip colon */
+    return TRUE;
+  }
+  else
+    return FALSE;
+}
+
+static BOOL parseHex(char **s, Bit32 *value){
+  enum { MAX_HEX_LEN = 5 };
+  if (**s == '$') {    
+    char *hex = ecalloc(MAX_HEX_LEN, sizeof(char));
+    int i = 0;
+
+    (*s)++; /* move pass $ */
+    for(; ishexdigit(**s) && i < MAX_HEX_LEN; (*s)++)
+      hex[i++] = **s;
+    
+    *value = strtol(hex,NULL,16);
+    free(hex);  
+    return TRUE;
+  }
+  else
+    return FALSE;
+}
+  
+static BOOL parseDec(char **s, Bit32 *value){
+  enum { MAX_DEC_LEN = 4 };
+  char *dec = ecalloc(MAX_DEC_LEN, sizeof(char));
+  int i;
+  for(i = 0; isdigit(**s) && i < MAX_DEC_LEN; (*s)++)
+    dec[i++] = **s;
+  
+  if (i > 0){
+    *value = atoi(dec);
+    free(dec);  
+    return TRUE;
+  }
+  else
+    return FALSE;
+}
+
+static BOOL parseValue(char **s, Bit32 *value){
+  skipSpace(s);
+  if (**s == '$')
+    return parseHex(s, value);
+  else
+    return parseDec(s, value);
+}
+
+static BOOL paramLabel(char **s, char **label){
+  int i;
+  for(i = 0; (isalnum(**s) || **s == '_') && i < MAX_LABEL_LEN; (*s)++)
+    (*label)[i++] = **s;
+
+  if (i > 0)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+static BOOL immediate(char **s, Param *param){
+  if (**s != '#') 
+    return FALSE;
+
+  (*s)++; /*Move past hash */
+  if (**s == '<' || **s == '>'){    
+    char *label = ecalloc(MAX_LABEL_LEN, sizeof(char));
+    param->type = (**s == '<') ? IMMEDIATE_LESS : IMMEDIATE_GREAT;
+    (*s)++; /* move past < or > */
+    if (paramLabel(s, &label)){
+      int ln = strlen(label) + 1;
+      strncpy(param->label, label, ln);
+      free(label);
+      return TRUE;
+    }    
+    free(label);
+  }
+  else {
+    Bit32 value;
+    if (parseValue(s, &value)){
+      if (value > 0xFF){
+       parseError("Immediate value is too large.");
+       return FALSE;
+      }
+      param->type = IMMEDIATE_VALUE;
+      return addvalue(param, value);
+    }
+  }
+  return FALSE;
+}
+
+static BOOL isDirection(char c){
+  return (c == 'X' || c == 'Y');
+}
+
+static BOOL getDirection(char **s, char *direction){
+  skipSpace(s);
+  if (**s == ','){
+    (*s)++;
+    skipSpace(s);
+    if (isDirection(**s)){
+      *direction = **s;
+      (*s)++;
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+  
+static BOOL indirect(char **s, Param *param){
+  Bit32 value;
+  char c;
+  if (**s == '(') 
+    (*s)++;
+  else
+    return FALSE;
+  
+  if (! parseHex(s,&value)) 
+    return FALSE;
+  if (value > 0xFF) {
+    parseError("Indirect value is too large.");
+    return FALSE;
+  }
+  if (!addvalue(param, value))
+    return FALSE;
+  skipSpace(s);
+  if (**s == ')'){
+    (*s)++;
+    if (getDirection(s,&c)) {
+      if (c == 'Y'){
+       param->type = INDIRECT_Y;
+       return TRUE;
+      }
+    }
+  }
+  else if (getDirection(s, &c)){
+    if (c == 'X'){
+      skipSpace(s);
+      if (**s == ')'){
+       (*s)++;
+       param->type = INDIRECT_X;
+       return TRUE;
+      }
+    }
+  }
+  return FALSE;
+}
+
+static BOOL dcbValue(char **s, Param *param){
+  Bit32 val;
+  if (! parseValue(s,&val))
+    return FALSE;
+
+  if (val > 0xFF) 
+    return FALSE;
+                   
+  if (!addvalue(param,val))
+    return FALSE;
+
+  param->type = DCB_PARAM;
+
+  skipSpace(s);
+  if(**s == ','){
+    (*s)++;
+    return dcbValue(s, param);
+  }
+  else
+    return TRUE;
+} 
+
+static BOOL value(char **s, Param *param){
+  Bit32 val;
+  BOOL abs;
+  BOOL dir;
+  char c = '\0';
+  if (! parseValue(s,&val))
+    return FALSE;
+
+  abs = (val > 0xFF);
+  dir = getDirection(s,&c);
+  if (!addvalue(param,val))
+    return FALSE;
+
+  if(abs && dir){
+    if (c == 'X')
+      param->type = ABS_X;
+    else if (c == 'Y')
+      param->type = ABS_Y;
+    else
+      return FALSE;
+  }
+  else if (abs)
+    param->type = ABS_VALUE;
+  else if (dir){
+    if (c == 'X')
+      param->type = ZERO_X;
+    else if (c == 'Y')
+      param->type = ZERO_Y;
+    else
+      return FALSE;
+  }
+  else
+    param->type = ZERO;
+
+  return TRUE;
+}
+
+static BOOL label(char **s, Param *param){
+  char *label = ecalloc(MAX_LABEL_LEN, sizeof(char));
+  char c;
+  BOOL labelOk = FALSE;
+  if (paramLabel(s, &label)){
+    labelOk = TRUE;
+    param->type = ABS_OR_BRANCH;
+    if (getDirection(s, &c)){
+      if (c == 'X')
+       param->type = ABS_LABEL_X;
+      else if (c == 'Y')
+       param->type = ABS_LABEL_Y;
+      else
+       labelOk = FALSE;
+    }
+    strncpy(param->label,label,MAX_LABEL_LEN);
+  }
+  free(label);
+  return labelOk;
+}
+
+static BOOL parameter(const char *cmd, char **s, Param *param){
+  skipSpace(s);
+  if (**s == '\0' || **s == '\n')
+    return TRUE;
+  else if (**s == '#')
+    return immediate(s,param);
+  else if (**s == '(')
+    return indirect(s,param);
+  else if (**s == '$' || isdigit(**s)){
+    if (strcmp(cmd, "DCB") == 0)
+      return dcbValue(s,param);
+    else
+      return value(s,param);
+  }
+  else if (isalpha(**s))
+    return label(s ,param);
+  else
+    return FALSE; /* Invalid Parameter */
+}
+
+static void comment(char **s){
+  skipSpace(s);
+  if (**s == ';')
+    for(;**s != '\n' && **s != '\0'; (*s)++)
+      ;
+}
+
+static void initParam(Param *param){
+  int i;
+  param->type = SINGLE;
+  for(i = 0; i < MAX_PARAM_VALUE; i++)
+    param->value[i] = 0;
+  param->vp = 0;
+  nullify(param->label,MAX_LABEL_LEN);
+}
+  
+
+static AsmLine *parseAssembly(machine_6502 *machine, BOOL *codeOk, const char *code){
+  char *s;
+  char *cmd = ecalloc(MAX_CMD_LEN, sizeof(char));
+  char *label = ecalloc(MAX_LABEL_LEN, sizeof(char));
+  char *start; /*pointer to the start of the code.*/
+  unsigned int lc = 1;
+  Param *param;
+  BOOL decl;
+  AsmLine *listp = NULL;
+
+  *codeOk = TRUE;
+  param = newParam();
+  s = estrdup(code);
+  start = s;
+  stoupper(&s);
+
+  while(*s != '\0' && *codeOk){
+    initParam(param);
+    nullify(cmd, MAX_CMD_LEN);
+    nullify(label, MAX_LABEL_LEN);
+    decl = FALSE;
+    skipSpace(&s);
+    comment(&s);
+    if (*s == '\n'){
+      lc++;
+      s++;
+      continue; /* blank line */
+    }
+    else if (*s == '\0')
+      continue; /* no newline at the end of the code */
+    else if (hasChar(s,':')){
+      decl = TRUE;
+      if(! declareLabel(&s,&label)){
+       *codeOk = FALSE;
+       break;
+      }
+      skipSpace(&s);
+    }
+    if(!command(machine, &s, &cmd)){
+      *codeOk = FALSE;
+      break;
+    }
+    skipSpace(&s);
+    comment(&s);
+    if(!parameter(cmd, &s, param)){
+      *codeOk = FALSE;
+      break;
+    }
+    skipSpace(&s);
+    comment(&s);
+    if (*s == '\n' || *s == '\0'){
+      AsmLine *asmm;
+      asmm = newAsmLine(cmd,label,decl,param,lc);
+      listp = addend(listp,asmm);
+    }
+    else {
+      *codeOk = FALSE;
+      break;
+    }
+  }
+  if (! *codeOk)
+    fprintf(stderr,"Syntax error at line %u\n", lc);
+  free(start);
+  free(cmd);
+  free(label);
+  freeParam(param);
+  return listp;
+}
+    
+/* fileToBuffer() - Allocates a buffer and loads all of the file into memory. */
+static char *fileToBuffer(char *filename){
+  const int defaultSize = 1024;
+  FILE *ifp;
+  int c;
+  int size = defaultSize;
+  int i = 0;
+  char *buffer = ecalloc(defaultSize,sizeof(char));
+
+  if (buffer == NULL) 
+    eprintf("Could not allocate memory for buffer.");
+
+  ifp = fopen(filename, "rb");
+  if (ifp == NULL)
+    eprintf("Could not open file.");
+
+  while((c = getc(ifp)) != EOF){
+    buffer[i++] = c;
+    if (i == size){
+      size += defaultSize;
+      buffer = realloc(buffer, size);
+      if (buffer == NULL) {
+       fclose(ifp);
+       eprintf("Could not resize buffer.");
+      }
+    }
+  }
+  fclose(ifp);
+  buffer = realloc(buffer, i+2);
+  if (buffer == NULL) 
+    eprintf("Could not resize buffer.");
+  /* Make sure we have a line feed at the end */
+  buffer[i] = '\n';
+  buffer[i+1] = '\0';
+  return buffer;
+}
+
+\f
+/* Routines */
+
+/* reset() - Reset CPU and memory. */
+static void reset(machine_6502 *machine){
+  int x, y;
+  for ( y = 0; y < 32; y++ ){
+    for (x = 0; x < 32; x++){
+      machine->screen[x][y] = 0;
+    }
+  }
+
+  for(x=0; x < MEM_64K; x++)
+    machine->memory[x] = 0;
+
+  machine->codeCompiledOK = FALSE;
+  machine->regA = 0;
+  machine->regX = 0;
+  machine->regY = 0;
+  machine->regP = setBit(machine->regP, FUTURE_FL, 1);
+  machine->regPC = 0x600; 
+  machine->regSP = STACK_TOP;
+  machine->runForever = FALSE;
+  machine->labelPtr = 0;
+  machine->codeRunning = FALSE;
+}
+
+/* hexDump() - Dump the memory to output */
+void hexDump(machine_6502 *machine, Bit16 start, Bit16 numbytes, FILE *output){
+  Bit32 address;
+  Bit32 i;
+  for( i = 0; i < numbytes; i++){
+    address = start + i;
+    if ( (i&15) == 0 ) {
+      fprintf(output,"\n%.4x: ", address);
+    }
+    fprintf(output,"%.2x%s",machine->memory[address], (i & 1) ? " ":"");
+  }
+  fprintf(output,"%s\n",(i&1)?"--":"");
+}
+
+void save_program(machine_6502 *machine, char *filename){
+  FILE *ofp;
+  Bit16 pc = 0x600;
+  Bit16 end = pc + machine->codeLen;
+  Bit16 n;
+  ofp = fopen(filename, "w");
+  if (ofp == NULL)
+    eprintf("Could not open file.");
+  
+  fprintf(ofp,"Bit8 prog[%d] =\n{",machine->codeLen);
+  n = 1;
+  while(pc < end)
+    fprintf(ofp,"0x%.2x,%s",machine->memory[pc++],n++%10?" ":"\n");
+  fseek(ofp,-2,SEEK_CUR);
+  fprintf(ofp,"};\n");
+  
+  fclose(ofp);
+}
+
+static BOOL translate(Opcodes *op,Param *param, machine_6502 *machine){
+   switch(param->type){
+    case SINGLE:
+      if (op->SNGL)
+       pushByte(machine, op->SNGL);
+      else {
+       fprintf(stderr,"%s needs a parameter.\n",op->name);
+       return FALSE;
+      }
+      break;
+    case IMMEDIATE_VALUE:
+      if (op->Imm) {
+       pushByte(machine, op->Imm);
+       pushByte(machine, param->value[0]);
+       break;
+      }
+      else {
+       fprintf(stderr,"%s does not take IMMEDIATE_VALUE parameters.\n",op->name);
+       return FALSE;
+      }
+    case IMMEDIATE_GREAT:
+      if (op->Imm) {
+       pushByte(machine, op->Imm);
+       pushByte(machine, param->lbladdr / 0xFF);
+       break;
+      }
+      else {
+       fprintf(stderr,"%s does not take IMMEDIATE_GREAT parameters.\n",op->name);
+       return FALSE;
+      }
+    case IMMEDIATE_LESS:
+      if (op->Imm) {
+       pushByte(machine, op->Imm);
+       pushByte(machine, param->lbladdr & 0xFF);
+       break;
+      }
+      else {
+       fprintf(stderr,"%s does not take IMMEDIATE_LESS parameters.\n",op->name);
+       return FALSE;
+      }
+    case INDIRECT_X:
+      if (op->INDX) {
+       pushByte(machine, op->INDX);
+       pushByte(machine, param->value[0]);
+       break;
+      }
+      else {
+       fprintf(stderr,"%s does not take INDIRECT_X parameters.\n",op->name);
+       return FALSE;
+      }
+    case INDIRECT_Y:
+      if (op->INDY) {
+       pushByte(machine, op->INDY);
+       pushByte(machine, param->value[0]);
+       break;
+      }
+      else {
+       fprintf(stderr,"%s does not take INDIRECT_Y parameters.\n",op->name);
+       return FALSE;
+      }
+    case ZERO:
+      if (op->ZP) {
+       pushByte(machine, op->ZP);
+       pushByte(machine, param->value[0]);
+       break;
+      }
+      else {
+       fprintf(stderr,"%s does not take ZERO parameters.\n",op->name);
+       return FALSE;
+      }
+    case ZERO_X:
+      if (op->ZPX) {
+       pushByte(machine, op->ZPX);
+       pushByte(machine, param->value[0]);
+       break;
+      }
+      else {
+       fprintf(stderr,"%s does not take ZERO_X parameters.\n",op->name);
+       return FALSE;
+      }
+    case ZERO_Y:
+      if (op->ZPY) {
+       pushByte(machine, op->ZPY);
+       pushByte(machine, param->value[0]);
+       break;
+      }
+      else {
+       fprintf(stderr,"%s does not take ZERO_Y parameters.\n",op->name);
+       return FALSE;
+      }
+    case ABS_VALUE:
+      if (op->ABS) {
+       pushByte(machine, op->ABS);
+       pushWord(machine, param->value[0]);
+       break;
+      }
+      else {
+       fprintf(stderr,"%s does not take ABS_VALUE parameters.\n",op->name);
+       return FALSE;
+      }
+    case ABS_OR_BRANCH:
+      if (op->ABS > 0){
+       pushByte(machine, op->ABS);
+       pushWord(machine, param->lbladdr);
+      }
+      else {
+       if (op->BRA) {
+         pushByte(machine, op->BRA);
+         if (param->lbladdr < (machine->codeLen + 0x600))
+           pushByte(machine,
+                    (0xff - (machine->codeLen-param->lbladdr)) & 0xff);
+         else
+           pushByte(machine,
+                    (param->lbladdr - machine->codeLen-1) & 0xff);
+       }
+       else {
+         fprintf(stderr,"%s does not take BRANCH parameters.\n",op->name);
+         return FALSE;
+       }
+      }
+      break;
+    case ABS_X:
+      if (op->ABSX) {
+       pushByte(machine, op->ABSX);
+       pushWord(machine, param->value[0]);
+       break;
+      }
+      else {
+       fprintf(stderr,"%s does not take ABS_X parameters.\n",op->name);
+       return FALSE;
+      }
+    case ABS_Y:
+      if (op->ABSY) {
+       pushByte(machine, op->ABSY);
+       pushWord(machine, param->value[0]);
+       break;
+      }
+      else {
+       fprintf(stderr,"%s does not take ABS_Y parameters.\n",op->name);
+       return FALSE;
+      }
+    case ABS_LABEL_X:
+      if (op->ABSX) {
+       pushByte(machine, op->ABSX);
+       pushWord(machine, param->lbladdr);
+       break;
+      }
+      else {
+       fprintf(stderr,"%s does not take ABS_LABEL_X parameters.\n",op->name);
+       return FALSE;
+      }
+    case ABS_LABEL_Y:
+      if (op->ABSY) {
+       pushByte(machine, op->ABSY);
+       pushWord(machine, param->lbladdr);
+       break;
+      }
+      else {
+       fprintf(stderr,"%s does not take ABS_LABEL_Y parameters.\n",op->name);
+       return FALSE;
+      }
+   case DCB_PARAM:
+     /* Handled elsewhere */
+     break;
+   }
+   return TRUE;
+}
+
+/* compileLine() - Compile one line of code. Returns
+   TRUE if it compile successfully. */
+static BOOL compileLine(AsmLine *asmline, void *args){
+  machine_6502 *machine;
+  machine = args;
+  if (isBlank(asmline->command)) return TRUE;
+
+  if (strcmp("DCB",asmline->command) == 0){
+    int i;
+    for(i = 0; i < asmline->param->vp; i++)
+      pushByte(machine, asmline->param->value[i]);
+  }    
+  else{
+    int i;
+    char *command = asmline->command;
+    Opcodes op;
+    for(i = 0; i < NUM_OPCODES; i++){
+      if (strcmp(machine->opcodes[i].name, command) == 0){
+       op = machine->opcodes[i];
+       break;      
+      }
+    }
+    if (i == NUM_OPCODES)
+      return FALSE; /* unknow upcode */
+    else
+      return translate(&op,asmline->param,machine);
+  }
+  return TRUE;
+}
+
+/* indexLabels() - Get the address for each label */
+static BOOL indexLabels(AsmLine *asmline, void *arg){
+  machine_6502 *machine; 
+  int thisPC;
+  machine = arg;
+  thisPC = machine->regPC;
+  /* Figure out how many bytes this instruction takes */
+  machine->codeLen = 0;
+  if ( ! compileLine(asmline, machine) ){
+    return FALSE;
+  }
+  machine->regPC += machine->codeLen;
+  if (asmline->labelDecl) {
+    asmline->label->addr = thisPC;
+  }
+   return TRUE; 
+}
+
+static BOOL changeParamLabelAddr(AsmLine *asmline, void *label){
+  Label *la = label;
+  if (strcmp(asmline->param->label, la->label) == 0)
+    asmline->param->lbladdr = la->addr;
+  return TRUE;
+}
+
+static BOOL linkit(AsmLine *asmline, void *asmlist){
+  apply(asmlist,changeParamLabelAddr,asmline->label);
+  return TRUE;
+}
+
+/* linkLabels - Make sure all of the references to the labels contain
+   the right address*/
+static void linkLabels(AsmLine *asmlist){
+  apply(asmlist,linkit,asmlist);
+}
+
+/* compileCode() - Compile the current assembly code for the machine */
+static BOOL compileCode(machine_6502 *machine, const char *code){
+  BOOL codeOk;
+  AsmLine *asmlist;
+
+  reset(machine);
+  machine->regPC = 0x600;
+  asmlist = parseAssembly(machine, &codeOk, code);
+
+  if(codeOk){
+    /* First pass: Find the addresses for the labels */
+    if (!apply(asmlist, indexLabels, machine))
+      return FALSE;
+    /* update label references */
+    linkLabels(asmlist);
+    /* Second pass: translate the instructions */
+    machine->codeLen = 0;
+    if (!apply(asmlist, compileLine, machine))
+      return FALSE;
+
+    if (machine->codeLen > 0 ){
+      machine->memory[0x600+machine->codeLen] = 0x00;
+      codeOk = TRUE;
+    }
+    else{
+      fprintf(stderr,"No Code to run.\n");
+      codeOk = FALSE;
+    }
+  }
+  else{
+    fprintf(stderr,"An error occured while parsing the file.\n");  
+    codeOk = FALSE;
+  }
+  freeallAsmLine(asmlist);
+  return codeOk;
+}
+
+
+/*
+ *  execute() - Executes one instruction.
+ *              This is the main part of the CPU emulator.
+ *
+ */
+
+static void execute(machine_6502 *machine){
+  Bit8 opcode;
+  AddrMode adm;
+  int opidx;
+
+  if(!machine->codeRunning) return;
+
+  opcode = popByte(machine);
+  if (opcode == 0x00)
+    machine->codeRunning = FALSE;
+  else {
+    opidx = opIndex(machine,opcode,&adm);
+    if(opidx > -1)
+      machine->opcodes[opidx].func(machine, adm);
+    else
+      fprintf(stderr,"Invalid opcode!\n");
+  }
+  if( (machine->regPC == 0) || 
+      (!machine->codeRunning) || 
+      (machine->regPC > (machine->codeLen+0x600)) ) {
+    machine->codeRunning = FALSE;
+  }
+}
+
+machine_6502 *build6502(){
+  machine_6502 *machine;
+  machine = emalloc(sizeof(machine_6502));
+  assignOpCodes(machine->opcodes);
+  buildIndexCache(machine);
+  reset(machine);
+  return machine;
+}
+
+void destroy6502(machine_6502 *machine){
+  free(machine);
+  machine = NULL;
+}
+
+void trace(machine_6502 *machine, FILE *output){
+  Bit8 opcode = memReadByte(machine,machine->regPC);
+  AddrMode adm;
+  Pointer ptr;
+  int opidx = opIndex(machine,opcode,&adm);
+  int stacksz = STACK_TOP - machine->regSP;
+
+  fprintf(output,"\n   NVFBDIZC\nP: %d%d%d%d%d%d%d%d ",
+        bitOn(machine->regP,NEGATIVE_FL),
+        bitOn(machine->regP,OVERFLOW_FL),
+        bitOn(machine->regP,FUTURE_FL),
+        bitOn(machine->regP,BREAK_FL),
+        bitOn(machine->regP,DECIMAL_FL),
+        bitOn(machine->regP,INTERRUPT_FL),
+        bitOn(machine->regP,ZERO_FL),
+        bitOn(machine->regP,CARRY_FL));
+  fprintf(output,"A: %.2x X: %.2x Y: %.2x SP: %.4x PC: %.4x\n",
+        machine->regA, machine->regX, machine->regY, machine->regSP, machine->regPC);
+  if (opidx > -1){
+    Bit16 pc = machine->regPC;
+    fprintf(output,"\n%.4x:\t%s",machine->regPC, machine->opcodes[opidx].name);
+    if (peekValue(machine, adm, &ptr, pc+1))
+      fprintf(output,"\tAddress:%.4x\tValue:%.4x\n",
+            ptr.addr,ptr.value);
+    else
+      fprintf(output,"\n");
+  }
+  fprintf(output,"STACK:");
+  hexDump(machine,(STACK_TOP - stacksz) + 1, stacksz, output);
+  fprintf(output,"\n================================================================================\n");
+}
+
+    
+
+\f
+void eval_file(machine_6502 *machine, char *filename, Plotter plot, void *plotterState){
+  char *code = NULL;
+
+  machine->plot = plot;
+  machine->plotterState = plotterState;
+
+  code = fileToBuffer(filename);
+  
+  if (! compileCode(machine, code) ){
+    eprintf("Could not compile code.\n");
+  }
+
+  free(code);
+
+  machine->regPC = 0x600;
+  machine->codeRunning = TRUE;
+  do{
+    sleep(0); /* XXX */
+#if 0
+    trace(machine);
+#endif
+    execute(machine);
+    if (!machine->codeRunning) 
+      break;
+  }while((machine->regPC - 0x600) < machine->codeLen);
+}
+
+void start_eval_file(machine_6502 *machine, char *filename, Plotter plot, void *plotterState){
+  char *code = NULL;
+  reset(machine);
+
+  machine->plot = plot;
+  machine->plotterState = plotterState;
+
+  code = fileToBuffer(filename);
+  
+  if (! compileCode(machine, code) ){
+    eprintf("Could not compile code.\n");
+  }
+
+  free(code);
+
+  machine->regPC = 0x600;
+  machine->codeRunning = TRUE;
+  execute(machine);
+}
+
+void start_eval_binary(machine_6502 *machine, Bit8 *program,
+                      unsigned int proglen,
+                      Plotter plot, void *plotterState){
+  unsigned int pc, n;
+  reset(machine);
+  machine->plot = plot;
+  machine->plotterState = plotterState;
+
+  machine->regPC = 0x600;
+  pc = machine->regPC;
+  machine->codeLen = proglen;
+  n = 0;
+  while (n < proglen){
+    machine->memory[pc++] = program[n++];
+  }
+  machine->codeRunning = TRUE;
+  execute(machine);
+}
+
+void next_eval(machine_6502 *machine, int insno){
+  int i = 0;
+  for (i = 1; i < insno; i++){
+    if (machine->codeRunning){/* && ((machine->regPC - 0x600) < machine->codeLen))*/
+#if 0
+      trace(machine);
+#endif
+      execute(machine);
+    }
+    else
+      break;
+  }
+}
+  
diff --git a/hacks/asm6502.h b/hacks/asm6502.h
new file mode 100644 (file)
index 0000000..bd7e79c
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2007 Jeremy English <jhe@jeremyenglish.org>
+ * 
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  No representations are made about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or 
+ * implied warranty.
+ * 
+ * Created: 07-May-2007 
+ */
+
+/* 
+      This is a port of the javascript 6502 assembler, compiler and
+      debugger. The orignal code was copyright 2006 by Stian Soreng -
+      www.6502asm.com
+
+   The stack space is in page $100 to $1ff. The video buffer starts at
+   $200 and is 1024 bytes. Programs get loaded at address
+   $600. Address $fe is random and byte $ff is used for user input.
+
+   User input is disabled.
+*/
+
+#ifndef __ASM6502_H__
+#define __ASM6502_H__
+
+typedef uint8_t  Bit8;
+typedef uint16_t Bit16;
+typedef uint32_t Bit32;
+
+#undef  BOOL
+#undef  TRUE
+#undef  FALSE
+#define BOOL  Bit8
+#define TRUE  1
+#define FALSE 0
+
+enum {
+  MAX_LABEL_LEN = 80, 
+  NUM_OPCODES = 56, /* Number of unique instructions not counting DCB */
+  MEM_64K = 65536, /* We have 64k of memory to work with. */
+  MAX_PARAM_VALUE = 25, /* The number of values allowed behind dcb */
+  MAX_CMD_LEN = 4, /* Each assembly command is 3 characeters long */
+/* The stack works from the top down in page $100 to $1ff */
+  STACK_TOP = 0x1ff,
+  STACK_BOTTOM = 0x100 
+};
+
+typedef enum{
+  SINGLE, IMMEDIATE_VALUE, IMMEDIATE_GREAT, 
+    IMMEDIATE_LESS, INDIRECT_X, INDIRECT_Y,
+    ZERO, ZERO_X, ZERO_Y,
+    ABS_VALUE, ABS_OR_BRANCH, ABS_X, ABS_Y,
+    ABS_LABEL_X, ABS_LABEL_Y, DCB_PARAM
+} AddrMode;
+
+typedef struct machine_6502 machine_6502;
+
+typedef struct {
+  char name[MAX_CMD_LEN];
+  Bit8 Imm;
+  Bit8 ZP;
+  Bit8 ZPX;
+  Bit8 ZPY;
+  Bit8 ABS;
+  Bit8 ABSX;
+  Bit8 ABSY;
+  Bit8 INDX;
+  Bit8 INDY;
+  Bit8 SNGL;
+  Bit8 BRA;
+  void (*func) (machine_6502*, AddrMode);
+} Opcodes;
+
+/* Used to cache the index of each opcode */
+typedef struct {
+  Bit8 index;
+  AddrMode adm;
+} OpcodeIndex;
+
+/* Plotter is a function that will be called everytime a pixel
+   needs to be updated. The first two parameter are the x and y
+   values. The third parameter is the color index:
+
+   Color Index Table
+   00 black      #000000
+   01 white      #ffffff
+   02 Red        #880000
+   03 seafoam    #aaffee
+   04 fuscia     #cc44cc
+   05 green      #00cc55
+   06 blue       #0000aa
+   07 Yellow     #eeee77
+   08 tangerine  #dd8855
+   09 brown      #664400
+   10 salmon     #ff7777
+   11 charcoal   #333333
+   12 smoke      #777777
+   13 lime       #aaff66
+   14 light blue #0088ff
+   15 gray       #bbbbbb
+
+   The plotter state variable of the machine gets passed as the forth
+   parameter. You can use this parameter to store state information.
+
+*/
+typedef void (*Plotter) (Bit8, Bit8, Bit8, void*);
+
+struct machine_6502 {
+  BOOL codeCompiledOK;
+  Bit8 regA;
+  Bit8 regX;
+  Bit8 regY;
+  Bit8 regP;
+  Bit16 regPC; /* A pair of 8 bit registers */
+  Bit16 regSP;
+  Bit8 memory[MEM_64K];
+  BOOL runForever;
+  int labelPtr;
+  BOOL codeRunning;
+  int myInterval;
+  Opcodes opcodes[NUM_OPCODES];
+  int screen[32][32];
+  int codeLen;
+  OpcodeIndex opcache[0xff];
+  Plotter plot;
+  void *plotterState;
+};
+
+/* build6502() - Creates an instance of the 6502 machine */
+machine_6502 *build6502(void);
+
+/* destroy6502() - compile the file and exectue it until the program
+   is finished */
+void destroy6502(machine_6502 *machine);
+
+/* eval_file() - Compiles and runs a file until the program is
+   finished */
+void eval_file(machine_6502 *machine, char *filename, 
+              Plotter plot, void *plotterState);
+
+/* start_eval_file() - Compile the file and execute the first
+   instruction */
+void start_eval_file(machine_6502 *machine, char *filename, 
+                    Plotter plot, void *plotterState);
+
+void start_eval_binary(machine_6502 *machine, Bit8 *program,
+                      unsigned int proglen,
+                      Plotter plot, void *plotterState);
+
+/* next_eval() - Execute the next insno of machine instructions */
+void next_eval(machine_6502 *machine, int insno);
+
+/* hexDump() - Dumps memory to output */
+void hexDump(machine_6502 *machine, Bit16 start, 
+            Bit16 numbytes, FILE *output);
+
+/* trace() - Prints to output the current value of registers, the
+   current nmemonic, memory address and value. */
+void trace(machine_6502 *machine, FILE *output);
+
+/* save_program() - Writes a binary file of the program loaded in
+   memory. */
+void save_program(machine_6502 *machine, char *filename);
+
+#endif /* __ASM6502_H__ */
index a0b5d7635534f1b8111be30b2a85b88664dc084d..29489acde3129caf59c0d20cf8fe96abf50ba0b7 100644 (file)
@@ -5,6 +5,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) APOLLONIAN.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) APPLE2.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) APPLE2-MAIN.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) ASM6502.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) ATTRACTION.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BARCODE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BLASTER.C
@@ -23,6 +24,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) CORAL.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) CRITICAL.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) CRYSTAL.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) CWAVES.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) CYNOSURE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DECAYSCREEN.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DECO.C
@@ -71,6 +73,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) LISSIE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) LMORPH.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) LOOP.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) M6502.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) MAZE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) MEMSCROLLER.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) METABALLS.C
index a0b5d7635534f1b8111be30b2a85b88664dc084d..29489acde3129caf59c0d20cf8fe96abf50ba0b7 100644 (file)
@@ -5,6 +5,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) APOLLONIAN.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) APPLE2.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) APPLE2-MAIN.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) ASM6502.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) ATTRACTION.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BARCODE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) BLASTER.C
@@ -23,6 +24,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) CORAL.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) CRITICAL.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) CRYSTAL.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) CWAVES.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) CYNOSURE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DECAYSCREEN.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) DECO.C
@@ -71,6 +73,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) LISSIE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) LMORPH.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) LOOP.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) M6502.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) MAZE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) MEMSCROLLER.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) METABALLS.C
index af3616c2745c10b84d68caa23089c35cf19db27c..61534da18a820d6bd3b3ae7a8a21d8272f5a3792 100644 (file)
@@ -4,8 +4,8 @@
             a screen saver and locker for the X window system
                             by Jamie Zawinski
 
-                              version 5.02
-                               20-Apr-2007
+                              version 5.03
+                               17-Jul-2007
 
                      http://www.jwz.org/xscreensaver/
 
diff --git a/hacks/config/cwaves.xml b/hacks/config/cwaves.xml
new file mode 100644 (file)
index 0000000..33ddf36
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<screensaver name="cwaves" _label="CWaves">
+
+  <command arg="-root"/>
+
+<!--
+  <number id="delay" type="slider" arg="-delay %"
+          _label="Speed" _low-label="Slow" _high-label="Fast"
+          low="0" high="30000" default="20000"
+          convert="invert"/>
+-->
+
+  <number id="waves" type="slider" arg="-waves %"
+          _label="Complexity" _low-label="Low" _high-label="High"
+          low="1" high="100" default="15"/>
+
+  <number id="ncolors" type="slider" arg="-colors %"
+            _label="Color Transitions" _low-label="Rough" _high-label="Smooth"
+            low="2" high="1000" default="600"/>
+
+  <_description>
+This generates a languidly-scrolling vertical field of sinusoidal colors.
+
+Written by Jamie Zawinski; 2007.
+  </_description>
+</screensaver>
diff --git a/hacks/config/glcells.xml b/hacks/config/glcells.xml
new file mode 100644 (file)
index 0000000..b76bfb7
--- /dev/null
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<screensaver name="glcells" _label="GLCells">
+
+  <command arg="-root"/>
+
+  <number id="delay" type="slider" arg="-delay %"
+          _label="Animation Speed" _low-label="Slow" _high-label="Fast"
+          low="0" high="50000" default="20000"
+          convert="invert"/>
+  
+  <number id="pause" type="slider" arg="-pause %"
+          _label="Pause at end" _low-label="Short" _high-label="Long"
+          low="0" high="400" default="20"/>
+  
+  <number id="maxcells" type="slider" arg="-maxcells %"
+          _label="Max. number of cells" _low-label="Few" _high-label="Many"
+          low="50" high="10000" default="800"/>
+  
+  <number id="radius" type="slider" arg="-radius %"
+          _label="Cell radius" _low-label="Small" _high-label="Huge"
+          low="5" high="200" default="40"/>
+  
+  <number id="seeds" type="slider" arg="-seeds %"
+          _label="Number of seeds" _low-label="Few" _high-label="Many"
+          low="1" high="16" default="1"/>
+  
+  <number id="quality" type="slider" arg="-quality %"
+          _label="Sphere quality" _low-label="Low" _high-label="High"
+          low="0" high="5" default="2"/>
+  
+  <number id="minfood" type="slider" arg="-minfood %"
+          _label="Min. amount of food" _low-label="Small" _high-label="A lot"
+          low="0" high="1000" default="5"/>
+  
+  <number id="maxfood" type="slider" arg="-maxfood %"
+          _label="Max. amount of food" _low-label="Small" _high-label="A lot"
+          low="0" high="1000" default="20"/>
+  
+  <number id="divideage" type="slider" arg="-divideage %"
+          _label="Cell division" _low-label="Quick" _high-label="Slow"
+          low="1" high="1000" default="20"/>
+  
+  <number id="mindist" type="slider" arg="-mindist %"
+          _label="Min. distance" _low-label="Small" _high-label="Large"
+          low="1.0" high="3.0" default="1.4"/>
+
+
+  <boolean id="keepold" _label="Keep dead cells" arg-set="-keepold"/>
+  
+  <boolean id="showfps" _label="Show Frames-per-Second" arg-set="-fps"/>
+  
+  <boolean id="wireframe" _label="Wireframe" arg-set="-wireframe"/>
+
+  <_description>
+Cells growing, dividing and dying on your screen.
+
+Written by Matthias Toussaint; 2007.
+  </_description>
+</screensaver>
diff --git a/hacks/config/m6502.xml b/hacks/config/m6502.xml
new file mode 100644 (file)
index 0000000..26db9f9
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<screensaver name="m6502" _label="M6502">
+
+  <command arg="-root" />
+
+  <number id="displaytime" type="slider" arg="-displaytime %"
+          _label="Display time for each program"
+          _low-label="5 seconds" _high-label="2 minutes"
+         low="5" high="120" default="10" />
+
+  <file id="file" _label="Assembly File" arg="-file %"/>
+
+  <_description> 
+The m6502 screensaver emulates a 6502 microprocessor.  The family
+of 6502 chips were used throughout the 70's and 80's in machines
+such as the Atari 2600, Commodore PET, VIC20 and C64, Apple ][,
+and the NES. Some example programs are included, and it can also
+read in an assembly file as input.
+
+Original JavaScript Version by Stian Soreng: http://www.6502asm.com/.
+Ported to XScreenSaver by Jeremy English.
+
+Written by Stian Soreng and Jeremy English; 2007.
+  </_description>
+</screensaver>
diff --git a/hacks/config/voronoi.xml b/hacks/config/voronoi.xml
new file mode 100644 (file)
index 0000000..6698ed8
--- /dev/null
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<screensaver name="voronoi" _label="Voronoi">
+
+  <command arg="-root"/>
+
+  <number id="delay" type="slider" arg="-delay %"
+          _label="Frame Rate" _low-label="Slow" _high-label="Fast"
+          low="0" high="100000" default="20000"
+          convert="invert"/>
+
+  <number id="points" type="slider" arg="-points %"
+          _label="Points" _low-label="Few" _high-label="Many"
+          low="1" high="50" default="10"/>
+
+  <number id="pointSize" type="slider" arg="-point-size %"
+          _label="Point Size" _low-label="0" _high-label="50 pixels"
+          low="0" high="50" default="9"/>
+
+  <number id="pointSpeed" type="slider" arg="-point-speed %"
+          _label="Wander Speed" _low-label="Slow" _high-label="Fast"
+          low="0.0" high="10.0" default="1.0"/>
+
+  <number id="pointDelay" type="slider" arg="-point-delay %"
+          _label="Insertion Speed" _low-label="Slow" _high-label="Fast"
+          low="0.0" high="3.0" default="0.1"
+          convert="invert"/>
+
+  <number id="zoomSpeed" type="slider" arg="-zoom-speed %"
+          _label="Zoom Speed" _low-label="Slow" _high-label="Fast"
+          low="0.1" high="10.0" default="1.0"/>
+
+  <number id="zoomDelay" type="slider" arg="-zoom-delay %"
+          _label="Zoom Frequency" _low-label="0" _high-label="60 Seconds"
+          low="0" high="60" default="10"/>
+
+  <_description>
+Draws a randomly-colored Voronoi tessellation, and periodically zooms 
+in and adds new points.  The existing points also wander around.
+
+There are a set of control points on the plane, each at the center of
+a colored cell.  Every pixel within that cell is closer to that cell's
+control point than to any other control point.  That is what
+determines the cell's shapes.
+
+Written by Jamie Zawinski; 2007.
+  </_description>
+</screensaver>
diff --git a/hacks/cwaves.c b/hacks/cwaves.c
new file mode 100644 (file)
index 0000000..cb72a07
--- /dev/null
@@ -0,0 +1,150 @@
+/* xscreensaver, Copyright (c) 2007 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  No representations are made about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or 
+ * implied warranty.
+ *
+ * cwaves -- languid sinusoidal colors.
+ */
+
+#include "screenhack.h"
+#include <stdio.h>
+#include "xpm-pixmap.h"
+
+#define ALIVE   1
+#define CHANGED 2
+#define UNDEAD  4
+
+typedef struct {
+  double scale;
+  double offset;
+  double delta;
+} wave;
+
+typedef struct {
+  Display *dpy;
+  Window window;
+  XWindowAttributes xgwa;
+  GC gc;
+  int delay;
+  int ncolors;
+  XColor *colors;
+
+  int nwaves;
+  wave *waves;
+
+} state;
+
+
+static void *
+cwaves_init (Display *dpy, Window window)
+{
+  int i;
+  XGCValues gcv;
+  state *st = (state *) calloc (1, sizeof (*st));
+
+  st->dpy = dpy;
+  st->window = window;
+  XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
+
+  st->ncolors = get_integer_resource (dpy, "ncolors", "Integer");
+  if (st->ncolors < 4) st->ncolors = 4;
+  st->colors = (XColor *) malloc (sizeof(*st->colors) * (st->ncolors+1));
+  make_smooth_colormap (st->dpy, st->xgwa.visual, st->xgwa.colormap,
+                        st->colors, &st->ncolors,
+                        True, 0, False);
+
+  st->gc = XCreateGC (st->dpy, st->window, 0, &gcv);
+  st->delay = get_integer_resource (dpy, "delay", "Integer");
+
+  st->nwaves  = get_integer_resource (dpy, "nwaves", "Integer");
+  st->waves  = (wave *) calloc (st->nwaves,  sizeof(*st->waves));
+
+  for (i = 0; i < st->nwaves; i++)
+    {
+      st->waves[i].scale  = frand(0.05) + 0.005;
+      st->waves[i].offset = frand(M_PI);
+      st->waves[i].delta  = (frand(2) - 1) / 20.0;
+    }
+
+  return st;
+}
+
+
+static unsigned long
+cwaves_draw (Display *dpy, Window window, void *closure)
+{
+  state *st = (state *) closure;
+  int i, x;
+
+  for (i = 0; i < st->nwaves; i++)
+    st->waves[i].offset += st->waves[i].delta;
+
+  for (x = 0; x < st->xgwa.width; x++)
+    {
+      double v = 0;
+      int j;
+      for (i = 0; i < st->nwaves; i++)
+        v += cos ((x * st->waves[i].scale) - st->waves[i].offset);
+      v /= st->nwaves;
+
+      j = st->ncolors * (v/2 + 0.5);
+      if (j < 0 || j >= st->ncolors) abort();
+      XSetForeground (st->dpy, st->gc, st->colors[j].pixel);
+      XDrawLine (st->dpy, st->window, st->gc, x, 0, x, st->xgwa.height);
+    }
+
+  return st->delay;
+}
+
+
+static void
+cwaves_reshape (Display *dpy, Window window, void *closure, 
+                 unsigned int w, unsigned int h)
+{
+  state *st = (state *) closure;
+  XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
+}
+
+static Bool
+cwaves_event (Display *dpy, Window window, void *closure, XEvent *event)
+{
+  state *st = (state *) closure;
+  if (event->type == ButtonPress)
+    {
+      make_smooth_colormap (st->dpy, st->xgwa.visual, st->xgwa.colormap,
+                            st->colors, &st->ncolors,
+                            True, 0, False);
+      return True;
+    }
+  return False;
+}
+
+static void
+cwaves_free (Display *dpy, Window window, void *closure)
+{
+}
+
+
+static const char *cwaves_defaults [] = {
+  ".background:                   black",
+  ".foreground:                   white",
+  "*ncolors:              600",
+  "*nwaves:               15",
+  "*delay:                20000",
+  0
+};
+
+static XrmOptionDescRec cwaves_options [] = {
+  { "-delay",          ".delay",               XrmoptionSepArg, 0 },
+  { "-waves",          ".nwaves",              XrmoptionSepArg, 0 },
+  { "-colors",         ".ncolors",             XrmoptionSepArg, 0 },
+  { 0, 0, 0, 0 }
+};
+
+
+XSCREENSAVER_MODULE ("CWaves", cwaves)
diff --git a/hacks/cwaves.man b/hacks/cwaves.man
new file mode 100644 (file)
index 0000000..a7fd78b
--- /dev/null
@@ -0,0 +1,72 @@
+.TH XScreenSaver 1 "14-Jun-97" "X Version 11"
+.SH NAME
+cwaves - languid sinusoidal colors
+.SH SYNOPSIS
+.B cwaves
+[\-display \fIhost:display.screen\fP]
+[\-foreground \fIcolor\fP]
+[\-background \fIcolor\fP]
+[\-window]
+[\-root]
+[\-mono]
+[\-install]
+[\-visual \fIvisual\fP]
+[\-delay \fIusecs\fP]
+[\-waves \fIint\fP]
+[\-colors \fIint\fP]
+.SH DESCRIPTION
+The \fIcwaves\fP program draws a languidly-scrolling vertical field
+of sinusoidal colors.
+.SH OPTIONS
+.I cwaves
+accepts the following options:
+.TP 8
+.B \-window
+Draw on a newly-created window.  This is the default.
+.TP 8
+.B \-root
+Draw on the root window.
+.TP 8
+.B \-mono 
+If on a color display, pretend we're on a monochrome display.
+.TP 8
+.B \-install
+Install a private colormap for the window.
+.TP 8
+.B \-visual \fIvisual\fP
+Specify which visual to use.  Legal values are the name of a visual class,
+or the id number (decimal or hex) of a specific visual.
+.TP 8
+.B \-delay \fImicroseconds\fP
+How much of a delay should be introduced between steps of the animation.
+Default 20000, or about 1/50th second.
+.TP 8
+.B \-waves \fIint\fP
+How many cosines to add together.  The more waves, the more complex
+the apparent motion.
+.TP 8
+.B \-colors \fIint\fP
+How many colors to use.  Default 800.  The more colors, the smoother the
+blending will be.
+.SH ENVIRONMENT
+.PP
+.TP 8
+.B DISPLAY
+to get the default host and display number.
+.TP 8
+.B XENVIRONMENT
+to get the name of a resource file that overrides the global resources
+stored in the RESOURCE_MANAGER property.
+.SH SEE ALSO
+.BR X (1),
+.BR xscreensaver (1)
+.SH COPYRIGHT
+Copyright \(co 2007 by Jamie Zawinski.  Permission to use, copy, modify, 
+distribute, and sell this software and its documentation for any purpose is 
+hereby granted without fee, provided that the above copyright notice appear 
+in all copies and that both that copyright notice and this permission notice
+appear in supporting documentation.  No representations are made about the 
+suitability of this software for any purpose.  It is provided "as is" without
+express or implied warranty.
+.SH AUTHOR
+Jamie Zawinski <jwz@jwz.org>, 2-Jul-2007.
index 2e6fd72741cec6fb20340206a1eea818c4ebfb8e..ed1635fd2db9b96a42b2d7f8e4959e9a5f8dce95 100644 (file)
@@ -102,7 +102,8 @@ SRCS                = xscreensaver-gl-helper.c normals.c glxfonts.c \
                  antinspect.c providence.c pinion.c boing.c texfont.c \
                  carousel.c fliptext.c antmaze.c tangram.c tangram_shapes.c \
                  crackberg.c glhanoi.c cube21.c timetunnel.c juggler3d.c \
-                 topblock.c glschool.c glschool_gl.c glschool_alg.c
+                 topblock.c glschool.c glschool_gl.c glschool_alg.c \
+                 glcells.c voronoi.c
 
 OBJS           = xscreensaver-gl-helper.o normals.o glxfonts.o \
                  atlantis.o b_draw.o b_lockglue.o b_sphere.o bubble3d.o \
@@ -134,7 +135,8 @@ OBJS                = xscreensaver-gl-helper.o normals.o glxfonts.o \
                  antinspect.o providence.o pinion.o boing.o texfont.o \
                  carousel.o fliptext.o antmaze.o tangram.o tangram_shapes.o \
                  crackberg.o glhanoi.o cube21.o timetunnel.o juggler3d.o \
-                 topblock.o glschool.o glschool_gl.o glschool_alg.o
+                 topblock.o glschool.o glschool_gl.o glschool_alg.o \
+                 glcells.o voronoi.o
 
 GL_EXES                = cage gears moebius pipes sproingies stairs superquadrics \
                  morph3d rubik atlantis lament bubble3d glplanet pulsar \
@@ -147,7 +149,7 @@ GL_EXES             = cage gears moebius pipes sproingies stairs superquadrics \
                  gleidescope mirrorblob blinkbox noof polyhedra \
                  antinspect providence pinion boing carousel fliptext \
                  antmaze tangram crackberg glhanoi cube21 timetunnel \
-                 juggler3d topblock glschool
+                 juggler3d topblock glschool glcells voronoi
 GLE_EXES       = extrusion
 GL_UTIL_EXES   = xscreensaver-gl-helper
 HACK_EXES      = @GL_EXES@ @GLE_EXES@
@@ -187,7 +189,8 @@ GL_MEN              = atlantis.man boxed.man bubble3d.man cage.man circuit.man \
                  antinspect.man providence.man pinion.man boing.man \
                  carousel.man fliptext.man antmaze.man tangram.man \
                  crackberg.man glhanoi.man cube21.man timetunnel.man \
-                 juggler3d.man topblock.man glschool.man
+                 juggler3d.man topblock.man glschool.man glcells.man \
+                 voronoi.man
 MEN            = @GL_MEN@
 EXTRAS         = README Makefile.in dxf2gl.pl molecules.sh starwars.txt
 
@@ -694,13 +697,19 @@ juggler3d:        juggler3d.o     $(HACK_TRACK_OBJS)
 dnalogo:       dnalogo.o      tube.o normals.o $(HACK_TRACK_OBJS)
        $(CC_HACK) -o $@ $@.o  tube.o normals.o $(HACK_TRACK_OBJS) $(HACK_LIBS)
 
-topblock:      topblock.o      $(DB_OBJS)
-       $(CC_HACK) -o $@ $@.o   $(DB_OBJS) $(HACK_LIBS)
+topblock:      topblock.o      sphere.o $(HACK_TRACK_OBJS)
+       $(CC_HACK) -o $@ $@.o   sphere.o $(HACK_TRACK_OBJS) $(HACK_LIBS)
 
 SCHOOL_OBJS=glschool.o glschool_alg.o glschool_gl.o sphere.o tube.o $(HACK_OBJS)
 glschool: $(SCHOOL_OBJS)
        $(CC_HACK) -o $@ $(SCHOOL_OBJS) $(HACK_LIBS)
 
+glcells:       glcells.o       $(HACK_OBJS)
+       $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) $(HACK_LIBS)
+
+voronoi:       voronoi.o       $(HACK_OBJS)
+       $(CC_HACK) -o $@ $@.o   $(HACK_OBJS) $(HACK_LIBS)
+
 ##############################################################################
 #
 # DO NOT DELETE: updated by make distdepend
@@ -1253,6 +1262,18 @@ glblur.o: $(UTILS_SRC)/xshm.h
 glblur.o: $(UTILS_SRC)/yarandom.h
 glblur.o: $(HACK_SRC)/xlockmoreI.h
 glblur.o: $(HACK_SRC)/xlockmore.h
+glcells.o: ../../config.h
+glcells.o: $(HACK_SRC)/screenhackI.h
+glcells.o: $(UTILS_SRC)/colors.h
+glcells.o: $(UTILS_SRC)/grabscreen.h
+glcells.o: $(UTILS_SRC)/hsv.h
+glcells.o: $(UTILS_SRC)/resources.h
+glcells.o: $(UTILS_SRC)/usleep.h
+glcells.o: $(UTILS_SRC)/visual.h
+glcells.o: $(UTILS_SRC)/xshm.h
+glcells.o: $(UTILS_SRC)/yarandom.h
+glcells.o: $(HACK_SRC)/xlockmoreI.h
+glcells.o: $(HACK_SRC)/xlockmore.h
 gleidescope.o: ../../config.h
 gleidescope.o: $(srcdir)/grab-ximage.h
 gleidescope.o: $(HACK_SRC)/screenhackI.h
@@ -1971,6 +1992,18 @@ tunnel_draw.o: $(UTILS_SRC)/visual.h
 tunnel_draw.o: $(UTILS_SRC)/xshm.h
 tunnel_draw.o: $(UTILS_SRC)/yarandom.h
 tunnel_draw.o: $(HACK_SRC)/xlockmoreI.h
+voronoi.o: ../../config.h
+voronoi.o: $(HACK_SRC)/screenhackI.h
+voronoi.o: $(UTILS_SRC)/colors.h
+voronoi.o: $(UTILS_SRC)/grabscreen.h
+voronoi.o: $(UTILS_SRC)/hsv.h
+voronoi.o: $(UTILS_SRC)/resources.h
+voronoi.o: $(UTILS_SRC)/usleep.h
+voronoi.o: $(UTILS_SRC)/visual.h
+voronoi.o: $(UTILS_SRC)/xshm.h
+voronoi.o: $(UTILS_SRC)/yarandom.h
+voronoi.o: $(HACK_SRC)/xlockmoreI.h
+voronoi.o: $(HACK_SRC)/xlockmore.h
 whale.o: $(srcdir)/atlantis.h
 whale.o: ../../config.h
 whale.o: $(HACK_SRC)/screenhackI.h
index f3272c2e7d58c36df3bdeee93a816ebeee80e23e..87e34c65751374f2988d0ca88f865708a95afc1c 100644 (file)
@@ -90,6 +90,10 @@ static Bool draw_ant(antspotlightstruct *mp,
   float sin2 = sin(ant_step + 2 * Pi / 3);
   float sin3 = sin(ant_step + 4 * Pi / 3);
   
+  glEnable(GL_POLYGON_SMOOTH);
+  glEnable(GL_BLEND);
+  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
   glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->mono ? MaterialGray5 : Material);
   glEnable(GL_CULL_FACE);
   glPushMatrix();
@@ -123,6 +127,10 @@ static Bool draw_ant(antspotlightstruct *mp,
   glDisable(GL_LIGHTING);
   
   /* ANTENNAS */
+  glEnable(GL_LINE_SMOOTH);
+  glEnable(GL_BLEND);
+  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+   
   glBegin(GL_LINES);
   glColor3fv(mp->mono ? MaterialGray5 : Material);
   glVertex3f(0.00, 0.30, 0.00);
@@ -277,7 +285,7 @@ static void draw_board(antspotlightstruct *mp)
      i should be finding the intersection of the cone of light and
      the board-plane.
   */
-  for(i = -8; i < 8; ++i) {
+  for(i = -12; i < 12; ++i) {
 
     double theta1, theta2;
 
@@ -291,7 +299,7 @@ static void draw_board(antspotlightstruct *mp)
     theta1 = mp->ant->direction + i*(cutoff/8);
     theta2 = mp->ant->direction + (i+1)*(cutoff/8);
 
-    for(j = 1; j <= 40; ++j) {
+    for(j = 1; j <= 64; ++j) {
       double point[3], tex[2];
       /* double fj = pow(1.05, j) - 1.0;*/
       double fj = j / 6.0;
@@ -447,6 +455,11 @@ static void draw_antspotlight_strip(ModeInfo *mi)
     reset_ant(mp);
   }
 
+  if(random()%100 == 0) {
+    reset_ant(mp);
+  }
+
+
   /* move toward goal, correct ant direction if required */
   else {
     
@@ -526,7 +539,8 @@ static void pinit(void)
   glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
   glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
   glLightfv(GL_LIGHT1, GL_POSITION, position1);
-/*   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); */
+
+  glLightModelfv(GL_LIGHT_MODEL_AMBIENT, spotlight_ambient);
   glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHT0);
diff --git a/hacks/glx/glcells.c b/hacks/glx/glcells.c
new file mode 100644 (file)
index 0000000..86355f1
--- /dev/null
@@ -0,0 +1,1297 @@
+/* -*- Mode: C; tab-width: 2 -*- */
+/* glcells --- Cells growing on your screen */
+
+/*-
+ * Cells growing on your screen
+ *
+ * Copyright (c) 2006 by Matthias Toussaint
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * This file is provided AS IS with no warranties of any kind.  The author
+ * shall have no liability with respect to the infringement of copyrights,
+ * trade secrets or any patents by this file or any part thereof.  In no
+ * event will the author be liable for any lost revenue or profits or
+ * other special, indirect and consequential damages.
+ *
+ * 2006: Written by Matthias Toussaint
+ */
+#include <sys/time.h> /* gettimeofday */
+
+#include "xlockmore.h"
+#include <math.h>
+
+/**********************************
+  DEFINES
+ **********************************/
+
+#define INDEX_OFFSET 100000
+#define NUM_CELL_SHAPES 10
+
+#define refresh_glcells 0
+#define glcells_handle_event 0
+
+#define DEF_DELAY     "20000"
+#define DEF_MAXCELLS  "800"
+#define DEF_RADIUS    "40"
+#define DEF_SEEDS     "1"
+#define DEF_QUALITY   "3"
+#define DEF_KEEPOLD   "False"
+#define DEF_MINFOOD   "5"
+#define DEF_MAXFOOD   "20"
+#define DEF_DIVIDEAGE "20"
+#define DEF_MINDIST   "1.40"
+#define DEF_PAUSE     "50"
+
+#define DEFAULTS       "*delay:        30000            \n" \
+                       "*showFPS:      False            \n" \
+                       "*wireframe:    False            \n" \
+
+#undef countof
+#define countof(x) (sizeof((x))/sizeof((*x)))
+
+#define USE_VERTEX_ARRAY
+
+#define TEX_SIZE 64
+
+/**********************************
+  TYPEDEFS
+ **********************************/
+typedef struct    /* a 3-D vector */
+{
+  double x, y, z;   /* 3-D coordinates (we don't need w here) */
+} Vector;
+
+typedef struct    /* a triangle (indexes of vertexes in some list) */
+{
+  int i[3];         /* the three indexes for the triangle corners */
+} Triangle;
+
+typedef struct
+{
+  float *vertex;
+  float *normal;
+  unsigned *index;
+  int num_index;
+} VertexArray;
+
+typedef struct    /* an 3-D object without normal vectors */
+{ 
+  Vector *vertex;       /* the vertexes */
+  Triangle *triangle;   /* triangle list */
+  int num_vertex;       /* number of vertexes */
+  int num_triangle;     /* number of triangles */
+} Object;
+
+typedef struct    /* an 3-D object with smooth normal vectors */
+{
+  Vector *vertex;       /* the vertexes */
+  Vector *normal;       /* the vertex normal vectors */
+  Triangle *triangle;   /* triangle list */
+  int num_vertex;       /* number of vertexes */
+  int num_triangle;     /* number of triangles */
+} ObjectSmooth;
+
+typedef struct    /* Cell */
+{
+  double x, y;      /* position */
+  double vx, vy;    /* movement vector */
+  int age;          /* cells age */
+  double min_dist;  /* minimum distance to other cells */
+  int energy;       /* health */
+  double rotation;  /* random rot, so they don't look all the same */
+  double radius;    /* current size of cell */
+  double growth;    /* current growth rate. might be <1.0 while dividing,
+                       >1.0 when finished dividing and food is available
+                       and 1.0 when grown up */
+} Cell;
+
+typedef struct    /* hacks state */
+{
+  GLXContext *glx_context;
+  int width, height;    /* current size of viewport */
+  int num_cells;        /* current number of cell in list */
+  Cell *cell;           /* array of cells */
+  int cell_polys;
+  GLfloat color[4];     /* current cell color */
+  int radius;           /* cell radius */
+  int move_dist;        /* min distance from neighbours for forking */
+  int max_cells;        /* maximum number of cells */
+  int num_seeds;        /* number of initial seeds */
+  int keep_old_cells;   /* draw dead cells? */
+  int divide_age;       /* min age for division */
+                        /* display lists for the cell stages */
+  int cell_list[NUM_CELL_SHAPES];    
+  int nucleus_list;
+  int minfood;          /* minimum amount of food per area unit */
+  int maxfood;          /* maximum amount of food per area unit */
+  int pause;            /* pause at end (all cells dead) */
+  int pause_counter;
+  int wire;             /* draw wireframe? */
+  Object *sphere;       /* the raw undisturbed sphere */
+  double *disturbance;  /* disturbance values for the vertexes */
+  int *food;            /* our petri dish (e.g. screen) */
+  GLubyte *texture;     /* texture data for nucleus */
+  GLuint texture_name;  /* texture name for binding */
+} State;
+
+/**********************************
+  STATIC STUFF
+ **********************************/
+static State *sstate = NULL;
+
+static XrmOptionDescRec opts[] = {
+  { "-maxcells",   ".maxcells",   XrmoptionSepArg, 0 },
+  { "-radius",     ".radius",     XrmoptionSepArg, 0 },
+  { "-seeds",      ".seeds",      XrmoptionSepArg, 0 },
+  { "-quality",    ".quality",    XrmoptionSepArg, 0 },
+  { "-minfood",    ".minfood",    XrmoptionSepArg, 0 },
+  { "-maxfood",    ".maxfood",    XrmoptionSepArg, 0 },
+  { "-divideage",  ".divideage",  XrmoptionSepArg, 0 },
+  { "-mindist",    ".mindist",    XrmoptionSepArg, 0 },
+  { "-pause",      ".pause",      XrmoptionSepArg, 0 },
+  { "-keepold",    ".keepold",    XrmoptionNoArg, "True" }
+};
+
+static int  s_maxcells;
+static int  s_radius;
+static int  s_seeds;
+static int  s_quality;
+static int  s_minfood;
+static int  s_maxfood;
+static int  s_divideage;
+static int  s_pause;
+static float s_min_dist;
+static Bool s_keepold;
+
+static argtype vars[] = {
+  {&s_maxcells,  "maxcells",  "Max Cells",      DEF_MAXCELLS, t_Int},
+  {&s_radius,    "radius",    "Radius",         DEF_RADIUS,   t_Int},
+  {&s_seeds,     "seeds",     "Seeds",          DEF_SEEDS,    t_Int},
+  {&s_quality,   "quality",   "Quality",        DEF_QUALITY,  t_Int},
+  {&s_minfood,   "minfood",   "Min Food",       DEF_MINFOOD,  t_Int},
+  {&s_maxfood,   "maxfood",   "Max Food",       DEF_MAXFOOD,  t_Int},
+  {&s_pause,   "pause",     "Pause at end",   DEF_PAUSE,  t_Int},
+  {&s_divideage, "divideage", "Age for duplication (Ticks)",       DEF_DIVIDEAGE,  t_Int},
+  {&s_min_dist,  "mindist",   "Minimum prefered distance to other cells",       DEF_MINDIST,  t_Float},
+  {&s_keepold,   "keepold",   "Keep old cells", DEF_KEEPOLD,  t_Bool}
+};
+
+/**********************************
+  PROTOTYPES
+ **********************************/
+/* render scene */
+static int render( State *st );
+/* create initial cells and fill petri dish with food */
+static void create_cells( State * );
+/* do one animation step */
+static void tick( State *st );
+/* draw a single cell */
+static void draw_cell( State *st, int shape );
+/* draw cells nucleus */
+static void draw_nucleus( State *st );
+/* return randum number in the interval min-max */
+static int random_interval( int min, int max );
+/* retunr random number in the interval 0-max */
+static int random_max( int max );
+/* create display list for given disturbance weighting factor */
+static int create_list( State *st, double fac );
+/* return length of vector */
+static double vector_length( Vector * );
+/* normalize vector */
+static void vector_normalize( Vector * );
+/* a += b */
+static void vector_add( Vector *a, Vector *b );
+/* a -= b */
+static void vector_sub( Vector *a, Vector *b );
+/* a *= fac */
+static void vector_mul( Vector *a, double fac );
+/* a.x = a.y = a.z = 0 */
+static void vector_clear( Vector *a );
+/* return crossproduct a*b in out */
+static void vector_crossprod( Vector *a, Vector *b, Vector *out );
+/* return 1 if vectors are equal (epsilon compare) otherwise 0 */
+static int vector_compare( Vector *a, Vector *b );
+/* compute normal vector of given triangle and return in out */
+static void triangle_normal( Vector *a, Vector *b, Vector *c, Vector *out );
+/* take an Object and create an ObjectSmooth out of it */
+static ObjectSmooth *create_ObjectSmooth( Object * );
+/* Subdivide the Object once (assuming it's supposed to be a shpere */
+static Object *subdivide( Object *obj );
+/* free an Object */
+static void free_Object( Object * );
+/* free an ObjectSmooth */
+static void free_ObjectSmooth( ObjectSmooth * );
+/* scale an Object. return pointer to the object */
+/*static Object *scale_Object( Object *obj, double scale );*/
+/* create a perfect sphere refining with divisions */
+static Object *create_sphere( State *st, int divisions );
+/* make a copy of the given Object */
+static Object *clone_Object( Object * );
+/* return 1 if cell is capable to divide */
+static int can_divide( State *st, Cell *cell );
+static VertexArray *array_from_ObjectSmooth( ObjectSmooth * );
+static void create_nucleus_texture( State *st );
+
+ENTRYPOINT ModeSpecOpt glcells_opts = { countof(opts), opts,                                                   countof(vars), vars, 
+                                        NULL };
+                                        
+
+/**********************************
+  INLINE FUNCTIONS
+ **********************************/
+/* create random numbers
+*/
+static inline int random_interval( int min, int max )
+{
+  return min+(random()%(max-min));
+}
+
+static inline int random_max( int max )
+{
+  return random()%max;
+}
+
+/* Vector stuff
+*/
+
+/* a += b */
+static inline void vector_add( Vector *a, Vector *b )
+{
+  a->x += b->x;
+  a->y += b->y;
+  a->z += b->z;
+}
+
+/* a -= b */
+static inline void vector_sub( Vector *a, Vector *b )
+{
+  a->x -= b->x;
+  a->y -= b->y;
+  a->z -= b->z;
+}
+
+/* a *= v */
+static inline void vector_mul( Vector *a, double v )
+{
+  a->x *= v;
+  a->y *= v;
+  a->z *= v;
+}
+
+/* set to 0 */
+static inline void vector_clear( Vector *vec )
+{
+  vec->x = vec->y = vec->z = 0;
+}
+
+/* return vector length */
+static inline double vector_length( Vector *vec )
+{
+  return sqrt( vec->x*vec->x + vec->y*vec->y + vec->z*vec->z );
+}
+
+/* normalize vector */
+static inline void vector_normalize( Vector *vec )
+{
+  double len = vector_length( vec );
+  
+  if (len != 0.0) {
+    vector_mul( vec, 1.0 / len );
+  }
+}
+
+/* crossproduct */
+static inline void vector_crossprod( Vector *a, Vector *b, Vector *out )
+{
+  out->x = a->y*b->z - a->z*b->y;
+  out->y = a->z*b->x - a->x*b->z;
+  out->z = a->x*b->y - a->y*b->x;
+}
+
+/* epsilon compare of two vectors */
+static inline int vector_compare( Vector *a, Vector *b )
+{
+  const double epsilon = 0.0000001;
+  Vector delta = *a;
+  
+  vector_sub( &delta, b );
+  if (fabs(delta.x) < epsilon && 
+      fabs(delta.y) < epsilon &&
+      fabs(delta.z) < epsilon) {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/* check if given cell is capable of dividing 
+   needs space, must be old enough, grown up and healthy
+*/
+static inline int can_divide( State *st, Cell *cell )
+{
+  if (cell->min_dist > st->move_dist &&
+      cell->age >= st->divide_age &&
+      cell->radius > 0.99 * st->radius &&
+      cell->energy > 0) {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**********************************
+  FUNCTIONS
+ **********************************/
+
+/* compute normal vector of given 
+   triangle spanned by the points a, b, c 
+*/
+static void triangle_normal( Vector *a, Vector *b, Vector *c, Vector *out )
+{
+  Vector v1 = *a;
+  Vector v2 = *a;
+  
+  vector_sub( &v1, b );
+  vector_sub( &v2, c );
+  vector_crossprod( &v1, &v2, out );
+}
+
+/* free */
+static void free_Object( Object *obj )
+{
+  free( obj->vertex );
+  free( obj->triangle );
+  free( obj );
+}
+
+static void free_ObjectSmooth( ObjectSmooth *obj )
+{
+  free( obj->vertex );
+  free( obj->triangle );
+  free( obj->normal );
+  free( obj );
+}
+
+/* scale the given Object */
+#if 0
+static Object *scale_Object( Object *obj, double scale )
+{
+  int v;
+  
+  for (v=0; v<obj->num_vertex; ++v) {
+    vector_mul( &obj->vertex[v], scale );
+  }
+  
+  return obj;
+}
+#endif
+
+/* create a copy of the given Object */
+static Object *clone_Object( Object *obj )
+{
+  /* alloc */
+  Object *ret = (Object *) malloc( sizeof( Object ) );
+  
+  ret->vertex = 
+      (Vector *) malloc( obj->num_vertex*sizeof(Vector) );
+  ret->triangle = 
+      (Triangle *) malloc( obj->num_triangle*sizeof(Triangle) );
+  ret->num_vertex = obj->num_vertex;
+  ret->num_triangle = obj->num_triangle;
+  /* copy */
+  memcpy( ret->vertex, obj->vertex, 
+          obj->num_vertex*sizeof(Vector) );
+  memcpy( ret->triangle, obj->triangle,
+          obj->num_triangle*sizeof(Triangle) );
+  
+  return ret;
+}
+
+static VertexArray *array_from_ObjectSmooth( ObjectSmooth *obj )
+{
+  int i, j;
+  VertexArray *array = (VertexArray *) malloc( sizeof( VertexArray ) );
+  
+  array->vertex = (float *) malloc( 3*sizeof(float)*obj->num_vertex );
+  array->normal = (float *) malloc( 3*sizeof(float)*obj->num_vertex );
+  array->index = (unsigned *) malloc( 3*sizeof(unsigned)*obj->num_triangle );
+  array->num_index = obj->num_triangle*3;
+  
+  for (i=0, j=0; i<obj->num_vertex; ++i) {
+    array->vertex[j]   = obj->vertex[i].x;
+    array->normal[j++] = obj->normal[i].x;
+    array->vertex[j]   = obj->vertex[i].y;
+    array->normal[j++] = obj->normal[i].y;
+    array->vertex[j]   = obj->vertex[i].z;
+    array->normal[j++] = obj->normal[i].z;
+  }
+
+  for (i=0, j=0; i<obj->num_triangle; ++i) {
+    array->index[j++] = obj->triangle[i].i[0];
+    array->index[j++] = obj->triangle[i].i[1];
+    array->index[j++] = obj->triangle[i].i[2];
+  }
+  
+  return array;
+}
+
+/* create a smoothed version of the given Object
+   by computing average normal vectors for the vertexes 
+*/
+static ObjectSmooth *create_ObjectSmooth( Object *obj )
+{
+  int t, v, i;
+  Vector *t_normal = 
+      (Vector *) malloc( obj->num_triangle*sizeof(Vector) );
+  ObjectSmooth *ret = 
+      (ObjectSmooth *) malloc( sizeof( ObjectSmooth ) );
+  
+  /* fill in vertexes and triangles */
+  ret->num_vertex = obj->num_vertex;
+  ret->num_triangle = obj->num_triangle;
+  ret->vertex = 
+      (Vector *) malloc( obj->num_vertex * sizeof( Vector ) );
+  ret->normal = 
+      (Vector *) malloc( obj->num_vertex * sizeof( Vector ) );
+  ret->triangle = 
+      (Triangle *) malloc( obj->num_triangle * sizeof( Triangle ) );
+  
+  for (v=0; v<obj->num_vertex; ++v) {
+    ret->vertex[v] = obj->vertex[v];
+  }
+  
+  for (t=0; t<obj->num_triangle; ++t) {
+    ret->triangle[t] = obj->triangle[t];
+  }
+  
+  /* create normals (triangles) */
+  for (t=0; t<ret->num_triangle; ++t) {
+    triangle_normal( &ret->vertex[ret->triangle[t].i[0]],
+                     &ret->vertex[ret->triangle[t].i[1]],
+                     &ret->vertex[ret->triangle[t].i[2]],
+                     &t_normal[t] );
+  }
+  
+  /* create normals (vertex) by averaging triangle 
+     normals at vertex
+  */
+  for (v=0; v<ret->num_vertex; ++v) {
+    vector_clear( &ret->normal[v] );
+    for (t=0; t<ret->num_triangle; ++t) {
+      for (i=0; i<3; ++i) {
+        if (ret->triangle[t].i[i] == v) {
+          vector_add( &ret->normal[v], &t_normal[t] );
+        }
+      }
+    }
+    /* as we have only a half sphere we force the
+       normals at the bortder to be perpendicular to z.
+       the simple algorithm above makes an error here.
+    */
+    if (fabs(ret->vertex[v].z) < 0.0001) {
+      ret->normal[v].z = 0.0;
+    }  
+    
+    vector_normalize( &ret->normal[v] );
+  }
+  
+  free( t_normal );
+  
+  return ret;
+}
+
+/* subdivide the triangles of the object once
+   The order of this algorithm is probably something like O(n^42) :)
+   but I can't think of something smarter at the moment 
+*/
+static Object *subdivide( Object *obj )
+{
+  /* create for worst case (which I dont't know) */
+  int start, t, i, v;
+  int index_list[1000];
+  int index_cnt, index_found;
+  Object *tmp = (Object *)malloc( sizeof(Object) );
+  Object *ret = (Object *)malloc( sizeof(Object) );
+  Object *c_ret;
+  
+  tmp->vertex = 
+      (Vector *)malloc( 100*obj->num_vertex*sizeof( Vector ) );
+  tmp->triangle = 
+      (Triangle *)malloc( 4*obj->num_triangle*sizeof( Triangle ) );
+  tmp->num_vertex = 0;
+  tmp->num_triangle = 0;
+  ret->vertex = 
+      (Vector *)malloc( 100*obj->num_vertex*sizeof( Vector ) );
+  ret->triangle = 
+      (Triangle *)malloc( 4*obj->num_triangle*sizeof( Triangle ) );
+  ret->num_vertex = 0;
+  ret->num_triangle = 0;
+#ifdef PRINT_STAT
+  fprintf( stderr, "in v=%d t=%d\n", 
+           obj->num_vertex, obj->num_triangle );
+#endif
+  /* for each triangle create 3 new vertexes and the 4 
+     corresponding triangles 
+  */
+  for (t=0; t<obj->num_triangle; ++t) {
+    /* copy the three original vertexes */
+    for (i=0; i<3; ++i) {
+      tmp->vertex[tmp->num_vertex++] =
+        obj->vertex[obj->triangle[t].i[i]];
+    }
+    
+    /* create 3 new */
+    tmp->vertex[tmp->num_vertex] = 
+        obj->vertex[obj->triangle[t].i[0]];
+    vector_add( &tmp->vertex[tmp->num_vertex],
+                 &obj->vertex[obj->triangle[t].i[1]] );
+    vector_mul( &tmp->vertex[tmp->num_vertex++], 0.5 ); 
+    
+    tmp->vertex[tmp->num_vertex] = 
+        obj->vertex[obj->triangle[t].i[1]];
+    vector_add( &tmp->vertex[tmp->num_vertex],
+                 &obj->vertex[obj->triangle[t].i[2]] );
+    vector_mul( &tmp->vertex[tmp->num_vertex++], 0.5 ); 
+    
+    tmp->vertex[tmp->num_vertex] = 
+        obj->vertex[obj->triangle[t].i[2]];
+    vector_add( &tmp->vertex[tmp->num_vertex],
+                 &obj->vertex[obj->triangle[t].i[0]] );
+    vector_mul( &tmp->vertex[tmp->num_vertex++], 0.5 ); 
+
+    /* create triangles */
+    start = tmp->num_vertex-6;
+    
+    tmp->triangle[tmp->num_triangle].i[0] = start;
+    tmp->triangle[tmp->num_triangle].i[1] = start+3;
+    tmp->triangle[tmp->num_triangle++].i[2] = start+5;
+      
+    tmp->triangle[tmp->num_triangle].i[0] = start+3;
+    tmp->triangle[tmp->num_triangle].i[1] = start+1;
+    tmp->triangle[tmp->num_triangle++].i[2] = start+4;
+      
+    tmp->triangle[tmp->num_triangle].i[0] = start+5;
+    tmp->triangle[tmp->num_triangle].i[1] = start+4;
+    tmp->triangle[tmp->num_triangle++].i[2] = start+2;
+      
+    tmp->triangle[tmp->num_triangle].i[0] = start+3;
+    tmp->triangle[tmp->num_triangle].i[1] = start+4;
+    tmp->triangle[tmp->num_triangle++].i[2] = start+5;
+  }
+  
+  /* compress object eliminating double vertexes 
+     (welcome to the not so smart section)
+  */
+  /* copy original triangle list */
+  for (t=0; t<tmp->num_triangle; ++t) {
+    ret->triangle[t] = tmp->triangle[t];
+  }
+  ret->num_triangle = tmp->num_triangle;
+  
+  /* copy unique vertexes and correct triangle list */
+  for (v=0; v<tmp->num_vertex; ++v) {
+    /* create list of vertexes that are the same */
+    index_cnt = 0;
+    for (i=0; i<tmp->num_vertex; ++i) {
+      /* check if i and v are the same
+         first in the list is the smallest index
+      */
+      if (vector_compare( &tmp->vertex[v], &tmp->vertex[i] )) {
+        index_list[index_cnt++] = i;
+      }
+    }
+    
+    /* check if vertex unknown so far */
+    index_found = 0;
+    for (i=0; i<ret->num_vertex; ++i) {
+      if (vector_compare( &ret->vertex[i],
+          &tmp->vertex[index_list[0]] )) {
+        index_found = 1;
+        break;
+      }
+    }
+    
+    if (!index_found) {
+      ret->vertex[ret->num_vertex] = tmp->vertex[index_list[0]];
+      
+      /* correct triangles 
+         (we add an offset to the index, so we can tell them apart)
+      */
+      for (t=0; t<ret->num_triangle; ++t) {
+        for (i=0; i<index_cnt; ++i) {
+          if (ret->triangle[t].i[0] == index_list[i]) {
+            ret->triangle[t].i[0] = ret->num_vertex+INDEX_OFFSET;
+          }
+          if (ret->triangle[t].i[1] == index_list[i]) {
+            ret->triangle[t].i[1] = ret->num_vertex+INDEX_OFFSET;
+          }
+          if (ret->triangle[t].i[2] == index_list[i]) {
+            ret->triangle[t].i[2] = ret->num_vertex+INDEX_OFFSET;
+          }
+        }
+      }
+      ret->num_vertex++;
+    }
+  }
+  
+  free_Object( tmp );
+  
+  /* correct index offset */
+  for (t=0; t<ret->num_triangle; ++t) {
+    ret->triangle[t].i[0] -= INDEX_OFFSET;
+    ret->triangle[t].i[1] -= INDEX_OFFSET;
+    ret->triangle[t].i[2] -= INDEX_OFFSET;
+  }
+  
+  /* normalize vertexes */
+  for (v=0; v<ret->num_vertex; ++v) {
+    vector_normalize( &ret->vertex[v] );
+  }
+#ifdef PRINT_STAT
+  fprintf( stderr, "out v=%d t=%d\n", 
+           ret->num_vertex, ret->num_triangle );
+#endif
+  /* shrink the arrays by cloning */
+  c_ret = clone_Object( ret );
+  free_Object( ret );
+  
+  return c_ret;
+}
+
+static int render( State *st )
+{
+#ifdef PRINT_STAT
+  struct timeval tv1, tv2;
+  int usec;
+#endif
+  GLfloat LightAmbient[]= { 0.1f, 0.1f, 0.1f, 1.0f };
+  GLfloat LightPosition[]= { -20.0f, -10.0f, -100.0f, 0.0f };
+  int b;
+  int num_paint = 0;
+  
+  if (0 == st->food) return 0;
+#ifdef PRINT_STAT
+  gettimeofday( &tv1, NULL );
+#endif
+  /* life goes on... */
+  tick( st );
+#ifdef PRINT_STAT
+  gettimeofday( &tv2, NULL );
+  usec = (tv2.tv_sec-tv1.tv_sec)*1000000+(tv2.tv_usec-tv1.tv_usec);
+  fprintf( stderr, "tick %d\n", usec );
+  gettimeofday( &tv1, NULL );
+#endif
+  glClearColor( 0, 0, 0, 0 );
+  
+  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+  glDepthFunc(GL_LESS);
+  glEnable(GL_DEPTH_TEST);
+  glLightfv( GL_LIGHT0, GL_AMBIENT, LightAmbient );
+  glLightfv( GL_LIGHT0, GL_DIFFUSE, st->color );
+  glLightfv( GL_LIGHT0, GL_POSITION, LightPosition );
+  
+  /* prepare lighting vs. wireframe */
+  if (!st->wire) {
+    glEnable( GL_LIGHT0 );
+    glEnable( GL_LIGHTING );
+    glEnable( GL_NORMALIZE );
+    glPolygonMode( GL_FRONT, GL_FILL );
+  } else {
+    glPolygonMode( GL_FRONT, GL_LINE );
+  }
+  
+  /* draw the dead cells if choosen */
+  if (st->keep_old_cells) {
+    for (b=0; b<st->num_cells; ++b) {
+      if (st->cell[b].energy <= 0) {
+        num_paint++;
+        glPushMatrix();
+        glTranslatef( st->cell[b].x, st->cell[b].y, 0.0 );
+        glRotatef( st->cell[b].rotation, 0.0, 0.0, 1.0 );
+        glScalef( st->cell[b].radius, st->cell[b].radius, st->cell[b].radius );
+        draw_cell( st, 9 );
+        glPopMatrix();
+      }
+    }
+  }
+  
+  /* draw the living cells */
+  for (b=0; b<st->num_cells; ++b) {
+     if (st->cell[b].energy >0) { 
+      double fac = (double)st->cell[b].energy / 50.0; 
+      int shape;
+      if (fac < 0.0) fac = 0.0;
+      if (fac > 1.0) fac = 1.0;
+      
+      shape = (int)(9.0*fac);
+      num_paint++;
+      /*glColor3f( fac, fac, fac );*/
+      
+      glPushMatrix();
+      glTranslatef( st->cell[b].x, st->cell[b].y, 0.0 );
+      glRotatef( st->cell[b].rotation, 0.0, 0.0, 1.0 );
+      glScalef( st->cell[b].radius, st->cell[b].radius, st->cell[b].radius );
+      draw_cell( st, 9-shape );
+      glPopMatrix();
+    }
+  }
+  
+  /* draw cell nuclei */
+  if (!st->wire)
+  {
+    glDisable( GL_LIGHT0 );
+    glDisable( GL_LIGHTING );
+    
+    glEnable( GL_BLEND );
+    glDisable( GL_DEPTH_TEST );
+    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );    
+    glEnable( GL_TEXTURE_2D );
+    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+    glBindTexture( GL_TEXTURE_2D, st->texture_name );
+    
+    for (b=0; b<st->num_cells; ++b) {
+      if (st->cell[b].energy>0 || st->keep_old_cells) {
+        glPushMatrix();
+        glTranslatef( st->cell[b].x, st->cell[b].y, 0.0 );
+        glScalef( st->cell[b].radius, st->cell[b].radius, st->cell[b].radius );
+        draw_nucleus( st );
+        glPopMatrix();
+      }
+    }
+    
+    glDisable( GL_TEXTURE_2D );
+    glDisable( GL_BLEND );
+  }
+  
+#ifdef PRINT_STAT
+  gettimeofday( &tv2, NULL );
+  usec = (tv2.tv_sec-tv1.tv_sec)*1000000+(tv2.tv_usec-tv1.tv_usec);
+  fprintf( stderr, "OpenGL %d\n", usec );
+#endif
+  return num_paint * st->cell_polys;
+}
+
+/* this creates the initial subdivided half-dodecaedron */
+static Object *create_sphere( State *st, int divisions )
+{
+  int num_vertex = 9;
+  int num_triangle = 10;  
+  int i, v, t;
+  double a, aStep = (double)M_PI / 3.0;
+  double e;
+  int vi[30] = { 0, 7, 1, 1, 7, 2, 2, 8, 3, 3, 8, 4, 4, 6, 5,
+                 5, 6, 0, 0, 6, 7, 2, 7, 8, 4, 8, 6, 6, 8, 7 };
+  Object *obj = (Object *)malloc( sizeof( Object ) );
+  
+  obj->vertex = (Vector *)malloc( num_vertex*sizeof( Vector ) );
+  obj->triangle = 
+      (Triangle *)malloc( num_triangle*sizeof( Triangle ) );
+  obj->num_vertex = num_vertex;
+  obj->num_triangle = num_triangle;
+                
+  /* create vertexes for dodecaedron */
+  a = 0.0;
+  for (v=0; v<6; ++v) {
+    obj->vertex[v].x = sin( a );
+    obj->vertex[v].y = -cos( a );
+    obj->vertex[v].z = 0.0;
+  
+    a += aStep;
+  }
+
+  a = -60.0/180.0*(double)M_PI;
+  e = 58.2825/180.0 * (double)M_PI;
+  for (;v<9; ++v) {
+    obj->vertex[v].x = sin( a )*cos( e );
+    obj->vertex[v].y = -cos( a )*cos( e );
+    obj->vertex[v].z = -sin( e );
+  
+    a += 2.0*aStep;
+  }
+
+  /* create triangles */
+  for (t=0; t<obj->num_triangle; ++t) {
+    obj->triangle[t].i[0] = vi[3*t];
+    obj->triangle[t].i[1] = vi[3*t+1];
+    obj->triangle[t].i[2] = vi[3*t+2];
+  }
+
+  /* subdivide as specified */
+  for (i=0; i<divisions; ++i) {
+    Object *newObj = subdivide( obj );
+    free_Object( obj );
+    obj = newObj;
+  }
+  
+  st->cell_polys = obj->num_triangle;
+  
+  return obj;
+}
+
+static int create_list( State *st, double fac )
+{
+  int v;
+  Object *obj = clone_Object( st->sphere );
+  ObjectSmooth *smooth;
+#ifdef USE_VERTEX_ARRAY
+  VertexArray *vertex_array;
+#endif
+  int list = glGenLists(1);  
+  
+  /* apply wrinckle factor */
+  for (v=0; v<obj->num_vertex; ++v) {
+    vector_mul( &obj->vertex[v], 1.0+fac*st->disturbance[v] );
+  }
+  
+  /* compute normals */
+  smooth = create_ObjectSmooth( obj );
+  free_Object( obj );
+  
+  /* Create display list */
+  glNewList( list, GL_COMPILE );
+#ifdef USE_VERTEX_ARRAY
+  vertex_array = array_from_ObjectSmooth( smooth );
+  glEnableClientState( GL_VERTEX_ARRAY );
+  glEnableClientState( GL_NORMAL_ARRAY );
+  glVertexPointer( 3, GL_FLOAT, 0, vertex_array->vertex );
+  glNormalPointer( GL_FLOAT, 0, vertex_array->normal );
+  glDrawElements( GL_TRIANGLES, vertex_array->num_index, 
+                  GL_UNSIGNED_INT, vertex_array->index );
+  free( vertex_array );
+#else
+  glBegin( GL_TRIANGLES );
+  
+  for (t=0; t<smooth->num_triangle; ++t) {
+    for (i=0; i<3; ++i) {
+      glNormal3f( smooth->normal[smooth->triangle[t].i[i]].x, 
+                  smooth->normal[smooth->triangle[t].i[i]].y, 
+                  smooth->normal[smooth->triangle[t].i[i]].z );
+      glVertex3f( smooth->vertex[smooth->triangle[t].i[i]].x, 
+                  smooth->vertex[smooth->triangle[t].i[i]].y, 
+                  smooth->vertex[smooth->triangle[t].i[i]].z );
+    }
+  }    
+  
+  glEnd();
+#endif
+  glEndList();
+  
+  free_ObjectSmooth( smooth );
+  
+  return list;
+}
+
+static void draw_cell( State *st, int shape )
+{
+  if (-1 == st->cell_list[shape]) {
+    st->cell_list[shape] = create_list( st, (double)shape/10.0 );
+  }
+  
+  glCallList( st->cell_list[shape] );
+}
+
+static void create_nucleus_texture( State *st )
+{
+  int x, y;
+  int w2 = TEX_SIZE/2;
+  float s = w2*w2/4.0;
+  
+  st->texture = (GLubyte *) malloc( 4*TEX_SIZE*TEX_SIZE );
+  
+  for (y=0; y<TEX_SIZE; ++y) {
+    for (x=0; x<TEX_SIZE; ++x) {
+      float r2 = ((x-w2)*(x-w2)+(y-w2)*(y-w2));
+      float v = 120.0 * expf( -(r2) / s );
+      st->texture[4*(x+y*TEX_SIZE)]   = (GLubyte)0;
+      st->texture[4*(x+y*TEX_SIZE)+1] = (GLubyte)0;
+      st->texture[4*(x+y*TEX_SIZE)+2] = (GLubyte)0;
+      st->texture[4*(x+y*TEX_SIZE)+3] = (GLubyte)v;
+    }
+  }
+  
+  glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
+  glGenTextures( 1, &st->texture_name );
+  glBindTexture( GL_TEXTURE_2D, st->texture_name );
+  
+  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
+  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
+  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+  glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, TEX_SIZE, TEX_SIZE, 0,
+                GL_RGBA, GL_UNSIGNED_BYTE, st->texture );
+}
+
+static void draw_nucleus( State *st )
+{
+  if (-1 == st->nucleus_list) {
+    float z = -1.2f;
+    float r=1.0/2.0f;
+    st->nucleus_list = glGenLists( 1 );
+    glNewList( st->nucleus_list, GL_COMPILE );
+    glBegin( GL_QUADS );
+    glTexCoord2f( 0.0f, 0.0f ); glVertex3f( -r, -r, z );
+    glTexCoord2f( 0.0f, 1.0f ); glVertex3f( -r, r, z );
+    glTexCoord2f( 1.0f, 1.0f ); glVertex3f( r, r, z );
+    glTexCoord2f( 1.0f, 0.0f ); glVertex3f( r, -r, z );    
+    glEnd();
+    glEndList();
+  }
+  
+  glCallList( st->nucleus_list );
+}
+
+static void create_cells( State *st )
+{
+  int i, foodcnt;
+  int w = st->width-400;
+  int h = st->height-400;
+  
+  st->color[0] = 0.5 + random_max( 1000 ) * 0.0005;
+  st->color[1] = 0.5 + random_max( 1000 ) * 0.0005;
+  st->color[2] = 0.5 + random_max( 1000 ) * 0.0005;
+  st->color[3] = 1.0f;
+  
+  /* allocate if startup */
+  if (!st->cell) {
+    st->cell = (Cell *) malloc( st->max_cells * sizeof(Cell));
+  }
+  
+  /* fill the screen with random food for our little critters */
+  foodcnt = (st->width*st->height)/16;  
+  for (i=0; i<foodcnt; ++i) {
+    st->food[i] = random_interval( st->minfood, st->maxfood );
+  }
+    
+  /* create the requested seed-cells */
+  st->num_cells = st->num_seeds;
+
+  for (i=0; i<st->num_cells; ++i) {
+    st->cell[i].x        = 200 + random_max( w );
+    st->cell[i].y        = 200 + random_max( h );
+    st->cell[i].vx       = 0.0;
+    st->cell[i].vy       = 0.0;
+    st->cell[i].age      = random_max( 0x0f );
+    st->cell[i].min_dist = 500.0;
+    st->cell[i].energy   = random_interval( 5, 5+0x3f );
+    st->cell[i].rotation = ((double)random()/(double)RAND_MAX)*360.0;
+    st->cell[i].radius   = st->radius;
+    st->cell[i].growth   = 1.0;
+  }
+}
+
+/* all this is rather expensive :( */
+static void tick( State *st )
+{
+  int new_num_cells, num_cells=0;
+  int b, j;
+  int x, y, w4=st->width/4, h4=st->height/4, offset;
+  double min_dist;
+  int min_index;
+  int num_living = 0;
+  const double check_dist = 0.75*st->move_dist;
+  const double grow_dist = 0.75*st->radius;
+  
+  /* find number of cells capable of division 
+     and count living cells
+  */
+  for (b=0; b<st->num_cells; ++b) {
+    if (st->cell[b].energy > 0) num_living++;
+    if (can_divide( st, &st->cell[b] )) num_cells++;
+  }
+  new_num_cells = st->num_cells + num_cells;
+  
+  /* end of simulation ? */
+  if (0 == num_living || new_num_cells >= st->max_cells) {
+    if (st->pause_counter > 0) st->pause_counter--;
+    if (st->pause_counter > 0) return;
+    create_cells( st );
+    st->pause_counter = st->pause;
+  } else if (num_cells) { /* any fertile candidates ? */
+    for (b=0, j=st->num_cells; b<st->num_cells; ++b) {
+      if (can_divide( st, &st->cell[b] )) {
+        st->cell[b].vx      = random_interval( -50, 50 ) * 0.01;
+        st->cell[b].vy      = random_interval( -50, 50 ) * 0.01;
+        st->cell[b].age     = random_max( 0x0f );
+        /* half energy for both plus some bonus for forking */
+        st->cell[b].energy  = 
+            st->cell[b].energy/2 + random_max( 0x0f );
+        /* forking makes me shrink */
+        st->cell[b].growth  = 0.995;
+        
+        /* this one initially goes into the oposite direction */
+        st->cell[j].vx       = -st->cell[b].vx;
+        st->cell[j].vy       = -st->cell[b].vy;
+        /* same center */
+        st->cell[j].x        = st->cell[b].x;
+        st->cell[j].y        = st->cell[b].y;
+        st->cell[j].age      = random_max( 0x0f );
+        st->cell[j].energy   = (st->cell[b].energy);
+        st->cell[j].rotation =
+            ((double)random()/(double)RAND_MAX)*360.0;
+        st->cell[j].growth   = st->cell[b].growth;
+        st->cell[j].radius   = st->cell[b].radius;
+        ++j;
+      } else {
+        st->cell[b].vx = 0.0;
+        st->cell[b].vy = 0.0;
+      }
+    }
+    
+    st->num_cells = new_num_cells;
+  }
+
+  /* for each find a direction to escape */
+  if (st->num_cells > 1) {
+    for (b=0; b<st->num_cells; ++b) {
+      if (st->cell[b].energy > 0) {
+        double vx;
+        double vy;
+        double len;
+        
+        /* grow or shrink */
+        st->cell[b].radius *= st->cell[b].growth;
+        /* find closest neighbour */
+        min_dist = 100000.0;
+        min_index = 0;
+        for (j=0; j<st->num_cells; ++j) {
+          if (j!=b) {
+            const double dx = st->cell[b].x - st->cell[j].x;
+            const double dy = st->cell[b].y - st->cell[j].y;
+            
+            if (fabs(dx) < check_dist || fabs(dy) < check_dist) {
+              const double dist = sqrt( dx*dx+dy*dy );
+              if (dist<min_dist) {
+                min_dist = dist;
+                min_index = j;
+              }
+            }
+          }
+        }
+        /* escape step is away from closest normalized with distance */
+        vx = st->cell[b].x - st->cell[min_index].x;
+        vy = st->cell[b].y - st->cell[min_index].y;
+        len = sqrt( vx*vx + vy*vy );
+        if (len > 0.0001) {
+          st->cell[b].vx = vx/len;
+          st->cell[b].vy = vy/len;
+        }
+        st->cell[b].min_dist = len;
+        /* if not adult (radius too small) */
+        if (st->cell[b].radius < st->radius) {
+          /* if too small 60% stop shrinking */
+          if (st->cell[b].radius < st->radius * 0.6) {
+            st->cell[b].growth = 1.0;
+          }
+          /* at safe distance we start growing again */
+          if (len > grow_dist) {
+            if (st->cell[b].energy > 30) {
+              st->cell[b].growth = 1.005;
+            } 
+          }
+        } else {  /* else keep size */
+          st->cell[b].growth = 1.0;
+        }
+      }
+    }
+  } else {
+    st->cell[0].min_dist = 2*st->move_dist;
+  }
+    
+  /* now move em, snack and burn energy */
+  for (b=0; b<st->num_cells; ++b) {
+    /* if still alive */
+    if (st->cell[b].energy > 0) {
+      /* agility depends on amount of energy */
+      double fac = (double)st->cell[b].energy / 50.0;
+      if (fac < 0.0) fac = 0.0;
+      if (fac > 1.0) fac = 1.0;
+      
+      st->cell[b].x += fac*(2.0 - 
+          (4.0*(double)random() / (double)RAND_MAX) + 
+          st->cell[b].vx);
+      st->cell[b].y += fac*(2.0 - 
+          (4.0*(double)random() / (double)RAND_MAX) + 
+          st->cell[b].vy);
+      
+      /* get older and burn energy */
+      if (st->cell[b].energy > 0) {
+        st->cell[b].age++;
+        st->cell[b].energy--;
+      }
+      
+      /* have a snack */
+      x = ((int)st->cell[b].x)/4;
+      if (x<0) x=0; if (x>=w4) x = w4-1;
+      y = ((int)st->cell[b].y)/4;
+      if (y<0) y=0; if (y>=h4) y = h4-1;
+    
+      offset = x+y*w4;
+    
+      /* don't eat if already satisfied */
+      if (st->cell[b].energy < 100 &&
+          st->food[offset] > 0) {
+        st->food[offset]--;
+        st->cell[b].energy++;
+        /* if you are hungry, eat more */
+        if (st->cell[b].energy < 50 && 
+            st->food[offset] > 0) {
+          st->food[offset]--;
+          st->cell[b].energy++;
+        }
+      }
+    }
+  }
+}
+
+ENTRYPOINT void 
+reshape_glcells( ModeInfo *mi, int width, int height )
+{
+  State *st  = &sstate[MI_SCREEN(mi)];
+  st->height = height;
+  st->width  = width;
+  
+  glViewport (0, 0, (GLint) width, (GLint) height);
+
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  glOrtho( 0, width, height, 0, 200, 0 );
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+  
+  if (st->food) free( st->food );
+  st->food = (int *)malloc( ((width*height)/16)*sizeof(int) );
+  
+  create_cells( st );
+}
+
+ENTRYPOINT void 
+init_glcells( ModeInfo *mi )
+{
+  int i, divisions;
+  State *st=0;
+  
+  if (!sstate) {
+    sstate = (State *)
+        calloc( MI_NUM_SCREENS(mi), sizeof(State) );
+    if (!sstate) {
+      fprintf( stderr, "%s: out of memory\n", progname );
+      exit(1);
+    }
+  }
+  st = &sstate[MI_SCREEN(mi)];
+  
+  st->glx_context = init_GL(mi);
+  st->cell = 0;
+  st->num_cells = 0;
+  st->wire = MI_IS_WIREFRAME(mi);
+  
+  /* get settings */
+  st->max_cells = s_maxcells;;
+  if (st->max_cells < 50) st->max_cells = 50;
+  if (st->max_cells > 10000) st->max_cells = 10000;
+  
+  st->pause = s_pause;
+  if (st->pause < 0) st->pause = 0;
+  if (st->pause > 400) st->pause = 400;
+  st->pause_counter = st->pause;
+  
+  st->radius = s_radius;
+  if (st->radius < 5) st->radius = 5;
+  if (st->radius > 200) st->radius = 200;
+  
+  divisions = s_quality;
+  if (divisions < 0) divisions = 0;
+  if (divisions > 5) divisions = 5;
+  
+  st->num_seeds = s_seeds;
+  if (st->num_seeds < 1) st->num_seeds = 1;
+  if (st->num_seeds > 16) st->num_seeds = 16;
+  
+  st->minfood = s_minfood;
+  if (st->minfood < 0) st->minfood = 0;
+  if (st->minfood > 1000) st->minfood = 1000;
+  
+  st->maxfood = s_maxfood;
+  if (st->maxfood < 0) st->maxfood = 0;
+  if (st->maxfood > 1000) st->maxfood = 1000;
+  
+  if (st->maxfood < st->minfood) st->maxfood = st->minfood+1;
+  
+  st->keep_old_cells = s_keepold;
+  
+  st->divide_age = s_divideage;
+  if (st->divide_age < 1) st->divide_age = 1;
+  if (st->divide_age > 1000) st->divide_age = 1000;
+     
+  st->move_dist = s_min_dist;
+  if (st->move_dist < 1.0) st->move_dist = 1.0;
+  if (st->move_dist > 3.0) st->move_dist = 3.0;
+  st->move_dist *= st->radius;
+  
+  for (i=0; i<NUM_CELL_SHAPES; ++i) st->cell_list[i] = -1;
+  st->nucleus_list = -1;
+  st->food = 0;
+  
+  st->sphere = create_sphere( st, divisions );
+  st->disturbance = 
+      (double *) malloc( st->sphere->num_vertex*sizeof(double) );
+  for (i=0; i<st->sphere->num_vertex; ++i) {
+    st->disturbance[i] = 
+        0.05-((double)random()/(double)RAND_MAX*0.1);
+  }
+  
+  create_nucleus_texture( st );
+
+  reshape_glcells (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
+}
+
+ENTRYPOINT void
+draw_glcells( ModeInfo *mi )
+{
+  State *st = &sstate[MI_SCREEN(mi)];
+  Display *dpy = MI_DISPLAY(mi);
+  Window window = MI_WINDOW(mi);
+  
+  if (!st->glx_context) return;
+
+  glXMakeCurrent( MI_DISPLAY(mi), MI_WINDOW(mi), 
+                  *(st->glx_context) );
+  
+  mi->polygon_count = render( st );
+  
+  if (mi->fps_p) do_fps (mi);
+  
+  glFinish();
+  glXSwapBuffers( dpy, window );
+}
+
+ENTRYPOINT void 
+release_glcells( ModeInfo *mi )
+{
+  int i;
+  State *st  = &sstate[MI_SCREEN(mi)];
+  
+  /* nuke everything before exit */
+  if (st->sphere) free_Object( st->sphere );
+  if (st->food)   free( st->food );
+  for (i=0; i<NUM_CELL_SHAPES; ++i) {
+    if (st->cell_list[i] != -1) {
+      glDeleteLists( st->cell_list[i], 1 );
+    }
+  }
+  if (st->cell) free( st->cell );
+  free( st->disturbance );
+  glDeleteTextures( 1, &st->texture_name );
+  free( st->texture );
+}
+
+XSCREENSAVER_MODULE( "GLCells", glcells )
diff --git a/hacks/glx/glcells.man b/hacks/glx/glcells.man
new file mode 100644 (file)
index 0000000..2d24017
--- /dev/null
@@ -0,0 +1,99 @@
+.TH XScreenSaver 1 "June 2007"
+.SH NAME
+glcells \- growing cells graphics hack
+.SH SYNOPSIS
+.B glcells
+[\-display \fIhost:display.screen\fP] [\-window] [\-root] [\-install]
+[\-visual \fIvisual\fP]
+[\-delay \fInum\fP] [\-pause \fInum\fP] [\-maxcells \fInum\fP]
+[\-radius \fInum\fP] [\-seeds \fInum\fP] [\-quality \fInum\fP]
+[\-minfood \fInum\fP] [\-maxfood \fInum\fP] [\-divideage \fInum\fP]
+[\-mindist \fInum\fP]
+[\-keepold]
+[\-wireframe]
+[\-fps]
+.SH DESCRIPTION
+The \fIglcells\fP program draws cells that divide exponentially, eat and eventually die.
+.SH OPTIONS
+.I glcells
+accepts the following options:
+.TP 8
+.B \-window
+Draw on a newly-created window.  This is the default.
+.TP 8
+.B \-root
+Draw on the root window.
+.TP 8
+.B \-install
+Install a private colormap for the window.
+.TP 8
+.B \-visual \fIvisual\fP\fP
+Specify which visual to use.  Legal values are the name of a visual class,
+or the id number (decimal or hex) of a specific visual.
+.TP 8
+.B \-pause \fInum\fP\fP
+Specifies the pause at the end of the animation (all cells dead or maximum amount of cells reached). Unit is in frames, default 20.
+.TP 8
+.B \-maxcells \fInum\fP\fP
+Specifies the maximum number of cells on screen (dead cells also count, even if invisible). Default is 800.
+.TP 8
+.B \-radius \fInum\fP\fP
+Specifies the radius of the cells. Default is 40.
+.TP 8
+.B \-seeds \fInum\fP\fP
+Specifies the number of cells when animation starts. Default is 1.
+.TP 8
+.B \-quality \fInum\fP\fP
+Specifies subdivision quality of the spheres used to draw the cells [0...5]. Default is 3.
+.TP 8
+.B \-minfood \fInum\fP\fP
+Food is ditributed randomly on the screen (Yes, the cells need to eat). This parameter specifies the
+minimum amount of food per pixel. Default is 5.
+.TP 8
+.B \-maxfood \fInum\fP\fP
+Food is ditributed randomly on the screen (Yes, the cells need to eat). This parameter specifies the
+maximum amount of food per pixel. Default is 20.
+.TP 8
+.B \-divideage \fInum\fP\fP
+Specifies the minimum age in frames a cell needs to have before beeing able to divide. Default is 20
+.TP 8
+.B \-mindist \fInum\fP\fP
+Specifies the minimum distance between cells. Default 1.4
+.TP 8
+.B \-delay \fInum\fP
+How long to pause between frames.  Default is 20000, or 0.02 second.
+.TP 8
+.B \-fps
+Display a running tally of how many frames per second are being rendered.
+In conjunction with \fB\-delay 0\fP, this can be a useful benchmark of 
+your GL performance.
+.TP 8
+.B \-wireframe
+Draw wireframe only.
+.TP 8
+.B \-keepold
+Dead cells stay on screen.
+.SH ENVIRONMENT
+.PP
+.TP 8
+.B DISPLAY
+to get the default host and display number.
+.TP 8
+.B XENVIRONMENT
+to get the name of a resource file that overrides the global resources
+stored in the RESOURCE_MANAGER property.
+.SH SEE ALSO
+.BR X (1),
+.BR xscreensaver (1)
+.BR xscreensaver\-demo (1),
+.SH COPYRIGHT
+Copyright \(co 2007 by Matthias Toussaint.  Permission to use, copy, modify,
+distribute, and sell this software and its documentation for any purpose is
+hereby granted without fee, provided that the above copyright notice appear
+in all copies and that both that copyright notice and this permission notice
+appear in supporting documentation.  No representations are made about the
+suitability of this software for any purpose.  It is provided "as is" without
+express or implied warranty.
+.SH AUTHOR
+Matthias Toussaint <glcells@mtoussaint.de>, 17-Jun-2007.
index 7414838fa84e8c9460579d740a88b9a057b0147d..bd8f981a3a9e071763ebd97ef9ba5b9d8295ded0 100644 (file)
@@ -116,8 +116,13 @@ createDrawLists(BBox *bbox, GLuint *bboxList, GLuint *goalList, GLuint *fishList
 
        *fishList = glGenLists(1);
        glNewList(*fishList, GL_COMPILE);
+#if 0
        gluSphere(Quadratic, 2.0, 10, 5);
        gluCylinder(Quadratic, 2.0, 0.0, 10.0, 10, 5);
+#else
+        gluSphere(Quadratic, 2.0, 3, 2);
+        gluCylinder(Quadratic, 2.0, 0.0, 10.0, 3, 2);
+#endif
        glEndList();
 }
 
diff --git a/hacks/glx/voronoi.c b/hacks/glx/voronoi.c
new file mode 100644 (file)
index 0000000..c59e6ba
--- /dev/null
@@ -0,0 +1,523 @@
+/* voronoi, Copyright (c) 2007 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  No representations are made about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or 
+ * implied warranty.
+ */
+
+#define DEFAULTS        "*delay:        20000              \n" \
+                        "*showFPS:      False              \n" \
+
+
+# define refresh_voronoi 0
+# define release_voronoi 0
+#undef countof
+#define countof(x) (sizeof((x))/sizeof((*x)))
+
+#define BELLRAND(n) ((frand((n)) + frand((n)) + frand((n))) / 3)
+
+
+#include "xlockmore.h"
+#include <ctype.h>
+
+#ifdef USE_GL /* whole file */
+
+#define DEF_POINTS      "10"
+#define DEF_POINT_SIZE  "9"
+#define DEF_POINT_SPEED "1"
+#define DEF_POINT_DELAY "0.1"
+#define DEF_ZOOM_SPEED  "1"
+#define DEF_ZOOM_DELAY  "10"
+
+typedef struct node {
+  GLfloat x, y;
+  GLfloat dx, dy;
+  GLfloat ddx, ddy;
+  struct node *next;
+  GLfloat color[4], color2[4];
+  int rot;
+} node;
+
+typedef struct {
+  GLXContext *glx_context;
+  node *nodes;
+  int nnodes;
+  node *dragging;
+  int ncolors;
+  XColor *colors;
+
+  enum { MODE_WAITING, MODE_ADDING, MODE_ZOOMING } mode;
+  int adding;
+  double last_time;
+
+  GLfloat zooming;         /* 1.0 starting zoom, 0.0 no longer zooming. */
+  GLfloat zoom_toward[2];
+
+} voronoi_configuration;
+
+static voronoi_configuration *vps = NULL;
+
+/* command line arguments */
+static int npoints;
+static GLfloat point_size, point_speed, point_delay;
+static GLfloat zoom_speed, zoom_delay;
+
+static XrmOptionDescRec opts[] = {
+  { "-points",       ".points",      XrmoptionSepArg, 0 },
+  { "-point-size",   ".pointSize",   XrmoptionSepArg, 0 },
+  { "-point-speed",  ".pointSpeed",  XrmoptionSepArg, 0 },
+  { "-point-delay",  ".pointDelay",  XrmoptionSepArg, 0 },
+  { "-zoom-speed",   ".zoomSpeed",   XrmoptionSepArg, 0 },
+  { "-zoom-delay",   ".zoomDelay",   XrmoptionSepArg, 0 },
+};
+
+static argtype vars[] = {
+  {&npoints,      "points",      "Points",      DEF_POINTS,       t_Int},
+  {&point_size,   "pointSize",   "PointSize",   DEF_POINT_SIZE,   t_Float},
+  {&point_speed,  "pointSpeed",  "PointSpeed",  DEF_POINT_SPEED,  t_Float},
+  {&point_delay,  "pointDelay",  "PointDelay",  DEF_POINT_DELAY,  t_Float},
+  {&zoom_speed,   "zoomSpeed",   "ZoomSpeed",   DEF_ZOOM_SPEED,   t_Float},
+  {&zoom_delay,   "zoomDelay",   "ZoomDelay",   DEF_ZOOM_DELAY,   t_Float},
+};
+
+ENTRYPOINT ModeSpecOpt voronoi_opts =
+  {countof(opts), opts, countof(vars), vars, NULL};
+
+
+/* Returns the current time in seconds as a double.
+ */
+static double
+double_time (void)
+{
+  struct timeval now;
+# ifdef GETTIMEOFDAY_TWO_ARGS
+  struct timezone tzp;
+  gettimeofday(&now, &tzp);
+# else
+  gettimeofday(&now);
+# endif
+
+  return (now.tv_sec + ((double) now.tv_usec * 0.000001));
+}
+
+
+static node *
+add_node (voronoi_configuration *vp, GLfloat x, GLfloat y)
+{
+  node *nn = (node *) calloc (1, sizeof (*nn));
+  int i;
+  nn->x = x;
+  nn->y = y;
+
+  i = random() % vp->ncolors;
+  nn->color[0] = vp->colors[i].red   / 65536.0;
+  nn->color[1] = vp->colors[i].green / 65536.0;
+  nn->color[2] = vp->colors[i].blue  / 65536.0;
+  nn->color[3] = 1.0;
+
+  nn->color2[0] = nn->color[0] * 0.7;
+  nn->color2[1] = nn->color[1] * 0.7;
+  nn->color2[2] = nn->color[2] * 0.7;
+  nn->color2[3] = 1.0;
+
+  nn->ddx = frand (0.000001 * point_speed) * (random() & 1 ? 1 : -1);
+  nn->ddy = frand (0.000001 * point_speed) * (random() & 1 ? 1 : -1);
+
+  nn->rot = (random() % 360) * (random() & 1 ? 1 : -1);
+
+  nn->next = vp->nodes;
+  vp->nodes = nn;
+  vp->nnodes++;
+  return nn;
+}
+
+
+static int
+cone (void)
+{
+  int i;
+  int faces = 64;
+  GLfloat step = M_PI * 2 / faces;
+  GLfloat s2 = step/2;
+  GLfloat th;
+  GLfloat x, y, x0, y0;
+
+  glBegin(GL_TRIANGLES);
+
+  th = 0;
+  x = 1;
+  y = 0;
+  x0 = cos (s2);
+  y0 = sin (s2);
+
+  for (i = 0; i < faces; i++)
+    {
+      glVertex3f(0,  0, 1);
+      glVertex3f(x, y, 0);
+
+      th += step;
+      x0 = cos (th + s2);
+      y0 = sin (th + s2);
+      x  = cos (th);
+      y  = sin (th);
+
+      glVertex3f(x, y, 0);
+    }
+  glEnd();
+  return faces;
+}
+
+
+static void
+move_points (voronoi_configuration *vp)
+{
+  node *nn;
+  for (nn = vp->nodes; nn; nn = nn->next)
+    {
+      if (nn == vp->dragging) continue;
+      nn->x  += nn->dx;
+      nn->y  += nn->dy;
+
+      if (vp->mode == MODE_WAITING)
+        {
+          nn->dx += nn->ddx;
+          nn->dy += nn->ddy;
+        }
+    }
+}
+
+
+static void
+prune_points (voronoi_configuration *vp)
+{
+  node *nn;
+  node *prev = 0;
+  int lim = 5;
+
+  for (nn = vp->nodes; nn; prev = nn, nn = (nn ? nn->next : 0))
+    if (nn->x < -lim || nn->x > lim ||
+        nn->y < -lim || nn->y > lim)
+      {
+        if (prev)
+          prev->next = nn->next;
+        else
+          vp->nodes = nn->next;
+        free (nn);
+        vp->nnodes--;
+        nn = prev;
+     }
+}
+
+
+static void
+zoom_points (voronoi_configuration *vp)
+{
+  node *nn;
+
+  GLfloat tick = sin (vp->zooming * M_PI);
+  GLfloat scale = 1 + (tick * 0.02 * zoom_speed);
+
+  vp->zooming -= (0.01 * zoom_speed);
+  if (vp->zooming < 0) vp->zooming = 0;
+
+  if (vp->zooming <= 0) return;
+
+  if (scale < 1) scale = 1;
+
+  for (nn = vp->nodes; nn; nn = nn->next)
+    {
+      GLfloat x = nn->x - vp->zoom_toward[0];
+      GLfloat y = nn->y - vp->zoom_toward[1];
+      x *= scale;
+      y *= scale;
+      nn->x = x + vp->zoom_toward[0];
+      nn->y = y + vp->zoom_toward[1];
+    }
+}
+
+
+
+static void
+draw_cells (ModeInfo *mi)
+{
+  voronoi_configuration *vp = &vps[MI_SCREEN(mi)];
+  node *nn;
+  int lim = 5;
+
+  for (nn = vp->nodes; nn; nn = nn->next)
+    {
+      if (nn->x < -lim || nn->x > lim ||
+          nn->y < -lim || nn->y > lim)
+        continue;
+
+      glPushMatrix();
+      glTranslatef (nn->x, nn->y, 0);
+      glScalef (lim*2, lim*2, 1);
+      glColor4fv (nn->color);
+      mi->polygon_count += cone ();
+      glPopMatrix();
+    }
+
+  glClear (GL_DEPTH_BUFFER_BIT);
+
+  if (point_size <= 0)
+    ;
+  else if (point_size < 3)
+    {
+      glPointSize (point_size);
+      for (nn = vp->nodes; nn; nn = nn->next)
+        {
+          glBegin (GL_POINTS);
+          glColor4fv (nn->color2);
+          glVertex2f (nn->x, nn->y);
+          glEnd();
+        }
+    }
+  else
+    {
+      for (nn = vp->nodes; nn; nn = nn->next)
+        {
+          int w = MI_WIDTH (mi);
+          int h = MI_HEIGHT (mi);
+          int s = point_size;
+          int i;
+
+          glColor4fv (nn->color2);
+          glPushMatrix();
+          glTranslatef (nn->x, nn->y, 0);
+          glScalef (1.0 / w * s, 1.0 / h * s, 1);
+
+          glLineWidth (point_size / 10);
+          nn->rot += (nn->rot < 0 ? -1 : 1);
+          glRotatef (nn->rot, 0, 0, 1);
+
+          glRotatef (180, 0, 0, 1);
+          for (i = 0; i < 5; i++)
+            {
+              glBegin (GL_TRIANGLES);
+              glVertex2f (0, 1);
+              glVertex2f (-0.2, 0);
+              glVertex2f ( 0.2, 0);
+              glEnd ();
+              glRotatef (360.0/5, 0, 0, 1);
+            }
+          glPopMatrix();
+        }
+    }
+}
+
+
+/* Window management, etc
+ */
+ENTRYPOINT void
+reshape_voronoi (ModeInfo *mi, int width, int height)
+{
+/*  voronoi_configuration *vp = &vps[MI_SCREEN(mi)];*/
+
+  glViewport (0, 0, (GLint) width, (GLint) height);
+
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  glOrtho (0, 1, 1, 0, -1, 1);
+
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+
+  glClear(GL_COLOR_BUFFER_BIT);
+}
+
+
+static node *
+find_node (ModeInfo *mi, GLfloat x, GLfloat y)
+{
+  voronoi_configuration *vp = &vps[MI_SCREEN(mi)];
+  int ps = (point_size < 5 ? 5 : point_size);
+  GLfloat hysteresis = (1.0 / MI_WIDTH (mi)) * ps;
+  node *nn;
+  for (nn = vp->nodes; nn; nn = nn->next)
+    if (nn->x > x - hysteresis && nn->x < x + hysteresis &&
+        nn->y > y - hysteresis && nn->y < y + hysteresis)
+      return nn;
+  return 0;
+}
+
+
+ENTRYPOINT Bool
+voronoi_handle_event (ModeInfo *mi, XEvent *event)
+{
+  voronoi_configuration *vp = &vps[MI_SCREEN(mi)];
+
+  if (event->xany.type == ButtonPress)
+    {
+      GLfloat x = (GLfloat) event->xbutton.x / MI_WIDTH (mi);
+      GLfloat y = (GLfloat) event->xbutton.y / MI_HEIGHT (mi);
+      node *nn = find_node (mi, x, y);
+      if (!nn)
+        nn = add_node (vp, x, y);
+      vp->dragging = nn;
+
+      return True;
+    }
+  else if (event->xany.type == ButtonRelease && vp->dragging)
+    {
+      vp->dragging = 0;
+      return True;
+    }
+  else if (event->xany.type == MotionNotify && vp->dragging)
+    {
+      vp->dragging->x = (GLfloat) event->xmotion.x / MI_WIDTH (mi);
+      vp->dragging->y = (GLfloat) event->xmotion.y / MI_HEIGHT (mi);
+      return True;
+    }
+
+  return False;
+}
+
+static void
+state_change (ModeInfo *mi)
+{
+  voronoi_configuration *vp = &vps[MI_SCREEN(mi)];
+  double now = double_time();
+
+  if (vp->dragging)
+    {
+      vp->last_time = now;
+      vp->adding = 0;
+      vp->zooming = 0;
+      return;
+    }
+
+  switch (vp->mode)
+    {
+    case MODE_WAITING:
+      if (vp->last_time + zoom_delay <= now)
+        {
+          node *tn = vp->nodes;
+          vp->zoom_toward[0] = (tn ? tn->x : 0.5);
+          vp->zoom_toward[1] = (tn ? tn->y : 0.5);
+
+          vp->mode = MODE_ZOOMING;
+          vp->zooming = 1;
+
+          vp->last_time = now;
+        }
+      break;
+
+    case MODE_ADDING:
+      if (vp->last_time + point_delay <= now)
+        {
+          add_node (vp, 
+                    BELLRAND(0.5) + 0.25, 
+                    BELLRAND(0.5) + 0.25);
+          vp->last_time = now;
+          vp->adding--;
+          if (vp->adding <= 0)
+            {
+              vp->adding = 0;
+              vp->mode = MODE_WAITING;
+              vp->last_time = now;
+            }
+        }
+      break;
+
+    case MODE_ZOOMING:
+      {
+        zoom_points (vp);
+        if (vp->zooming <= 0)
+          {
+            vp->mode = MODE_ADDING;
+            vp->adding = npoints;
+            vp->last_time = now;
+          }
+      }
+      break;
+
+    default:
+      abort();
+    }
+}
+
+
+ENTRYPOINT void 
+init_voronoi (ModeInfo *mi)
+{
+  voronoi_configuration *vp;
+
+  if (!vps) {
+    vps = (voronoi_configuration *)
+      calloc (MI_NUM_SCREENS(mi), sizeof (voronoi_configuration));
+    if (!vps) {
+      fprintf(stderr, "%s: out of memory\n", progname);
+      exit(1);
+    }
+
+    vp = &vps[MI_SCREEN(mi)];
+  }
+
+  vp = &vps[MI_SCREEN(mi)];
+
+  vp->glx_context = init_GL(mi);
+
+  if (point_size < 0) point_size = 10;
+
+  vp->ncolors = 64;
+  vp->colors = (XColor *) calloc (vp->ncolors, sizeof(XColor));
+#if 0
+  make_random_colormap (0, 0, 0,
+                        vp->colors, &vp->ncolors,
+                        True, False, 0, False);
+#else
+  make_smooth_colormap (0, 0, 0,
+                        vp->colors, &vp->ncolors,
+                        False, False, False);
+#endif
+
+  reshape_voronoi (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
+
+  vp->mode = MODE_ADDING;
+  vp->adding = npoints * 2;
+  vp->last_time = 0;
+}
+
+
+ENTRYPOINT void
+draw_voronoi (ModeInfo *mi)
+{
+  voronoi_configuration *vp = &vps[MI_SCREEN(mi)];
+  Display *dpy = MI_DISPLAY(mi);
+  Window window = MI_WINDOW(mi);
+
+  if (!vp->glx_context)
+    return;
+
+  glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(vp->glx_context));
+
+  glShadeModel(GL_SMOOTH);
+  glEnable(GL_POINT_SMOOTH);
+  glEnable(GL_LINE_SMOOTH);
+  glEnable(GL_POLYGON_SMOOTH);
+
+  glEnable (GL_DEPTH_TEST);
+  glDepthFunc (GL_LEQUAL);
+
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+  mi->polygon_count = 0;
+  draw_cells (mi);
+  move_points (vp);
+  prune_points (vp);
+  state_change (mi);
+
+  if (mi->fps_p) do_fps (mi);
+  glFinish();
+
+  glXSwapBuffers(dpy, window);
+}
+
+XSCREENSAVER_MODULE ("Voronoi", voronoi)
+
+#endif /* USE_GL */
diff --git a/hacks/glx/voronoi.man b/hacks/glx/voronoi.man
new file mode 100644 (file)
index 0000000..526fb70
--- /dev/null
@@ -0,0 +1,88 @@
+.TH XScreenSaver 1 "" "X Version 11"
+.SH NAME
+voronoi - draws a randomly-colored Voronoi tessellation
+.SH SYNOPSIS
+.B voronoi
+[\-display \fIhost:display.screen\fP]
+[\-visual \fIvisual\fP]
+[\-window]
+[\-root]
+[\-points \fIint\fP]
+[\-point\-size \fIint\fP]
+[\-point\-speed \fIratio\fP]
+[\-point\-delay \fIseconds\fP]
+[\-zoom\-speed \fIratio\fP]
+[\-zoom\-delay \fIseconds\fP]
+[\-fps]
+.SH DESCRIPTION
+Draws a randomly-colored Voronoi tessellation, and periodically zooms 
+in and adds new points.  The existing points also wander around.
+
+There are a set of control points on the plane, each at the center of
+a colored cell.  Every pixel within that cell is closer to that cell's
+control point than to any other control point.  That is what
+determines the cell's shapes.
+
+When running in a window, you can click  to insert a new point at
+the mouse position.  Clicking on an existing point lets you drag
+it around.
+
+This implementation takes advantage of the OpenGL depth buffer to
+compute the cells for us, by rendering the intersection of overlapping
+cones in an orthographic plane.
+.SH OPTIONS
+.TP 8
+.B \-visual \fIvisual\fP
+Specify which visual to use.  Legal values are the name of a visual class,
+or the id number (decimal or hex) of a specific visual.
+.TP 8
+.B \-window
+Draw on a newly-created window.  This is the default.
+.TP 8
+.B \-root
+Draw on the root window.
+.TP 8
+.B \-points \fIint\fP
+How many points to add each time we zoom in.
+.TP 8
+.B \-point\-size \fIint\fP
+How big to draw the stars, in pixels.  0 for no stars.
+.TP 8
+.B \-point\-speed \fIratio\fP
+How fast the points should wander.  
+Less than 1 for slower, greater than 1 for faster.
+.TP 8
+.B \-point\-delay \fIseconds\fP
+How quickly to insert new points, when adding.
+.TP 8
+.B \-zoom\-speed \fIratio\fP
+How fast to zoom in.
+Less than 1 for slower, greater than 1 for faster.
+.TP 8
+.B \-zoom\-delay \fIseconds\fP
+Zoom in every this-many seconds.
+.TP 8
+.B \-fps | \-no-fps
+Whether to show a frames-per-second display at the bottom of the screen.
+.SH ENVIRONMENT
+.PP
+.TP 8
+.B DISPLAY
+to get the default host and display number.
+.TP 8
+.B XENVIRONMENT
+to get the name of a resource file that overrides the global resources
+stored in the RESOURCE_MANAGER property.
+.SH SEE ALSO
+.BR X (1),
+.BR xscreensaver (1)
+.SH COPYRIGHT
+Copyright \(co 2007 by Jamie Zawinski.  Permission to use, copy, modify, 
+distribute, and sell this software and its documentation for any purpose is 
+hereby granted without fee, provided that the above copyright notice appear 
+in all copies and that both that copyright notice and this permission notice
+appear in supporting documentation.  No representations are made about the 
+suitability of this software for any purpose.  It is provided "as is" without
+express or implied warranty.
+.SH AUTHOR
+Jamie Zawinski.
index 1455bc0e7331c378917d51cc97d99e89f224b547..eeb78731d75ff5aef76d0d4c08a2f8302f32534e 100644 (file)
@@ -3,40 +3,40 @@ static char *osx_10_2[] = {
 /* width height ncolors chars_per_pixel */
 "468 256 35 1",
 /* colors */
-"  c black",
-". c dark grey",
+"  c #000000",
+". c #A9A9A9",
 "X c #9D9D9D",
 "o c #959595",
-"O c gray42",
-"+ c gray35",
-"@ c gray91",
+"O c #6B6B6B",
+"+ c #595959",
+"@ c #E8E8E8",
 "# c #E4E4E4",
 "$ c #E2E2E2",
-"% c gray88",
-"& c gray87",
-"* c gainsboro",
-"= c gray16",
-"- c gray83",
+"% c #E0E0E0",
+"& c #DEDEDE",
+"* c #DCDCDC",
+"= c #292929",
+"- c #D4D4D4",
 "; c #D0D0D0",
 ": c #CECECE",
-"> c gray80",
+"> c #CCCCCC",
 ", c #CACACA",
 "< c #848484",
 "1 c #4C4C4C",
-"2 c gray21",
-"3 c gray89",
+"2 c #363636",
+"3 c #E3E3E3",
 "4 c #E1E1E1",
 "5 c #DFDFDF",
 "6 c #DDDDDD",
 "7 c #2A2A2A",
-"8 c gray85",
-"9 c gray14",
-"0 c gray82",
-"q c gray81",
+"8 c #D9D9D9",
+"9 c #242424",
+"0 c #D1D1D1",
+"q c #CFCFCF",
 "w c #CDCDCD",
-"e c gray10",
+"e c #1A1A1A",
 "r c #101010",
-"t c gray74",
+"t c #BDBDBD",
 "y c #060606",
 /* pixels */
 "&55555555&5555555&&&555555&555555555555555555&5555&5555555555555&5&5555555&5&555555555555555555555555555555555&55555&555555555&555555555&555555555555555&5555&55&5555&5555&555555&5&55555&55555555555555&5&&5555555555&5&&555&5&55&5&&5555555555555555555555555555&5555555&&5555555&555555555&555&&&555555&&55555555555&55&55555555555555&&555555&5&&555555&5&55&555&5&555555&5555&5&5555&&&5&5555555555555&&&5555555&5555555555555555&555&5555555555555&5555555&5555555555555555&55",
index dc06e1558eb5d0fe9dfbb6745f838889e706c616..352539cde8f7bd709aeb540e93dfc35c1c5bfe32 100644 (file)
@@ -3,20 +3,20 @@ static char *osx_10_3[] = {
 /* width height ncolors chars_per_pixel */
 "474 256 16 1",
 /* colors */
-"  c gray49",
+"  c #7D7D7D",
 ". c #5F5F5F",
 "X c #393939",
 "o c #E4E4E4",
-"O c gray12",
+"O c #1F1F1F",
 "+ c #191919",
 "@ c #151515",
 "# c #A2A2A2",
 "$ c #4E4E4E",
 "% c #F9F9F9",
 "& c #444444",
-"* c gray25",
+"* c #404040",
 "= c #2A2A2A",
-"- c gray10",
+"- c #1A1A1A",
 "; c #181818",
 ": c #C5C5C5",
 /* pixels */
diff --git a/hacks/m6502.c b/hacks/m6502.c
new file mode 100644 (file)
index 0000000..059d762
--- /dev/null
@@ -0,0 +1,833 @@
+/*
+ * Copyright (c) 2007 Jeremy English <jhe@jeremyenglish.org>
+ * 
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  No representations are made about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or 
+ * implied warranty.
+ * 
+ * Created: 07-May-2007 
+ */
+
+#include <stdint.h> 
+#include <string.h>
+#include "screenhack.h"
+#include "analogtv.h"
+#include "asm6502.h"
+
+/* We want to paint on a 32 by 32 grid of pixels. We will needed to
+   divided the screen up into chuncks */
+enum {
+  SCREEN_W = ANALOGTV_VIS_LEN,
+  SCREEN_H = ANALOGTV_VISLINES,
+  NUM_PROGS = 9
+};
+
+struct state {
+  Display *dpy;
+  Window window;
+  
+  Bit8 pixels[32][32];
+
+  machine_6502 *machine;
+
+  analogtv *tv;
+  analogtv_input *inp;
+  analogtv_reception reception;
+  int pixw; /* pixel width */
+  int pixh;/* pixel height */
+  int topb;/* top boarder */
+  int field_ntsc[4];/* used for clearing the screen*/ 
+  int dt;/* how long to wait before changing the demo*/
+  unsigned int pc;/* program counter */
+  struct timeval start_time; 
+};
+
+static void
+plot6502(Bit8 x, Bit8 y, Bit8 color, void *closure)
+{
+  struct state *st = (struct state *) closure;
+  st->pixels[x][y] = color;
+}
+
+static void 
+start_rand_bin_prog(machine_6502 *machine, struct state *st){
+  int r = random() % NUM_PROGS;
+
+  Bit8 noise[] =
+    {0xa0, 0xff, 0xa2, 0x00, 0xa5, 0xfe, 0x9d, 0x00, 0x02, 0x29, 
+     0x07, 0x9d, 0x00, 0x03, 0x29, 0x03, 0x9d, 0x00, 0x04, 0x29, 
+     0x01, 0x9d, 0x00, 0x05, 0xe8, 0x88, 0xd0, 0xe8, 0x60, 0x00};
+
+  Bit8 random[22] =
+    {0xa5, 0xfe, 0x85, 0x00, 0xa5, 0xfe, 0x29, 0x03, 0x18, 0x69,
+     0x02, 0x85, 0x01, 0xa5, 0xfe, 0xa0, 0x00, 0x91, 0x00, 0x4c,
+     0x00, 0x06};
+
+  Bit8 atari[629] =
+    {0xa9, 0x5c, 0x85, 0x00, 0xa9, 0x06, 0x85, 0x01, 0xa9, 0x00,
+     0x85, 0x02, 0xa9, 0x02, 0x85, 0x03, 0xa5, 0x03, 0xc9, 0x06,
+     0xd0, 0x01, 0x60, 0xa2, 0x00, 0xa1, 0x00, 0xc9, 0xff, 0xd0,
+     0x1a, 0xe8, 0xa1, 0x00, 0xa8, 0xe8, 0xa1, 0x00, 0xa2, 0x00,
+     0x81, 0x02, 0x20, 0x51, 0x06, 0x88, 0xd0, 0xf6, 0x20, 0x46,
+     0x06, 0x20, 0x46, 0x06, 0x4c, 0x10, 0x06, 0xa2, 0x00, 0x81,
+     0x02, 0x20, 0x51, 0x06, 0x20, 0x46, 0x06, 0x4c, 0x10, 0x06,
+     0xe6, 0x00, 0xa5, 0x00, 0xc9, 0x00, 0xd0, 0x02, 0xe6, 0x01,
+     0x60, 0xe6, 0x02, 0xa6, 0x02, 0xe0, 0x00, 0xd0, 0x02, 0xe6,
+     0x03, 0x60, 0xff, 0x2b, 0x01, 0x0f, 0x0f, 0x0f, 0x0c, 0x0f,
+     0x0f, 0x0f, 0xff, 0x18, 0x01, 0x0c, 0x0f, 0x0c, 0x00, 0x0c,
+     0x0f, 0x0c, 0xff, 0x18, 0x01, 0x00, 0x0f, 0x0c, 0x00, 0x0c,
+     0x0f, 0x0c, 0xff, 0x18, 0x01, 0x0c, 0x0f, 0x0c, 0x00, 0x0c,
+     0x0f, 0x0c, 0xff, 0x18, 0x01, 0x00, 0x0f, 0x0c, 0x00, 0x0c,
+     0x0f, 0x0c, 0xff, 0x18, 0x01, 0x0c, 0x0f, 0x00, 0x00, 0x0c,
+     0x0f, 0x0c, 0xff, 0x18, 0x01, 0x00, 0x0f, 0x0c, 0x00, 0x0c,
+     0x0f, 0x0c, 0xff, 0x18, 0x01, 0x00, 0x0f, 0x0c, 0x00, 0x0c,
+     0x0f, 0x00, 0xff, 0x18, 0x01, 0x00, 0x0f, 0x0c, 0x00, 0x0c,
+     0x0f, 0x00, 0xff, 0x17, 0x01, 0x0f, 0x00, 0x0f, 0x0c, 0x00,
+     0x0c, 0x0f, 0x00, 0x0f, 0xff, 0x16, 0x01, 0x0c, 0x00, 0x01,
+     0x0c, 0x00, 0x0c, 0x0f, 0x00, 0x0c, 0xff, 0x15, 0x01, 0x0f,
+     0x00, 0x00, 0x01, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0xff,
+     0x15, 0x01, 0x0c, 0x00, 0x0c, 0x01, 0x0c, 0x00, 0x0c, 0x01,
+     0x0c, 0x00, 0x0c, 0xff, 0x13, 0x01, 0x0f, 0x00, 0x00, 0x0f,
+     0x01, 0x0c, 0x00, 0x0c, 0x01, 0x0f, 0x00, 0x00, 0x0f, 0xff,
+     0x11, 0x01, 0x0f, 0x00, 0x00, 0x00, 0x01, 0x01, 0x0c, 0x00,
+     0x0c, 0x01, 0x01, 0x00, 0x00, 0x00, 0xff, 0x10, 0x01, 0x0f,
+     0x00, 0x00, 0x00, 0x0f, 0x01, 0x01, 0x00, 0x00, 0x0c, 0x01,
+     0x01, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x0d, 0x01, 0x0c,
+     0x00, 0x00, 0x00, 0x0c, 0x01, 0x01, 0x01, 0x0c, 0x00, 0x0c,
+     0x01, 0x01, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0xff, 0x0a,
+     0x01, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x01, 0x01,
+     0x01, 0x00, 0x00, 0x0c, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x0c, 0xff, 0x08, 0x01, 0x00, 0x00, 0x00,
+     0x00, 0x0c, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x0c,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x00,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
+     0x00, 0x0c, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0c,
+     0x00, 0x0c, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0f, 0x0c,
+     0x00, 0x00, 0xff, 0x12, 0x01, 0x0f, 0xff, 0x35, 0x01, 0x00,
+     0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x01, 0x0c,
+     0x0c, 0x01, 0x01, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x01,
+     0x00, 0x0f, 0x0f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x0c, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x0f, 0x01, 0x01,
+     0x0f, 0x00, 0x00, 0x0f, 0x01, 0x01, 0x00, 0x0f, 0x01, 0x0c,
+     0x0c, 0x01, 0x00, 0x0f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x00, 0x0f, 0x00, 0x0f, 0x01, 0x01, 0x00, 0x0f,
+     0x01, 0x01, 0x0f, 0x0c, 0x0c, 0x0c, 0x01, 0x01, 0x00, 0x01,
+     0x01, 0x0f, 0x00, 0x01, 0x00, 0x0f, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x0c, 0x0f, 0x01, 0x01,
+     0x0c, 0x0f, 0x01, 0x01, 0x00, 0x0f, 0x0f, 0x00, 0x01, 0x01,
+     0x00, 0x0f, 0x0f, 0x00, 0x0f, 0x01, 0x00, 0x0f, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x0c, 0x00, 0x0c, 0x00, 0x00,
+     0x01, 0x01, 0x00, 0x0f, 0x01, 0x01, 0x00, 0x0c, 0x0c, 0x00,
+     0x0f, 0x01, 0x00, 0x0f, 0x00, 0x0f, 0x01, 0x01, 0x00, 0x0f,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x0c, 0x0f,
+     0x0f, 0x00, 0x0f, 0x01, 0x0c, 0x0f, 0x01, 0x0c, 0x0c, 0x0f,
+     0x0f, 0x0c, 0x0c, 0x01, 0x00, 0x01, 0x0f, 0x0c, 0x01, 0x01,
+     0x00, 0x0f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0f, 0x00,
+     0x01, 0x01, 0x01, 0x0c, 0x0c, 0x01, 0x00, 0x0f, 0x01, 0x00,
+     0x0f, 0x01, 0x01, 0x0f, 0x00, 0x01, 0x00, 0x0f, 0x01, 0x00,
+     0x0f, 0x01, 0x00, 0x0f, 0xff, 0x10, 0x01, 0x0f, 0xff, 0x05,
+     0x01, 0x0f, 0x01, 0x01, 0x01, 0x0f, 0xff, 0x26, 0x01};
+  
+  Bit8 c64[1076] =
+    {0xa9, 0x34, 0x85, 0x00, 0xa9, 0x06, 0x85, 0x01, 0xa9, 0x00,
+     0x85, 0x02, 0xa9, 0x02, 0x85, 0x03, 0xa2, 0x00, 0xa1, 0x00,
+     0x81, 0x02, 0xe6, 0x00, 0xa5, 0x00, 0xc9, 0x00, 0xd0, 0x02,
+     0xe6, 0x01, 0xe6, 0x02, 0xa5, 0x02, 0xc9, 0x00, 0xd0, 0x08,
+     0xa5, 0x03, 0xc9, 0x05, 0xf0, 0x05, 0xe6, 0x03, 0x4c, 0x12,
+     0x06, 0x60, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x01, 0x06, 0x06, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x01, 0x01, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x01, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x01, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02,
+     0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+     0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+     0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02,
+     0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02,
+     0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
+     0x01, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06,
+     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+     0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
+  
+  Bit8 demoscene[2109] =
+    {0xa2, 0x00, 0xbd, 0x1c, 0x0e, 0xc9, 0xff, 0xf0, 0x0a, 0x9d,
+     0xe0, 0x04, 0x9d, 0xe0, 0x05, 0xe8, 0x4c, 0x02, 0x06, 0x20,
+     0xbd, 0x06, 0xa9, 0x00, 0x85, 0x10, 0x85, 0x11, 0x20, 0xd0,
+     0x06, 0x20, 0x4e, 0x06, 0x20, 0x28, 0x06, 0x4c, 0x1c, 0x06,
+     0xa2, 0x00, 0xbd, 0x21, 0x05, 0x9d, 0x20, 0x05, 0xbd, 0x41,
+     0x05, 0x9d, 0x40, 0x05, 0xbd, 0x61, 0x05, 0x9d, 0x60, 0x05,
+     0xbd, 0x81, 0x05, 0x9d, 0x80, 0x05, 0xbd, 0xa1, 0x05, 0x9d,
+     0xa0, 0x05, 0xe8, 0xe0, 0x1f, 0xd0, 0xdd, 0x60, 0xa5, 0x10,
+     0xc9, 0x00, 0xd0, 0x0d, 0xe6, 0x11, 0xa6, 0x11, 0xbd, 0xf0,
+     0x09, 0xaa, 0xbd, 0xd4, 0x09, 0x85, 0x10, 0xc6, 0x10, 0xa6,
+     0x11, 0xbd, 0xf0, 0x09, 0xc9, 0xff, 0xd0, 0x07, 0xa9, 0x00,
+     0x85, 0x10, 0x85, 0x11, 0x60, 0x0a, 0xaa, 0xbd, 0x64, 0x0a,
+     0x85, 0x02, 0xe8, 0xbd, 0x64, 0x0a, 0x85, 0x03, 0xa9, 0x9c,
+     0x18, 0x65, 0x02, 0x85, 0x00, 0xa9, 0x0a, 0x65, 0x03, 0x85,
+     0x01, 0xa6, 0x10, 0xa1, 0x00, 0x8d, 0x3f, 0x05, 0x8a, 0x18,
+     0x69, 0x06, 0xaa, 0xa1, 0x00, 0x8d, 0x5f, 0x05, 0x8a, 0x18,
+     0x69, 0x06, 0xaa, 0xa1, 0x00, 0x8d, 0x7f, 0x05, 0x8a, 0x18,
+     0x69, 0x06, 0xaa, 0xa1, 0x00, 0x8d, 0x9f, 0x05, 0x8a, 0x18,
+     0x69, 0x06, 0xaa, 0xa1, 0x00, 0x8d, 0xbf, 0x05, 0x60, 0xa9,
+     0xf3, 0x85, 0x20, 0xa9, 0x06, 0x85, 0x21, 0xa9, 0x00, 0x85,
+     0x22, 0xa9, 0x02, 0x85, 0x23, 0xa2, 0x00, 0x60, 0xa1, 0x20,
+     0xc9, 0xff, 0xf0, 0x1c, 0x81, 0x22, 0xe6, 0x20, 0xa5, 0x20,
+     0xc9, 0x00, 0xd0, 0x02, 0xe6, 0x21, 0xe6, 0x22, 0xa5, 0x22,
+     0xc9, 0x00, 0xd0, 0x08, 0xa5, 0x23, 0xc9, 0x05, 0xf0, 0x02,
+     0xe6, 0x23, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x0b, 0x0b, 0x0c, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+     0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0b, 0x0c, 0x0c, 0x0f, 0x0f,
+     0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x0b, 0x0c, 0x0c, 0x0f, 0x0c, 0x0f,
+     0x0f, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x00, 0x0b, 0x0b, 0x0c,
+     0x0f, 0x0f, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x0c, 0x0b, 0x0f, 0x0c,
+     0x0f, 0x0f, 0x0c, 0x0c, 0x0b, 0x00, 0x0b, 0x0c, 0x0c, 0x0c,
+     0x0f, 0x0f, 0x01, 0x0f, 0x0c, 0x0b, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x0b, 0x0c,
+     0x0c, 0x0c, 0x0f, 0x0f, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+     0x0c, 0x0f, 0x0c, 0x0f, 0x0f, 0x0f, 0x0f, 0x0b, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00,
+     0x00, 0x0b, 0x0c, 0x0c, 0x0f, 0x0f, 0x0f, 0x0f, 0x0c, 0x0f,
+     0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x01, 0x0f, 0x0f, 0x0c,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x0b, 0x0b, 0x0b, 0x0c, 0x0f, 0x0f, 0x01, 0x0f,
+     0x0f, 0x0c, 0x0f, 0x0f, 0x0f, 0x01, 0x0f, 0x0f, 0x0f, 0x0f,
+     0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x0f,
+     0x01, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x01,
+     0x0f, 0x0f, 0x0f, 0x0f, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x0b, 0x0c, 0x0b,
+     0x0c, 0x0c, 0x01, 0x01, 0x0f, 0x01, 0x0f, 0x01, 0x0f, 0x01,
+     0x0f, 0x0f, 0x01, 0x0f, 0x0f, 0x01, 0x0b, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x0b, 0x0b, 0x0c,
+     0x0c, 0x0b, 0x0c, 0x0f, 0x01, 0x01, 0x01, 0x0f, 0x0f, 0x01,
+     0x0f, 0x0f, 0x01, 0x0f, 0x0f, 0x0f, 0x0f, 0x01, 0x0c, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x0b,
+     0x0c, 0x0c, 0x0c, 0x0b, 0x0c, 0x0c, 0x0f, 0x01, 0x01, 0x01,
+     0x0f, 0x0f, 0x01, 0x0f, 0x01, 0x0f, 0x01, 0x0f, 0x0f, 0x01,
+     0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x0b,
+     0x0b, 0x0c, 0x0c, 0x0c, 0x0f, 0x0c, 0x0c, 0x0f, 0x0f, 0x01,
+     0x01, 0x01, 0x01, 0x0f, 0x0f, 0x0f, 0x01, 0x0f, 0x01, 0x0f,
+     0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x0b, 0x0c, 0x0c, 0x0c, 0x0f, 0x0c, 0x0f, 0x0c, 0x0f,
+     0x0f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0f, 0x0f, 0x01, 0x0f,
+     0x0f, 0x0f, 0x0f, 0x01, 0x0f, 0x0b, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c, 0x0f, 0x0c, 0x0f, 0x0f,
+     0x0c, 0x0f, 0x0f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0f, 0x0f,
+     0x0f, 0x01, 0x0f, 0x0f, 0x0f, 0x01, 0x0c, 0x0b, 0x0b, 0x00,
+     0x00, 0x00, 0x00, 0x0b, 0x0b, 0x0c, 0x0f, 0x0c, 0x0f, 0x0f,
+     0x0f, 0x0f, 0x0f, 0x0c, 0x0f, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x0f, 0x0f, 0x0f, 0x01, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0b,
+     0x0b, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x0c, 0x0c, 0x0c, 0x0f,
+     0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x01, 0x01,
+     0x01, 0x0f, 0x0b, 0x0f, 0x0f, 0x0f, 0x01, 0x0f, 0x0f, 0x0f,
+     0x0f, 0x0b, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x0c, 0x0c,
+     0x0f, 0x0c, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+     0x0f, 0x0f, 0x0c, 0x0b, 0x0f, 0x0f, 0x01, 0x0f, 0x0f, 0x0f,
+     0x0f, 0x0f, 0x0f, 0x0c, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x0b,
+     0x0b, 0x0c, 0x0c, 0x0f, 0x0c, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+     0x0f, 0x0c, 0x0c, 0x0b, 0x0c, 0x0c, 0x0f, 0x0f, 0x01, 0x0c,
+     0x0c, 0x0f, 0x0f, 0x0f, 0x0f, 0x0c, 0x0b, 0x00, 0x00, 0x00,
+     0x00, 0x0b, 0x0b, 0x0c, 0x0c, 0x0c, 0x0f, 0x0f, 0x0f, 0x0f,
+     0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x01, 0x0f,
+     0x0c, 0x0b, 0x0f, 0x0c, 0x0f, 0x0c, 0x0f, 0x0c, 0x0b, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, 0x0f,
+     0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+     0x0c, 0x0b, 0x0c, 0x0c, 0x0c, 0x0f, 0x0f, 0x0c, 0x0f, 0x0c,
+     0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x0b, 0x0c, 0x0c,
+     0x0c, 0x0c, 0x0c, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+     0x0c, 0x0b, 0x0b, 0x0c, 0x0c, 0x0c, 0x0f, 0x0c, 0x0f, 0x0f,
+     0x0f, 0x0c, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x0b,
+     0x0b, 0x0b, 0x0c, 0x0c, 0x0f, 0x0c, 0x0f, 0x0f, 0x0f, 0x0c,
+     0x0c, 0x0b, 0x0b, 0x0b, 0x0c, 0x0b, 0x0b, 0x0c, 0x0c, 0x0f,
+     0x0c, 0x0c, 0x0f, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x0b, 0x0b, 0x0c, 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+     0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x0b, 0x0b, 0x0c, 0x0c,
+     0x0f, 0x0f, 0x0f, 0x0c, 0x0c, 0x0c, 0x0b, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c,
+     0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c,
+     0x0c, 0x0f, 0x0f, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xff,
+     0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x02, 0x05,
+     0x05, 0x05, 0x06, 0x06, 0x05, 0x05, 0x06, 0x05, 0x05, 0x04,
+     0x05, 0x06, 0x06, 0x06, 0x06, 0x05, 0x02, 0x03, 0x00, 0x0e,
+     0x0d, 0x0b, 0x18, 0x1b, 0x03, 0x04, 0x0f, 0x13, 0x07, 0x1b,
+     0x0c, 0x00, 0x0a, 0x04, 0x12, 0x1b, 0x08, 0x13, 0x1b, 0x0f,
+     0x0e, 0x12, 0x12, 0x08, 0x01, 0x0b, 0x04, 0x1a, 0x1a, 0x1a,
+     0x13, 0x07, 0x08, 0x12, 0x1b, 0x08, 0x12, 0x1b, 0x13, 0x07,
+     0x04, 0x1b, 0x05, 0x08, 0x11, 0x12, 0x13, 0x1b, 0x03, 0x04,
+     0x0c, 0x0e, 0x1b, 0x0c, 0x00, 0x03, 0x04, 0x1b, 0x08, 0x0d,
+     0x1b, 0x13, 0x07, 0x08, 0x12, 0x1b, 0x04, 0x0d, 0x15, 0x1a,
+     0x1a, 0x1a, 0x1a, 0x1b, 0x07, 0x0e, 0x0f, 0x04, 0x1b, 0x18,
+     0x0e, 0x14, 0x1b, 0x0b, 0x08, 0x0a, 0x04, 0x1b, 0x08, 0x13,
+     0x1a, 0x1a, 0x1a, 0x1b, 0x1b, 0x16, 0x16, 0x16, 0x1a, 0x03,
+     0x04, 0x0f, 0x13, 0x07, 0x1a, 0x0e, 0x11, 0x06, 0x1b, 0x1b,
+     0x1b, 0x1b, 0x1b, 0xff, 0x00, 0x00, 0x20, 0x00, 0x40, 0x00,
+     0x60, 0x00, 0x80, 0x00, 0xa0, 0x00, 0xc0, 0x00, 0xe0, 0x00,
+     0x00, 0x01, 0x20, 0x01, 0x40, 0x01, 0x60, 0x01, 0x80, 0x01,
+     0xa0, 0x01, 0xc0, 0x01, 0xe0, 0x01, 0x00, 0x02, 0x20, 0x02,
+     0x40, 0x02, 0x60, 0x02, 0x80, 0x02, 0xa0, 0x02, 0xc0, 0x02,
+     0xe0, 0x02, 0x00, 0x03, 0x20, 0x03, 0x40, 0x03, 0x60, 0x03,
+     0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01,
+     0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00,
+     0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00,
+     0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00,
+     0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
+     0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+     0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+     0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00,
+     0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
+     0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+     0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+     0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+     0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
+     0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+     0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+     0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00,
+     0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
+     0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+     0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00,
+     0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01,
+     0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
+     0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01,
+     0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+     0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
+     0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+     0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
+     0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+     0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00,
+     0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00,
+     0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+     0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
+     0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01,
+     0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01,
+     0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
+     0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
+     0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00,
+     0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+     0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00,
+     0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+     0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+     0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01,
+     0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00,
+     0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
+     0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
+     0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
+     0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+     0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00,
+     0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+     0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+     0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
+     0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
+     0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
+     0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x09, 0x0b, 0x09,
+     0x08, 0x09, 0x08, 0x0a, 0x08, 0x0a, 0x07, 0x0a, 0x07, 0x01,
+     0x07, 0x01, 0x01, 0x07, 0x01, 0x07, 0x0a, 0x07, 0x0a, 0x08,
+     0x0a, 0x08, 0x09, 0x08, 0x09, 0x0b, 0x09, 0x0b, 0xff};
+
+  Bit8 breakout[219] =
+    {0xa9, 0xfe, 0x85, 0x02, 0xa9, 0xee, 0x85, 0x03, 0xa9, 0x00,
+     0x85, 0x00, 0xa9, 0x02, 0x85, 0x01, 0xa2, 0x20, 0xa9, 0x02,
+     0x9d, 0xff, 0x01, 0x9d, 0xdf, 0x05, 0xa0, 0x00, 0x91, 0x00,
+     0xa0, 0x1f, 0x91, 0x00, 0xe0, 0x01, 0xf0, 0x15, 0xa9, 0x03,
+     0xa0, 0x17, 0x91, 0x00, 0xa9, 0x04, 0xc8, 0x91, 0x00, 0xa9,
+     0x05, 0xc8, 0x91, 0x00, 0xa9, 0x06, 0xc8, 0x91, 0x00, 0x18,
+     0xa5, 0x00, 0x69, 0x20, 0x85, 0x00, 0xa5, 0x01, 0x69, 0x00,
+     0x85, 0x01, 0xca, 0xd0, 0xc7, 0xa6, 0x02, 0xa4, 0x03, 0xa9,
+     0x44, 0x85, 0x00, 0xa9, 0x02, 0x85, 0x01, 0x8a, 0x48, 0xa9,
+     0x01, 0xa2, 0x00, 0x81, 0x00, 0x68, 0xaa, 0xca, 0xf0, 0x46,
+     0x88, 0xd0, 0xfa, 0x8a, 0x48, 0x20, 0xd5, 0x06, 0xa5, 0x03,
+     0x29, 0x01, 0xd0, 0x0d, 0x18, 0xa5, 0x00, 0x69, 0x20, 0x85,
+     0x00, 0x90, 0x11, 0xe6, 0x01, 0xd0, 0x0d, 0x38, 0xa5, 0x00,
+     0xe9, 0x20, 0x85, 0x00, 0xa5, 0x01, 0xe9, 0x00, 0x85, 0x01,
+     0xa2, 0x00, 0xa1, 0x00, 0xd0, 0x07, 0xa4, 0x03, 0x68, 0xaa,
+     0x4c, 0x57, 0x06, 0xc9, 0x02, 0xf0, 0x04, 0xa9, 0x00, 0x81,
+     0x00, 0xa9, 0x01, 0x45, 0x03, 0x85, 0x03, 0x4c, 0x6c, 0x06,
+     0x20, 0xd5, 0x06, 0xa5, 0x02, 0x29, 0x01, 0xd0, 0x04, 0xe6,
+     0x00, 0xd0, 0x02, 0xc6, 0x00, 0xa2, 0x00, 0xa1, 0x00, 0xd0,
+     0x05, 0xa6, 0x02, 0x4c, 0x57, 0x06, 0xc9, 0x02, 0xf0, 0x04,
+     0xa9, 0x00, 0x81, 0x00, 0xa9, 0x01, 0x45, 0x02, 0x85, 0x02,
+     0x4c, 0xad, 0x06, 0xa9, 0x00, 0xaa, 0x81, 0x00, 0x60};
+
+  Bit8 sierpinsky[145] =
+    {0xa2, 0x00, 0xa0, 0x00, 0xa5, 0xfe, 0x29, 0x03, 0xc9, 0x03,
+     0xd0, 0x03, 0x4c, 0x04, 0x06, 0x48, 0x0a, 0x0a, 0x0a, 0x85,
+     0xf3, 0x68, 0x29, 0x01, 0x0a, 0x0a, 0x0a, 0x0a, 0x85, 0xf4,
+     0x8a, 0x4a, 0x65, 0xf3, 0xaa, 0x98, 0x4a, 0x65, 0xf4, 0xa8,
+     0x20, 0x2e, 0x06, 0x4c, 0x04, 0x06, 0x48, 0x8a, 0x48, 0x98,
+     0x48, 0x48, 0x48, 0x86, 0xf2, 0xa4, 0xf2, 0xa9, 0x00, 0x85,
+     0xf0, 0xa9, 0x02, 0x85, 0xf1, 0xa9, 0x00, 0x68, 0x29, 0x07,
+     0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x18, 0x65, 0xf0, 0x85, 0xf0,
+     0x90, 0x02, 0xe6, 0xf1, 0x18, 0x68, 0x29, 0x18, 0x4a, 0x4a,
+     0x4a, 0x65, 0xf1, 0x85, 0xf1, 0x18, 0x98, 0x65, 0xf0, 0x65,
+     0xf1, 0xa9, 0x01, 0x20, 0x72, 0x06, 0x91, 0xf0, 0x68, 0xa8,
+     0x68, 0xaa, 0x68, 0x60, 0xb1, 0xf0, 0xc9, 0x00, 0xd0, 0x03,
+     0xa9, 0x0b, 0x60, 0xc9, 0x0b, 0xd0, 0x03, 0xa9, 0x0c, 0x60,
+     0xc9, 0x0c, 0xd0, 0x03, 0xa9, 0x0f, 0x60, 0xc9, 0x0f, 0xd0,
+     0x03, 0xa9, 0x01, 0x60, 0x60};
+
+Bit8 spacer[583] =
+  {0x20, 0x62, 0x06, 0x20, 0x90, 0x06, 0x20, 0xe6, 0x06, 0x20,
+   0x52, 0x06, 0x4c, 0x03, 0x06, 0xa5, 0x82, 0xa8, 0xb9, 0x07,
+   0x07, 0x85, 0x00, 0xc8, 0xb9, 0x07, 0x07, 0x85, 0x01, 0xa2,
+   0x2a, 0xa1, 0x00, 0xc9, 0x00, 0xf0, 0x02, 0xc9, 0x05, 0xa9,
+   0x05, 0x81, 0x00, 0xa5, 0x60, 0xc5, 0x61, 0xf0, 0x19, 0xa5,
+   0x61, 0x0a, 0xa8, 0xb9, 0x07, 0x07, 0x85, 0x00, 0xc8, 0xb9,
+   0x07, 0x07, 0x85, 0x01, 0xa9, 0x00, 0xa2, 0x2a, 0x81, 0x00,
+   0xa5, 0x60, 0x85, 0x61, 0x60, 0xa5, 0xfe, 0x81, 0x00, 0x4c,
+   0x4b, 0x06, 0xa5, 0xff, 0xc9, 0x77, 0xd0, 0x03, 0xc6, 0x60,
+   0x60, 0xc9, 0x78, 0xd0, 0x02, 0xe6, 0x60, 0x60, 0xa2, 0x00,
+   0xbd, 0x47, 0x07, 0x9d, 0x00, 0x05, 0xe8, 0xe0, 0x00, 0xd0,
+   0xf5, 0xa9, 0x0a, 0x85, 0x60, 0x85, 0x61, 0xa2, 0x00, 0xa9,
+   0x0c, 0x9d, 0x00, 0x02, 0x9d, 0x00, 0x04, 0xca, 0xe0, 0x00,
+   0xd0, 0xf5, 0xa9, 0x10, 0x85, 0x80, 0xa2, 0x0f, 0x95, 0x81,
+   0xca, 0x10, 0xfb, 0x60, 0xa9, 0x00, 0x85, 0x78, 0xa9, 0x20,
+   0x85, 0x79, 0xa9, 0xc0, 0x85, 0x7a, 0xa9, 0xe0, 0x85, 0x7b,
+   0xa2, 0x0f, 0xb5, 0x81, 0x95, 0x82, 0xa8, 0xb9, 0x07, 0x07,
+   0x85, 0x00, 0xc8, 0xb9, 0x07, 0x07, 0x85, 0x01, 0xa9, 0x0c,
+   0xa4, 0x78, 0x91, 0x00, 0xc8, 0x91, 0x00, 0xa4, 0x7b, 0x91,
+   0x00, 0xc8, 0x91, 0x00, 0xa4, 0x79, 0xa9, 0x00, 0x91, 0x00,
+   0xc8, 0x91, 0x00, 0xa4, 0x7a, 0x91, 0x00, 0xc8, 0x91, 0x00,
+   0xe6, 0x78, 0xe6, 0x79, 0xe6, 0x7a, 0xe6, 0x7b, 0xe6, 0x78,
+   0xe6, 0x79, 0xe6, 0x7a, 0xe6, 0x7b, 0xca, 0x10, 0xbd, 0x60,
+   0xa5, 0x80, 0xc5, 0x81, 0xf0, 0x09, 0xa5, 0x80, 0x18, 0xe5,
+   0x81, 0x10, 0x0f, 0x30, 0x08, 0xa5, 0xfe, 0x29, 0x0f, 0x0a,
+   0x85, 0x80, 0x60, 0xc6, 0x81, 0xc6, 0x81, 0x60, 0xe6, 0x81,
+   0xe6, 0x81, 0x60, 0x00, 0x02, 0x20, 0x02, 0x40, 0x02, 0x60,
+   0x02, 0x80, 0x02, 0xa0, 0x02, 0xc0, 0x02, 0xe0, 0x02, 0x00,
+   0x03, 0x20, 0x03, 0x40, 0x03, 0x60, 0x03, 0x80, 0x03, 0xa0,
+   0x03, 0xc0, 0x03, 0xe0, 0x03, 0x00, 0x04, 0x20, 0x04, 0x40,
+   0x04, 0x60, 0x04, 0x80, 0x04, 0xa0, 0x04, 0xc0, 0x04, 0xe0,
+   0x04, 0x00, 0x05, 0x20, 0x05, 0x40, 0x05, 0x60, 0x05, 0x80,
+   0x05, 0xa0, 0x05, 0xc0, 0x05, 0xe0, 0x05, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x01, 0x01, 0x01, 0x06, 0x01, 0x01, 0x01, 0x00, 0x00,
+   0x06, 0x01, 0x01, 0x06, 0x00, 0x00, 0x01, 0x01, 0x01, 0x06,
+   0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x06, 0x00,
+   0x00, 0x06, 0x01, 0x06, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06,
+   0x01, 0x06, 0x01, 0x06, 0x00, 0x01, 0x00, 0x01, 0x00, 0x06,
+   0x00, 0x06, 0x01, 0x06, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06,
+   0x01, 0x06, 0x00, 0x00, 0x06, 0x01, 0x01, 0x06, 0x06, 0x01,
+   0x01, 0x01, 0x00, 0x06, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01,
+   0x06, 0x00, 0x06, 0x06, 0x01, 0x01, 0x01, 0x00, 0x06, 0x01,
+   0x00, 0x06, 0x01, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01,
+   0x06, 0x01, 0x01, 0x06, 0x06, 0x06, 0x01, 0x01, 0x01, 0x01,
+   0x06, 0x01, 0x06, 0x06, 0x06, 0x06, 0x01, 0x06, 0x06, 0x06,
+   0x06, 0x01, 0x01, 0x01, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01,
+   0x01, 0x01, 0x0e, 0x01, 0x01, 0x0e, 0x06, 0x06, 0x01, 0x01,
+   0x06, 0x01, 0x06, 0x01, 0x01, 0x01, 0x01, 0x0e, 0x01, 0x01,
+   0x01, 0x01, 0x06, 0x01, 0x01, 0x06, 0x01, 0x06, 0x06, 0x06,
+   0x01, 0x01, 0x01, 0x06, 0x0e, 0x01, 0x01, 0x06, 0x0e, 0x06,
+   0x01, 0x01, 0x0e, 0x01, 0x0e, 0x06, 0x01, 0x01, 0x01, 0x06,
+   0x0e, 0x01, 0x01, 0x01, 0x0e, 0x01, 0x01, 0x06, 0x01, 0x06,
+   0x0e, 0x0e, 0x0e, 0x06, 0x0e, 0x0e, 0x06, 0x0e, 0x0e, 0x06,
+   0x0e, 0x0e, 0x06, 0x0e, 0x0e, 0x06, 0x0e, 0x0e, 0x06, 0x0e,
+   0x0e, 0x06, 0x0e, 0x0e, 0x06, 0x0e, 0x0e, 0x06, 0x0e, 0x0e,
+   0x06, 0x0e, 0x0e};
+
+ Bit8 pong[398] =
+  {0x20, 0x27, 0x06, 0x20, 0x18, 0x06, 0x20, 0x29, 0x07, 0x20,
+   0x5c, 0x06, 0x20, 0xf6, 0x06, 0xa5, 0x10, 0xc9, 0x1f, 0xd0,
+   0xf4, 0x4c, 0x15, 0x06, 0xa9, 0x0b, 0x85, 0x10, 0xa9, 0x05,
+   0x85, 0x11, 0xa9, 0xff, 0x85, 0x12, 0x85, 0x13, 0x60, 0xa9,
+   0x00, 0x85, 0x00, 0xa9, 0x02, 0x85, 0x01, 0xa2, 0x00, 0xa0,
+   0x1f, 0x98, 0xaa, 0xa9, 0x0e, 0x9d, 0x00, 0x02, 0x9d, 0x20,
+   0x02, 0xa2, 0x00, 0x81, 0x00, 0xe8, 0x81, 0x00, 0xa2, 0x1e,
+   0x81, 0x00, 0xe8, 0x81, 0x00, 0xa5, 0x00, 0xc9, 0xe0, 0xd0,
+   0x02, 0xe6, 0x01, 0x18, 0x69, 0x20, 0x85, 0x00, 0x88, 0xd0,
+   0xd8, 0x60, 0xa5, 0x10, 0x85, 0x15, 0xa5, 0x11, 0x85, 0x16,
+   0xa5, 0x10, 0x18, 0x65, 0x12, 0x85, 0x10, 0x20, 0xdf, 0x06,
+   0xc9, 0x00, 0xf0, 0x15, 0xa5, 0x12, 0xc9, 0x01, 0xd0, 0x09,
+   0xa9, 0xff, 0x85, 0x12, 0xc6, 0x10, 0x4c, 0x87, 0x06, 0xa9,
+   0x01, 0x85, 0x12, 0xe6, 0x10, 0xa5, 0x11, 0x18, 0x65, 0x13,
+   0x85, 0x11, 0x20, 0xdf, 0x06, 0xc9, 0x00, 0xf0, 0x15, 0xa5,
+   0x13, 0xc9, 0x01, 0xd0, 0x09, 0xa9, 0xff, 0x85, 0x13, 0xc6,
+   0x11, 0x4c, 0xaa, 0x06, 0xa9, 0x01, 0x85, 0x13, 0xe6, 0x11,
+   0xa5, 0x10, 0x29, 0x1f, 0x0a, 0xaa, 0xbd, 0x4e, 0x07, 0x85,
+   0x00, 0xe8, 0xbd, 0x4e, 0x07, 0x85, 0x01, 0xa5, 0x11, 0x29,
+   0x1f, 0xaa, 0xa9, 0x0d, 0x81, 0x00, 0xa5, 0x15, 0x29, 0x1f,
+   0x0a, 0xaa, 0xbd, 0x4e, 0x07, 0x85, 0x00, 0xe8, 0xbd, 0x4e,
+   0x07, 0x85, 0x01, 0xa5, 0x16, 0x29, 0x1f, 0xaa, 0xa9, 0x00,
+   0x81, 0x00, 0x60, 0xa5, 0x10, 0x0a, 0xaa, 0xbd, 0x4e, 0x07,
+   0x85, 0x00, 0xe8, 0xbd, 0x4e, 0x07, 0x85, 0x01, 0xa5, 0x11,
+   0x29, 0x1f, 0xaa, 0xa1, 0x00, 0x60, 0xa5, 0xff, 0xc9, 0x61,
+   0xd0, 0x08, 0xa5, 0x20, 0xc9, 0x00, 0xf0, 0x0e, 0xc6, 0x20,
+   0xc9, 0x64, 0xd0, 0x08, 0xa5, 0x20, 0xc9, 0x19, 0xf0, 0x02,
+   0xe6, 0x20, 0xa6, 0x20, 0xa9, 0x00, 0x9d, 0xe0, 0x05, 0xe8,
+   0xa0, 0x1e, 0xa9, 0x0f, 0x9d, 0xe0, 0x05, 0xe8, 0x88, 0xd0,
+   0xf7, 0xa9, 0x00, 0x9d, 0xe0, 0x05, 0x60, 0xa9, 0x00, 0x85,
+   0x05, 0xa9, 0x02, 0x85, 0x06, 0xe6, 0x06, 0xa5, 0xfe, 0x29,
+   0x0f, 0x18, 0x69, 0x05, 0xaa, 0xa5, 0x06, 0x0a, 0xa8, 0xa9,
+   0x0c, 0x81, 0x05, 0xe8, 0x88, 0xd0, 0xfa, 0xa5, 0x06, 0xc9,
+   0x05, 0xd0, 0xe4, 0x60, 0x00, 0x02, 0x20, 0x02, 0x40, 0x02,
+   0x60, 0x02, 0x80, 0x02, 0xa0, 0x02, 0xc0, 0x02, 0xe0, 0x02,
+   0x00, 0x03, 0x20, 0x03, 0x40, 0x03, 0x60, 0x03, 0x80, 0x03,
+   0xa0, 0x03, 0xc0, 0x03, 0xe0, 0x03, 0x00, 0x04, 0x20, 0x04,
+   0x40, 0x04, 0x60, 0x04, 0x80, 0x04, 0xa0, 0x04, 0xc0, 0x04,
+   0xe0, 0x04, 0x00, 0x05, 0x20, 0x05, 0x40, 0x05, 0x60, 0x05,
+   0x80, 0x05, 0xa0, 0x05, 0xc0, 0x05, 0xe0, 0x05};
+
+  switch(r){
+  case 0: 
+    start_eval_binary(machine,noise,30,plot6502,st);
+    break;
+  case 1:
+    start_eval_binary(machine,atari,629,plot6502,st);
+    break;
+  case 2:
+    start_eval_binary(machine,c64,1076,plot6502,st);
+    break;
+  case 3:
+    start_eval_binary(machine,random,22,plot6502,st);
+    break;
+  case 4:
+    start_eval_binary(machine,demoscene,2109,plot6502,st);
+    break;
+  case 5:
+    start_eval_binary(machine,breakout,219,plot6502,st);
+    break;
+  case 6:
+    start_eval_binary(machine,sierpinsky,145,plot6502,st);
+    break;
+  case 7:
+    start_eval_binary(machine,spacer,583,plot6502,st);
+    break;
+  case 8:
+   start_eval_binary(machine,pong,398,plot6502,st);
+   break;
+  } 
+}
+\f
+/*
+ * get_time ()
+ *
+ * returns the total time elapsed since the beginning of the demo
+ */
+static double get_time(struct state *st) {
+  struct timeval t;
+  float f;
+#if GETTIMEOFDAY_TWO_ARGS
+  gettimeofday(&t, NULL);
+#else
+  gettimeofday(&t);
+#endif
+  t.tv_sec -= st->start_time.tv_sec;
+  f = ((double)t.tv_sec) + t.tv_usec*1e-6;
+  return f;
+}
+
+/*
+ * init_time ()
+ *
+ * initialises the timing structures
+ */
+static void init_time(struct state *st) {
+#if GETTIMEOFDAY_TWO_ARGS
+  gettimeofday(&st->start_time, NULL);
+#else
+  gettimeofday(&st->start_time);
+#endif
+}
+
+static void *
+m6502_init (Display *dpy, Window window)
+{
+  struct state *st = (struct state *) calloc (1, sizeof(*st));
+  unsigned int x, y;
+  char *s = get_string_resource (dpy, "file", "File");
+  int n = get_integer_resource(dpy, "displaytime", "Displaytime");
+  int dh;
+  st->pc = 0;
+  st->dt = n;
+  st->dpy = dpy;
+  st->window = window;
+  st->tv=analogtv_allocate(st->dpy, st->window);
+  analogtv_set_defaults(st->tv, "");
+  
+  st->machine = build6502();
+  st->inp=analogtv_input_allocate();
+  analogtv_setup_sync(st->inp, 1, 0);
+  
+  st->reception.input = st->inp;
+  st->reception.level = 2.0;
+  st->reception.ofs=0;
+  
+  st->reception.multipath=0.0;
+  st->pixw = SCREEN_W / 32;
+  st->pixh = SCREEN_H / 32;
+  dh = SCREEN_H % 32;
+  st->topb = dh / 2;
+
+  init_time(st);
+  
+  if (strlen(s) > 0)
+    start_eval_file(st->machine,s, plot6502, st);
+  else
+    start_rand_bin_prog(st->machine,st);
+
+  analogtv_lcp_to_ntsc(ANALOGTV_BLACK_LEVEL, 0.0, 0.0, st->field_ntsc);
+
+  analogtv_draw_solid(st->inp,
+                      ANALOGTV_VIS_START, ANALOGTV_VIS_END,
+                      ANALOGTV_TOP, ANALOGTV_BOT,
+                      st->field_ntsc);
+
+  for(x = 0; x < 32; x++)
+    for(y = 0; y < 32; y++)
+      st->pixels[x][y] = 0;
+
+  return st;
+}
+
+static void
+paint_pixel(struct state *st, int x, int y, int idx)
+{
+  double clr_tbl[16][3] = {
+    {  0,   0,   0},
+    {255, 255, 255},
+    {136,   0,   0},
+    {170, 255, 238},
+    {204,  68, 204},
+    {  0, 204,  85},
+    {  0,   0, 170},
+    {238, 238, 119},
+    {221, 136,  85},
+    {102,  68,   0},
+    {255, 119, 119},
+    { 51,  51,  51},
+    {119, 119, 119},
+    {170, 255, 102},
+    {  0, 136, 255},
+    {187, 187, 187}
+  };
+  int ntsc[4], i;
+  int rawy,rawi,rawq;
+  /* RGB conversion taken from analogtv draw xpm */
+  rawy=( 5*clr_tbl[idx][0] + 11*clr_tbl[idx][1] + 2*clr_tbl[idx][2]) / 64;
+  rawi=(10*clr_tbl[idx][0] -  4*clr_tbl[idx][1] - 5*clr_tbl[idx][2]) / 64;
+  rawq=( 3*clr_tbl[idx][0] -  8*clr_tbl[idx][1] + 5*clr_tbl[idx][2]) / 64;
+
+  ntsc[0]=rawy+rawq;
+  ntsc[1]=rawy-rawi;
+  ntsc[2]=rawy-rawq;
+  ntsc[3]=rawy+rawi;
+
+  for (i=0; i<4; i++) {
+    if (ntsc[i]>ANALOGTV_WHITE_LEVEL) ntsc[i]=ANALOGTV_WHITE_LEVEL;
+    if (ntsc[i]<ANALOGTV_BLACK_LEVEL) ntsc[i]=ANALOGTV_BLACK_LEVEL;
+  }
+
+      
+  x *= st->pixw;
+  y *= st->pixh;
+  y += st->topb;
+  analogtv_draw_solid(st->inp,
+                     ANALOGTV_VIS_START + x, ANALOGTV_VIS_START + x + st->pixw,
+                     ANALOGTV_TOP + y, ANALOGTV_TOP + y + st->pixh, ntsc);                           
+}
+
+static unsigned long
+m6502_draw (Display *dpy, Window window, void *closure)
+{
+  struct state *st = (struct state *) closure;
+  unsigned int x = 0, y = 0;
+  double te;
+
+  next_eval(st->machine,500);
+
+  for (x = 0; x < 32; x++)
+    for (y = 0; y < 32; y++)
+      paint_pixel(st,x,y,st->pixels[x][y]);
+  
+  analogtv_init_signal(st->tv, 0.04);
+  analogtv_reception_update(&st->reception);
+  analogtv_add_signal(st->tv, &st->reception);
+  analogtv_draw(st->tv);
+  te = get_time(st);
+  
+  if (te > st->dt){ /* do something more interesting here XXX */
+    for(x = 0; x < 32; x++)
+      for(y = 0; y < 32; y++)
+       st->pixels[x][y] = 0;
+    init_time(st);
+    start_rand_bin_prog(st->machine,st);
+  }
+
+  return 10000;
+}
+
+
+\f
+
+static const char *m6502_defaults [] = {
+  ".background:      black",
+  ".foreground:      white",
+  "*file:",
+  "*displaytime:     20",
+  ANALOGTV_DEFAULTS
+  "*TVContrast:      150",
+  0
+};
+
+static XrmOptionDescRec m6502_options [] = {
+  { "-file",           ".file",     XrmoptionSepArg, 0 },
+  { "-displaytime",    ".displaytime", XrmoptionSepArg, 0},
+  ANALOGTV_OPTIONS
+  { 0, 0, 0, 0 }
+};
+
+static void
+m6502_reshape (Display *dpy, Window window, void *closure, 
+                 unsigned int w, unsigned int h)
+{
+  struct state *st = (struct state *) closure;
+  analogtv_reconfigure (st->tv);
+}
+
+static Bool
+m6502_event (Display *dpy, Window window, void *closure, XEvent *event)
+{
+  return False;
+}
+
+static void
+m6502_free (Display *dpy, Window window, void *closure)
+{
+  struct state *st = (struct state *) closure;
+  analogtv_release(st->tv);
+  free (st);
+}
+
+XSCREENSAVER_MODULE ("m6502", m6502)
index cd3fa4319bbf911a96d56e7323ed3320f84eb98c..9d76d1ab64d41c7bb37e63054c6e6c43edf81a08 100755 (executable)
@@ -60,7 +60,7 @@ use bytes;  # Larry can take Unicode and shove it up his ass sideways.
 
 
 my $progname = $0; $progname =~ s@.*/@@g;
-my $version = q{ $Revision: 1.133 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
+my $version = q{ $Revision: 1.135 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/;
 my $copyright = "WebCollage $version, Copyright (c) 1999-2005" .
     " Jamie Zawinski <jwz\@jwz.org>\n" .
     "            http://www.jwz.org/webcollage/\n";
@@ -400,6 +400,12 @@ sub get_document_1($$$) {
         # block this, you turkeys.
         $user_agent = "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.5)" .
           " Gecko/20041111 Firefox/1.0";
+
+        # 28-Jun-2007: Google Images now emits the entire page in JS if
+        # you claim to be Gecko.  They also still block "webcollage".
+        # They serve non-JS for unrecognised agents, so let's try this...
+        $user_agent = "NoJavascriptPlease/1.0"
+          if ($url =~ m@^http://images\.google\.com/@);
       }
 
       my $hdrs = "GET " . ($http_proxy ? $url : "/$path") . " HTTP/1.0\r\n" .
@@ -1820,7 +1826,7 @@ sub pick_from_flickr_recent($) {
     $page = html_unquote ($page);
     $thumb = html_unquote ($thumb);
 
-    next unless ($thumb =~ m@^http://photos\d*\.flickr\.com/@);
+    next unless ($thumb =~ m@^http://farm\d*\.static\.flickr\.com/@);
 
     my $base = "http://www.flickr.com/";
     $page  =~ s@^/@$base@;
@@ -2765,7 +2771,9 @@ sub x_or_pbm_output($) {
 
   # find a root-window displayer program.
   #
-  $ppm_to_root_window_cmd = pick_root_displayer();
+  if (!$no_output_p) {
+    $ppm_to_root_window_cmd = pick_root_displayer();
+  }
 
   if (defined ($window_id)) {
     error ("-window-id only works if xscreensaver-getimage is installed")
index 9f69c25d352ec67df84edf684986540fd21d51a7..b7af5b1e1ac8c4e06b71a1e540d07e73bb690cea 100644 (file)
@@ -1226,7 +1226,7 @@ hack_text (m_state *state)
                "\001disable grid nodes 21 - 48\n"
                "\n"
                "\002Warning: Disabling nodes 21-48 will disconnect sector 11"
-               " (27 nodes)\n"
+               " (28 nodes)\n"
                "\n"
                "\002         ARE YOU SURE? (y/n) "
 
index 74e747fd918c0bb8df2c7da9830eff1c20b90af6..d1d20563aa2a13a89b3c88465fe15a96fb6109da 100644 (file)
@@ -1,4 +1,4 @@
-# Auto-generated: Fri Apr 20 20:33:29 PDT 2007
+# Auto-generated: Tue Jul 17 02:03:02 PDT 2007
 driver/demo-Gtk-conf.c
 driver/demo-Gtk-support.c
 driver/demo-Gtk-widgets.c
@@ -46,6 +46,7 @@ hacks/config/crystal.xml
 hacks/config/cube21.xml
 hacks/config/cubenetic.xml
 hacks/config/cubestorm.xml
+hacks/config/cwaves.xml
 hacks/config/cynosure.xml
 hacks/config/dangerball.xml
 hacks/config/decayscreen.xml
@@ -83,6 +84,7 @@ hacks/config/galaxy.xml
 hacks/config/gears.xml
 hacks/config/gflux.xml
 hacks/config/glblur.xml
+hacks/config/glcells.xml
 hacks/config/gleidescope.xml
 hacks/config/glforestfire.xml
 hacks/config/glhanoi.xml
@@ -125,6 +127,7 @@ hacks/config/lisa.xml
 hacks/config/lissie.xml
 hacks/config/lmorph.xml
 hacks/config/loop.xml
+hacks/config/m6502.xml
 hacks/config/maze.xml
 hacks/config/memscroller.xml
 hacks/config/menger.xml
@@ -202,6 +205,7 @@ hacks/config/twang.xml
 hacks/config/vermiculate.xml
 hacks/config/vidwhacker.xml
 hacks/config/vines.xml
+hacks/config/voronoi.xml
 hacks/config/wander.xml
 hacks/config/webcollage.xml
 hacks/config/whirlwindwarp.xml
index 20664245c73dc448502389ccde1b40b2b29b6377..5c8d935af93e1c7838acecf80fc4659f776c50da 100644 (file)
--- a/setup.com
+++ b/setup.com
@@ -24,6 +24,7 @@ $ compass     :== $'mydir'compass
 $ coral                :== $'mydir'coral
 $ critical     :== $'mydir'critical
 $ crystal      :== $'mydir'crystal
+$ cwaves       :== $'mydir'cwaves
 $ cynosure     :== $'mydir'cynosure
 $ decayscreen  :== $'mydir'decayscreen
 $ deco         :== $'mydir'deco
@@ -71,6 +72,7 @@ $ lisa                :== $'mydir'lisa
 $ lissie       :== $'mydir'lissie
 $ lmorph       :== $'mydir'lmorph
 $ loop         :== $'mydir'loop
+$ m6502                :== $'mydir'm6502
 $ maze         :== $'mydir'maze
 $ memscroller  :== $'mydir'memscroller
 $ metaballs    :== $'mydir'metaballs
index e05c697abf6575d018c496a37686785a1a754dee..a6a04d3bcb94f832100e3833356afe6653a2c564 100644 (file)
@@ -1,2 +1,2 @@
 static const char screensaver_id[] =
-       "@(#)xscreensaver 5.02 (20-Apr-2007), by Jamie Zawinski (jwz@jwz.org)";
+       "@(#)xscreensaver 5.03 (17-Jul-2007), by Jamie Zawinski (jwz@jwz.org)";
index d1977d03d070541614e46bdcb66cbda5a69b89a9..282deb2052c0e1cccc37fff28af46bde9f3c1ed6 100644 (file)
@@ -1,5 +1,5 @@
 %define        name xscreensaver
-%define        version 5.02
+%define        version 5.03
 
 Summary:       X screen saver and locker
 Name:          %{name}
index aca417b87f634f6ca0bf23c67191ed617cd82c83..2bc937b9bfdb6f04534db2545843f078a91c34e1 100644 (file)
@@ -33,6 +33,7 @@
                                AF77797309B6604B00EA3033 /* PBXTargetDependency */,
                                AF77797109B6604B00EA3033 /* PBXTargetDependency */,
                                AF77796F09B6604A00EA3033 /* PBXTargetDependency */,
+                               AFF463530C44062500EE6509 /* PBXTargetDependency */,
                                AF77796D09B6604A00EA3033 /* PBXTargetDependency */,
                                AF77796B09B6604A00EA3033 /* PBXTargetDependency */,
                                AF77796909B6604A00EA3033 /* PBXTargetDependency */,
@@ -61,6 +62,7 @@
                                AF77793B09B6604900EA3033 /* PBXTargetDependency */,
                                AF77793909B6604800EA3033 /* PBXTargetDependency */,
                                AF77793709B6604800EA3033 /* PBXTargetDependency */,
+                               AF0DCA310C4C744D00D76972 /* PBXTargetDependency */,
                                AF77793509B6604800EA3033 /* PBXTargetDependency */,
                                AF77793309B6604800EA3033 /* PBXTargetDependency */,
                                AF77793109B6604800EA3033 /* PBXTargetDependency */,
                                AF777A2D09B660B400EA3033 /* PBXTargetDependency */,
                                AF777A2B09B660B400EA3033 /* PBXTargetDependency */,
                                AF777A2909B660B400EA3033 /* PBXTargetDependency */,
+                               AFF4636F0C440B3B00EE6509 /* PBXTargetDependency */,
                                AF777A2709B660B400EA3033 /* PBXTargetDependency */,
                                AF777A2509B660B400EA3033 /* PBXTargetDependency */,
                                AF777A2309B660B400EA3033 /* PBXTargetDependency */,
                                AF7779DF09B660AF00EA3033 /* PBXTargetDependency */,
                                AF7779DD09B660AF00EA3033 /* PBXTargetDependency */,
                                AF998EF70A083E1D0051049D /* PBXTargetDependency */,
+                               AF0DCA5C0C4CBB4300D76972 /* PBXTargetDependency */,
                        );
                        name = "All Savers (OpenGL)";
                        productName = "All Savers (OpenGL)";
                AF083A4A099311FF00277BE9 /* atunnel.c in Sources */ = {isa = PBXBuildFile; fileRef = AF083A31099311CE00277BE9 /* atunnel.c */; };
                AF083A4B0993120900277BE9 /* atunnel.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC258720988A468000655EE /* atunnel.xml */; };
                AF083A59099312B000277BE9 /* tunnel_draw.c in Sources */ = {isa = PBXBuildFile; fileRef = AF083A58099312B000277BE9 /* tunnel_draw.c */; };
+               AF0DC7B10C4C73F600D76972 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
+               AF0DC7B20C4C73F600D76972 /* analogtv.c in Sources */ = {isa = PBXBuildFile; fileRef = AF9D4CFA09B5AC94006E59CF /* analogtv.c */; };
+               AF0DC7B50C4C73F600D76972 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
+               AF0DC7B60C4C73F600D76972 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
+               AF0DC7B70C4C73F600D76972 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+               AF0DCA350C4C74A200D76972 /* asm6502.c in Sources */ = {isa = PBXBuildFile; fileRef = AF0DCA320C4C74A200D76972 /* asm6502.c */; };
+               AF0DCA360C4C74A200D76972 /* m6502.c in Sources */ = {isa = PBXBuildFile; fileRef = AF0DCA340C4C74A200D76972 /* m6502.c */; };
+               AF0DCA380C4C74B700D76972 /* m6502.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF0DCA370C4C74B700D76972 /* m6502.xml */; };
+               AF0DCA480C4CBB0D00D76972 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
+               AF0DCA4B0C4CBB0D00D76972 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
+               AF0DCA4C0C4CBB0D00D76972 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
+               AF0DCA4D0C4CBB0D00D76972 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+               AF0DCA4E0C4CBB0D00D76972 /* AGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF480FE70990375900FB32B8 /* AGL.framework */; };
+               AF0DCA4F0C4CBB0D00D76972 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF480DF1098F528500FB32B8 /* OpenGL.framework */; };
+               AF0DCA500C4CBB0D00D76972 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF48112B0990A2C700FB32B8 /* Carbon.framework */; };
+               AF0DCA600C4CBB7300D76972 /* voronoi.c in Sources */ = {isa = PBXBuildFile; fileRef = AF0DCA5F0C4CBB7300D76972 /* voronoi.c */; };
+               AF0DCA620C4CBB8E00D76972 /* voronoi.xml in Resources */ = {isa = PBXBuildFile; fileRef = AF0DCA610C4CBB8E00D76972 /* voronoi.xml */; };
                AF0FAF0C09CA6FF900EE1051 /* xscreensaver-text in Resources */ = {isa = PBXBuildFile; fileRef = AF0FAF0B09CA6FF900EE1051 /* xscreensaver-text */; };
                AF0FAF0D09CA6FF900EE1051 /* xscreensaver-text in Resources */ = {isa = PBXBuildFile; fileRef = AF0FAF0B09CA6FF900EE1051 /* xscreensaver-text */; };
                AF0FAF0E09CA6FF900EE1051 /* xscreensaver-text in Resources */ = {isa = PBXBuildFile; fileRef = AF0FAF0B09CA6FF900EE1051 /* xscreensaver-text */; };
                AFD573680997411200BA26F7 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
                AFD573700997418D00BA26F7 /* strange.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFC2591D0988A469000655EE /* strange.xml */; };
                AFD57372099741A200BA26F7 /* strange.c in Sources */ = {isa = PBXBuildFile; fileRef = AFD57371099741A200BA26F7 /* strange.c */; };
+               AFF4633C0C4403E400EE6509 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
+               AFF4633F0C4403E400EE6509 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
+               AFF463400C4403E400EE6509 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
+               AFF463410C4403E400EE6509 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+               AFF4634A0C44044F00EE6509 /* cwaves.c in Sources */ = {isa = PBXBuildFile; fileRef = AFF463490C44044E00EE6509 /* cwaves.c */; };
+               AFF4634C0C44046500EE6509 /* cwaves.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFF4634B0C44046500EE6509 /* cwaves.xml */; };
+               AFF4635F0C440AEF00EE6509 /* XScreenSaverSubclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AF9CC7A0099580E70075E99B /* XScreenSaverSubclass.m */; };
+               AFF463610C440AEF00EE6509 /* libjwxyz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF4808C1098C3B6C00FB32B8 /* libjwxyz.a */; };
+               AFF463620C440AEF00EE6509 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF976ED30989BF59001F8B92 /* ScreenSaver.framework */; };
+               AFF463630C440AEF00EE6509 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+               AFF463640C440AEF00EE6509 /* AGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF480FE70990375900FB32B8 /* AGL.framework */; };
+               AFF463650C440AEF00EE6509 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF480DF1098F528500FB32B8 /* OpenGL.framework */; };
+               AFF463660C440AEF00EE6509 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF48112B0990A2C700FB32B8 /* Carbon.framework */; };
+               AFF463720C440B9200EE6509 /* glcells.c in Sources */ = {isa = PBXBuildFile; fileRef = AFF463710C440B9200EE6509 /* glcells.c */; };
+               AFF463740C440BAC00EE6509 /* glcells.xml in Resources */ = {isa = PBXBuildFile; fileRef = AFF463730C440BAC00EE6509 /* glcells.xml */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXBuildStyle section */
                        remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
                        remoteInfo = jwxyz;
                };
+               AF0DC7AD0C4C73F600D76972 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
+                       remoteInfo = jwxyz;
+               };
+               AF0DCA300C4C744D00D76972 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AF0DC7AB0C4C73F600D76972 /* m6502 */;
+                       remoteInfo = m6502;
+               };
+               AF0DCA440C4CBB0D00D76972 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
+                       remoteInfo = jwxyz;
+               };
+               AF0DCA5B0C4CBB4300D76972 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AF0DCA420C4CBB0D00D76972 /* Voronoi */;
+                       remoteInfo = Voronoi;
+               };
                AF476FB7099D154F001F091E /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
                        remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
                        remoteInfo = jwxyz;
                };
+               AFF463380C4403E400EE6509 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
+                       remoteInfo = jwxyz;
+               };
+               AFF463520C44062500EE6509 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AFF463360C4403E400EE6509;
+                       remoteInfo = CWaves;
+               };
+               AFF4635A0C440AEF00EE6509 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AF4808C0098C3B6C00FB32B8;
+                       remoteInfo = jwxyz;
+               };
+               AFF4636E0C440B3B00EE6509 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = AFF463580C440AEF00EE6509;
+                       remoteInfo = GLCells;
+               };
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXFileReference section */
                AF083A48099311D700277BE9 /* Atunnel.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Atunnel.saver; sourceTree = BUILT_PRODUCTS_DIR; };
                AF083A58099312B000277BE9 /* tunnel_draw.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = tunnel_draw.c; path = hacks/glx/tunnel_draw.c; sourceTree = "<group>"; };
                AF083A5D099312DB00277BE9 /* tunnel_draw.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = tunnel_draw.h; path = hacks/glx/tunnel_draw.h; sourceTree = "<group>"; };
+               AF0DC7BD0C4C73F600D76972 /* m6502.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = m6502.saver; sourceTree = BUILT_PRODUCTS_DIR; };
+               AF0DC7C70C4C73F700D76972 /* XScreenSaver copy.plist */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = "XScreenSaver copy.plist"; path = "OSX/XScreenSaver copy.plist"; sourceTree = "<group>"; };
+               AF0DCA320C4C74A200D76972 /* asm6502.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = asm6502.c; path = hacks/asm6502.c; sourceTree = "<group>"; };
+               AF0DCA330C4C74A200D76972 /* asm6502.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = asm6502.h; path = hacks/asm6502.h; sourceTree = "<group>"; };
+               AF0DCA340C4C74A200D76972 /* m6502.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = m6502.c; path = hacks/m6502.c; sourceTree = "<group>"; };
+               AF0DCA370C4C74B700D76972 /* m6502.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = m6502.xml; sourceTree = "<group>"; };
+               AF0DCA560C4CBB0D00D76972 /* Voronoi.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Voronoi.saver; sourceTree = BUILT_PRODUCTS_DIR; };
+               AF0DCA570C4CBB0E00D76972 /* XScreenSaver copy.plist */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = "XScreenSaver copy.plist"; path = "OSX/XScreenSaver copy.plist"; sourceTree = "<group>"; };
+               AF0DCA5F0C4CBB7300D76972 /* voronoi.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = voronoi.c; path = hacks/glx/voronoi.c; sourceTree = "<group>"; };
+               AF0DCA610C4CBB8E00D76972 /* voronoi.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = voronoi.xml; sourceTree = "<group>"; };
                AF0FAF0B09CA6FF900EE1051 /* xscreensaver-text */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.perl; name = "xscreensaver-text"; path = "driver/xscreensaver-text"; sourceTree = "<group>"; };
                AF0FAF1209CA712600EE1051 /* xscreensaver-getimage-file */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.perl; name = "xscreensaver-getimage-file"; path = "driver/xscreensaver-getimage-file"; sourceTree = "<group>"; };
                AF34085409B80AAF00F2CEC1 /* StarWars.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StarWars.saver; sourceTree = BUILT_PRODUCTS_DIR; };
                AFC259150988A469000655EE /* spotlight.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = spotlight.xml; sourceTree = "<group>"; };
                AFC259160988A469000655EE /* sproingies.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = sproingies.xml; sourceTree = "<group>"; };
                AFC259170988A469000655EE /* squiral.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = squiral.xml; sourceTree = "<group>"; };
-               AFC259180988A469000655EE /* ssystem.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = ssystem.xml; sourceTree = "<group>"; };
                AFC259190988A469000655EE /* stairs.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = stairs.xml; sourceTree = "<group>"; };
                AFC2591A0988A469000655EE /* starfish.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = starfish.xml; sourceTree = "<group>"; };
                AFC2591B0988A469000655EE /* starwars.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = starwars.xml; sourceTree = "<group>"; };
                AFE1FD5B0981E3CB00F7970E /* yarandom.c */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.c; name = yarandom.c; path = utils/yarandom.c; sourceTree = "<group>"; };
                AFE1FD5C0981E3CB00F7970E /* yarandom.h */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.h; name = yarandom.h; path = utils/yarandom.h; sourceTree = "<group>"; };
                AFE1FD620981E40800F7970E /* rorschach.c */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.c; name = rorschach.c; path = hacks/rorschach.c; sourceTree = "<group>"; };
+               AFF463470C4403E400EE6509 /* CWaves.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CWaves.saver; sourceTree = BUILT_PRODUCTS_DIR; };
+               AFF463480C4403E500EE6509 /* XScreenSaver copy.plist */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = "XScreenSaver copy.plist"; path = "OSX/XScreenSaver copy.plist"; sourceTree = "<group>"; };
+               AFF463490C44044E00EE6509 /* cwaves.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = cwaves.c; path = hacks/cwaves.c; sourceTree = "<group>"; };
+               AFF4634B0C44046500EE6509 /* cwaves.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = cwaves.xml; sourceTree = "<group>"; };
+               AFF4636C0C440AEF00EE6509 /* GLCells.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GLCells.saver; sourceTree = BUILT_PRODUCTS_DIR; };
+               AFF4636D0C440AF000EE6509 /* XScreenSaver copy.plist */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = "XScreenSaver copy.plist"; path = "OSX/XScreenSaver copy.plist"; sourceTree = "<group>"; };
+               AFF463710C440B9200EE6509 /* glcells.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = glcells.c; path = hacks/glx/glcells.c; sourceTree = "<group>"; };
+               AFF463730C440BAC00EE6509 /* glcells.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = glcells.xml; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AF0DC7B40C4C73F600D76972 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AF0DC7B50C4C73F600D76972 /* libjwxyz.a in Frameworks */,
+                               AF0DC7B60C4C73F600D76972 /* ScreenSaver.framework in Frameworks */,
+                               AF0DC7B70C4C73F600D76972 /* Cocoa.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               AF0DCA4A0C4CBB0D00D76972 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AF0DCA4B0C4CBB0D00D76972 /* libjwxyz.a in Frameworks */,
+                               AF0DCA4C0C4CBB0D00D76972 /* ScreenSaver.framework in Frameworks */,
+                               AF0DCA4D0C4CBB0D00D76972 /* Cocoa.framework in Frameworks */,
+                               AF0DCA4E0C4CBB0D00D76972 /* AGL.framework in Frameworks */,
+                               AF0DCA4F0C4CBB0D00D76972 /* OpenGL.framework in Frameworks */,
+                               AF0DCA500C4CBB0D00D76972 /* Carbon.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AF476FBE099D154F001F091E /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AFF4633E0C4403E400EE6509 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AFF4633F0C4403E400EE6509 /* libjwxyz.a in Frameworks */,
+                               AFF463400C4403E400EE6509 /* ScreenSaver.framework in Frameworks */,
+                               AFF463410C4403E400EE6509 /* Cocoa.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               AFF463600C440AEF00EE6509 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AFF463610C440AEF00EE6509 /* libjwxyz.a in Frameworks */,
+                               AFF463620C440AEF00EE6509 /* ScreenSaver.framework in Frameworks */,
+                               AFF463630C440AEF00EE6509 /* Cocoa.framework in Frameworks */,
+                               AFF463640C440AEF00EE6509 /* AGL.framework in Frameworks */,
+                               AFF463650C440AEF00EE6509 /* OpenGL.framework in Frameworks */,
+                               AFF463660C440AEF00EE6509 /* Carbon.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
                                AF48DF030A0C25E000F94CF9 /* GLSchool.saver */,
                                AFA339400B058505002B0E7D /* WebCollage.saver */,
                                AFA33BC70B058740002B0E7D /* webcollage-helper */,
+                               AFF463470C4403E400EE6509 /* CWaves.saver */,
+                               AFF4636C0C440AEF00EE6509 /* GLCells.saver */,
+                               AF0DC7BD0C4C73F600D76972 /* m6502.saver */,
+                               AF0DCA560C4CBB0D00D76972 /* Voronoi.saver */,
                        );
                        name = Products;
                        sourceTree = "<group>";
                                8D1107310486CEB800E47090 /* XScreenSaver.plist */,
                                AF0FAF1209CA712600EE1051 /* xscreensaver-getimage-file */,
                                AF0FAF0B09CA6FF900EE1051 /* xscreensaver-text */,
+                               AFF463480C4403E500EE6509 /* XScreenSaver copy.plist */,
+                               AFF4636D0C440AF000EE6509 /* XScreenSaver copy.plist */,
+                               AF0DC7C70C4C73F700D76972 /* XScreenSaver copy.plist */,
+                               AF0DCA570C4CBB0E00D76972 /* XScreenSaver copy.plist */,
                        );
                        name = Resources;
                        sourceTree = "<group>";
                                AF9D4CFA09B5AC94006E59CF /* analogtv.c */,
                                AF9D4CFB09B5AC94006E59CF /* analogtv.h */,
                                AF9D4CFC09B5AC94006E59CF /* pong.c */,
+                               AF0DCA320C4C74A200D76972 /* asm6502.c */,
+                               AF0DCA330C4C74A200D76972 /* asm6502.h */,
+                               AF0DCA340C4C74A200D76972 /* m6502.c */,
                                AF47766D099DA80D001F091E /* critical.c */,
                                AF477657099DA75D001F091E /* squiral.c */,
                                AF47762A099DA2E9001F091E /* kumppa.c */,
                                AF47721B099D4F47001F091E /* whirlygig.c */,
                                AF477205099D4EB6001F091E /* nerverot.c */,
                                AF4771EF099D4DFE001F091E /* ccurve.c */,
+                               AFF463490C44044E00EE6509 /* cwaves.c */,
                                AF64270709A1C9EF000F4CD4 /* sonar.c */,
                                AF4771BA099D4997001F091E /* t3d.c */,
                                AF477192099D4864001F091E /* wander.c */,
                                AFA563B90993991300F3E977 /* juggler3d.c */,
                                AFA5638E0993980D00F3E977 /* timetunnel.c */,
                                AF998EF80A083E750051049D /* topblock.c */,
+                               AF0DCA5F0C4CBB7300D76972 /* voronoi.c */,
                                AFA563660993970F00F3E977 /* cube21.c */,
                                AFA563460993963400F3E977 /* glhanoi.c */,
                                AF77778B09B64A2A00EA3033 /* gleidescope.c */,
                                AFA55EAB0993608800F3E977 /* toaster.c */,
                                AFA55EAC0993608800F3E977 /* toaster.dxf */,
                                AFA55E4509935FD300F3E977 /* glblur.c */,
+                               AFF463710C440B9200EE6509 /* glcells.c */,
                                AFA55E2209935F2B00F3E977 /* chessgames.h */,
                                AFA55E2309935F2B00F3E977 /* chessmodels.c */,
                                AFA55E2409935F2B00F3E977 /* chessmodels.h */,
                                AFC258820988A468000655EE /* cage.xml */,
                                AFC258830988A468000655EE /* carousel.xml */,
                                AFC258840988A468000655EE /* ccurve.xml */,
+                               AFF4634B0C44046500EE6509 /* cwaves.xml */,
                                AFC258850988A468000655EE /* celtic.xml */,
                                AFC258860988A468000655EE /* circuit.xml */,
                                AFC258870988A468000655EE /* cloudlife.xml */,
                                AFC258B20988A468000655EE /* gears.xml */,
                                AFC258B30988A468000655EE /* gflux.xml */,
                                AFC258B40988A468000655EE /* glblur.xml */,
+                               AFF463730C440BAC00EE6509 /* glcells.xml */,
                                AFC258B50988A468000655EE /* gleidescope.xml */,
                                AFC258B60988A468000655EE /* glforestfire.xml */,
                                AFC258B70988A468000655EE /* glhanoi.xml */,
                                AFC258F80988A469000655EE /* polyominoes.xml */,
                                AFC258F90988A469000655EE /* polytopes.xml */,
                                AFC258FA0988A469000655EE /* pong.xml */,
+                               AF0DCA370C4C74B700D76972 /* m6502.xml */,
                                AFC258FB0988A469000655EE /* popsquares.xml */,
                                AFC258FC0988A469000655EE /* providence.xml */,
                                AFC258FD0988A469000655EE /* pulsar.xml */,
                                AFC259150988A469000655EE /* spotlight.xml */,
                                AFC259160988A469000655EE /* sproingies.xml */,
                                AFC259170988A469000655EE /* squiral.xml */,
-                               AFC259180988A469000655EE /* ssystem.xml */,
                                AFC259190988A469000655EE /* stairs.xml */,
                                AFC2591A0988A469000655EE /* starfish.xml */,
                                AFC2591B0988A469000655EE /* starwars.xml */,
                                AFC259220988A469000655EE /* tangram.xml */,
                                AFC259230988A469000655EE /* thornbird.xml */,
                                AFC259240988A469000655EE /* timetunnel.xml */,
+                               AF0DCA610C4CBB8E00D76972 /* voronoi.xml */,
                                AFC259250988A469000655EE /* triangle.xml */,
                                AFC259260988A469000655EE /* truchet.xml */,
                                AFC259270988A469000655EE /* twang.xml */,
        <string>yes</string>
 </dict>
 </plist>
+";
+                       productType = "com.apple.product-type.bundle";
+               };
+               AF0DC7AB0C4C73F600D76972 /* m6502 */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = AF0DC7BA0C4C73F600D76972 /* Build configuration list for PBXNativeTarget "m6502" */;
+                       buildPhases = (
+                               AF0DC7AE0C4C73F600D76972 /* Resources */,
+                               AF0DC7B00C4C73F600D76972 /* Sources */,
+                               AF0DC7B40C4C73F600D76972 /* Frameworks */,
+                               AF0DC7B80C4C73F600D76972 /* Rez */,
+                               AF0DC7B90C4C73F600D76972 /* ShellScript */,
+                       );
+                       buildRules = (
+                       );
+                       buildSettings = {
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_PRECOMPILE_PREFIX_HEADER = YES;
+                               GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h";
+                               INFOPLIST_FILE = "Deco-Info.plist";
+                               INSTALL_PATH = "$(HOME)/Library/Bundles";
+                               OTHER_LDFLAGS = (
+                                       "-framework",
+                                       Carbon,
+                               );
+                               PREBINDING = NO;
+                               PRODUCT_NAME = Deco;
+                               WRAPPER_EXTENSION = bundle;
+                               ZERO_LINK = YES;
+                       };
+                       dependencies = (
+                               AF0DC7AC0C4C73F600D76972 /* PBXTargetDependency */,
+                       );
+                       name = m6502;
+                       productName = Pong;
+                       productReference = AF0DC7BD0C4C73F600D76972 /* m6502.saver */;
+                       productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
+<plist version=\"1.0\">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleExecutable</key>
+       <string>Deco</string>
+       <key>CFBundleIdentifier</key>
+       <string>com.yourcompany.Deco</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundlePackageType</key>
+       <string>BNDL</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1.0</string>
+       <key>CSResourcesFileMapped</key>
+       <string>yes</string>
+</dict>
+</plist>
+";
+                       productType = "com.apple.product-type.bundle";
+               };
+               AF0DCA420C4CBB0D00D76972 /* Voronoi */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = AF0DCA530C4CBB0D00D76972 /* Build configuration list for PBXNativeTarget "Voronoi" */;
+                       buildPhases = (
+                               AF0DCA450C4CBB0D00D76972 /* Resources */,
+                               AF0DCA470C4CBB0D00D76972 /* Sources */,
+                               AF0DCA4A0C4CBB0D00D76972 /* Frameworks */,
+                               AF0DCA510C4CBB0D00D76972 /* Rez */,
+                               AF0DCA520C4CBB0D00D76972 /* ShellScript */,
+                       );
+                       buildRules = (
+                       );
+                       buildSettings = {
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_PRECOMPILE_PREFIX_HEADER = YES;
+                               GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h";
+                               INFOPLIST_FILE = "Deco-Info.plist";
+                               INSTALL_PATH = "$(HOME)/Library/Bundles";
+                               OTHER_LDFLAGS = (
+                                       "-framework",
+                                       Carbon,
+                               );
+                               PREBINDING = NO;
+                               PRODUCT_NAME = Deco;
+                               WRAPPER_EXTENSION = bundle;
+                               ZERO_LINK = YES;
+                       };
+                       dependencies = (
+                               AF0DCA430C4CBB0D00D76972 /* PBXTargetDependency */,
+                       );
+                       name = Voronoi;
+                       productName = TopBlock;
+                       productReference = AF0DCA560C4CBB0D00D76972 /* Voronoi.saver */;
+                       productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
+<plist version=\"1.0\">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleExecutable</key>
+       <string>Deco</string>
+       <key>CFBundleIdentifier</key>
+       <string>com.yourcompany.Deco</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundlePackageType</key>
+       <string>BNDL</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1.0</string>
+       <key>CSResourcesFileMapped</key>
+       <string>yes</string>
+</dict>
+</plist>
 ";
                        productType = "com.apple.product-type.bundle";
                };
        <string>yes</string>
 </dict>
 </plist>
+";
+                       productType = "com.apple.product-type.bundle";
+               };
+               AFF463360C4403E400EE6509 /* CWaves */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = AFF463440C4403E400EE6509 /* Build configuration list for PBXNativeTarget "CWaves" */;
+                       buildPhases = (
+                               AFF463390C4403E400EE6509 /* Resources */,
+                               AFF4633B0C4403E400EE6509 /* Sources */,
+                               AFF4633E0C4403E400EE6509 /* Frameworks */,
+                               AFF463420C4403E400EE6509 /* Rez */,
+                               AFF463430C4403E400EE6509 /* ShellScript */,
+                       );
+                       buildRules = (
+                       );
+                       buildSettings = {
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_PRECOMPILE_PREFIX_HEADER = YES;
+                               GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h";
+                               INFOPLIST_FILE = "Deco-Info.plist";
+                               INSTALL_PATH = "$(HOME)/Library/Bundles";
+                               OTHER_LDFLAGS = (
+                                       "-framework",
+                                       Carbon,
+                               );
+                               PREBINDING = NO;
+                               PRODUCT_NAME = Deco;
+                               WRAPPER_EXTENSION = bundle;
+                               ZERO_LINK = YES;
+                       };
+                       dependencies = (
+                               AFF463370C4403E400EE6509 /* PBXTargetDependency */,
+                       );
+                       name = CWaves;
+                       productName = CCurve;
+                       productReference = AFF463470C4403E400EE6509 /* CWaves.saver */;
+                       productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
+<plist version=\"1.0\">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleExecutable</key>
+       <string>Deco</string>
+       <key>CFBundleIdentifier</key>
+       <string>com.yourcompany.Deco</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundlePackageType</key>
+       <string>BNDL</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1.0</string>
+       <key>CSResourcesFileMapped</key>
+       <string>yes</string>
+</dict>
+</plist>
+";
+                       productType = "com.apple.product-type.bundle";
+               };
+               AFF463580C440AEF00EE6509 /* GLCells */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = AFF463690C440AEF00EE6509 /* Build configuration list for PBXNativeTarget "GLCells" */;
+                       buildPhases = (
+                               AFF4635B0C440AEF00EE6509 /* Resources */,
+                               AFF4635D0C440AEF00EE6509 /* Sources */,
+                               AFF463600C440AEF00EE6509 /* Frameworks */,
+                               AFF463670C440AEF00EE6509 /* Rez */,
+                               AFF463680C440AEF00EE6509 /* ShellScript */,
+                       );
+                       buildRules = (
+                       );
+                       buildSettings = {
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_PRECOMPILE_PREFIX_HEADER = YES;
+                               GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h";
+                               INFOPLIST_FILE = "Deco-Info.plist";
+                               INSTALL_PATH = "$(HOME)/Library/Bundles";
+                               OTHER_LDFLAGS = (
+                                       "-framework",
+                                       Carbon,
+                               );
+                               PREBINDING = NO;
+                               PRODUCT_NAME = Deco;
+                               WRAPPER_EXTENSION = bundle;
+                               ZERO_LINK = YES;
+                       };
+                       dependencies = (
+                               AFF463590C440AEF00EE6509 /* PBXTargetDependency */,
+                       );
+                       name = GLCells;
+                       productName = GLBlur;
+                       productReference = AFF4636C0C440AEF00EE6509 /* GLCells.saver */;
+                       productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
+<plist version=\"1.0\">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleExecutable</key>
+       <string>Deco</string>
+       <key>CFBundleIdentifier</key>
+       <string>com.yourcompany.Deco</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundlePackageType</key>
+       <string>BNDL</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1.0</string>
+       <key>CSResourcesFileMapped</key>
+       <string>yes</string>
+</dict>
+</plist>
 ";
                        productType = "com.apple.product-type.bundle";
                };
                                AF477169099D4786001F091E /* Compass */,
                                AF4775D8099D9F69001F091E /* Coral */,
                                AF47765A099DA78E001F091E /* Critical */,
+                               AFF463360C4403E400EE6509 /* CWaves */,
                                AF4778E8099DDDC8001F091E /* Cynosure */,
                                AF9D466609B5109C006E59CF /* DecayScreen */,
                                AF976FBB0989CAA2001F8B92 /* Deco */,
                                AF477499099D8A74001F091E /* Kaleidescope */,
                                AF477613099DA26C001F091E /* Kumppa */,
                                AF4774B4099D8B5F001F091E /* LMorph */,
+                               AF0DC7AB0C4C73F600D76972 /* m6502 */,
                                AF4774CE099D8BFF001F091E /* Maze */,
                                AF975AFC099C6FE400B05160 /* MemScroller */,
                                AF975A36099C681F00B05160 /* MetaBalls */,
                                AF77777409B6497800EA3033 /* Gleidescope */,
                                AFA55B9109933FDA00F3E977 /* GFlux */,
                                AFA55E2F09935F8E00F3E977 /* GLBlur */,
+                               AFF463580C440AEF00EE6509 /* GLCells */,
                                AFA55CCC09934CE400F3E977 /* GLForestFire */,
                                AFA56331099395ED00F3E977 /* GLHanoi */,
                                AFA55FF909936C6D00F3E977 /* GLKnots */,
                                AFA562F20993943B00F3E977 /* Tangram */,
                                AFA56379099397B300F3E977 /* TimeTunnel */,
                                AF998EDA0A083DB30051049D /* TopBlock */,
+                               AF0DCA420C4CBB0D00D76972 /* Voronoi */,
                                AF9771D60989DC4A001F8B92 /* SaverTester */,
                        );
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AF0DC7AE0C4C73F600D76972 /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AF0DCA380C4C74B700D76972 /* m6502.xml in Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               AF0DCA450C4CBB0D00D76972 /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AF0DCA620C4CBB8E00D76972 /* voronoi.xml in Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AF476FB8099D154F001F091E /* Resources */ = {
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AFF463390C4403E400EE6509 /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AFF4634C0C44046500EE6509 /* cwaves.xml in Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               AFF4635B0C440AEF00EE6509 /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AFF463740C440BAC00EE6509 /* glcells.xml in Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
 /* End PBXResourcesBuildPhase section */
 
 /* Begin PBXRezBuildPhase section */
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AF0DC7B80C4C73F600D76972 /* Rez */ = {
+                       isa = PBXRezBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               AF0DCA510C4CBB0D00D76972 /* Rez */ = {
+                       isa = PBXRezBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AF476FC2099D154F001F091E /* Rez */ = {
                        isa = PBXRezBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AFF463420C4403E400EE6509 /* Rez */ = {
+                       isa = PBXRezBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               AFF463670C440AEF00EE6509 /* Rez */ = {
+                       isa = PBXRezBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
 /* End PBXRezBuildPhase section */
 
 /* Begin PBXShellScriptBuildPhase section */
+               AF0DC7B90C4C73F600D76972 /* ShellScript */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "$SOURCE_ROOT/OSX/update-info-plist.pl $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
+               };
+               AF0DCA520C4CBB0D00D76972 /* ShellScript */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "$SOURCE_ROOT/OSX/update-info-plist.pl $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
+               };
                AF48DEFF0A0C25E000F94CF9 /* ShellScript */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
                        shellPath = /bin/sh;
                        shellScript = "$SOURCE_ROOT/OSX/update-info-plist.pl $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
                };
+               AFF463430C4403E400EE6509 /* ShellScript */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "$SOURCE_ROOT/OSX/update-info-plist.pl $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
+               };
+               AFF463680C440AEF00EE6509 /* ShellScript */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "$SOURCE_ROOT/OSX/update-info-plist.pl $BUILT_PRODUCTS_DIR/$PRODUCT_NAME$WRAPPER_SUFFIX";
+               };
 /* End PBXShellScriptBuildPhase section */
 
 /* Begin PBXSourcesBuildPhase section */
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AF0DC7B00C4C73F600D76972 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AF0DC7B10C4C73F600D76972 /* XScreenSaverSubclass.m in Sources */,
+                               AF0DC7B20C4C73F600D76972 /* analogtv.c in Sources */,
+                               AF0DCA350C4C74A200D76972 /* asm6502.c in Sources */,
+                               AF0DCA360C4C74A200D76972 /* m6502.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               AF0DCA470C4CBB0D00D76972 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AF0DCA480C4CBB0D00D76972 /* XScreenSaverSubclass.m in Sources */,
+                               AF0DCA600C4CBB7300D76972 /* voronoi.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                AF476FBB099D154F001F091E /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               AFF4633B0C4403E400EE6509 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AFF4633C0C4403E400EE6509 /* XScreenSaverSubclass.m in Sources */,
+                               AFF4634A0C44044F00EE6509 /* cwaves.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               AFF4635D0C440AEF00EE6509 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               AFF4635F0C440AEF00EE6509 /* XScreenSaverSubclass.m in Sources */,
+                               AFF463720C440B9200EE6509 /* glcells.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
 /* End PBXSourcesBuildPhase section */
 
 /* Begin PBXTargetDependency section */
                        target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
                        targetProxy = AF083A34099311D700277BE9 /* PBXContainerItemProxy */;
                };
+               AF0DC7AC0C4C73F600D76972 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
+                       targetProxy = AF0DC7AD0C4C73F600D76972 /* PBXContainerItemProxy */;
+               };
+               AF0DCA310C4C744D00D76972 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AF0DC7AB0C4C73F600D76972 /* m6502 */;
+                       targetProxy = AF0DCA300C4C744D00D76972 /* PBXContainerItemProxy */;
+               };
+               AF0DCA430C4CBB0D00D76972 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
+                       targetProxy = AF0DCA440C4CBB0D00D76972 /* PBXContainerItemProxy */;
+               };
+               AF0DCA5C0C4CBB4300D76972 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AF0DCA420C4CBB0D00D76972 /* Voronoi */;
+                       targetProxy = AF0DCA5B0C4CBB4300D76972 /* PBXContainerItemProxy */;
+               };
                AF476FB6099D154F001F091E /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
                        target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
                        targetProxy = AFD5735F0997411200BA26F7 /* PBXContainerItemProxy */;
                };
+               AFF463370C4403E400EE6509 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
+                       targetProxy = AFF463380C4403E400EE6509 /* PBXContainerItemProxy */;
+               };
+               AFF463530C44062500EE6509 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AFF463360C4403E400EE6509 /* CWaves */;
+                       targetProxy = AFF463520C44062500EE6509 /* PBXContainerItemProxy */;
+               };
+               AFF463590C440AEF00EE6509 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AF4808C0098C3B6C00FB32B8 /* jwxyz */;
+                       targetProxy = AFF4635A0C440AEF00EE6509 /* PBXContainerItemProxy */;
+               };
+               AFF4636F0C440B3B00EE6509 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = AFF463580C440AEF00EE6509 /* GLCells */;
+                       targetProxy = AFF4636E0C440B3B00EE6509 /* PBXContainerItemProxy */;
+               };
 /* End PBXTargetDependency section */
 
 /* Begin PBXVariantGroup section */
                        };
                        name = Release;
                };
+               AF0DC7BB0C4C73F600D76972 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                       };
+                       name = Debug;
+               };
+               AF0DC7BC0C4C73F600D76972 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                       };
+                       name = Release;
+               };
+               AF0DCA540C4CBB0D00D76972 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+                                       "USE_GL=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+                               );
+                       };
+                       name = Debug;
+               };
+               AF0DCA550C4CBB0D00D76972 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+                                       "USE_GL=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+                               );
+                       };
+                       name = Release;
+               };
                AF476FC4099D154F001F091E /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        };
                        name = Release;
                };
+               AFF463450C4403E400EE6509 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                       };
+                       name = Debug;
+               };
+               AFF463460C4403E400EE6509 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                       };
+                       name = Release;
+               };
+               AFF4636A0C440AEF00EE6509 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+                                       "USE_GL=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+                               );
+                       };
+                       name = Debug;
+               };
+               AFF4636B0C440AEF00EE6509 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+                                       "USE_GL=1",
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)",
+                               );
+                       };
+                       name = Release;
+               };
                C01FCF4F08A954540054247B /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
+               AF0DC7BA0C4C73F600D76972 /* Build configuration list for PBXNativeTarget "m6502" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               AF0DC7BB0C4C73F600D76972 /* Debug */,
+                               AF0DC7BC0C4C73F600D76972 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               AF0DCA530C4CBB0D00D76972 /* Build configuration list for PBXNativeTarget "Voronoi" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               AF0DCA540C4CBB0D00D76972 /* Debug */,
+                               AF0DCA550C4CBB0D00D76972 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
                AF476FC3099D154F001F091E /* Build configuration list for PBXNativeTarget "Interference" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
+               AFF463440C4403E400EE6509 /* Build configuration list for PBXNativeTarget "CWaves" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               AFF463450C4403E400EE6509 /* Debug */,
+                               AFF463460C4403E400EE6509 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               AFF463690C440AEF00EE6509 /* Build configuration list for PBXNativeTarget "GLCells" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               AFF4636A0C440AEF00EE6509 /* Debug */,
+                               AFF4636B0C440AEF00EE6509 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
                C01FCF4E08A954540054247B /* Build configuration list for PBXProject "xscreensaver" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (