|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T m
Length: 9961 (0x26e9)
Types: TextFile
Names: »main.c.orig«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/Sun/Qix/main.c.orig«
/*
* The game of Qix for the Sun3 workstation running Sunview (probably 3.0)--
* Appearance ONLY shamelessly stolen from the real video game wonderfully
* and admirably written by individual(s) unknown at Taito Corp (I think).
*
* Copyright 1987 by Dan Heller (island!argv@sun.com or argv@spam.istc.sri.com)
*
* Various polygon filling routines written by
* -- Dan "Sky" Shultz (island!sky@sun.com) and
* -- Don Hatch (splat%ucscb@ucscc.ucsc.edu [fall, 1987])
* additional help (general debugging, recursive polyfill)
*
* Move mouse to go in direction. Left button does fast draw. Middle does
* slow draw. Rogue/vi keys moves -- upper case draws. There is no slow
* draw for keyboard input.
*
* There is not yet a stage where you split two qix.
*
* Sparx don't do what they should; they move randomly and without purpose.
* They only kill the user -- there are no aggressive sparx.
*
* The qix will sometimes get into an infinite loop trying to get itself
* or a portion of itself out of a place it shouldn't be (closed area).
*/
#include "qix.h"
/* the main icon for when the tool is closed */
short qix_icon_dat[] = {
#include "qix.icon"
};
DEFINE_ICON_FROM_IMAGE(qix_icon, qix_icon_dat);
int (*old_repaint_func)();
redraw(args)
{
stop_timer();
(*old_repaint_func)(&args);
start_timer();
}
main(argc, argv)
char *argv[];
{
int catch();
char **newargv = argv;
(void) signal(SIGBUS, catch);
(void) signal(SIGSEGV, catch);
(void) signal(SIGXCPU, catch);
#ifdef DEBUG
/*
* specify debug levels "-d level"
* a level of 2 prints polygon fill info. 4 disables spark-generation
* but doesn't kill current sparks. debug level 1 does prints things...
*/
while (*++newargv)
if (!strcmp(*newargv, "-q"))
no_qix_kill = 1;
else if (!strcmp(*newargv, "-d"))
debug = (*++newargv) ? atoi(*newargv) : 1;
#endif DEBUG
frame = window_create(NULL, FRAME,
FRAME_LABEL, argv[0],
WIN_X, 250, WIN_Y, 45,
FRAME_ICON, &qix_icon,
FRAME_ARGS, argc, argv,
FRAME_NO_CONFIRM, TRUE,
0);
Draw = window_create(frame, CANVAS,
WIN_HEIGHT, BOARD_HEIGHT_IN_PIXELS,
WIN_WIDTH, BOARD_WIDTH_IN_PIXELS,
WIN_EVENT_PROC, move_joystick,
0);
draw_win = canvas_pixwin(Draw);
window_set(Draw,
CANVAS_FAST_MONO, TRUE,
WIN_CONSUME_PICK_EVENTS,
WIN_MOUSE_BUTTONS,
0,
WIN_CONSUME_KBD_EVENTS,
WIN_ASCII_EVENTS,
SHIFT_CTRL, SHIFT_META,
0,
WIN_INPUT_DESIGNEE, window_get(Draw, WIN_DEVICE_NUMBER),
0);
Joystick = window_create(frame, CANVAS,
WIN_X, 0,
WIN_BELOW, Draw,
WIN_HEIGHT, 68,
WIN_WIDTH, WIN_EXTEND_TO_EDGE,
0);
joystick_win = canvas_pixwin(Joystick);
window_fit(frame);
if (!(small_font = pf_open("/usr/people/argv/computer.14")) &&
!(small_font = pf_default()) ||
!(big_font = pf_open("/usr/lib/fonts/fixedwidthfonts/serif.r.16")) &&
!(big_font = pf_default()))
perror("can't open default font"), exit(1);
level = -2; /* two screens before player may split two qix */
moving = NO_MOVE;
fast = 1,
srandom(time(0));
srand(time(0));
update_score();
init_qix();
draw_joystick();
pw_text(joystick_win, 92, 24, PIX_SRC, small_font, "Fast Slow");
play_mode = SHOW_SCORES;
update_score();
score_board(TRUE, FALSE);
time_left = 100; /* timeout before next demo mode switch */
(void) signal(SIGALRM, move_pen);
old_repaint_func = (int(*)())window_get(frame, CANVAS_REPAINT_PROC);
window_set(frame, CANVAS_REPAINT_PROC, redraw, 0);
start_timer();
window_main_loop(frame); /* main loop to read input */
exit(0);
}
clear_board()
{
register int x, y;
clear_sparks();
area_closed = 0;
pen_x = (BOARD_WIDTH-1)/2, pen_y = BOARD_HEIGHT-1;
remove_msgs(1);
/* give left->right sweeping effect like the real game */
for (x = 0; x < BOARD_WIDTH_IN_PIXELS; x++)
draw(x, 0, x, BOARD_HEIGHT_IN_PIXELS-1, PIX_CLR);
box(convert_x(0), convert_y(0),
convert_x(BOARD_WIDTH-1), convert_y(BOARD_HEIGHT-1), PIX_SRC);
/* clear the interior of the board */
for (x = 1; x < BOARD_WIDTH-1; x++)
for (y = 1; y < BOARD_HEIGHT-1; y++)
board[x][y] = 0;
for (x = 1; x < BOARD_WIDTH-1; x++) {
board[x][0] = CL_LN_LF | CL_LN_RT | OLD_LINE | CL_PNT_TOP;
board[x][BOARD_HEIGHT-1] = CL_LN_LF | CL_LN_RT | OLD_LINE | CL_PNT_BOT;
}
for (y = 1; y < BOARD_HEIGHT-1; y++) {
board[0][y] = CL_LN_UP | CL_LN_DN | OLD_LINE | CL_PNT_LEFT;
board[BOARD_WIDTH-1][y] = CL_LN_UP | CL_LN_DN | OLD_LINE | CL_PNT_RIGHT;
}
/* set the corners explicitly */
board[0][0] = (CL_LN_DN | CL_LN_RT | CL_PNT_TOP | CL_PNT_LEFT | OLD_LINE);
board[0][BOARD_HEIGHT-1] =
(CL_LN_UP | CL_LN_RT | CL_PNT_BOT | CL_PNT_LEFT | OLD_LINE);
board[BOARD_WIDTH-1][0] =
(CL_LN_DN | CL_LN_LF | CL_PNT_TOP | CL_PNT_RIGHT | OLD_LINE);
board[BOARD_WIDTH-1][BOARD_HEIGHT-1] =
(CL_LN_UP | CL_LN_LF | CL_PNT_BOT | CL_PNT_RIGHT | OLD_LINE);
}
/*
* change the status of the player. If he's living, we add special
* effects and do the cleanup from the last game. setup the right icons
* and grab all the io on the screen. If he's dead, release the IO
* from the screen and reset critical values.
*/
change_life(live_or_die)
{
register int x, n, m = (live_or_die == -1)? 40 : 300;
stop_timer();
if (live_or_die == LIVE) {
move_fuse(fuse = (struct region *)NULL); /* erase the last fuse */
if (region) {
pen_x = region->x, pen_y = region->y;
rm_cur_line(PIX_CLR); /* remove the current line drawn */
}
if (lives <= 0) {
if (play_mode == DEMO)
lives = 1;
else
lives = MAX_LIVES;
clear_board(); /* resets pen_x, pen_y */
level = -2, score = 0;
} else {
extern int qix1_x0[], qix1_x1[], qix1_y0[], qix1_y1[];
extern int qix2_x0[], qix2_x1[], qix2_y0[], qix2_y1[];
draw(convert_x(qix1_x0[0]), convert_y(qix1_y0[0]),
convert_x(qix1_x1[0]), convert_y(qix1_y1[0]), PIX_CLR);
if (level >= 0)
draw(convert_x(qix2_x0[0]), convert_y(qix2_y0[0]),
convert_x(qix2_x1[0]), convert_y(qix2_y1[0]), PIX_CLR);
}
Speed = 3 + min(level/3, 3);
#ifdef DEBUG
if (debug)
printf("Speed = %d\n", Speed);
#endif DEBUG
clear_sparks();
update_score();
moving = STOP;
drawing = FALSE;
if (level > 0) {
msg("All scores now\n%d times\ntheir original value.", level+1);
sleep(3);
remove_msgs(0);
}
place_pen(); /* make pen appear */
}
for (x = 0; x < 2; x++)
for (n = m; n >= 40 && n <= 300; n -= 5 * live_or_die)
box(pen_coord_x(pen_x)-n/2, pen_coord_y(pen_y)-n/2,
pen_coord_x(pen_x)+n/2, pen_coord_y(pen_y)+n/2, XOR);
if (live_or_die == DIE) {
is_alive = FALSE;
if (--lives <= 0) {
reset_joystick_win(TRUE);
msg("Game Over.");
sleep(2);
/* if he got on the scoreboard, let him put his initials up */
if (play_mode == REAL_PLAY)
score_board(FALSE, FALSE);
if (play_mode == SHOW_SPIRAL)
time_left = 50; /* demo mode comes after spiral death trap */
else {
score_board(TRUE, FALSE);
play_mode = SHOW_SCORES;
time_left = 100; /* show scores after demo mode or real play */
}
moving = NO_MOVE;
} else {
moving = STOP;
drawing = 0;
}
place_pen(); /* erase pen */
} else {
is_alive = TRUE;
reset_joystick_win(FALSE);
}
start_timer();
}
update_score()
{
char buf[128];
int x;
sprintf(buf, "Score: %6d", score);
pw_text(joystick_win, 500, 22, PIX_SRC, big_font, buf);
pw_text(joystick_win, 500, 22, PIX_SRC|PIX_DST, big_font, buf);
if (play_mode != REAL_PLAY) {
pw_text(draw_win, 105, 12, PIX_SRC, small_font,
"Click RIGHT mouse button or use <spacebar> to start new game.");
return;
}
pw_text(joystick_win, 500, 45, PIX_SRC, big_font, "Lives: ");
for (x = 0; x < MAX_LIVES; x++)
pw_rop(joystick_win, 575+(x*20), 32, 16,16, (x < lives-1)?
PIX_SRC:PIX_CLR, &pen_image, 0, 0);
sprintf(buf, "Filled: %d%%",(int)((double)area_closed/TOTAL_AREA*100));
pw_text(draw_win, 280, 12, PIX_SRC, small_font, buf);
pw_text(draw_win, 281, 12, PIX_SRC|PIX_DST, small_font, buf);
}
Pixrect *save[15]; /* area under text to be redisplayed upon removal of text */
int x_save[15], y_save, x_pos[15], y_pos[15];
static int msgs; /* the number of text lines displayed on the board */
/* print a message somewhere at the top of the playing board for two seconds */
msg(fmt, args)
char *fmt;
{
char buf[BUFSIZ], *index();
register char *p2, *p = buf;
y_save = l_height(big_font) + 1;
vsprintf(buf, fmt, &args);
#ifdef DEBUG
puts(buf);
#endif DEBUG
do {
if (p2 = index(p, '\n'))
*p2 = 0;
x_save[msgs] = strlen(p) * l_width(big_font) + 1;
x_pos[msgs] = BOARD_WIDTH_IN_PIXELS/2 - x_save[msgs]/2;
y_pos[msgs] = TOP_BORDER + (1+msgs) * 2 * y_save;
if (!(save[msgs] = mem_create(x_save[msgs], y_save, 1))) {
puts("whoops! Out of memory... no sense going on with this.");
exit(1);
}
pr_rop(save[msgs], 0, 0, x_save[msgs], y_save, PIX_SRC,
draw_win->pw_prretained, x_pos[msgs], y_pos[msgs]);
pw_text(draw_win, x_pos[msgs], y_pos[msgs]+l_height(big_font)-5,
PIX_SRC, big_font, p);
pw_text(draw_win, x_pos[msgs]+1, y_pos[msgs]+l_height(big_font)-5,
PIX_SRC|PIX_DST, big_font, p);
} while (++msgs < 15 && p2 && *(p = p2+1));
}
/* remove all messages from the board and put back the images underneith */
remove_msgs(clearing)
{
while (msgs--) {
if (!clearing)
pw_rop(draw_win, x_pos[msgs], y_pos[msgs], x_save[msgs], y_save,
PIX_SRC, save[msgs], 0, 0);
pr_destroy(save[msgs]);
}
msgs = 0;
}
catch(sig)
{
stop_timer();
if (sig == SIGXCPU) {
msg("CPU timelimit exceeded. Go home and eat dinner.");
sleep(2);
remove_msgs(0);
return;
}
change_life(DIE);
if (sig == SIGSEGV)
fprintf(stderr, "Segmentation fault.\n");
else
fprintf(stderr, "Bus Error\n");
abort();
}