/* * cycvb.c --- Dan Silva's DPaint color cycling interrupt code * * Use this fragment as an example for interrupt driven color cycling * If compiled with SAS, include flags -v -y on LC2 */ #include <exec/types.h> #include <exec/interrupts.h> #include <graphics/view.h> #include <iff/compiler.h> #define MAXNCYCS 4 #define NO FALSE #define YES TRUE #define LOCAL static typedef struct { SHORT count; SHORT rate; SHORT flags; UBYTE low, high; /* bounds of range */ } Range; /* Range flags values */ #define RNG_ACTIVE 1 #define RNG_REVERSE 2 #define RNG_NORATE 36 /* if rate == NORATE, don't cycle */ /* cycling frame rates */ #define OnePerTick 16384 #define OnePerSec OnePerTick/60 extern Range cycles[]; extern BOOL cycling[]; extern WORD cycols[]; extern struct ViewPort *vport; extern SHORT nColors; MyVBlank() { int i,j; LOCAL Range *cyc; LOCAL WORD temp; LOCAL BOOL anyChange; #ifdef IS_AZTEC #asm movem.l a2-a7/d2-d7,-(sp) move.l a1,a4 #endasm #endif if (cycling) { anyChange = NO; for (i=0; i<MAXNCYCS; i++) { cyc = &cycles[i]; if ( (cyc->low == cyc->high) || ((cyc->flags&RNG_ACTIVE) == 0) || (cyc->rate == RNG_NORATE) ) continue; cyc->count += cyc->rate; if (cyc->count >= OnePerTick) { anyChange = YES; cyc->count -= OnePerTick; if (cyc->flags&RNG_REVERSE) { temp = cycols[cyc->low]; for (j=cyc->low; j < cyc->high; j++) cycols[j] = cycols[j+1]; cycols[cyc->low] = temp; } else { temp = cycols[cyc->high]; for (j=cyc->high; j > cyc->low; j--) cycols[j] = cycols[j-1]; cycols[cyc->low] = temp; } } } if (anyChange) LoadRGB4(vport,cycols,nColors); } #ifdef IS_AZTEC ; /* this is necessary */ #asm movem.l (sp)+,a2-a7/d2-d7 #endasm #endif return(0); /* interrupt routines have to do this */ } /* * Code to install/remove cycling interrupt handler */ LOCAL char myname[] = "MyVB"; /* Name of interrupt handler */ LOCAL struct Interrupt intServ; typedef void (*VoidFunc)(); StartVBlank() { #ifdef IS_AZTEC intServ.is_Data = GETAZTEC(); /* returns contents of register a4 */ #else intServ.is_Data = NULL; #endif intServ.is_Code = (VoidFunc)&MyVBlank; intServ.is_Node.ln_Succ = NULL; intServ.is_Node.ln_Pred = NULL; intServ.is_Node.ln_Type = NT_INTERRUPT; intServ.is_Node.ln_Pri = 0; intServ.is_Node.ln_Name = myname; AddIntServer(5,&intServ); } StopVBlank() { RemIntServer(5,&intServ); } /**/