|
|
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 b
Length: 4553 (0x11c9)
Types: TextFile
Names: »blast.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/Sun/Sdi/blast.c«
/*************************************** 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);
}