From c8c6deae79b408cffbc88043c766b3bc12cf0f13 Mon Sep 17 00:00:00 2001 From: Zygo Blaxell Date: Mon, 2 Mar 2009 00:43:46 -0500 Subject: [PATCH] http://nanonyme.dy.fi/mirrors/hvl/distfiles/xscreensaver/xscreensaver-5.03.tar.gz -rw-r--r-- 1 zblaxell zblaxell 5412089 Mar 1 04:09 xscreensaver-5.03.tar.gz e283a52faf6148273a82a9e5c9ed70c5722cdcb8 xscreensaver-5.03.tar.gz --- OSX/SaverTester.plist | 4 +- OSX/XScreenSaver.plist | 4 +- OSX/bindist.rtf | 2 +- README | 5 + configure | 2 +- configure.in | 2 +- driver/Makefile.in | 2 - driver/XScreenSaver.ad.in | 9 +- driver/XScreenSaver_ad.h | 5 + driver/lock.c | 4 +- driver/xscreensaver-getimage-video | 40 +- driver/xscreensaver.man | 16 +- hacks/Makefile.in | 47 +- hacks/asm6502.c | 2148 ++++++++++++++++++++++++ hacks/asm6502.h | 169 ++ hacks/compile_axp.com | 3 + hacks/compile_decc.com | 3 + hacks/config/README | 4 +- hacks/config/cwaves.xml | 27 + hacks/config/glcells.xml | 60 + hacks/config/m6502.xml | 26 + hacks/config/voronoi.xml | 48 + hacks/cwaves.c | 150 ++ hacks/cwaves.man | 72 + hacks/glx/Makefile.in | 45 +- hacks/glx/antspotlight.c | 20 +- hacks/glx/glcells.c | 1297 ++++++++++++++ hacks/glx/glcells.man | 99 ++ hacks/glx/glschool_gl.c | 5 + hacks/glx/voronoi.c | 523 ++++++ hacks/glx/voronoi.man | 88 + hacks/images/osx_10_2.xpm | 38 +- hacks/images/osx_10_3.xpm | 8 +- hacks/m6502.c | 833 +++++++++ hacks/webcollage | 14 +- hacks/xmatrix.c | 2 +- po/POTFILES.in | 6 +- setup.com | 2 + utils/version.h | 2 +- xscreensaver.spec | 2 +- xscreensaver.xcodeproj/project.pbxproj | 706 +++++++- 41 files changed, 6449 insertions(+), 93 deletions(-) create mode 100644 hacks/asm6502.c create mode 100644 hacks/asm6502.h create mode 100644 hacks/config/cwaves.xml create mode 100644 hacks/config/glcells.xml create mode 100644 hacks/config/m6502.xml create mode 100644 hacks/config/voronoi.xml create mode 100644 hacks/cwaves.c create mode 100644 hacks/cwaves.man create mode 100644 hacks/glx/glcells.c create mode 100644 hacks/glx/glcells.man create mode 100644 hacks/glx/voronoi.c create mode 100644 hacks/glx/voronoi.man create mode 100644 hacks/m6502.c diff --git a/OSX/SaverTester.plist b/OSX/SaverTester.plist index 141266be..0b6c514f 100644 --- a/OSX/SaverTester.plist +++ b/OSX/SaverTester.plist @@ -15,11 +15,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 5.02 + 5.03 CFBundleSignature ???? CFBundleVersion - 5.02 + 5.03 LSMinimumSystemVersion 10.4.0 NSMainNibFile diff --git a/OSX/XScreenSaver.plist b/OSX/XScreenSaver.plist index 7eaf05da..25027930 100644 --- a/OSX/XScreenSaver.plist +++ b/OSX/XScreenSaver.plist @@ -15,11 +15,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 5.02 + 5.03 CFBundleSignature ???? CFBundleVersion - 5.02 + 5.03 LSMinimumSystemVersion 10.4.0 NSMainNibFile diff --git a/OSX/bindist.rtf b/OSX/bindist.rtf index 2e04b929..b9e13eef 100644 --- a/OSX/bindist.rtf +++ b/OSX/bindist.rtf @@ -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 776ef128..5fbf2300 100644 --- 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'. diff --git a/configure b/configure index 18570b3c..3bbf0ad3 100755 --- 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. diff --git a/configure.in b/configure.in index fcc8f886..adab2635 100644 --- a/configure.in +++ b/configure.in @@ -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 diff --git a/driver/Makefile.in b/driver/Makefile.in index 2f9fb89f..5daf8a26 100644 --- a/driver/Makefile.in +++ b/driver/Makefile.in @@ -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 diff --git a/driver/XScreenSaver.ad.in b/driver/XScreenSaver.ad.in index f7d563e3..29f69600 100644 --- a/driver/XScreenSaver.ad.in +++ b/driver/XScreenSaver.ad.in @@ -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 diff --git a/driver/XScreenSaver_ad.h b/driver/XScreenSaver_ad.h index 2843bdcc..2f632ab1 100644 --- a/driver/XScreenSaver_ad.h +++ b/driver/XScreenSaver_ad.h @@ -203,6 +203,8 @@ 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 \ @@ -289,6 +291,8 @@ 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 \ @@ -401,4 +405,5 @@ "*hacks.glhanoi.name: GLHanoi", "*hacks.topblock.name: TopBlock", "*hacks.glschool.name: GLSchool", +"*hacks.glcells.name: GLCells", "*hacks.documentation.isInstalled: True", diff --git a/driver/lock.c b/driver/lock.c index bba326b0..e36b5913 100644 --- a/driver/lock.c +++ b/driver/lock.c @@ -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); } diff --git a/driver/xscreensaver-getimage-video b/driver/xscreensaver-getimage-video index 468bf3af..6b9c1408 100755 --- a/driver/xscreensaver-getimage-video +++ b/driver/xscreensaver-getimage-video @@ -1,5 +1,5 @@ #!/usr/bin/perl -w -# Copyright © 2001, 2002, 2003, 2005 Jamie Zawinski . +# Copyright © 2001-2007 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 @@ -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 () { $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++; } diff --git a/driver/xscreensaver.man b/driver/xscreensaver.man index 9484831f..0d2f65fc 100644 --- a/driver/xscreensaver.man +++ b/driver/xscreensaver.man @@ -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 diff --git a/hacks/Makefile.in b/hacks/Makefile.in index ae934eb0..b95f56d3 100644 --- a/hacks/Makefile.in +++ b/hacks/Makefile.in @@ -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 index 00000000..aeda4826 --- /dev/null +++ b/hacks/asm6502.c @@ -0,0 +1,2148 @@ +/* Copyright (C) 2007 Jeremy English + * + * 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 +#include +/*#include */ +#include +#include +#include +#include +#include +#include +#include +#include + +#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 ); +} + + + +/* 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); +} + + + +/* 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; +} + + +/* 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; +} + + +/* 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"); +} + + + + +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 index 00000000..bd7e79ca --- /dev/null +++ b/hacks/asm6502.h @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2007 Jeremy English + * + * 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__ */ diff --git a/hacks/compile_axp.com b/hacks/compile_axp.com index a0b5d763..29489acd 100644 --- a/hacks/compile_axp.com +++ b/hacks/compile_axp.com @@ -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 diff --git a/hacks/compile_decc.com b/hacks/compile_decc.com index a0b5d763..29489acd 100644 --- a/hacks/compile_decc.com +++ b/hacks/compile_decc.com @@ -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 diff --git a/hacks/config/README b/hacks/config/README index af3616c2..61534da1 100644 --- a/hacks/config/README +++ b/hacks/config/README @@ -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 index 00000000..33ddf36d --- /dev/null +++ b/hacks/config/cwaves.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + <_description> +This generates a languidly-scrolling vertical field of sinusoidal colors. + +Written by Jamie Zawinski; 2007. + + diff --git a/hacks/config/glcells.xml b/hacks/config/glcells.xml new file mode 100644 index 00000000..b76bfb72 --- /dev/null +++ b/hacks/config/glcells.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_description> +Cells growing, dividing and dying on your screen. + +Written by Matthias Toussaint; 2007. + + diff --git a/hacks/config/m6502.xml b/hacks/config/m6502.xml new file mode 100644 index 00000000..26db9f96 --- /dev/null +++ b/hacks/config/m6502.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + <_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. + + diff --git a/hacks/config/voronoi.xml b/hacks/config/voronoi.xml new file mode 100644 index 00000000..6698ed88 --- /dev/null +++ b/hacks/config/voronoi.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + <_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. + + diff --git a/hacks/cwaves.c b/hacks/cwaves.c new file mode 100644 index 00000000..cb72a07b --- /dev/null +++ b/hacks/cwaves.c @@ -0,0 +1,150 @@ +/* xscreensaver, Copyright (c) 2007 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. + * + * cwaves -- languid sinusoidal colors. + */ + +#include "screenhack.h" +#include +#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 index 00000000..a7fd78b5 --- /dev/null +++ b/hacks/cwaves.man @@ -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 , 2-Jul-2007. diff --git a/hacks/glx/Makefile.in b/hacks/glx/Makefile.in index 2e6fd727..ed1635fd 100644 --- a/hacks/glx/Makefile.in +++ b/hacks/glx/Makefile.in @@ -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 diff --git a/hacks/glx/antspotlight.c b/hacks/glx/antspotlight.c index f3272c2e..87e34c65 100644 --- a/hacks/glx/antspotlight.c +++ b/hacks/glx/antspotlight.c @@ -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 index 00000000..86355f10 --- /dev/null +++ b/hacks/glx/glcells.c @@ -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 /* gettimeofday */ + +#include "xlockmore.h" +#include + +/********************************** + 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; vnum_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; inum_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; inum_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; vnum_vertex; ++v) { + ret->vertex[v] = obj->vertex[v]; + } + + for (t=0; tnum_triangle; ++t) { + ret->triangle[t] = obj->triangle[t]; + } + + /* create normals (triangles) */ + for (t=0; tnum_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; vnum_vertex; ++v) { + vector_clear( &ret->normal[v] ); + for (t=0; tnum_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; tnum_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; tnum_triangle; ++t) { + ret->triangle[t] = tmp->triangle[t]; + } + ret->num_triangle = tmp->num_triangle; + + /* copy unique vertexes and correct triangle list */ + for (v=0; vnum_vertex; ++v) { + /* create list of vertexes that are the same */ + index_cnt = 0; + for (i=0; inum_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; inum_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; tnum_triangle; ++t) { + for (i=0; itriangle[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; tnum_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; vnum_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; bnum_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; bnum_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; bnum_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; tnum_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; icell_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; vnum_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; tnum_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; ytexture[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; ifood[i] = random_interval( st->minfood, st->maxfood ); + } + + /* create the requested seed-cells */ + st->num_cells = st->num_seeds; + + for (i=0; inum_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; bnum_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; bnum_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; bnum_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; jnum_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 (distcell[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; bnum_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; icell_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; isphere->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; icell_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 index 00000000..2d240174 --- /dev/null +++ b/hacks/glx/glcells.man @@ -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 , 17-Jun-2007. + diff --git a/hacks/glx/glschool_gl.c b/hacks/glx/glschool_gl.c index 7414838f..bd8f981a 100644 --- a/hacks/glx/glschool_gl.c +++ b/hacks/glx/glschool_gl.c @@ -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 index 00000000..c59e6ba8 --- /dev/null +++ b/hacks/glx/voronoi.c @@ -0,0 +1,523 @@ +/* voronoi, Copyright (c) 2007 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. + */ + +#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 + +#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 index 00000000..526fb70d --- /dev/null +++ b/hacks/glx/voronoi.man @@ -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. diff --git a/hacks/images/osx_10_2.xpm b/hacks/images/osx_10_2.xpm index 1455bc0e..eeb78731 100644 --- a/hacks/images/osx_10_2.xpm +++ b/hacks/images/osx_10_2.xpm @@ -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", diff --git a/hacks/images/osx_10_3.xpm b/hacks/images/osx_10_3.xpm index dc06e155..352539cd 100644 --- a/hacks/images/osx_10_3.xpm +++ b/hacks/images/osx_10_3.xpm @@ -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 index 00000000..059d7629 --- /dev/null +++ b/hacks/m6502.c @@ -0,0 +1,833 @@ +/* + * Copyright (c) 2007 Jeremy English + * + * 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 +#include +#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; + } +} + +/* + * 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]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; +} + + + + +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) diff --git a/hacks/webcollage b/hacks/webcollage index cd3fa431..9d76d1ab 100755 --- a/hacks/webcollage +++ b/hacks/webcollage @@ -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 \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") diff --git a/hacks/xmatrix.c b/hacks/xmatrix.c index 9f69c25d..b7af5b1e 100644 --- a/hacks/xmatrix.c +++ b/hacks/xmatrix.c @@ -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) " diff --git a/po/POTFILES.in b/po/POTFILES.in index 74e747fd..d1d20563 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -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 diff --git a/setup.com b/setup.com index 20664245..5c8d935a 100644 --- 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 diff --git a/utils/version.h b/utils/version.h index e05c697a..a6a04d3b 100644 --- a/utils/version.h +++ b/utils/version.h @@ -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)"; diff --git a/xscreensaver.spec b/xscreensaver.spec index d1977d03..282deb20 100644 --- a/xscreensaver.spec +++ b/xscreensaver.spec @@ -1,5 +1,5 @@ %define name xscreensaver -%define version 5.02 +%define version 5.03 Summary: X screen saver and locker Name: %{name} diff --git a/xscreensaver.xcodeproj/project.pbxproj b/xscreensaver.xcodeproj/project.pbxproj index aca417b8..2bc937b9 100644 --- a/xscreensaver.xcodeproj/project.pbxproj +++ b/xscreensaver.xcodeproj/project.pbxproj @@ -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 */, @@ -206,6 +208,7 @@ AF777A2D09B660B400EA3033 /* PBXTargetDependency */, AF777A2B09B660B400EA3033 /* PBXTargetDependency */, AF777A2909B660B400EA3033 /* PBXTargetDependency */, + AFF4636F0C440B3B00EE6509 /* PBXTargetDependency */, AF777A2709B660B400EA3033 /* PBXTargetDependency */, AF777A2509B660B400EA3033 /* PBXTargetDependency */, AF777A2309B660B400EA3033 /* PBXTargetDependency */, @@ -246,6 +249,7 @@ AF7779DF09B660AF00EA3033 /* PBXTargetDependency */, AF7779DD09B660AF00EA3033 /* PBXTargetDependency */, AF998EF70A083E1D0051049D /* PBXTargetDependency */, + AF0DCA5C0C4CBB4300D76972 /* PBXTargetDependency */, ); name = "All Savers (OpenGL)"; productName = "All Savers (OpenGL)"; @@ -307,6 +311,23 @@ 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 */; }; @@ -1863,6 +1884,21 @@ 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 */ @@ -1895,6 +1931,34 @@ 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 */; @@ -4786,6 +4850,34 @@ 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 */ @@ -4806,6 +4898,16 @@ 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 = ""; }; AF083A5D099312DB00277BE9 /* tunnel_draw.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = tunnel_draw.h; path = hacks/glx/tunnel_draw.h; sourceTree = ""; }; + 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 = ""; }; + AF0DCA320C4C74A200D76972 /* asm6502.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = asm6502.c; path = hacks/asm6502.c; sourceTree = ""; }; + AF0DCA330C4C74A200D76972 /* asm6502.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = asm6502.h; path = hacks/asm6502.h; sourceTree = ""; }; + AF0DCA340C4C74A200D76972 /* m6502.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = m6502.c; path = hacks/m6502.c; sourceTree = ""; }; + AF0DCA370C4C74B700D76972 /* m6502.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = m6502.xml; sourceTree = ""; }; + 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 = ""; }; + AF0DCA5F0C4CBB7300D76972 /* voronoi.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = voronoi.c; path = hacks/glx/voronoi.c; sourceTree = ""; }; + AF0DCA610C4CBB8E00D76972 /* voronoi.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = voronoi.xml; sourceTree = ""; }; AF0FAF0B09CA6FF900EE1051 /* xscreensaver-text */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.perl; name = "xscreensaver-text"; path = "driver/xscreensaver-text"; sourceTree = ""; }; AF0FAF1209CA712600EE1051 /* xscreensaver-getimage-file */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.perl; name = "xscreensaver-getimage-file"; path = "driver/xscreensaver-getimage-file"; sourceTree = ""; }; AF34085409B80AAF00F2CEC1 /* StarWars.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StarWars.saver; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -5468,7 +5570,6 @@ AFC259150988A469000655EE /* spotlight.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = spotlight.xml; sourceTree = ""; }; AFC259160988A469000655EE /* sproingies.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = sproingies.xml; sourceTree = ""; }; AFC259170988A469000655EE /* squiral.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = squiral.xml; sourceTree = ""; }; - AFC259180988A469000655EE /* ssystem.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = ssystem.xml; sourceTree = ""; }; AFC259190988A469000655EE /* stairs.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = stairs.xml; sourceTree = ""; }; AFC2591A0988A469000655EE /* starfish.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = starfish.xml; sourceTree = ""; }; AFC2591B0988A469000655EE /* starwars.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = starwars.xml; sourceTree = ""; }; @@ -5602,6 +5703,14 @@ AFE1FD5B0981E3CB00F7970E /* yarandom.c */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.c; name = yarandom.c; path = utils/yarandom.c; sourceTree = ""; }; AFE1FD5C0981E3CB00F7970E /* yarandom.h */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.h; name = yarandom.h; path = utils/yarandom.h; sourceTree = ""; }; AFE1FD620981E40800F7970E /* rorschach.c */ = {isa = PBXFileReference; fileEncoding = 12; lastKnownFileType = sourcecode.c.c; name = rorschach.c; path = hacks/rorschach.c; sourceTree = ""; }; + 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 = ""; }; + AFF463490C44044E00EE6509 /* cwaves.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = cwaves.c; path = hacks/cwaves.c; sourceTree = ""; }; + AFF4634B0C44046500EE6509 /* cwaves.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = cwaves.xml; sourceTree = ""; }; + 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 = ""; }; + AFF463710C440B9200EE6509 /* glcells.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = glcells.c; path = hacks/glx/glcells.c; sourceTree = ""; }; + AFF463730C440BAC00EE6509 /* glcells.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = glcells.xml; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -5631,6 +5740,29 @@ ); 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; @@ -7874,6 +8006,29 @@ ); 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 */ @@ -8109,6 +8264,10 @@ AF48DF030A0C25E000F94CF9 /* GLSchool.saver */, AFA339400B058505002B0E7D /* WebCollage.saver */, AFA33BC70B058740002B0E7D /* webcollage-helper */, + AFF463470C4403E400EE6509 /* CWaves.saver */, + AFF4636C0C440AEF00EE6509 /* GLCells.saver */, + AF0DC7BD0C4C73F600D76972 /* m6502.saver */, + AF0DCA560C4CBB0D00D76972 /* Voronoi.saver */, ); name = Products; sourceTree = ""; @@ -8137,6 +8296,10 @@ 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 = ""; @@ -8205,6 +8368,9 @@ 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 */, @@ -8233,6 +8399,7 @@ AF47721B099D4F47001F091E /* whirlygig.c */, AF477205099D4EB6001F091E /* nerverot.c */, AF4771EF099D4DFE001F091E /* ccurve.c */, + AFF463490C44044E00EE6509 /* cwaves.c */, AF64270709A1C9EF000F4CD4 /* sonar.c */, AF4771BA099D4997001F091E /* t3d.c */, AF477192099D4864001F091E /* wander.c */, @@ -8339,6 +8506,7 @@ AFA563B90993991300F3E977 /* juggler3d.c */, AFA5638E0993980D00F3E977 /* timetunnel.c */, AF998EF80A083E750051049D /* topblock.c */, + AF0DCA5F0C4CBB7300D76972 /* voronoi.c */, AFA563660993970F00F3E977 /* cube21.c */, AFA563460993963400F3E977 /* glhanoi.c */, AF77778B09B64A2A00EA3033 /* gleidescope.c */, @@ -8412,6 +8580,7 @@ AFA55EAB0993608800F3E977 /* toaster.c */, AFA55EAC0993608800F3E977 /* toaster.dxf */, AFA55E4509935FD300F3E977 /* glblur.c */, + AFF463710C440B9200EE6509 /* glcells.c */, AFA55E2209935F2B00F3E977 /* chessgames.h */, AFA55E2309935F2B00F3E977 /* chessmodels.c */, AFA55E2409935F2B00F3E977 /* chessmodels.h */, @@ -8517,6 +8686,7 @@ AFC258820988A468000655EE /* cage.xml */, AFC258830988A468000655EE /* carousel.xml */, AFC258840988A468000655EE /* ccurve.xml */, + AFF4634B0C44046500EE6509 /* cwaves.xml */, AFC258850988A468000655EE /* celtic.xml */, AFC258860988A468000655EE /* circuit.xml */, AFC258870988A468000655EE /* cloudlife.xml */, @@ -8566,6 +8736,7 @@ AFC258B20988A468000655EE /* gears.xml */, AFC258B30988A468000655EE /* gflux.xml */, AFC258B40988A468000655EE /* glblur.xml */, + AFF463730C440BAC00EE6509 /* glcells.xml */, AFC258B50988A468000655EE /* gleidescope.xml */, AFC258B60988A468000655EE /* glforestfire.xml */, AFC258B70988A468000655EE /* glhanoi.xml */, @@ -8636,6 +8807,7 @@ AFC258F80988A469000655EE /* polyominoes.xml */, AFC258F90988A469000655EE /* polytopes.xml */, AFC258FA0988A469000655EE /* pong.xml */, + AF0DCA370C4C74B700D76972 /* m6502.xml */, AFC258FB0988A469000655EE /* popsquares.xml */, AFC258FC0988A469000655EE /* providence.xml */, AFC258FD0988A469000655EE /* pulsar.xml */, @@ -8664,7 +8836,6 @@ AFC259150988A469000655EE /* spotlight.xml */, AFC259160988A469000655EE /* sproingies.xml */, AFC259170988A469000655EE /* squiral.xml */, - AFC259180988A469000655EE /* ssystem.xml */, AFC259190988A469000655EE /* stairs.xml */, AFC2591A0988A469000655EE /* starfish.xml */, AFC2591B0988A469000655EE /* starwars.xml */, @@ -8678,6 +8849,7 @@ AFC259220988A469000655EE /* tangram.xml */, AFC259230988A469000655EE /* thornbird.xml */, AFC259240988A469000655EE /* timetunnel.xml */, + AF0DCA610C4CBB8E00D76972 /* voronoi.xml */, AFC259250988A469000655EE /* triangle.xml */, AFC259260988A469000655EE /* truchet.xml */, AFC259270988A469000655EE /* twang.xml */, @@ -8941,6 +9113,124 @@ yes +"; + 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 = " + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + Deco + CFBundleIdentifier + com.yourcompany.Deco + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + CSResourcesFileMapped + yes + + +"; + 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 = " + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + Deco + CFBundleIdentifier + com.yourcompany.Deco + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + CSResourcesFileMapped + yes + + "; productType = "com.apple.product-type.bundle"; }; @@ -20921,6 +21211,124 @@ yes +"; + 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 = " + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + Deco + CFBundleIdentifier + com.yourcompany.Deco + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + CSResourcesFileMapped + yes + + +"; + 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 = " + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + Deco + CFBundleIdentifier + com.yourcompany.Deco + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + CSResourcesFileMapped + yes + + "; productType = "com.apple.product-type.bundle"; }; @@ -20960,6 +21368,7 @@ AF477169099D4786001F091E /* Compass */, AF4775D8099D9F69001F091E /* Coral */, AF47765A099DA78E001F091E /* Critical */, + AFF463360C4403E400EE6509 /* CWaves */, AF4778E8099DDDC8001F091E /* Cynosure */, AF9D466609B5109C006E59CF /* DecayScreen */, AF976FBB0989CAA2001F8B92 /* Deco */, @@ -20988,6 +21397,7 @@ AF477499099D8A74001F091E /* Kaleidescope */, AF477613099DA26C001F091E /* Kumppa */, AF4774B4099D8B5F001F091E /* LMorph */, + AF0DC7AB0C4C73F600D76972 /* m6502 */, AF4774CE099D8BFF001F091E /* Maze */, AF975AFC099C6FE400B05160 /* MemScroller */, AF975A36099C681F00B05160 /* MetaBalls */, @@ -21111,6 +21521,7 @@ AF77777409B6497800EA3033 /* Gleidescope */, AFA55B9109933FDA00F3E977 /* GFlux */, AFA55E2F09935F8E00F3E977 /* GLBlur */, + AFF463580C440AEF00EE6509 /* GLCells */, AFA55CCC09934CE400F3E977 /* GLForestFire */, AFA56331099395ED00F3E977 /* GLHanoi */, AFA55FF909936C6D00F3E977 /* GLKnots */, @@ -21151,6 +21562,7 @@ AFA562F20993943B00F3E977 /* Tangram */, AFA56379099397B300F3E977 /* TimeTunnel */, AF998EDA0A083DB30051049D /* TopBlock */, + AF0DCA420C4CBB0D00D76972 /* Voronoi */, AF9771D60989DC4A001F8B92 /* SaverTester */, ); }; @@ -21173,6 +21585,22 @@ ); 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; @@ -22824,6 +23252,22 @@ ); 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 */ @@ -22841,6 +23285,20 @@ ); 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; @@ -24248,9 +24706,49 @@ ); 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; @@ -26903,6 +27401,32 @@ 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 */ @@ -26929,6 +27453,26 @@ ); 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; @@ -28854,6 +29398,24 @@ ); 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 */ @@ -28867,6 +29429,26 @@ 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 */; @@ -30932,6 +31514,26 @@ 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 */ @@ -30994,6 +31596,38 @@ }; 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 = { @@ -34176,6 +34810,38 @@ }; 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 = { @@ -34317,6 +34983,24 @@ 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 = ( @@ -36207,6 +36891,24 @@ 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 = ( -- 2.30.2