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 >
C/C++ Source or Header  |  1995-03-17  |  6KB  |  191 lines

  1. /* kwsaver_rain.c                        */
  2. /* by Joel Mathew Hegberg                */
  3. /* a Type 3 KWSaver screen-saver program */
  4. /* which runs on any type screen.        */
  5.  
  6. /* NOTE: This program uses a K-Windows graphic buffer, which */
  7. /*       must be killed before exiting (or else the memory   */
  8. /*       used by the buffer will not be returned to the      */
  9. /*       system), so a signal trap (handler) is implemented  */
  10. /*       to detect when it's time to exit.                   */
  11. /*       Even more importantly, the program must unlink from */
  12. /*       the memory data module "kwsaver_data" when it's     */
  13. /*       time to exit, or the module will never go away,     */
  14. /*       hogging up the user's RAM!                          */
  15.  
  16. #include <stdio.h>
  17. #include <module.h>
  18. #include <types.h>
  19. #include <ctype.h>
  20. #include <MACHINE/regs.h>
  21.  
  22. /* Remember to include "module.h" for Type 3 screen-savers. */
  23.  
  24. #define PATH 1
  25.  
  26. extern int sighandler();
  27. extern mod_exec *modlink();
  28.  
  29. int sigcode=0,screen_size,bytes_per_scanline,total_scan_lines,
  30.         max_x_pixel_coord,bits_per_pixel,max_colors;
  31.  
  32. main()
  33. {
  34.     int x,y,loop,pid,pixels_per_byte,*dataptr,v;
  35.     unsigned char *screen_data,*bfradd,text[80],*scradd,*tempadd,*tempadd2;
  36.     mod_exec *mp;
  37.     REGISTERS reg;
  38.     
  39.     pid=getpid();    /* get process-id for unique kwgroup value */
  40.     intercept(sighandler);    /* install signal handler */
  41.     
  42.     /* Attempt to link to the kwsaver_data module.    */
  43.     /* Since this screen-saver program requires that  */
  44.     /* module, if it does not exist, we'll just run   */
  45.     /* a dummy routine (called do_nothing) to leave   */
  46.     /* the screen blank until KWSaver signals it's    */
  47.     /* time to die.                                   */
  48.     
  49.     mp=modlink("kwsaver_data",0);
  50.     if (mp==(mod_exec *)-1)        /* kwsaver_data module does not exist */
  51.     {
  52.         Bell(PATH);
  53.         do_nothing();
  54.         exit(0);
  55.     }
  56.     
  57.     /* Let's set up an integer pointer to the kwsaver_data module's info. */
  58.     dataptr=(int *)((char *)mp+mp->_mexec);
  59.     
  60.     /* Now, let's get the information...           */
  61.     /* Note that not all of this data is actually  */
  62.     /* used within this screen-saver program.  I'm */
  63.     /* merely illustrating how to get all of the   */
  64.     /* information as an example.                  */
  65.     
  66.     screen_size=dataptr[1];
  67.     bytes_per_scanline=dataptr[2];
  68.     total_scan_lines=dataptr[3];
  69.     max_x_pixel_coord=dataptr[4];
  70.     bits_per_pixel=dataptr[5];
  71.     max_colors=dataptr[6];
  72.     
  73.     /* Set up a pointer to the start of the raw-screen data */
  74.     /* within the data module.                              */
  75.     
  76.     screen_data=(unsigned char *)((int *)dataptr+7);    /* pointer to saved screen */
  77.     
  78.     /* We can compute how many pixels are in each byte, if we want... */
  79.     
  80.     pixels_per_byte=8/bits_per_pixel;    /* this can be most useful. */
  81.     
  82.     
  83.     /* Next, define a K-Windows graphics buffer, and get it's address... */
  84.     
  85.     ScaleSw(PATH,0);    /* graphics scaling off (default is on) */
  86.     GetBlk(PATH,pid,1,0,0,max_x_pixel_coord+1,1);
  87.     /* the following 5 lines request the buffer's address from K-Windows */
  88.     reg.d[0]=PATH;
  89.     reg.d[1]=0x00a9;
  90.     reg.d[2]=(pid<<8)+1;
  91.     _osk(0x8d,®);
  92.     bfradd=reg.a[0];    /* graphics buffer address */
  93.     
  94.     /* The following loop will copy the screen data saved in the    */
  95.     /* memory data module back onto the screen, using our K-Windows */
  96.     /* graphics buffer we've defined.  You should ALWAYS use a      */
  97.     /* K-Windows buffer to write screen data back to the screen...  */
  98.     /* NEVER do direct writes to screen-memory!                     */
  99.     
  100.     for(y=0;y<total_scan_lines;y++)
  101.     {
  102.         memcpy(bfradd,screen_data+y*bytes_per_scanline,bytes_per_scanline);
  103.         PutBlk(PATH,pid,1,0,y);
  104.     }
  105.     
  106.     /* Now, do our rain-routine until we receive a signal to die from */
  107.     /* the KWSaver program.                                           */
  108.     
  109.     while(!sigcode)
  110.     {
  111.         /* This next loop manipulates the screen data within the       */
  112.         /* memory data module itself, which is completely legal.       */
  113.         /* Don't worry too much about what's going on in this loop...  */
  114.         /* This is just causing the screen's lines to drip down a bit. */
  115.         
  116.         for(v=0;v<(bytes_per_scanline/24);v++)
  117.         {
  118.             x=rand(bytes_per_scanline)-1;
  119.             tempadd=screen_data+bytes_per_scanline*(total_scan_lines-2)+x;
  120.             tempadd2=tempadd+bytes_per_scanline;
  121.             for(y=0;y<(total_scan_lines-1);y++,tempadd-=bytes_per_scanline,tempadd2-=bytes_per_scanline)
  122.                 *tempadd2=*tempadd;
  123.             *(screen_data+x)=0x00;
  124.         }
  125.         
  126.         /* Okay, now that our screen data has been manipulated, it's */
  127.         /* time to copy the updated screen data to the screen, using */
  128.         /* the same routine we used above to copy the screen data    */
  129.         /* from the memory data module to the screen.                */
  130.         
  131.         for(y=0;y<total_scan_lines;y++)
  132.         {
  133.             memcpy(bfradd,screen_data+y*bytes_per_scanline,bytes_per_scanline);
  134.             PutBlk(PATH,pid,1,0,y);
  135.         }
  136.         
  137.         /* Sleep for a couple ticks... Give the CPU time to breathe. */
  138.         tsleep(2);
  139.     }
  140.  
  141.     /* Time to die... Kill our K-Windows graphics buffer and */
  142.     /* be sure to unlink from the data memory module.        */
  143.     
  144.     KilBuf(PATH,pid,1);
  145.     munlink(mp);
  146. }
  147.  
  148. do_nothing()
  149. {
  150.     sleep(0);    /* sleep until a signal is received */
  151. }
  152.  
  153.  
  154. /* rand( val ) : return a pseudo-random value between 1 and val.
  155. **               IF val is -1, it is used as a seed.
  156. **               IF val is negative the better the seed.
  157. */
  158.  
  159. static int rndval=10000;
  160.  
  161. rand( val )
  162. int val;
  163. {
  164.         int bit0, bit1, bit14, num, i;
  165.         
  166.     /* see if -1 */
  167.     if ( val < 0 )
  168.       rndval = -val;
  169.       
  170.     for ( i = 0; i < 10; i++ )
  171.     {
  172.         bit0 = rndval & 1;
  173.         bit1 = (rndval & 2) >> 1;
  174.         bit14 = bit0 ^ bit1;
  175.         rndval >>=1;
  176.         rndval |= (bit14 << 14);
  177.     }
  178.     num = rndval % val;
  179.     return( num ? num : val );
  180. }
  181.  
  182.  
  183. /* My short & sweet signal handler function. */
  184.  
  185. sighandler(signal)
  186. int signal;
  187. {
  188.     sigcode=signal;
  189. }
  190.  
  191.