home *** CD-ROM | disk | FTP | other *** search
- /* vi:tabstop=4:shiftwidth=4:smartindent
- *
- * demo.c - a demo of using the event handler functions.
- *
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
-
- #include "kernel.h"
- #include "swis.h"
- #define vdu(x) _kernel_oswrch(x)
- #define swi(n, r, s) _kernel_swi(n, r, s)
-
- #include "event.h"
-
- /* The handler function. A couple of things to note
- * here:
- * 1) You must not call any C library function from this handler.
- * The C library is probably not re-entrant, so calling e.g.
- * printf when printf is already running will almost certainly
- * crash your program. You could probably write your own SWI
- * caller to allow calling of re-entrant SWIs in this routine,
- * but in that case you're on your own - I'd prefer to do such
- * a thing as an assembler function in any case...
- *
- * 2) Because of this, there's not much you can do except alter a variable,
- * which brings me to the second point. Such a variable must be of type
- * volatile if the main thread is to monitor it. Otherwise the compiler
- * will quite likely optimise the memory access away and you'll never
- * see the value change.
- */
- static volatile int vsync = 0;
- static volatile int keypress = 0;
- void handler(int event)
- {
- if (event==EVENT_VSYNC)
- {
- vsync = 1;
- }
- if (event==EVENT_KEYPRESS)
- {
- keypress=1;
- }
- }
-
- /* This disables the events and turns off the handler.
- * It is used as an atexit function so that no matter how
- * the program exits, we still leave the handler safely disabled.
- */
- void quit(void)
- {
- e_disable(EVENT_VSYNC);
- e_disable(EVENT_KEYPRESS);
- event(EVENT_RELEASE, handler);
- }
-
- int main(void)
- {
- _kernel_swi_regs r;
- int red=0, grn=0, blu=0;
-
- /* Install the handler
- */
- event(EVENT_CLAIM, handler);
-
- /* Install the atexit function for safe exits.
- */
- atexit(quit);
-
- /* Enable the VSYNC and KEYPRESS events
- */
- e_enable(EVENT_VSYNC);
- e_enable(EVENT_KEYPRESS);
-
- /* Mode 0
- */
- vdu(22);
- vdu(0);
-
- /* Now let's do something which would be difficult to
- * do any other way... plot points as quickly as possible
- * while altering the palette on vsync.
- */
- while (!keypress)
- {
- /* Plot points continuously...
- */
- r.r[0] = 69;
- r.r[1] = rand() % 1280;
- r.r[2] = rand() % 1024;
- swi(OS_Plot, &r, &r);
-
- /* Monitor the trigger value. This will be 1
- * soon after a vsync.
- */
- if (vsync)
- {
- /* Reset the trigger
- */
- vsync = 0;
-
- /* Change palette
- */
- red = (red + 2) & 0xff;
- grn = (grn + 3) & 0xff;
- blu = (blu - 1) & 0xff;
- vdu(19);
- vdu(1);
- vdu(16);
- vdu((int)(128+127*sin((double)red*6.283/256)));
- vdu((int)(128+127*sin((double)grn*6.283/256)));
- vdu((int)(128+127*sin((double)blu*6.283/256)));
- }
- }
- exit(0);
- }
-