Files
Arquivotheca.SunOS-4.1.4/games/tool/boggletool/sand.c
seta75D ff309bfe1c Init
2021-10-11 18:37:13 -03:00

138 lines
3.9 KiB
C

#ifndef lint
static char sccsid[] = "@(#)sand.c 1.1 94/10/31 Copyr 1985 Sun Micro";
#endif
/*
* Copyright (c) 1985 by Sun Microsystems, Inc.
*/
/*
* sand.c: routines to handle the hourglass timer
*/
#include <suntool/tool_hs.h>
#include <stdio.h>
#include "defs.h"
#include "outline.h"
#include "sandframes.h"
#define TOPSANDMAX 68
#define SANDMAXHEIGHT 62
#define STARTBUFFER 10
int bellcurve[TIMER_WIDTH] = {
11, 10, 9, 8, 8, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 2, 2, 2, 1, 0,
1, 2, 2, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 11
};
int sandtodpy[TIMER_WIDTH], sandlefttodpy;
int sandheight;
int lastsandframe;
int topsandbuffer;
int topsandline;
struct rect timerrect = { TIMER_BASELEFT, TIMER_BASETOP, TIMER_WIDTH, TIMER_HEIGHT };
struct timeval lastgrain;
unsigned long sand_delay = compute_delay(3); /* 3 minutes */
struct timeval tv_poll = {0, 0};
#define restartsanddpy(c) for (c = 0; c < TIMER_WIDTH; c++) { sandtodpy[c] = c; } sandlefttodpy = TIMER_WIDTH
#define shiftsanddpy(s,c) for (c = s; c < TIMER_WIDTH-1; c++) { sandtodpy[c] = sandtodpy[c+1]; } sandlefttodpy--
starttimer()
{
int x, y;
lastsandframe = -1;
sandheight = 0;
topsandbuffer = STARTBUFFER;
topsandline = 0;
restartsanddpy(x);
gettimeofday(&lastgrain, NULL);
pr_rop(&sandstencil_pr, 0, 0, TIMER_WIDTH, TIMER_HEIGHT, PIX_NOT(PIX_SRC), &hourglass_pr, 0, 0);
for (y = 0; y < TOPSANDHEIGHT; y++)
pr_rop(&sandstencil_pr, topsandlines[y][0], y + STARTTOPSAND, topsandlines[y][1], 1, PIX_SRC, 0, 0, 0);
bogsw->ts_io.tio_timer = &tv_poll;
}
drawtimer()
{
pw_write(bogwin, TIMER_BASELEFT, TIMER_BASETOP, TIMER_WIDTH,
TIMER_HEIGHT, PIX_NOT(PIX_SRC), &sandstencil_pr, 0, 0);
}
movesand()
{
struct timeval now;
unsigned long udiff;
movefallingsand();
gettimeofday(&now, 0);
udiff = (now.tv_sec - lastgrain.tv_sec) * 1000000 + (now.tv_usec - lastgrain.tv_usec);
lastgrain.tv_usec += (udiff - udiff % sand_delay);
while (lastgrain.tv_usec > 1000000) {
lastgrain.tv_sec += 1;
lastgrain.tv_usec -= 1000000;
}
while (udiff > sand_delay) {
if (movebottomsand()) {
erasefallingsand();
return(1);
}
udiff -= sand_delay;
}
return(0);
}
movefallingsand()
{
pw_lock(bogwin, &timerrect);
if (lastsandframe != -1)
pw_stencil(bogwin, TIMER_BASELEFT + SANDFALL_SHIFT, TIMER_BASETOP + SANDFALL_OFFSET, SANDFALL_WIDTH, SANDFALL_HEIGHT, PIX_NOT(PIX_SRC) & PIX_DST, &sandstencil_pr, SANDFALL_SHIFT, SANDFALL_OFFSET, sand_pr[lastsandframe], 0, 0);
lastsandframe = random() % SANDFRAMES;
pw_write(bogwin, TIMER_BASELEFT + SANDFALL_SHIFT, TIMER_BASETOP + SANDFALL_OFFSET, SANDFALL_WIDTH, SANDFALL_HEIGHT, PIX_SRC | PIX_DST, sand_pr[lastsandframe], 0, 0);
pw_unlock(bogwin);
}
erasefallingsand()
{
if (lastsandframe != -1)
pw_stencil(bogwin, TIMER_BASELEFT + SANDFALL_SHIFT, TIMER_BASETOP + SANDFALL_OFFSET, SANDFALL_WIDTH, SANDFALL_HEIGHT, PIX_NOT(PIX_SRC) & PIX_DST, &sandstencil_pr, SANDFALL_SHIFT, SANDFALL_OFFSET, sand_pr[lastsandframe], 0, 0);
lastsandframe = -1;
}
movebottomsand()
{
int index, x, y, c;
if (sandheight > SANDMAXHEIGHT)
return(1);
for (;;) {
if (sandlefttodpy <= 0) {
restartsanddpy(c);
sandheight++;
if (sandheight > SANDMAXHEIGHT)
return(1);
}
index = random() % sandlefttodpy;
x = sandtodpy[index];
shiftsanddpy(index, c);
y = TIMER_HEIGHT - sandheight + bellcurve[x];
if (y >= TIMER_HEIGHT)
continue;
if ((c = pr_get(&fullhourglass_pr, x, y)) == 0)
continue;
pr_put(&sandstencil_pr, x, y, c ^ 1);
pw_put(bogwin, x + TIMER_BASELEFT, y + TIMER_BASETOP, c);
if (++topsandbuffer == topsandlines[topsandline][1]) {
pw_write(bogwin, TIMER_BASELEFT + topsandlines[topsandline][0], topsandline + STARTTOPSAND + TIMER_BASETOP, topsandlines[topsandline][1], 1, PIX_SRC, 0, 0, 0);
pr_rop(&sandstencil_pr, topsandlines[topsandline][0], topsandline + STARTTOPSAND, topsandlines[topsandline][1], 1, PIX_NOT(PIX_SRC), 0, 0, 0);
topsandbuffer = 0;
topsandline++;
}
break;
}
return(0);
}