DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T b

⟦419f7374a⟧ TextFile

    Length: 4553 (0x11c9)
    Types: TextFile
    Names: »blast.c«

Derivation

└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
    └─⟦this⟧ »EUUGD18/Sun/Sdi/blast.c« 

TextFile

/***************************************  blast.c  ********************/
#include <pixrect/pixrect_hs.h>
#include "sdi.h"
#include <sunwindow/notify.h>

/*
 * Copyright 1987 by Mark Weiser.
 * Permission to reproduce and use in any manner whatsoever on Suns is granted
 * so long as this copyright and other identifying marks of authorship
 * in the code and the game remain intact and visible.  Use of this code
 * in other products is reserved to me--I'm working on Mac and IBM versions.
 */

/*
 * Blast-related routines are here and in intersect.c.  Also here is
 * the main dispatch point for display updating called, for historical
 * reasons, 'blast_timer'.
 */

static Notify_value blast_timer();
extern int draw_blast(), doto_missiles(), update_missile();

/*
 * Start the main dispatch timer.
 */
init_blast()
{
	static char *me = (char *)&me;
	struct itimerval timer;
	timer.it_interval.tv_usec = 0;
	timer.it_interval.tv_sec = 0;
	timer.it_value.tv_usec = 1;
	timer.it_value.tv_sec = 0;
	notify_set_itimer_func(me, blast_timer, ITIMER_REAL, &timer, NULL);
}

/*
 * Construct a new blast and put it on the display list.
 */
start_blast(x, y, xinc, yinc, pw, circle_type)
int x, y;
Pixwin *pw;
struct circ *circle_type;
{
	struct blast *bid = (struct blast *)malloc(sizeof(struct blast));
	bid->pw = pw;
	bid->next = NULL;
	bid->circ = 0;
	bid->x = x;
	bid->orig_y = bid->y = y;
	bid->x_inc = xinc;
	bid->y_inc = yinc;
	bid->num_circles = circle_type->num_circles;
	bid->circles = circle_type->circles;
	bid->masks = circle_type->masks;
	bid->width = bid->circles[0]->pr_size.x;
	update_blast_rect(bid);
	add_blast(bid);
	draw_blast(bid);
}

#define INSCRIBING_FUDGE_FACTOR 2

/*
 * Construct a square which approximates the size of the current
 * blast circle.
 */
update_blast_rect(bid)
struct blast *bid;
{
	register int w = bid->width / 2 - INSCRIBING_FUDGE_FACTOR;
	register int h = bid->width - 2*INSCRIBING_FUDGE_FACTOR;
	bid->r.r_left = bid->x - w;
	bid->r.r_top = bid->y - w;
	bid->r.r_width = h;
	bid->r.r_height = h;
}

/*
 * The main dispatch routine.
 * 'blast_timer' is called at fixed intervals, queries routines
 * for launch, missiles, lasers, and blasts for their next update.
 */
static Notify_value
blast_timer(me, which)
int *me;
int which;
{
	extern Panel_item foe_ground_item;
	Pixwin *pw1 = citypw;
	Pixwin *pw2 = launchpw;
	struct itimerval timer;
	struct rect r;
	Event event;

	if (!running) return NOTIFY_DONE;

	if (suspended) {
		suspendor(blast_timer, me, which, 1);
		return NOTIFY_DONE;
	}

	if (missile_count <= 0 && blast_count <= 0 &&
		panel_get_value(ballistic_item) <= 0 &&
		panel_get_value(foe_ground_item) <= 0)
			finish_round();

	checkinput();

	timer.it_interval.tv_usec = 0;
	timer.it_interval.tv_sec = 0;
	timer.it_value.tv_usec = blast_delay;
	timer.it_value.tv_sec = 0;
	notify_set_itimer_func(pw1, blast_timer, ITIMER_REAL, &timer, NULL);


	(void) pw_get_region_rect(pw1, &r);
	pw_batch_on(pw1);
	pw_lock(pw1, &r);
	(void) pw_get_region_rect(pw2, &r);
	pw_batch_on(pw2);
	pw_lock(pw2, &r);

	if (need_a_bell != NULL) {
		struct timeval tv;
		tv.tv_sec = 0;
		tv.tv_usec = 30000; /* this is the minimal reliable bell length */
		win_bell(window_get(cityframe, WIN_FD), tv, need_a_bell);
		need_a_bell = NULL;
	}

	doto_missiles(update_missile);
	doto_lasers();
	doto_blasts(draw_blast);
	doto_rocks();
	doto_launch();

	pw_unlock(pw2);
	pw_batch_off(pw2);
	pw_unlock(pw1);
	pw_batch_off(pw1);

	return NOTIFY_DONE;
}

/*
 * Helper routine passed into 'doto_blasts'.  Updates the
 * blast circle, and frees the blast structure if done.
 */
draw_blast(bid)
struct blast *bid;
{
	int old_circ =  bid->circ;

	if (bid->circ < 0 || bid->x_inc || bid->y_inc) {
		/* shrinking or moving, remove old blast */
		pw_rop(bid->pw, B_OFFSET_X(bid), B_OFFSET_Y(bid),
			B_WIDTH(bid), B_HEIGHT(bid),
			PIX_NOT(PIX_SRC) & PIX_DST,
			bid->masks[ABS(bid->circ)], 0, 0);
	}


	/* Update the next blast circle.  
	   Positive values are growing, negative are shrinking
	 */
	bid->circ += 1;
	if (bid->circ >= bid->num_circles) {
		bid->circ = -bid->num_circles +1;
	}
	if (bid->circ) {
		/* Draw the new blast */
		bid->x += bid->x_inc;
		bid->y += bid->y_inc;
		bid->width = bid->circles[ABS((bid)->circ)]->pr_size.x;
		pw_rop(bid->pw, B_OFFSET_X(bid), B_OFFSET_Y(bid),
			B_WIDTH(bid), B_HEIGHT(bid),
			PIX_SRC | PIX_DST, bid->circles[ABS(bid->circ)], 0, 0);
	}
	if (old_circ == -1) {
		remove_blast(bid);
		free(bid);
	} 
	bid->width = bid->circles[ABS((bid)->circ)]->pr_size.x;
	update_blast_rect(bid);
}