home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
MM1
/
GRAPHICS
/
kwsaver25.lzh
/
programmer.lzh
/
kwsaver_rain.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-17
|
6KB
|
191 lines
/* kwsaver_rain.c */
/* by Joel Mathew Hegberg */
/* a Type 3 KWSaver screen-saver program */
/* which runs on any type screen. */
/* NOTE: This program uses a K-Windows graphic buffer, which */
/* must be killed before exiting (or else the memory */
/* used by the buffer will not be returned to the */
/* system), so a signal trap (handler) is implemented */
/* to detect when it's time to exit. */
/* Even more importantly, the program must unlink from */
/* the memory data module "kwsaver_data" when it's */
/* time to exit, or the module will never go away, */
/* hogging up the user's RAM! */
#include <stdio.h>
#include <module.h>
#include <types.h>
#include <ctype.h>
#include <MACHINE/regs.h>
/* Remember to include "module.h" for Type 3 screen-savers. */
#define PATH 1
extern int sighandler();
extern mod_exec *modlink();
int sigcode=0,screen_size,bytes_per_scanline,total_scan_lines,
max_x_pixel_coord,bits_per_pixel,max_colors;
main()
{
int x,y,loop,pid,pixels_per_byte,*dataptr,v;
unsigned char *screen_data,*bfradd,text[80],*scradd,*tempadd,*tempadd2;
mod_exec *mp;
REGISTERS reg;
pid=getpid(); /* get process-id for unique kwgroup value */
intercept(sighandler); /* install signal handler */
/* Attempt to link to the kwsaver_data module. */
/* Since this screen-saver program requires that */
/* module, if it does not exist, we'll just run */
/* a dummy routine (called do_nothing) to leave */
/* the screen blank until KWSaver signals it's */
/* time to die. */
mp=modlink("kwsaver_data",0);
if (mp==(mod_exec *)-1) /* kwsaver_data module does not exist */
{
Bell(PATH);
do_nothing();
exit(0);
}
/* Let's set up an integer pointer to the kwsaver_data module's info. */
dataptr=(int *)((char *)mp+mp->_mexec);
/* Now, let's get the information... */
/* Note that not all of this data is actually */
/* used within this screen-saver program. I'm */
/* merely illustrating how to get all of the */
/* information as an example. */
screen_size=dataptr[1];
bytes_per_scanline=dataptr[2];
total_scan_lines=dataptr[3];
max_x_pixel_coord=dataptr[4];
bits_per_pixel=dataptr[5];
max_colors=dataptr[6];
/* Set up a pointer to the start of the raw-screen data */
/* within the data module. */
screen_data=(unsigned char *)((int *)dataptr+7); /* pointer to saved screen */
/* We can compute how many pixels are in each byte, if we want... */
pixels_per_byte=8/bits_per_pixel; /* this can be most useful. */
/* Next, define a K-Windows graphics buffer, and get it's address... */
ScaleSw(PATH,0); /* graphics scaling off (default is on) */
GetBlk(PATH,pid,1,0,0,max_x_pixel_coord+1,1);
/* the following 5 lines request the buffer's address from K-Windows */
reg.d[0]=PATH;
reg.d[1]=0x00a9;
reg.d[2]=(pid<<8)+1;
_osk(0x8d,®);
bfradd=reg.a[0]; /* graphics buffer address */
/* The following loop will copy the screen data saved in the */
/* memory data module back onto the screen, using our K-Windows */
/* graphics buffer we've defined. You should ALWAYS use a */
/* K-Windows buffer to write screen data back to the screen... */
/* NEVER do direct writes to screen-memory! */
for(y=0;y<total_scan_lines;y++)
{
memcpy(bfradd,screen_data+y*bytes_per_scanline,bytes_per_scanline);
PutBlk(PATH,pid,1,0,y);
}
/* Now, do our rain-routine until we receive a signal to die from */
/* the KWSaver program. */
while(!sigcode)
{
/* This next loop manipulates the screen data within the */
/* memory data module itself, which is completely legal. */
/* Don't worry too much about what's going on in this loop... */
/* This is just causing the screen's lines to drip down a bit. */
for(v=0;v<(bytes_per_scanline/24);v++)
{
x=rand(bytes_per_scanline)-1;
tempadd=screen_data+bytes_per_scanline*(total_scan_lines-2)+x;
tempadd2=tempadd+bytes_per_scanline;
for(y=0;y<(total_scan_lines-1);y++,tempadd-=bytes_per_scanline,tempadd2-=bytes_per_scanline)
*tempadd2=*tempadd;
*(screen_data+x)=0x00;
}
/* Okay, now that our screen data has been manipulated, it's */
/* time to copy the updated screen data to the screen, using */
/* the same routine we used above to copy the screen data */
/* from the memory data module to the screen. */
for(y=0;y<total_scan_lines;y++)
{
memcpy(bfradd,screen_data+y*bytes_per_scanline,bytes_per_scanline);
PutBlk(PATH,pid,1,0,y);
}
/* Sleep for a couple ticks... Give the CPU time to breathe. */
tsleep(2);
}
/* Time to die... Kill our K-Windows graphics buffer and */
/* be sure to unlink from the data memory module. */
KilBuf(PATH,pid,1);
munlink(mp);
}
do_nothing()
{
sleep(0); /* sleep until a signal is received */
}
/* rand( val ) : return a pseudo-random value between 1 and val.
** IF val is -1, it is used as a seed.
** IF val is negative the better the seed.
*/
static int rndval=10000;
rand( val )
int val;
{
int bit0, bit1, bit14, num, i;
/* see if -1 */
if ( val < 0 )
rndval = -val;
for ( i = 0; i < 10; i++ )
{
bit0 = rndval & 1;
bit1 = (rndval & 2) >> 1;
bit14 = bit0 ^ bit1;
rndval >>=1;
rndval |= (bit14 << 14);
}
num = rndval % val;
return( num ? num : val );
}
/* My short & sweet signal handler function. */
sighandler(signal)
int signal;
{
sigcode=signal;
}