home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 2 / RISC_DISC_2.iso / pd_share / program / code / event / c / demo
Encoding:
Text File  |  1995-02-12  |  2.7 KB  |  119 lines

  1. /* vi:tabstop=4:shiftwidth=4:smartindent
  2.  *
  3.  * demo.c - a demo of using the event handler functions.
  4.  *
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <math.h>
  10.  
  11. #include "kernel.h"
  12. #include "swis.h"
  13. #define vdu(x) _kernel_oswrch(x)
  14. #define swi(n, r, s) _kernel_swi(n, r, s)
  15.  
  16. #include "event.h"
  17.  
  18. /* The handler function. A couple of things to note
  19.  * here: 
  20.  *  1) You must not call any C library function from this handler.
  21.  *     The C library is probably not re-entrant, so calling e.g.
  22.  *     printf when printf is already running will almost certainly
  23.  *     crash your program. You could probably write your own SWI
  24.  *     caller to allow calling of re-entrant SWIs in this routine,
  25.  *     but in that case you're on your own - I'd prefer to do such
  26.  *     a thing as an assembler function in any case...
  27.  *
  28.  *  2) Because of this, there's not much you can do except alter a variable,
  29.  *     which brings me to the second point. Such a variable must be of type
  30.  *     volatile if the main thread is to monitor it. Otherwise the compiler
  31.  *     will quite likely optimise the memory access away and you'll never
  32.  *     see the value change.
  33.  */
  34. static volatile int    vsync = 0;
  35. static volatile int keypress = 0;
  36. void handler(int event)
  37. {
  38.     if (event==EVENT_VSYNC)
  39.     {
  40.         vsync = 1;
  41.     }
  42.     if (event==EVENT_KEYPRESS)
  43.     {
  44.         keypress=1;
  45.     }
  46. }
  47.  
  48. /* This disables the events and turns off the handler.
  49.  * It is used as an atexit function so that no matter how
  50.  * the program exits, we still leave the handler safely disabled.
  51.  */
  52. void quit(void)
  53. {
  54.     e_disable(EVENT_VSYNC);
  55.     e_disable(EVENT_KEYPRESS);
  56.     event(EVENT_RELEASE, handler);
  57. }
  58.  
  59. int main(void)
  60. {
  61.     _kernel_swi_regs    r;
  62.     int red=0, grn=0, blu=0;
  63.  
  64.     /* Install the handler
  65.      */
  66.     event(EVENT_CLAIM, handler);
  67.  
  68.     /* Install the atexit function for safe exits.
  69.      */
  70.     atexit(quit);
  71.  
  72.     /* Enable the VSYNC and KEYPRESS events
  73.      */
  74.     e_enable(EVENT_VSYNC);
  75.     e_enable(EVENT_KEYPRESS);
  76.  
  77.     /* Mode 0
  78.      */
  79.     vdu(22);
  80.     vdu(0);
  81.  
  82.     /* Now let's do something which would be difficult to
  83.      * do any other way... plot points as quickly as possible
  84.      * while altering the palette on vsync.
  85.      */
  86.     while (!keypress)
  87.     {
  88.         /* Plot points continuously...
  89.          */
  90.         r.r[0] = 69;
  91.         r.r[1] = rand() % 1280;
  92.         r.r[2] = rand() % 1024;
  93.         swi(OS_Plot, &r, &r);
  94.  
  95.         /* Monitor the trigger value. This will be 1
  96.          * soon after a vsync.
  97.          */
  98.         if (vsync)
  99.         {
  100.             /* Reset the trigger
  101.              */
  102.             vsync = 0;
  103.  
  104.             /* Change palette
  105.              */
  106.             red = (red + 2) & 0xff;
  107.             grn = (grn + 3) & 0xff;
  108.             blu = (blu - 1) & 0xff;
  109.             vdu(19);
  110.             vdu(1);
  111.             vdu(16);
  112.             vdu((int)(128+127*sin((double)red*6.283/256)));
  113.             vdu((int)(128+127*sin((double)grn*6.283/256)));
  114.             vdu((int)(128+127*sin((double)blu*6.283/256)));
  115.         }
  116.     }
  117.     exit(0);
  118. }
  119.