X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fm6502.c;h=ce18e9d3d9af074e85182ff49f327f59787e9432;hb=39809ded547bdbb08207d3e514950425215b4410;hp=705af37c2304b9ec9815ded71bec6d0f1e6f2c62;hpb=6b1c86cf395f59389e4ece4ea8f4bea2c332745b;p=xscreensaver diff --git a/hacks/m6502.c b/hacks/m6502.c index 705af37c..ce18e9d3 100644 --- a/hacks/m6502.c +++ b/hacks/m6502.c @@ -12,7 +12,14 @@ * Created: 07-May-2007 */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#if defined(HAVE_STDINT_H) #include +#elif defined(HAVE_INTTYPES_H) +#include +#endif #include #include "screenhack.h" #include "analogtv.h" @@ -23,11 +30,16 @@ ISO C89 compilers are required to support" when includng the following data file... */ # endif -const char * const demo_files[] = { +static const char * const demo_files[] = { # include "m6502.h" }; +#ifndef HAVE_MOBILE +# define READ_FILES +#endif + + /* We want to paint on a 32 by 32 grid of pixels. We will needed to divided the screen up into chuncks */ enum { @@ -51,10 +63,14 @@ struct state { 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*/ + double dt;/* how long to wait before changing the demo*/ int which;/* the program to run*/ int demos;/* number of demos included */ - struct timeval start_time; + double start_time; + int reset_p; + char *file; + double last_frame, last_delay; + unsigned ips; }; static void @@ -74,48 +90,32 @@ start_rand_bin_prog(machine_6502 *machine, struct state *st){ while(n == st->which) n = random() % st->demos; st->which = n; - start_eval_string(machine, demo_files[st->which], plot6502, st); + m6502_start_eval_string(machine, demo_files[st->which], plot6502, st); } /* - * get_time () + * double_time () * - * returns the total time elapsed since the beginning of the demo + * returns the current time as a floating-point value */ -static double get_time(struct state *st) { +static double double_time(void) { struct timeval t; - float f; + double 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 n = get_float_resource(dpy, "displaytime", "Displaytime"); int dh; st->demos = countof(demo_files); st->which = random() % st->demos; @@ -125,7 +125,7 @@ m6502_init (Display *dpy, Window window) st->tv=analogtv_allocate(st->dpy, st->window); analogtv_set_defaults(st->tv, ""); - st->machine = build6502(); + st->machine = m6502_build(); st->inp=analogtv_input_allocate(); analogtv_setup_sync(st->inp, 1, 0); @@ -139,12 +139,15 @@ m6502_init (Display *dpy, Window window) 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); + st->last_frame = double_time(); + st->last_delay = 0; + st->ips = get_integer_resource(dpy, "ips", "IPS"); + +#ifdef READ_FILES + st->file = get_string_resource (dpy, "file", "File"); +#endif + + st->reset_p = 1; analogtv_lcp_to_ntsc(ANALOGTV_BLACK_LEVEL, 0.0, 0.0, st->field_ntsc); @@ -153,10 +156,6 @@ m6502_init (Display *dpy, Window window) 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; } @@ -212,29 +211,45 @@ m6502_draw (Display *dpy, Window window, void *closure) { struct state *st = (struct state *) closure; unsigned int x = 0, y = 0; - double te; + double now, last_delay = st->last_delay >= 0 ? st->last_delay : 0; + double insno = st->ips * ((1 / 29.97) + last_delay - st->last_delay); + const analogtv_reception *reception = &st->reception; + + if (st->reset_p){ /* do something more interesting here XXX */ + st->reset_p = 0; + for(x = 0; x < 32; x++) + for(y = 0; y < 32; y++) + st->pixels[x][y] = 0; + st->start_time = st->last_frame + last_delay; - next_eval(st->machine,500); +#ifdef READ_FILES + if (st->file && *st->file) + m6502_start_eval_file(st->machine, st->file, plot6502, st); + else +#endif + start_rand_bin_prog(st->machine,st); + } + + if (insno < 10) + insno = 10; + else if (insno > 100000) /* Real 6502 went no faster than 3 MHz. */ + insno = 100000; + m6502_next_eval(st->machine,insno); 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); - } + analogtv_draw(st->tv, 0.04, &reception, 1); + now = double_time(); + st->last_delay = (1 / 29.97) + st->last_frame + last_delay - now; + st->last_frame = now; + + if (now - st->start_time > st->dt) + st->reset_p = 1; - return 10000; + return st->last_delay >= 0 ? st->last_delay * 1e6 : 0; } @@ -244,15 +259,18 @@ static const char *m6502_defaults [] = { ".background: black", ".foreground: white", "*file:", - "*displaytime: 20", + "*displaytime: 30.0", /* demoscene: 24s, dmsc: 48s, sierpinsky: 26s + sflake, two runs: 35s + */ + "*ips: 15000", /* Actual MOS 6502 ran at least 1 MHz. */ ANALOGTV_DEFAULTS - "*TVContrast: 150", 0 }; static XrmOptionDescRec m6502_options [] = { { "-file", ".file", XrmoptionSepArg, 0 }, { "-displaytime", ".displaytime", XrmoptionSepArg, 0}, + { "-ips", ".ips", XrmoptionSepArg, 0}, ANALOGTV_OPTIONS { 0, 0, 0, 0 } }; @@ -268,6 +286,12 @@ m6502_reshape (Display *dpy, Window window, void *closure, static Bool m6502_event (Display *dpy, Window window, void *closure, XEvent *event) { + struct state *st = (struct state *) closure; + if (screenhack_event_helper (dpy, window, event)) + { + st->reset_p = 1; + return True; + } return False; } @@ -276,6 +300,7 @@ m6502_free (Display *dpy, Window window, void *closure) { struct state *st = (struct state *) closure; analogtv_release(st->tv); + free (st->file); free (st); }