home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dream 52
/
Amiga_Dream_52.iso
/
Linux
/
Divers
/
bomb.tar.gz
/
bomb.tar
/
bomb
/
bomb.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-03-08
|
65KB
|
2,772 lines
/*
bomb - automatic interactive visual stimulation
Copyright (C) 1994 Scott Draves <spot@cs.cmu.edu>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "defs.h"
#include "image.h"
#include "image_db.h"
#include "bomb.h"
#include "match.h"
#include "sound.h"
board_t board[2];
board_t board2[2];
board_t board3[2];
int dbuf=0;
int remap[max_heat]; /* > largest possible mask */
int p1 = 0;
int auto_mode = 0;
int auto_rule = 0;
int delayed_fill = 0;
char status_string[status_string_length];
int key;
int frame = 0;
double timer = 500;
int overdrive_speed = 20;
int dtime = 1;
int flipper, flipper2;
int param = 0;
int curs = 0;
int *gparam;
int old_rule;
int pulse = 0;
int pulse_driver = 0;
int periodic_write = 0;
int cmap_changed = 0;
int image_rate = 0; /* should be in rule struct */
int image_dst = 0;
int rule_lock = 0;
int pop_back = 0, back_to;
int permuting = 0;
double delay = 0.0;
int kbd_mode = 0;
int stabilize_fps;
int display_fps = 0;
int rule_mask = -1;
int last_clear = 0;
int fastflip = 0;
int scramble = 0;
int keyboard_enabled = 1;
double fps;
/* for colormap changes */
static u_char target_cmap[256][3];
int current_cmap[256 * 3];
#define SET_TARGET_PALETTE(x, r, g, b) \
target_cmap[x][0] = r; \
target_cmap[x][1] = g; \
target_cmap[x][2] = b
cmap_t cmap;
fill_t fill2;
rule_t rule;
int nrecords = 0;
FILE *recording = NULL;
image8_t fb;
int masks[max_heat];
#if mac_bomb && !use_sioux
#include <console.h>
short InstallConsole(short fd){return 0;}
void RemoveConsole(void){}
long WriteCharsToConsole(char *buffer, long n){return 0;}
long ReadCharsFromConsole(char *buffer, long n){return 0;}
#endif
#if xws_bomb && vga_bomb
int running_x;
#endif
#if (xws_bomb|ogl_bomb)
Display *disp;
Visual *visual;
int fb_bpp;
Window win;
Colormap xws_cmap;
int depth;
int *xws_lut;
#if xws_bomb
GC gc;
XImage *xws_image;
char *image_buf;
#endif
#endif
#if mac_bomb
#include <AppleEvents.h>
#include <Types.h>
#include <Resources.h>
#include <QuickDraw.h>
#include <Fonts.h>
#include <Events.h>
#include <Windows.h>
#include <Menus.h>
#include <TextEdit.h>
#include <Dialogs.h>
#include <Desk.h>
#include <ToolUtils.h>
#include <Memory.h>
#include <SegLoad.h>
#include <Files.h>
#include <OSUtils.h>
#include <OSEvents.h>
#include <DiskInit.h>
#include <Packages.h>
#include <Traps.h>
#include <QDOffscreen.h>
#include <Palettes.h>
#include <LowMem.h>
#endif
void
ramp(int c, int i0, int i1, int n, int k)
{
int x, r, g, b;
for (x = 0; x < n; x++) {
double alpha = x / (double) n;
r = (int) (the_cmaps[c][i0][0] * (1 - alpha) +
the_cmaps[c][i1][0] * alpha);
g = (int) (the_cmaps[c][i0][1] * (1 - alpha) +
the_cmaps[c][i1][1] * alpha);
b = (int) (the_cmaps[c][i0][2] * (1 - alpha) +
the_cmaps[c][i1][2] * alpha);
SET_TARGET_PALETTE(k + x, r, g, b);
}
}
int
round_up8(int n)
{
if (n < 0)
n = (n - 7) >> 3;
else
n = (n + 7) >> 3;
return n;
}
int
round_up5(int n)
{
if (n < 0)
n = (n - 31) >> 5;
else
n = (n + 31) >> 5;
return n;
}
void
step_cmap()
{
int i;
for (i = 0; i < 256; i++) {
current_cmap[3*i] += round_up8(target_cmap[i][0] - current_cmap[3*i]);
current_cmap[3*i+1] += round_up8(target_cmap[i][1] - current_cmap[3*i+1]);
current_cmap[3*i+2] += round_up8(target_cmap[i][2] - current_cmap[3*i+2]);
}
#define difff(x,y) ((x)!=(y))
for (i = 0; i < 256; i++) {
if (difff(current_cmap[3*i+0], target_cmap[i][0]) ||
difff(current_cmap[3*i+1], target_cmap[i][1]) ||
difff(current_cmap[3*i+2], target_cmap[i][2])) {
image8_set_cmap(0, 256, current_cmap);
return;
}
}
}
void brighten_cmap() {
int i;
for (i = 0; i < 256; i++) {
int r = (255 + 4*current_cmap[3*i+0])/5;
int g = (255 + 4*current_cmap[3*i+1])/5;
int b = (255 + 4*current_cmap[3*i+2])/5;
SET_TARGET_PALETTE(i, r, g, b);
}
}
void pulse_cmap_rotate() {
int i;
for (i = 1; i < 220; i++) {
current_cmap[3*i+0] = current_cmap[(3*i+0+90)%(3*256)];
current_cmap[3*i+1] = current_cmap[(3*i+0+91)%(3*256)];
current_cmap[3*i+2] = current_cmap[(3*i+0+92)%(3*256)];
}
}
void pulse_cmap_black() {
int i;
for (i = 100; i < 150; i++) {
current_cmap[3*i+0] = current_cmap[3*i+0] * (150 - i) / 50;
current_cmap[3*i+1] = current_cmap[3*i+1] * (150 - i) / 50;
current_cmap[3*i+2] = current_cmap[3*i+2] * (150 - i) / 50;
}
for (i = 150; i < 250; i++) {
current_cmap[3*i+0] = 0;
current_cmap[3*i+1] = 0;
current_cmap[3*i+2] = 0;
}
}
void pulse_cmap_white() {
int i;
for (i = 1; i < 10; i++) {
current_cmap[3*i+0] = ((current_cmap[3*i+0] * (10 - i) / 10) +
(255 * i / 10));
current_cmap[3*i+1] = ((current_cmap[3*i+1] * (10 - i) / 10) +
(255 * i / 10));
current_cmap[3*i+2] = ((current_cmap[3*i+2] * (10 - i) / 10) +
(255 * i / 10));
}
for (i = 10; i < 20; i++) {
current_cmap[3*i+0] = 255;
current_cmap[3*i+1] = 255;
current_cmap[3*i+2] = 255;
}
for (i = 20; i < 30; i++) {
current_cmap[3*i+0] = ((current_cmap[3*i+0] * (i - 20) / 10) +
(255 * (30 - i) / 10));
current_cmap[3*i+1] = ((current_cmap[3*i+1] * (i - 20) / 10) +
(255 * (30 - i) / 10));
current_cmap[3*i+2] = ((current_cmap[3*i+2] * (i - 20) / 10) +
(255 * (30 - i) / 10));
}
}
void
fade2cmap(cmap_t *p)
{
int r, g, b, x;
int c, i, i0, i1, i2;
switch (p->cmap) {
case cmap_mono:
for(x=0;x<256;x++) {
SET_TARGET_PALETTE(x,x,x,x);
}
break;
case cmap_mono4:
i0 = p->index;
i1 = p->index2;
for(x=0;x<256;x++) {
if (x == i0) {
r = (i1&3)<<4;
g = (i1&12)<<2;
b = (i1&48);
} else
r = g = b = (x&63)<<2;
SET_TARGET_PALETTE(x,r,g,b);
}
break;
case cmap_loop:
c = p->index;
i0 = R%256;
i1 = next_contrasting_color(c, i0, 60000);
i2 = next_contrasting_color(c, i1, 60000);
ramp(c, i0, i1, 64, 0);
ramp(c, i1, i2, 64, 64);
ramp(c, i2, i1, 64, 128);
ramp(c, i1, i0, 64, 192);
break;
case cmap_path:
if (1) {
int n = 10;
int len = 30000;
int each = 256/(n+1);
c = p->index;
i2 = i0 = R%256;
for (i = 0; i < n; i++) {
i1 = next_contrasting_color(c, i0, len);
ramp(c, i0, i1, each, i*each);
i0 = i1;
}
ramp(c, i1, i2, 256 - n*each, n*each);
}
break;
case cmap_heat:
/* black -> midred -> red -> yellow -> white
-> = 64 */
for (x = 0; x < 128; x++) {
r = g = 255;
b = x << 1;
SET_TARGET_PALETTE(128 + x, r, g, b);
}
for (x = 0; x < 64 ;x++) {
r = 255;
b = 0;
g = x<<2;
SET_TARGET_PALETTE(64 + x, r, g, b);
}
for(x = 0; x < 64; x++) {
r = x<<2;
g = 0;
b = 0;
SET_TARGET_PALETTE(x, r, g, b);
}
break;
case cmap_plain:
i = p->index;
for (x = 0; x < 256; x++) {
r = the_cmaps[i][x][0];
g = the_cmaps[i][x][1];
b = the_cmaps[i][x][2];
SET_TARGET_PALETTE(x,r,g,b);
}
break;
case cmap_split:
i = p->index;
for(x=0;x<128;x++) {
r = the_cmaps[i][x][0];
g = the_cmaps[i][x][1];
b = the_cmaps[i][x][2];
SET_TARGET_PALETTE(x,r,g,b);
}
i = p->index2;
for(x=128;x<256;x++) {
r = the_cmaps[i][x][0];
g = the_cmaps[i][x][1];
b = the_cmaps[i][x][2];
SET_TARGET_PALETTE(x,r,g,b);
}
break;
case cmap_noise:
for (x = 0; x < 256; x++) {
SET_TARGET_PALETTE(x,R,R,R);
}
break;
case cmap_black:
for (x = 0; x < 256; x++) {
SET_TARGET_PALETTE(x,0,0,0);
}
break;
case cmap_ramp:
c = p->index;
i0 = R%256;
i1 = next_contrasting_color(c, i0, 80000);
ramp(c, i0, i1, 256, 0);
break;
}
}
void set_remap(int mask, int rm) {
int x;
for (x = 0; x < mask; x++) {
int r;
r = rm
? (int)(255 * x / (double)mask)
: x;
r = r & 255;
if (0 == r) r = 1;
if (255 == r) r = 254;
remap[x] = r;
}
}
/* spook */
int
count_bits16(int i)
{
int b, r = 0;
for (b = 1; b < 0x10000; b = b << 1)
if (b & i)
r++;
return r;
}
/* find last set, like ffs */
int
fls(int i)
{
int r = 1;
int b = 1;
while (b < i) {
r++;
b = b << 1;
}
return r;
}
void
init_masks()
{
int i, c;
c = 0;
i = 1;
while (c < max_heat) {
if (8 < count_bits16(i)) {
masks[c++] = i;
}
i += 2;
}
}
int
compare_integers(const void *k, const void *a)
{
return *(int *)a - *(int *)k;
}
/* generally should just keep the index */
int
next_mask(int mask, int d)
{
int *r;
int i;
int s = (d > 0) ? 2 : -2;
d = abs(d);
d = (d > 0) ? d : -d;
while (d) {
if (8 < count_bits16(mask))
d--;
mask += s;
}
return mask;
#if 0
r = bsearch(&mask, masks, max_heat, sizeof(int), compare_integers);
if (NULL == r)
return masks[0];
i = (r - masks + d) % max_heat;
return masks[i];
#endif
}
int load_title(char *fn)
{
int i;
Image im;
#if !use_sioux
/* set cmaps to grayscale */
for (i = 0; i < 256; i++) {
int *v = ¤t_cmap[3*i];
v[0] = v[1] = v[2] = i;
}
image8_set_cmap(0, 256, current_cmap);
image_init(&im);
if (TCL_ERROR == image_read(&im, fn))
return 0;
image8_blit(&im, &fb);
image8_flush();
#endif
return 1;
}
#if mac_bomb
int GetBit( const void *data, int offset )
{
int d = ((unsigned char *)data)[offset >> 3];
return (d & (1 << (offset & 7))) != 0;
}
#endif
int
bomb_getkey() {
#if win_bomb
extern int win_getkey();
return win_getkey();
#endif
#if vga_bomb && xws_bomb
if (!running_x)
#endif
#if vga_bomb
return vga_getkey();
#endif
#if (xws_bomb|ogl_bomb)
{
XEvent ev;
if (XCheckWindowEvent(disp, win, KeyPressMask, &ev)) {
KeySym s;
s = XKeycodeToKeysym(disp, ev.xkey.keycode, 0);
/* doesn't work for shifted digits */
if (s > 255) return 0;
if (ShiftMask&ev.xkey.state) {
return ((int)s) - ('a' - 'A');
}
if (ControlMask&ev.xkey.state) {
return ((int)s) - 'a' + 1;
}
return (int) s;
} else
return 0;
}
#endif
#if mac_bomb
#if use_sioux
# define GetMacEvent GetNextEvent
#else
# define GetMacEvent GetOSEvent
#endif
static EventRecord gEvent;
if (GetMacEvent( keyDownMask, &gEvent)) {
int key = gEvent.message & charCodeMask;
if ('q' == key && (gEvent.modifiers & cmdKey))
return 3;
else
return(key);
} else
return(0);
#endif
}
void bomb_exit() {
if (recording)
fclose(recording);
exit_sound();
#if mac_bomb
if (1) {
GrafPtr wPort;
FlushEvents(everyEvent - osMask - diskMask, 0);
}
ExitToShell();
#endif
printf("\nbye\n");
exit(0);
}
#if ogl_bomb || vga_bomb || xws_bomb
void init_random() {
int t = time(NULL);
srandom(argd("seed", t));
}
#endif
#if mac_bomb
void
init_random()
{
srand(argd("seed", TickCount()));
}
void
init_mac()
{
#if mac_bomb
if (1) {
Ptr base_address;
SysEnvRec This_mac;
Rect *rr;
int cx, cy;
CWindowPtr myWindow;
printf("init bomb\n");
#if !use_sioux
InitGraf(&qd.thePort);
InitFonts();
FlushEvents(everyEvent - osMask - diskMask, 0);
InitWindows();
InitCursor();
MaxApplZone();
MoreMasters();
HideCursor();
#endif
SysEnvirons( 1, &This_mac );
if ( This_mac.hasColorQD ) {
GDHandle the_monitor;
the_monitor = GetMainDevice(); /* Get monitor with the menuBar on it. */
if ((**(**the_monitor).gdPMap).pixelSize != 8)
SetDepth(the_monitor, 8, 0, 0); /* Make sure we have 8-bit pixels */
base_address = (**(**the_monitor).gdPMap).baseAddr;
fb.stride = ((**(**the_monitor).gdPMap).rowBytes & 0x3FFF);
rr = &(**(**the_monitor).gdPMap).bounds;
SetGDevice(the_monitor);
// world_x = (**the_monitor).gdRect.left;
// world_y = (**the_monitor).gdRect.top;
} else {
ExitToShell(); /* Not much point if we don't have color quickdraw. */
}
#if !use_sioux
if (1) {
int i, j;
/* open window covering entire screen so things will be redrawn when the app quits */
myWindow = (CWindowPtr) NewCWindow(0, rr, "\pBomb", 1, 0, (WindowPtr) -1, 0, 0);
SetPort((WindowPtr)myWindow);
for (i = rr->top; i < rr->bottom; i++)
for (j = rr->left; j < rr->right; j++)
*(((u_char*)base_address) + j + (i * fb.stride)) = 0;
}
#endif
#if pix_rep
#ifdef copy_bits
if (1) {
extern PixMapPtr offscreenPixMapP, windowPixMapP;
extern Rect windowRect, offscreenRect;
PixMapHandle offscreenPixMapH, windowPixMapH;
GWorldPtr offscreenWorldP;
GWorldPtr saveWorld;
GDHandle saveDevice;
SetRect(&windowRect, 0, 0, pix_rep*320, pix_rep*200);
SetRect(&offscreenRect, 0, 0, 320, 200);
OffsetRect(&windowRect, (rr->right - rr->left - (pix_rep*320)) / 2 & (~3), (rr->bottom - rr->top - (pix_rep*200)) / 2);
// Get the Graphics World and Device associated with the window
GetGWorld(&saveWorld, &saveDevice);
// Set a pointer to the windows PixMap
windowPixMapH = GetGWorldPixMap(saveWorld);
HLockHi((Handle)windowPixMapH);
LockPixels(windowPixMapH);
windowPixMapP = *windowPixMapH;
// Set Up Offscreen GWorld
if (NewGWorld(&offscreenWorldP, 0, &offscreenRect, 0, saveDevice, noNewDevice))
DebugStr("\pCan't get GWorld.");
// Set a pointer to the Offscreen World's PixMap
offscreenPixMapH = GetGWorldPixMap(offscreenWorldP);
HLockHi((Handle)offscreenPixMapH);
LockPixels(offscreenPixMapH);
offscreenPixMapP = *offscreenPixMapH;
// Set up fb.
fb.p = (Byte*) (*offscreenPixMapH)->baseAddr;
fb.stride = (*offscreenPixMapH)->rowBytes & 0x3fff;
}
#else
if (1) {
extern unsigned char *real_screen_base;
extern int real_screen_stride;
cy = (rr->bottom - rr->top - (pix_rep*200)) / 2;
cx = (rr->right - rr->left - (pix_rep*320)) / 2;
real_screen_base = ((u_char *) base_address) + (cy * fb.stride) + cx;
real_screen_stride = fb.stride;
fb.p = malloc(320 * 200);
fb.stride = 320;
}
#endif
#else
cy = (rr->bottom - rr->top - 200) / 2;
cx = (rr->right - rr->left - 320) / 2;
fb.p = ((u_char *) base_address) + (cy * fb.stride) + cx;
#endif
fb.width = 320;
fb.height = 200;
}
#endif
}
#endif
#if vga_bomb
void
init_vga()
{
vga_modeinfo *modeinfo;
vga_init();
vga_setmode(G320x200x256);
modeinfo = vga_getmodeinfo(G320x200x256);
fb.p = vga_getgraphmem();
fb.stride = modeinfo->linewidth;
fb.width = 320;
fb.height = 200;
}
#endif
#if ogl_bomb || xws_bomb
int
screen_number (Screen *screen)
{
Display *dpy = DisplayOfScreen (screen);
int i;
for (i = 0; i < ScreenCount (dpy); i++)
if (ScreenOfDisplay (dpy, i) == screen)
return i;
abort ();
}
int
visual_class (Screen *screen, Visual *visual)
{
Display *dpy = DisplayOfScreen (screen);
XVisualInfo vi_in, *vi_out;
int out_count, c;
vi_in.screen = screen_number (screen);
vi_in.visualid = XVisualIDFromVisual (visual);
vi_out = XGetVisualInfo (dpy, VisualScreenMask|VisualIDMask,
&vi_in, &out_count);
if (! vi_out) abort ();
c = vi_out [0].class;
XFree ((char *) vi_out);
return c;
}
int
visual_depth (Screen *screen, Visual *visual)
{
Display *dpy = DisplayOfScreen (screen);
XVisualInfo vi_in, *vi_out;
int out_count, d;
vi_in.screen = screen_number (screen);
vi_in.visualid = XVisualIDFromVisual (visual);
vi_out = XGetVisualInfo (dpy, VisualScreenMask|VisualIDMask,
&vi_in, &out_count);
if (! vi_out) abort ();
d = vi_out [0].depth;
XFree ((char *) vi_out);
return d;
}
init_x()
{
Screen *scrn;
XSetWindowAttributes attr;
XWindowAttributes xgwa;
XGCValues argh;
int fb_sz;
unsigned long valuemask;
disp = XOpenDisplay(NULL);
if (NULL == disp) {
fprintf(stderr, "couldn't open display.\n");
exit(1);
}
scrn = DefaultScreenOfDisplay(disp);
#if ogl_bomb
if (1) {
int attrs[] = {None};
vl = glXChooseVisual(disp, 0, attrs);
if (NULL == vl) {
fprintf(stderr, "couldn't find GLX visual.\n");
exit(1);
}
}
#endif
visual = DefaultVisualOfScreen (scrn);
attr.event_mask = KeyPressMask;
valuemask = CWEventMask;
if (PseudoColor == visual_class(scrn, visual)) {
xws_cmap = XCreateColormap(disp, RootWindowOfScreen(scrn),
visual, AllocAll);
valuemask |= CWColormap;
attr.colormap = xws_cmap;
}
win = XCreateWindow(disp,
RootWindowOfScreen(scrn),
(WidthOfScreen(scrn)-pix_rep*320)/2,
(HeightOfScreen(scrn)-pix_rep*200)/2,
pix_rep*320, pix_rep*200, 5, CopyFromParent,
InputOutput, visual, valuemask, &attr);
XMapWindow(disp, win);
depth = visual_depth(DefaultScreenOfDisplay(disp), visual);
#if xws_bomb
argh.function = GXcopy;
gc = XCreateGC(disp, win, GCFunction, &argh);
fb_bpp = ((8 == depth) ? 1 : (16 == depth) ? 2 : 4);
#else
fb_bpp = 1;
#endif
fb_sz = 320 * 200 * fb_bpp;
fb.p = malloc(fb_sz);
fb.stride = 320;
fb.width = 320;
fb.height = 200;
#if xws_bomb
{
if (1 == pix_rep && fb_bpp == 1)
image_buf = (char *) fb.p;
else
image_buf = malloc(320 * 200 * pix_rep * pix_rep * fb_bpp);
xws_image = XCreateImage(disp, visual, depth,
ZPixmap, 0, image_buf,
pix_rep*320, pix_rep*200, 8, 0);
}
#endif
#if ogl_bomb
if (1) {
GLXContext cx;
cx = glXCreateContext(disp, vl, 0, GL_TRUE);
glXMakeCurrent(disp, win, cx);
glRasterPos2f(-1.0, -1.0);
glPixelZoom(pix_rep, pix_rep);
}
#endif
delay = 3.5;
}
#endif
void
init()
{
int i;
long t;
printf("bomb v1.18\n");
init_random();
#if vga_bomb && xws_bomb
if (getenv("DISPLAY")) {
running_x = 1;
init_x();
} else {
running_x = 0;
init_vga();
}
#else
#if vga_bomb
init_vga();
#endif
#if ogl_bomb|xws_bomb
init_x();
#endif
#endif
stabilize_fps = (int) getenv("fps");
fps = 10.0; // just a guess
gparam = &rule.speed;
init_sound();
begin_timer();
for (i = 0; i < status_string_length; i++)
status_string[i] = ' ';
#ifndef win_saver
if (!use_guile) {
char s[1000];
int r, i = 0;
do {
sprintf(s, "%stitle%d.tif", DATA_DIR, i++);
r = load_title(s);
if (1 == r)
while (0 == bomb_getkey());
} while (r);
sprintf(s, "%stitle.tif", DATA_DIR);
load_title(s);
load_title("title.tif");
}
#endif
init_masks();
init_rotor();
init_images();
init_seq();
init_cmaps();
#if use_mpeg
mpeg_init();
#endif
distrib(distrib_new, &rule, &cmap, &fill2);
rule.drift_time = 0.0;
drive_with_image(current_image);
#ifndef win_saver
/* start out with basically the same rule */
rule.rule = rule_rug;
rule.speed = -1;
rule.speed_base = -1;
rule.mask = 255;
rule.remap = 0;
rule.randomized_underflow = 1;
rule.speed_beat_size = sound_present ? 7 : 0;
cmap.cmap = cmap_plain;
cmap.index = 4%ncmaps;
fade2cmap(&cmap);
pix2heat(&fb, &board[dbuf]);
#else
fade2cmap(&cmap);
image8_set_cmap(0, 256, target_cmap);
fill_board(&fill2);
#endif
set_remap(rule.mask, rule.remap);
delayed_fill = 0;
/* this forces the next several rule changes */
auto_rule = 4;
// while (0 == bomb_getkey());
}
int
rule_symmetry(int rule)
{
int r;
switch (rule) {
case rule_rd: r = sym_tile4_stack2; break;
case rule_wave:
case rule_rug_brain:
case rule_rug_anneal:
case rule_rug_anneal2: r = sym_tile4; break;
case rule_acidlife2: r = sym_mirror4; break;
case rule_acidlife1: r = sym_mirror2; break;
case rule_fuse:
case rule_slip: r = sym_frame_buffer; break;
case rule_static: /* false, but useful */
default:
r = sym_one; break;
}
return r;
}
void
change_rules(int old, int new, image8_t *fb)
{
int old_sym = rule_symmetry(old);
int new_sym = rule_symmetry(new);
if (new == rule_rug_image && old != new) {
drive_with_image(current_image);
}
if (old_sym == new_sym)
return;
if (sym_frame_buffer == old_sym) {
pix2heat(fb, &board[dbuf]);
old_sym = sym_one;
}
change_rules2(old_sym, new_sym, &board[dbuf]);
change_rules2(old_sym, new_sym, &board2[dbuf]);
/* some of the rules don't copy board2
rug_rug is always going to fail sometimes until
dbuf/frame&1 is resolved XXX */
change_rules2(old_sym, new_sym, &board2[1-dbuf]);
}
static last_rec_event = 0;
void
record1(char *s, int *n, int nv)
{
if (*n == nv) return;
if (recording &&
frame != last_rec_event) {
fprintf(recording, "(frame %d)\n", frame - last_rec_event);
last_rec_event = frame;
}
*n = nv;
if (recording) {
fprintf(recording, "(%s %d)\n", s, nv);
}
}
void
distrib(int dist, rule_t *rulep, cmap_t *cmap, fill_t *fill)
{
int x, b, i, nbits, nv;
if (rulep) {
static int distrib[] =
{rule_rug, rule_rd, rule_rug_brain, rule_rotorug, rule_rug_image};
if (!(distrib_continuous & dist)) {
init_rotate();
init_shade();
init_wave();
if (!(distrib_rule_lock & dist)) {
do {
if (auto_rule) {
nv = distrib[auto_rule%alen(distrib)];
auto_rule--;
} else {
nv = (R%2) ? (R%nrules) : distrib[R%alen(distrib)];
}
} while (0 == (rule_mask & (1 << nv)));
record1("rule", &rulep->rule, nv);
}
record1("cycle-bkg", &rulep->cycle_bkg, (0 == R%10));
record1("brain", &rulep->brain, R);
if (high_growth_game(rulep)) {
delayed_fill = 1;
}
if (rule_rug_brain == rulep->rule)
record1("brain-shift", &rulep->brain_shift, (R%4) ? 0 : ((R%3) ? (R%5) : (R%25)));
else
record1("brain-shift", &rulep->brain_shift, R);
random_control_point(&rulep->flame_cp);
for (i = 0; i < flame_nspan; i++)
random_control_point(rulep->flame_span+i);
if (auto_rule) {
int i, j;
static int best[] = {0, 1, 2, 5};
int v = best[R%alen(best)];
for (i = 0; i < NXFORMS; i++) {
for (j = 0; j < NVARS; j++)
rulep->flame_cp.xform[i].var[j] = 0.0;
rulep->flame_cp.xform[i].var[v] = 1.0;
}
}
pick_liss_coefs();
if (auto_rule) {
record1("drift", &rulep->drift, 4);
} else if (rule_fuse == rulep->rule)
record1("drift", &rulep->drift, (R%5) ? (R%2) : ((R%2)+2));
else
record1("drift", &rulep->drift, R);
rulep->image_window_size = 2 + R%5;
rulep->speed_beat_speed = (R%3) ? (5 + R%10) : (30 + R%30);
if ((sound_present && (R%3)) || 0 == (R%3))
rulep->speed_beat_size = (R%2) ? (4 + R%12) : (10 + R%22);
else
rulep->speed_beat_size = 0;
rulep->seq[0] = R;
seq_start(rulep->seq);
p1 = R;
current_image = R;
}
rulep->fastflip_rate = ((R&1) ? 0 :
((R&1) ? (R%5) :
(5+(R%20))));
if (1) {
int rbase = 4 + R%8;
for (i = 0; i < MAXRHYTHM; i++)
rulep->rhythm[i] = (R%3 + 1)*rbase;
}
rulep->bsize = (R%4) ? (20 + R%20 + R%20) : (60 + R%80);
rulep->randomized_underflow = R&1;
rulep->search_time = 2 + R%5;
if (R%2) {
rulep->hot = 200;
rulep->cool = 5 + R%20 + R%20;
} else {
rulep->hot = 1 + 5 * (R%3);
rulep->cool = 5 + R%20 + R%10 + rulep->hot;
}
if ((distrib_original & dist) ||
rule_acidlife1 == rulep->rule ||
rule_acidlife2 == rulep->rule ||
rule_rotorug == rulep->rule) {
nbits = R%7 + 8;
rulep->mask = (1<<nbits) - 1;
for (b = R%4; b; b--)
rulep->mask &= ~(2<<(R%nbits));
} else {
nbits = 8 + (R%3 + 1) * (R%2 + 1);
rulep->mask = (1<<nbits) - 1;
for (b = R%3 + 1; b; b--)
rulep->mask &= ~(2<<(R%nbits));
}
switch (rulep->rule) {
case rule_acidlife1:
x = -(1 + (rulep->mask/100) + R%(rulep->mask/30));
break;
case rule_acidlife2:
x = -(R%20);
break;
case rule_rotorug:
x = -(9 + R%(rulep->mask/30));
break;
case rule_wave:
x = -(10 + R%10);
break;
default:
if (distrib_original & dist)
x = -(9 + R%(rulep->mask/30));
else
x = -1;
break;
}
rulep->speed_base = x;
rulep->speed = x;
if (R%4)
rulep->driver_slowdown = 1 + R%8 + R%7;
else
rulep->driver_slowdown = 13 + R%8;
rulep->drift_speed = 8 + R%5;
rulep->remap = R%4;
set_remap(rulep->mask, rulep->remap);
}
if (cmap) {
int nc;
static distrib0[] = {cmap_plain, cmap_plain, cmap_plain,
cmap_loop, cmap_path, cmap_path};
static distrib[] = {cmap_mono, cmap_mono, cmap_mono4, cmap_heat};
static distrib1[] = {cmap_mono, cmap_ramp, cmap_plain};
if (rule.rule == rule_fuse) {
nc = distrib1[R%alen(distrib1)];
} else if (rule.rule == rule_acidlife1)
nc = cmap_split;
else if ((rule.rule == rule_rd) && (R&1))
nc = cmap_path;
else if ((rule.rule == rule_rd2) ||
(rule.rule == rule_quad))
nc = cmap_plain;
else if (R%7)
nc = distrib0[R%alen(distrib0)];
else if (R%100)
nc = distrib[R%alen(distrib)];
else
nc = cmap_noise;
record1("color-type", &cmap->cmap, nc);
record1("color" , &cmap->index, R%ncmaps);
cmap->index2 = R%ncmaps;
}
if (fill) {
static distrib[] = {fill_vnoise, fill_noise};
if (rule.rule == rule_rd ||
rule.rule == rule_rd2 ||
R%2)
fill->fill = distrib[R%alen(distrib)];
else
fill->fill = R%nfills;
}
}
double adjust_speed(double dt) {
return dt * 10.0 / fps;
}
void print_state(rule_t *r) {
printf("rule=%d\n", r->rule);
printf("speed=%d\n", r->speed);
printf("mask=%d\n", r->mask);
printf("randomized_underflow=%d\n", r->randomized_underflow);
printf("cycle_bkg=%d\n", r->cycle_bkg);
printf("remap=%d\n", r->remap);
printf("floor=%d\n", r->floor);
printf("driver_slowdown=%d\n", r->driver_slowdown);
printf("brain=%d (%d)\n", r->brain, iclamp(r->brain, 44));
printf("brain_shift=%d (%d)\n", r->brain_shift, iclamp(r->brain_shift, 26));
printf("hot=%d\n", r->hot);
printf("cool=%d\n", r->cool);
printf("speed_base=%d\n", r->speed_base);
printf("speed_beast_speed=%d\n", r->speed_beat_speed);
printf("speed_beat_size=%d\n", r->speed_beat_size);
printf("drift=%d (%d)\n", r->drift, iclamp(r->drift, 9));
printf("drift_speed=%d\n", r->drift_speed);
printf("bsize=%d\n", r->bsize);
printf("p1=%d\n", p1);
printf("cmap=%d\n", cmap.index);
}
flip_image(int rule_lock)
{
/* Z = zxC-b */ /* at one point, that meant something */
int im = seq_next_image(rule.seq);
file_to_image(im, current_image);
distrib(distrib_new | distrib_continuous | rule_lock, &rule, 0, &fill2);
fill_board(&fill2);
}
int grad_state;
#if 0
int grad_step(int steps) {
int res;
/* fprintf(stderr, "gs%d ", grad_state); */
if (0 == grad_state)
return 1;
else if (grad_none == grad_state) {
grad_state = steps;
} else if (1 == grad_state ||
9 == ((steps - grad_state)%10)) {
image2grad(&board2[dbuf], &board3[0], 1);
} else {
blur(&board2[dbuf], &board2[1-dbuf]);
}
grad_state--;
res = ((steps - grad_state) > 10)
|| (0 == grad_state);
fprintf(stderr, " %d ", res);
return res;
}
#endif
cmap_permute_bits()
{
int i;
for (i = 0; i < 256; i++) {
int j = (i >> 1) | ((i&1) << 7);
int r = current_cmap[3*j+0];
int g = current_cmap[3*j+1];
int b = current_cmap[3*j+2];
SET_TARGET_PALETTE(i, r, g, b);
}
}
#define Rz(d,n) if (n <= 0) return; else d = R%(n)
image_to_heat(Image *src_img, image8_t *fb, board_t *board)
{
int bsize = rule.bsize;
int dest_x, dest_y;
Image src_rect;
image8_t dest = *fb;
int move_heat = 1;
switch (rule_symmetry(rule.rule)) {
case sym_tile4:
case sym_mirror4:
Rz(dest_x, (fb->width>>1) - bsize);
Rz(dest_y, (fb->height>>1) - bsize);
break;
case sym_mirror2:
Rz(dest_x, (fb->width>>1) - bsize);
Rz(dest_y, fb->height - bsize);
break;
case sym_frame_buffer:
move_heat = 0;
default:
Rz(dest_x, fb->width - bsize);
Rz(dest_y, fb->height - bsize);
break;
}
image_random_tile(&src_rect, src_img, bsize);
dest.p = fb->p + fb->stride * dest_y + dest_x;
dest.width = src_rect.width;
dest.height = src_rect.height;
/* could be any operation here, not just copy */
if (1) {
int i, j;
for (i = 0; i < src_rect.height; i++)
for (j = 0; j < src_rect.width; j++)
dest.p[dest.stride * i + j] =
255 - src_rect.pixels[src_rect.stride * i + j].r;
}
if (move_heat)
pix2heat2(fb, board,
dest_x, dest_y,
dest_x + src_rect.width, dest_y + src_rect.height);
}
Image *pick_image(rule_t *p)
{
Image *r;
int n = iclamp(R, p->image_window_size);
switch (p->rule) {
case rule_fuse:
case rule_static:
case rule_slip:
r = &global_images[n];
break;
default:
r = &global_images_small[n];
break;
}
return r;
}
void
changed_gparam(int *gparam)
{
if (&cmap.index == gparam) {
cmap.index = iclamp(cmap.index, ncmaps);
fade2cmap(&cmap);
} else if (&rule.cycle_bkg == gparam ||
&rule.remap == gparam ||
&rule.randomized_underflow == gparam)
*gparam = (*gparam)&1;
else if (&rule.image_window_size == gparam) {
if (*gparam > N_RAM_IMAGES)
*gparam = N_RAM_IMAGES;
else if (*gparam < 1)
*gparam = 1;
} else if (&rule.seq[0] == gparam) {
seq_start(rule.seq);
}
if (&rule.remap == gparam ||
&rule.mask == gparam) {
set_remap(rule.mask, rule.remap);
}
/* printf("changed gparam %#x to %d\n", gparam, *gparam); */
}
void do_mouse(int x, int y) {
switch (rule.rule) {
case rule_rotorug:
rule.bsize = iclamp(x, 320);
if (0) {
extern double spinner_time;
spinner_time = x + y*10;
rule.drift_time = x/32.0 + y;
}
break;
case rule_rug:
rule.speed = iclamp(x,320)/8-20;
break;
case rule_rug_brain:
pen(&board2[dbuf], 1, iclamp(x, 160), iclamp(y, 100), 10);
break;
case rule_rd:
pen(&board[dbuf], 0, iclamp(x,160), iclamp(y, 100), 5);
break;
default:
pen(&board[dbuf], rule.mask, iclamp(x,300), iclamp(y,180), 12);
break;
}
}
#if mac_bomb
static long start_time;
void begin_timer() {
start_time = TickCount();
}
double end_timer() {
return (TickCount() - start_time) / 60.0; /* just a guess */
}
#elif win_bomb
#else
#include <sys/time.h>
static struct timeval start_time;
void
begin_timer()
{
struct timezone tzp;
gettimeofday(&start_time, &tzp);
}
double
end_timer()
{
static struct timeval end_time;
struct timezone tzp;
double t;
gettimeofday(&end_time, &tzp);
return
((end_time.tv_sec - start_time.tv_sec) +
(end_time.tv_usec - start_time.tv_usec) * 1e-6);
}
#endif
void step_rule_rug(int frame, rule_t *p, image8_t *fb);
void step_rule_rug2(int frame, rule_t *p, image8_t *fb);
void step_rule_static(int frame, rule_t *p, image8_t *fb);
void step_rule_rotorug(int frame, rule_t *p, image8_t *fb);
void step_rule_acidlife1(int frame, rule_t *p, image8_t *fb);
void step_rule_acidlife2(int frame, rule_t *p, image8_t *fb);
void step_rule_rug_anneal(int frame, rule_t *p, image8_t *fb);
void step_rule_rug_anneal2(int frame, rule_t *p, image8_t *fb);
void step_rule_rug_rug(int frame, rule_t *p, image8_t *fb);
void step_rule_rug_brain(int frame, rule_t *p, image8_t *fb);
void step_rule_shade(int frame, rule_t *p, image8_t *fb);
void step_rule_wave(int frame, rule_t *p, image8_t *fb);
void step_rule_rug_image(int frame, rule_t *p, image8_t *fb);
void step_rule_slip(int frame, rule_t *p, image8_t *fb);
void step_rule_fuse(int frame, rule_t *p, image8_t *fb);
void step_rule_rug_multi(int frame, rule_t *p, image8_t *fb);
void step_rule_rd(int frame, rule_t *p, image8_t *fb);
void step_rule_rd2(int frame, rule_t *p, image8_t *fb);
int self_play_enabled = !use_guile;
void self_play() {
if (!self_play_enabled)
return;
if (0 >= timer) {
auto_mode = 1;
if (pop_back) {
rule.rule = back_to;
pop_back = 0;
timer = 100;
} else if (permuting) {
permuting--;
cmap_permute_bits();
timer = 150;
} else if (flipper && (rule_rug_brain == rule.rule) && (R%10)) {
switch (flipper) {
case 1:
rule.brain++;
break;
case 2:
distrib(distrib_new|distrib_continuous|rule_lock, &rule, 0, 0);
break;
case 3:
rule.brain_shift =
(R%8) ? (rule.brain_shift + ((R&1) ? -1 : 1)) : 0;
break;
}
timer = 50;
} else if (flipper && (rule_rug == rule.rule) && (R%5)) {
if (2 == flipper) {
rule.rule = rule_rug_image;
pop_back = 1;
back_to = rule_rug;
timer = (R%2) ? 4 : 30;
current_image = iclamp(current_image + 1,
rule.image_window_size);
drive_with_image(current_image);
}
} else if (flipper && (rule_rd == rule.rule) && (R%5)) {
timer = 100;
switch (flipper) {
case 1:
if (1) {
int im = seq_next_image(rule.seq);
file_to_image(im, current_image);
drive_with_image(current_image);
}
break;
case 2:
rule.brain = R;
break;
case 3:
rule.brain_shift = R;
break;
}
} else if (flipper && (rule_fuse == rule.rule) && (R%5)) {
rule.drift = (R%5) ? (R%2) : ((R%2)+2);
timer = 100;
} else if (flipper && (rule_rug_image == rule.rule) && (R%5)) {
static here = 0;
/* create an echo */
if (here = 1-here) {
current_image = iclamp(current_image + 1,
rule.image_window_size);
drive_with_image(current_image);
}
timer = 100;
switch (flipper) {
case 0:
break;
case 1:
if (1) {
int im = seq_next_image(rule.seq);
file_to_image(im, current_image);
drive_with_image(current_image);
}
break;
case 2:
flip_image(rule_lock);
break;
case 3:
rule.rule = rule_rug;
pop_back = 1;
back_to = rule_rug_image;
timer = (R%2) ? 4 : 30;
break;
}
} else if (flipper && (rule_rotorug == rule.rule) && (R%5)) {
timer = 100;
switch (flipper) {
case 1:
p1 = R;
rule.flame_cp = flames[iclamp(p1, nflames)];
break;
case 2:
random_control_point(&rule.flame_cp);
break;
}
} else if (flipper && (rule_rug_rug == rule.rule) && (R%5)) {
distrib(distrib_new|distrib_continuous|rule_lock, &rule, 0, 0);
timer = 200;
} else if (R%2 && (frame - cmap_changed) > 200) {
/* ugh */
if (rule.rule == rule_acidlife1) {
cmap.cmap = cmap_split;
fade2cmap(&cmap);
} else if (rule.rule == rule_quad && R%3) {
cmap_permute_bits();
} else if (rule.rule == rule_fuse && R%4) {
cmap.cmap = cmap_mono;
fade2cmap(&cmap);
} else {
if (frame > 10000 && !(R%20)) {
cmap_permute_bits();
permuting = 7;
} else {
distrib(distrib_new, 0, &cmap, 0);
fade2cmap(&cmap);
}
}
timer = 300;
cmap_changed = frame;
} else if (rule.rule == rule_quad && R%4) {
rule.brain++;
timer = 200;
} else if (R%4) {
int t = rule_lock;
/* this is the same condition as used for overdrive */
if (3 == flipper)
t |= distrib_rule_lock;
distrib(distrib_new | t, &rule, 0, 0);
timer = 300;
/* ugh */
if (rule.rule == rule_acidlife1) {
cmap.cmap = cmap_split;
fade2cmap(&cmap);
}
} else {
if (rule.rule == rule_rd ||
rule.rule == rule_rd2) {
timer = 100;
} else {
distrib(distrib_new, 0, 0, &fill2);
delayed_fill = 1;
timer = 300;
}
}
if (rule.rule == rule_quad) {
timer = timer / 4;
}
flipper = (frame >> 7) & 0x3;
if (!(R%20))
overdrive_speed = 5 + R%10 + R%20;
if (3 == flipper && !auto_rule)
timer = overdrive_speed;
}
if (auto_mode && !(R%500)) image_dst = !image_dst;
if (auto_mode && !(frame%1000)) {
rule.seq[0] = R;
seq_start(rule.seq);
}
/* i really don't know how much i like this stuff */
if (1) {
int tween;
static int tab1[] = {3000, 200, 100, 50};
static int tab2[] = {10000, 200, 100, 50};
if (auto_mode)
switch (rule.rule) {
case rule_slip:
case rule_fuse:
if (!(R%tab1[image_rate]))
image_rate = R&3;
break;
default:
if (frame < 10000)
image_rate = 0;
else if (!(R%tab2[image_rate]))
image_rate = R&3;
break;
}
if (image_rate) {
tween = 1 << ((3-image_rate) * 3);
if (!(frame%tween)) {
if ((3 == flipper2) && (frame > 20000)) {
if (image_dst)
image_to_heat(pick_image(&rule), &fb, &board[dbuf]);
else
image_to_heat(pick_image(&rule), &fb, &board2[dbuf]);
} else {
double_board(image_dst, &board[dbuf], rule_symmetry(rule.rule));
if (flipper2&1)
image_dst = 1-image_dst;
}
}
}
}
}
void param_tweeking(int key) {
/* parameter tweeking */
switch (key) {
/* boy this is really dumb */
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
param = 10 * param + (key - '0');
break;
case '\n':
*gparam = param;
param = 0;
changed_gparam(gparam);
break;
case '.':
incr:
(*gparam)++;
changed_gparam(gparam);
break;
case ',':
(*gparam)--;
changed_gparam(gparam);
break;
#define dogparm(field) \
if (gparam == &(field)) goto incr; gparam = &(field); break;
case 'q': dogparm(cmap.index);
case 'w': dogparm(rule.speed_beat_size);
case 'e': dogparm(rule.speed_beat_speed);
case 'r': dogparm(rule.speed_base);
case 't': dogparm(rule.image_window_size);
case 'y': dogparm(rule.seq[0]);
case 'u': dogparm(rule.remap);
/* should skip patterns without enough bits */
case 'i': dogparm(rule.mask);
case 'o': dogparm(p1); break;
case 'p': dogparm(rule.bsize);
case '[':
case ']': dogparm(rule.driver_slowdown);
case '\\':dogparm(rule.search_time);
case '{': dogparm(rule.hot);
case '}': dogparm(rule.cool);
case '|': dogparm(rule.brain);
case 'P': dogparm(rule.brain_shift);
case 'O': dogparm(rule.cycle_bkg);
case 'I': dogparm(rule.randomized_underflow);
case 5: dogparm(rule.fastflip_rate);
case 'a':
if (rule_rug == rule.rule)
rule.rule = rule_rug2;
else if (rule_rug2 == rule.rule)
rule.rule = rule_rug3;
else
rule.rule = rule_rug;
break;
case 's':
rule.rule = rule_rug_image;
break;
case 'd':
if (rule.rule == rule_rd)
rule.rule = rule_rd2;
else
rule.rule = rule_rd;
break;
case 'f':
if (rule.rule == rule_rotorug)
rule.drift++;
else
rule.rule = rule_rotorug;
break;
case 'g':
if (rule.rule == rule_acidlife2)
rule.rule = rule_acidlife1;
else
rule.rule = rule_acidlife2;
break;
case 'h':
rule.rule = rule_rug_multi;
break;
case 'j':
if (rule.rule == rule_rug_anneal)
rule.rule = rule_rug_anneal2;
else
rule.rule = rule_rug_anneal;
break;
case 'k':
rule.rule = rule_slip;
break;
case 'l':
rule.rule = rule_rug_rug;
break;
case ';':
rule.rule = rule_rug_brain;
break;
case '\'':
if (rule.rule == rule_shade)
rule.rule = rule_wave;
else
rule.rule = rule_shade;
break;
case 'A':
rule.rule = rule_static;
break;
case 'F':
if (rule.rule == rule_fuse)
rule.drift++;
else
rule.rule = rule_fuse;
break;
case 'G':
rule.rule = rule_quad;
break;
case 'L':
rule_lock = rule_lock ? 0 : distrib_rule_lock;
break;
case 'z':
distrib(distrib_new | distrib_continuous | rule_lock, &rule, 0, 0);
break;
case 'x':
if (rule_fuse == rule.rule)
scramble += 4;
else {
distrib(distrib_new, 0, 0, &fill2);
delayed_fill = 1;
}
break;
case 'c':
distrib(distrib_new, 0, &cmap, 0);
fade2cmap(&cmap);
break;
case 'v':
switch (rule.rule) {
case rule_rug:
case rule_rug2:
bomb_pulse();
break;
case rule_rug_image:
current_image = iclamp(current_image + 1,
rule.image_window_size);
drive_with_image(current_image);
break;
case rule_rug_rug:
bomb_pulse_driver();
break;
case rule_rotorug:
if (1) {
int i;
random_control_point(&rule.flame_cp);
for (i = 0; i < flame_nspan; i++)
random_control_point(rule.flame_span+i);
pick_liss_coefs();
init_rotate();
for (i = 0; i < MAXRHYTHM; i++)
rule.rhythm[i] = (R%3 + 1)*8;
}
break;
default:
rule.brain++;
break;
case rule_fuse:
rotate_images();
file_to_image(seq_next_image(rule.seq), 0);
break;
}
break;
case 'b':
switch (rule.rule) {
case rule_rug_brain:
rule.brain_shift = rule.brain_shift ? 0 : (R%7);
break;
case rule_rug_multi:
rule.brain_shift++;
break;
default:
case rule_rd:
/* maybe this should use seq_next_image, or at least
we want the capability (maybe use m) */
file_to_image(p1++, current_image);
drive_with_image(current_image);
break;
}
break;
case 'n':
rule.speed_beat_size = rule.speed_beat_size ? 0 : (R%22);
rule.speed_beat_speed = (R%3) ? (5 + R%10) : (30 + R%30);
break;
case 'm':
if (rule_rug_image == rule.rule) {
int im = seq_next_image(rule.seq);
file_to_image(im, current_image);
drive_with_image(current_image);
} else
rule.brain_shift++;
break;
case '/':
drive_with_image(current_image);
break;
case '?':
#if vga_bomb
vga_setmode(TEXT);
system("/usr/bin/less manual.txt");
vga_setmode(G320x200x256);
image8_set_cmap(0, 256, current_cmap);
#endif
break;
case '-':
*gparam = - (*gparam);
changed_gparam(gparam);
break;
case '=':
write_fb_ppm(&fb);
break;
case 22: /* ^V */
#if use_mpeg
if (periodic_write) {
mpeg_end();
periodic_write = 0;
} else {
char buf[20];
sprintf(buf, "dribble/%03d.mpg", frame);
mpeg_begin(320, 200, buf);
periodic_write = 1;
}
#else
periodic_write = 10 - periodic_write;
#endif
break;
case 'Z':
flip_image(rule_lock);
break;
case 'X':
/* X = zcm */
distrib(distrib_new | distrib_continuous | rule_lock, &rule, &cmap, 0);
init_rotate();
if (rule.rule == rule_acidlife1)
cmap.cmap = cmap_split;
fade2cmap(&cmap);
random_control_point(&rule.flame_cp);
pick_liss_coefs();
break;
case 'Q':
timer = 10;
break;
case 'W':
pulse_cmap_white();
break;
case 'E':
pulse_cmap_black();
break;
case 'R':
pulse_cmap_rotate();
break;
case 'T':
brighten_cmap();
break;
case 'D':
cmap_permute_bits();
break;
case 'V':
rule.brain = 0;
rule.brain_shift = 0;
rule.drift--;
break;
case 'C':
invert_board();
break;
case 'N':
if (1) {
extern smooth_checkers;
smooth_checkers = 1;
}
break;
case 'S':
switch (cmap.cmap) {
case cmap_plain: cmap.cmap = cmap_loop; break;
case cmap_loop: cmap.cmap = cmap_path; break;
case cmap_path: cmap.cmap = cmap_plain; break;
}
fade2cmap(&cmap);
break;
case 'Y':
cool(&fb);
break;
case 'U':
warm(&fb);
break;
case 'H':
double_board(1, &board[dbuf], rule_symmetry(rule.rule));
break;
case 'J':
double_board(0, &board[dbuf], rule_symmetry(rule.rule));
break;
case 2: /* ^B */
rotate_images();
file_to_image(R, current_image);
drive_with_image(current_image);
break;
case 15: /* ^O */
rotate_images();
file_to_image(R, 0);
break;
case 26: /* ^Z */
random_image_set();
break;
case 14: /* ^N */
if (recording) {
fclose(recording);
recording = NULL;
} else {
char buf[30];
sprintf(buf, "clip-%02d.scm", nrecords++);
recording = fopen(buf, "w");
if (!recording)
perror("fopen");
}
break;
case 'M':
rule.flame_cp = flames[iclamp(p1, nflames)];
break;
case 9: /* ^I */
image_to_heat(pick_image(&rule), &fb, &board[dbuf]);
image_dst = 1;
break;
case 21: /* ^U */
image_to_heat(pick_image(&rule), &fb, &board2[dbuf]);
image_dst = 0;
break;
case 25: /* ^Y */
image_rate = (image_rate+1)&0x3;
break;
/*
for rbd's ballet music
case 'P':
rule.speed = -1;
rule.speed_base = -1;
rule.mask = 767;
rule.driver_slowdown = 9;
cmap.cmap = cmap_loop;
fade2cmap(&cmap);
break;
case 'O':
rule.speed = -1;
rule.speed_base = -1;
rule.mask = 1023;
rule.driver_slowdown = 60;
cmap.cmap = cmap_plain;
cmap.index = 58;
fade2cmap(&cmap);
break;
case 'K':
cmap.cmap = cmap_mono;
fade2cmap(&cmap);
break;
case 'J':
cmap.cmap = cmap_heat;
fade2cmap(&cmap);
break;
*/
case 'B':
cmap.cmap = cmap_black;
fade2cmap(&cmap);
break;
case 18: /* ^R */
dtime++;
if (dtime == 8)
dtime = 1;
break;
default:
printf("unknown key = %d\n", key);
break;
}
}
void mood_organ(int key) {
switch (key) {
case 'a':
rule.rule = rule_rug;
rule.speed = -1;
rule.speed_base = -1;
rule.mask = 255;
rule.remap = 0;
rule.randomized_underflow = 1;
rule.speed_beat_size = 0;
rule.hot = 1;
rule.cool = 100;
cmap.cmap = cmap_plain;
fade2cmap(&cmap);
break;
case 'b':
rule.rule = rule_rug_image;
rule.speed = -1;
rule.mask = 255;
rule.remap = 0;
rule.randomized_underflow = 1;
rule.speed_base = -1;
rule.speed_beat_size = 10;
rule.speed_beat_speed = 50;
rule.hot = 1;
rule.cool = 100;
cmap.cmap = cmap_plain;
fade2cmap(&cmap);
break;
case 'c':
rule.rule = rule_rug;
rule.speed = -1;
rule.speed_base = -1;
rule.randomized_underflow = 0;
rule.mask = 759;
rule.remap = 0;
rule.hot = 1;
rule.cool = 20;
rule.speed_beat_size = 0;
break;
case 'd':
rule.rule = rule_rug2;
rule.speed = -1;
rule.randomized_underflow = 1;
rule.mask = 1023;
rule.remap = 0;
rule.hot = 6;
rule.cool = 32;
rule.speed_base = -1;
rule.speed_beat_size = 0;
fill2.fill = fill_vnoise;
fill_board(&fill2);
break;
case 'e':
rule.rule = rule_rug;
rule.speed = -1;
rule.speed_base = -1;
rule.mask = 1791;
rule.randomized_underflow = 1;
rule.hot = 6;
rule.remap = 0;
rule.cool = 2;
rule.speed_beat_size = 0;
fill2.fill = fill_noise;
fill_board(&fill2);
break;
case 'f':
rule.rule = rule_rug_image;
rule.speed = -1;
rule.mask = 255;
rule.remap = 0;
rule.randomized_underflow = 1;
rule.speed_base = -1;
rule.speed_beat_size = 0;
file_to_image(p1++, current_image);
drive_with_image(current_image);
fill2.fill = fill_noise;
fill_board(&fill2);
break;
case 'g':
rule.rule = rule_rd;
rule.brain = 0;
rule.brain_shift = 0;
fill2.fill = fill_noise;
fill_board(&fill2);
cmap.cmap = cmap_loop;
fade2cmap(&cmap);
break;
case 'h':
rule.rule = rule_rd;
rule.brain = 1;
rule.brain_shift = 3;
fill2.fill = fill_noise;
fill_board(&fill2);
cmap.cmap = cmap_loop;
fade2cmap(&cmap);
break;
case 'i':
rule.rule = rule_rd;
rule.brain = 1;
rule.brain_shift = 5;
fill2.fill = fill_noise;
fill_board(&fill2);
file_to_image(p1++, current_image);
drive_with_image(current_image);
cmap.cmap = cmap_loop;
fade2cmap(&cmap);
break;
case 'j':
rule.rule = rule_rotorug;
rule.speed = -18;
rule.speed_base = -18;
rule.speed_beat_size = 0;
rule.mask = 367;
rule.remap = 1;
rule.drift = 0;
rule.drift_speed = 13;
rule.bsize = 47;
cmap.cmap = cmap_plain;
fade2cmap(&cmap);
break;
case 'k':
rule.rule = rule_rotorug;
rule.mask = 255;
rule.speed = -1;
rule.speed_base = -1;
rule.speed_beat_size = 0;
rule.drift = 4;
rule.drift_speed = 10;
rule.bsize = 56;
rule.remap = 0;
cmap.cmap = cmap_plain;
fade2cmap(&cmap);
break;
case 'l':
rule.rule = rule_rotorug;
rule.mask = 509;
rule.speed_beat_size = 0;
rule.speed = -11;
rule.speed_base = -11;
rule.drift = 8;
rule.drift_speed = 8;
rule.bsize = 89;
rule.remap = 0;
cmap.cmap = cmap_plain;
fade2cmap(&cmap);
break;
case 'm':
rule.rule = rule_acidlife2;
rule.mask = 1919;
rule.speed_beat_size = 9;
rule.speed_beat_speed = 40;
rule.speed_base = -2;
rule.speed = -2;
rule.brain = 0;
break;
case 'n':
rule.rule = rule_acidlife1;
rule.mask = 511;
rule.brain = 0;
rule.speed_base = -19;
rule.speed = -19;
cmap.cmap = cmap_split;
fade2cmap(&cmap);
fill2.fill = fill_noise;
fill_board(&fill2);
break;
default:
printf("undefined mood = %d\n", key);
break;
}
}
void
bomb_work()
{
sprintf(status_string+20, "%d %d %d", rule.speed, rule.mask, cmap.index);
if (!((frame+1)%100)) {
int bs;
int notty = NULL != getenv("EMACS");
fps = 100.0/end_timer();
sprintf(status_string, "%04.1lf ", fps);
#if 0
if (!notty)
putchar(13);
printf ("frame=%d fps=%.3g delay=%.3g ",
frame+1, fps, delay);
if (notty)
printf("\n");
else
fflush(stdout);
#endif
begin_timer();
/* here is the target frames per second */
delay += 0.2 * (fps - argd("fps", 15.0));
if (delay < 0.0) delay = 0.0;
}
if (delay >= 1.0 && stabilize_fps) {
#ifdef sgi
sginap(quantize(delay));
#elif defined(linux)
usleep((int)(delay * 1e4));
#else
;
#endif
}
if (pulse) {
pulse = 0;
rule.floor = 0;
} else {
int n = rule.hot + rule.cool;
if (0 == n) rule.floor = 0;
else rule.floor = (frame % n) > rule.hot;
}
if (periodic_write &&
0 == (frame % periodic_write)) {
#if use_mpeg
write_fb_mpeg(&fb);
#else
write_fb_ppm(&fb);
#endif
}
if (rule.rule == rule_fuse
&& rule.fastflip_rate
&& --fastflip<=0) {
fastflip = rule.fastflip_rate;
rotate_images();
file_to_image(seq_next_image(rule.seq), 0);
}
if (rule.rule == rule_fuse && (1 == iclamp(rule.drift, fuse_ndrifts))) {
extern double avg_pix;
run_hist(&fb);
if (avg_pix > 180.0) cool(&fb);
} else if ( auto_mode && run_hist(&fb) &&
frame - last_clear > 400) {
fill2.fill = fill_noise;
delayed_fill = 1;
}
step_cmap();
#if win_bomb
if (1) {
extern int mouse_down, mouse_x, mouse_y;
if (mouse_down) {
do_mouse(mouse_x, mouse_y);
}
}
#endif
#if mac_bomb
if (1) {
Point p;
EventRecord gEvent;
if (GetOSEvent( mDownMask, &gEvent) || StillDown()) {
GetMouse(&p);
do_mouse(p.h, p.v);
}
GetOSEvent( mUpMask, &gEvent);
}
#endif
switch (rule.rule) {
case rule_rug:
step_rule_rug(frame, &rule, &fb);
break;
case rule_rug2:
step_rule_rug2(frame, &rule, &fb);
break;
case rule_rug3:
step_rule_rug3(frame, &rule, &fb);
break;
case rule_static:
step_rule_static(frame, &rule, &fb);
break;
case rule_rotorug:
step_rule_rotorug(frame, &rule, &fb);
break;
case rule_acidlife1:
step_rule_acidlife1(frame, &rule, &fb);
break;
case rule_acidlife2:
step_rule_acidlife2(frame, &rule, &fb);
break;
case rule_rug_anneal:
step_rule_rug_anneal(frame, &rule, &fb);
break;
case rule_rug_anneal2:
step_rule_rug_anneal2(frame, &rule, &fb);
break;
case rule_rug_rug:
step_rule_rug_rug(frame, &rule, &fb);
break;
case rule_rug_brain:
step_rule_rug_brain(frame, &rule, &fb);
break;
case rule_shade:
step_rule_shade(frame, &rule, &fb);
break;
case rule_wave:
step_rule_wave(frame, &rule, &fb);
break;
case rule_rug_image:
step_rule_rug_image(frame, &rule, &fb);
break;
case rule_slip:
step_rule_slip(frame, &rule, &fb);
break;
case rule_fuse:
step_rule_fuse(frame, &rule, &fb);
break;
case rule_rug_multi:
step_rule_rug_multi(frame, &rule, &fb);
break;
case rule_rd:
step_rule_rd(frame, &rule, &fb);
break;
case rule_rd2:
step_rule_rd2(frame, &rule, &fb);
break;
case rule_quad:
step_rule_quad(frame, &rule, &fb);
/*step_rule_quad(frame, &rule, &fb);*/
break;
default:
printf("bad rule: %d\n", rule.rule);
step_rule_rug(frame, &rule, &fb);
break;
}
frame++;
timer = timer - adjust_speed(dtime);
old_rule = rule.rule;
if (pulse_driver) {
pulse_driver = 0;
rule.driver_slowdown = 0;
}
if (((key = bomb_getkey()) > 0) && keyboard_enabled) {
timer = 100000;
auto_mode = 0;
image_rate = 0;
/* kbd_mode independent controls */
switch (key) {
case ' ':
auto_rule = 0;
distrib(distrib_new | rule_lock, &rule, &cmap, &fill2);
fade2cmap(&cmap);
delayed_fill = 1;
timer = 2000;
break;
case '`':
print_state(&rule);
break;
case 6: /* ^F */
display_fps = !display_fps;
break;
case '1':
kbd_mode = 0;
break;
case '2':
kbd_mode = 1;
break;
case '3':
kbd_mode = 2;
break;
case '4':
kbd_mode = 3;
break;
case 27:
case 3:
bomb_exit();
break;
default:
switch (kbd_mode) {
case 0:
param_tweeking(key);
break;
case 1:
mood_organ(key);
break;
case 2:
/* image organ */
file_to_image(key, current_image);
drive_with_image(current_image);
break;
case 3:
/* color organ */
cmap.index = (key>>1)%ncmaps;
cmap.cmap = (key&1) ? cmap_plain : cmap_loop;
fade2cmap(&cmap);
break;
}
}
}
#ifndef wbomb
self_play();
#endif
flipper = (frame >> 9) & 0x3;
flipper2 = (frame >> 10) & 0x3;
change_rules(old_rule, rule.rule, &fb);
if (delayed_fill) {
fill_board(&fill2);
delayed_fill = 0;
last_clear = frame;
}
#if !use_sioux
image8_flush();
#endif
if (1) {
int s;
if (rule.rule == rule_rotorug) {
if (sound_present) {
s = get_beat(1);
rule.drift_time = frame + 1000 + 2*s;
rule.drift_speed = s;
} else
rule.drift_time += rule.drift_speed;
} else {
s = get_beat(0);
if (sound_present) {
rule.speed = rule.speed_base - (rule.speed_beat_size * s / 3);
} else {
rule.speed = rule.speed_base + 0.5 * rule.speed_beat_size *
sin(2.0 * M_PI * frame / rule.speed_beat_speed);
}
}
#if mac_bomb
if (0) {
Rect r;
r.top = 0;
r.bottom = 100;
r.left = 0;
r.right = 800;
if (frame%800 == 0)
EraseRect(&r);
PenNormal();
MoveTo(frame%800, 50+s);
LineTo(frame%800, 50+0);
}
#endif
}
}
void
bomb_clear(int c) {
fill2.fill = c;
delayed_fill = 1;
}
void
bomb_pulse() {
rule.floor = 0;
rule.cool = 999999;
pulse = 1;
}
void
bomb_pulse_driver() {
rule.driver_slowdown = -1;
pulse_driver = 1;
}
void bomb_set_flame(int r) {
if (-1 == r) {
random_control_point(&rule.flame_cp);
pick_liss_coefs();
} else {
rule.flame_cp = flames[iclamp(r, nflames)];
}
}
void bomb_set_rule(int r) { rule.rule = r; }
void bomb_set_speed(int r) {
rule.speed = r;
rule.speed_base = r;
rule.speed_beat_size = 0;
}
void bomb_set_mask(int r) { rule.mask = r; }
void bomb_set_pen_size(int r) { rule.bsize = r; }
void bomb_set_drift(int r) { rule.drift = r; }
void bomb_set_brain(int r) { rule.brain = r; }
void bomb_set_brain_shift(int r) { rule.brain_shift = r; }
void bomb_set_drift_speed(int r) { rule.drift_speed = r; }
void bomb_set_randomized_underflow(int r) { rule.randomized_underflow = r; }
void bomb_set_color(int r) { cmap.index = r; fade2cmap(&cmap); }
void bomb_set_color_type(int r) { cmap.cmap = r; fade2cmap(&cmap); }
void bomb_set_cycle_background(int r) {rule.cycle_bkg = r;}
void bomb_set_remap_colors(int r) {rule.remap = r;}
#if !win_bomb
#if use_guile
#define gh_void (gh_int2scm(0))
SCM
c_bomb_work(SCM s_n) {
int n = gh_scm2int(s_n);
int i;
for (i = 0; i < n; i++) {
gh_defer_ints();
bomb_work();
gh_allow_ints();
}
return gh_void;
}
SCM
c_fill_board(SCM s_fill) {
int n = gh_scm2int(s_fill);
fill2.fill = n;
gh_defer_ints();
fill_board(&fill2);
gh_allow_ints();
return gh_void;
}
SCM
c_set_color(SCM s_color) {
int c;
gh_defer_ints();
c = gh_scm2int(s_color);
bomb_set_color(iclamp(c, ncmaps));
gh_allow_ints();
return gh_void;
}
SCM
c_set_color_type(SCM s_color) {
gh_defer_ints();
bomb_set_color_type(gh_scm2int(s_color));
gh_allow_ints();
return gh_void;
}
SCM
c_pulse() {
bomb_pulse();
return gh_void;
}
SCM
c_pulse_driver() {
bomb_pulse_driver();
return gh_void;
}
SCM
c_get_flame_cp() {
char buf[4000];
gh_defer_ints();
buf[0] = 0;
sprint_control_point(buf, &rule.flame_cp, 0);
gh_allow_ints();
return gh_str2scm(buf, strlen(buf));
}
SCM
c_set_flame_cp(SCM s_s) {
char *s = gh_scm2newstr(s_s, NULL);
gh_defer_ints();
parse_control_point(&s, &rule.flame_cp);
gh_allow_ints();
return gh_void;
}
SCM
c_random_flame_dir() {
pick_liss_coefs();
return gh_void;
}
SCM
c_random_flame_cp() {
random_control_point(&rule.flame_cp);
return gh_void;
}
SCM
c_get_flame_dir() {
char buf[4000];
gh_defer_ints();
buf[0] = 0;
sprint_control_point(buf, &cc_direction, 0);
gh_allow_ints();
return gh_str2scm(buf, strlen(buf));
}
SCM
c_set_flame_dir(SCM s_s) {
char *s = gh_scm2newstr(s_s, NULL);
gh_defer_ints();
parse_control_point(&s, &cc_direction);
normalize_liss_coefs();
gh_allow_ints();
return gh_void;
}
SCM
c_srandom(SCM s_s) {
int seed = gh_scm2int(s_s);
srandom(seed);
return gh_void;
}
SCM
c_set_drift_time(SCM s_var) {
int n = gh_scm2double(s_var);
rule.drift_time = n;
return gh_void;
}
SCM
c_get_drift_time() {
return gh_double2scm(rule.drift_time);
}
SCM
c_file_to_image(SCM s_im, SCM s_n) {
int im = gh_scm2int(s_im);
int n = gh_scm2int(s_n);
file_to_image(im, n);
return gh_void;
}
SCM
c_drive_with_image(s_n) {
int n = gh_scm2int(s_n);
drive_with_image(n);
return gh_void;
}
/* fails why? */
#define make_var(loc_name, name) \
SCM \
c_var_ ## name(SCM s_var) { \
if (NULL == s_var) \
return gh_int2scm(loc_name); \
loc_name = gh_scm2int(s_var); \
return gh_void; \
}
#define make_get_set(loc_name, name) \
\
SCM \
c_set_ ## name(SCM s_var) {\
int n = gh_scm2int(s_var);\
loc_name = n;\
return gh_void;\
}\
\
SCM \
c_get_ ## name() {\
return gh_int2scm(rule.rule);\
}
make_get_set(rule.rule, rule)
make_get_set(rule.speed, speed)
make_get_set(rule.mask, mask)
make_get_set(rule.randomized_underflow, randomized_underflow)
make_get_set(rule.cycle_bkg, cycle_bkg)
make_get_set(rule.remap, remap)
make_get_set(rule.floor, floor)
make_get_set(rule.driver_slowdown, driver_slowdown)
make_get_set(rule.brain, brain)
make_get_set(rule.brain_shift, brain_shift)
make_get_set(rule.drift, drift)
make_get_set(rule.drift_speed, drift_speed)
make_get_set(rule.bsize, bsize)
make_get_set(rule.hot, hot)
make_get_set(rule.cool, cool)
void
main_prog(int argc, char *argv[])
{
init();
gh_new_procedure1_0("bomb-do-frame", c_bomb_work);
gh_new_procedure1_0("bomb-fill", c_fill_board);
gh_new_procedure0_0("bomb-pulse", c_pulse);
gh_new_procedure0_0("bomb-pulse-driver", c_pulse_driver);
gh_new_procedure1_0("bomb-set-color", c_set_color);
gh_new_procedure1_0("bomb-set-color-type", c_set_color_type);
#if 0
gh_new_procedure0_1("bomb-rule", c_var_rule);
#endif
gh_new_procedure1_0("bomb-set-rule", c_set_rule);
gh_new_procedure0_0("bomb-get-rule", c_get_rule);
gh_new_procedure1_0("bomb-set-speed", c_set_speed);
gh_new_procedure0_0("bomb-get-speed", c_get_speed);
gh_new_procedure1_0("bomb-set-mask", c_set_mask);
gh_new_procedure0_0("bomb-get-mask", c_get_mask);
gh_new_procedure1_0("bomb-set-randomized-underflow", c_set_randomized_underflow);
gh_new_procedure0_0("bomb-get-randomized-underflow", c_get_randomized_underflow);
gh_new_procedure1_0("bomb-set-remap", c_set_remap);
gh_new_procedure0_0("bomb-get-remap", c_get_remap);
gh_new_procedure1_0("bomb-set-floor", c_set_floor);
gh_new_procedure0_0("bomb-get-floor", c_get_floor);
gh_new_procedure1_0("bomb-set-driver-slowdown", c_set_driver_slowdown);
gh_new_procedure0_0("bomb-get-driver-slowdown", c_get_driver_slowdown);
gh_new_procedure1_0("bomb-set-brain", c_set_brain);
gh_new_procedure0_0("bomb-get-brain", c_get_brain);
gh_new_procedure1_0("bomb-set-brain-shift", c_set_brain_shift);
gh_new_procedure0_0("bomb-get-brain-shift", c_get_brain_shift);
gh_new_procedure1_0("bomb-set-drift", c_set_drift);
gh_new_procedure0_0("bomb-get-drift", c_get_drift);
gh_new_procedure1_0("bomb-set-drift-speed", c_set_drift_speed);
gh_new_procedure0_0("bomb-get-drift-speed", c_get_drift_speed);
gh_new_procedure1_0("bomb-set-pen-size", c_set_bsize);
gh_new_procedure0_0("bomb-get-pen-size", c_get_bsize);
gh_new_procedure1_0("bomb-set-hot", c_set_hot);
gh_new_procedure0_0("bomb-get-hot", c_get_hot);
gh_new_procedure1_0("bomb-set-cool", c_set_cool);
gh_new_procedure0_0("bomb-get-cool", c_get_cool);
gh_new_procedure1_0("bomb-set-cycle-bkg", c_set_cycle_bkg);
gh_new_procedure0_0("bomb-get-cycle-bkg", c_get_cycle_bkg);
gh_new_procedure1_0("bomb-set-flame-cp", c_set_flame_cp);
gh_new_procedure0_0("bomb-get-flame-cp", c_get_flame_cp);
gh_new_procedure1_0("bomb-set-flame-dir", c_set_flame_dir);
gh_new_procedure0_0("bomb-get-flame-dir", c_get_flame_dir);
gh_new_procedure1_0("bomb-set-drift-time", c_set_drift_time);
gh_new_procedure0_0("bomb-get-drift-time", c_get_drift_time);
gh_new_procedure0_0("bomb-random-flame-cp", c_random_flame_cp);
gh_new_procedure0_0("bomb-random-flame-dir", c_random_flame_dir);
gh_new_procedure1_0("bomb-srandom", c_srandom);
gh_new_procedure1_0("bomb-drive-with-image", c_drive_with_image);
gh_new_procedure2_0("bomb-file-to-image", c_file_to_image);
gh_eval_str("(load \"bomb.scm\")");
if (1 == argc) {
while (1)
bomb_work();
} else {
int i;
char s[1000];
for (i = 1; i < argc; i++) {
sprintf(s, "(load \"%s\")", argv[i]);
gh_eval_str(s);
}
}
}
void
main(int argc, char *argv[])
{
gh_enter(argc, argv, main_prog);
}
#else
void
main()
{
init();
while (1) {
bomb_work();
}
}
#endif
message(char *s) {}
#endif