atari-sources-request@daisy.UUCP (08/09/87)
Submitted by: <sun!hplabs!tektronix!dadla.TEK.COM!jrb> comp.sources.atari.st: Volume 0, Issue 25 Archive-name: forever =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ [Ed.'s Note] aside from drawing pretty pictures, this is an example of how to use linea, the cksm is: bytes = 5985( 6407) cksm = 2353 kalidascope.c =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ I would like to submit the following which is a simple kalleidoscope program for the st. I am interesting in getting ahold of some non-trivial programming examples in C that manipulate linea primitives. Jim Binkley jrb@dadla.tek.com /* * forever.c - Atari st graphics kalleidoscope * * Any character to quit. * * Should be run in low rez. * * Uses linea routines. Mark Williams 2.0 C. */ #include <osbind.h> #include <linea.h> static int color; #define setColor(x) (color = x) #define setpixel(x,y) ((PTSIN[0]=x), (PTSIN[1]=y),(INTIN[0]=color),linea1()) #define WHITE 0x777 #define BLACK 0x000 #define BLUE 0x007 #define GREEN 0x070 #define RED 0x700 int bluePal[] = { 0x0777, 0x0124, 0x0214, 0x0324, 0x0424, 0x0417, 0x0336, 0x0517, 0x0437, 0x0716, 0x0727, 0x0700, 0x0704, 0x0705, 0x0706, 0x0707 }; static int gemPal[16]; /* assume 320 by 200 */ #define CENTERX 160 #define CENTERY 100 /* per "process" pen info */ static struct pp { int color; int howfat; } pi[4] = { 1,0, 1,0, 1,0, 1,0, }; /* per "process" coords */ static struct chaninfo { int cx,cy; int opType; int xdir,ydir; } ci[4]; main() { extern int bluePal[]; int count=0; int doit; int pal1,pal2; int palstate=0; openScreen(); newPal(bluePal); pal1 = 2; pal2 = 12; /* loop while no keyboard input */ for ( ; Cconis() == 0;count++ ) { drunkWalk(0); drunkWalk(1); drunkWalk(2); drunkWalk(3); if ( count == 500 ) if ((rand()%2)==0) doit = 1; else { shufflePal(bluePal); doit = 0; } if ( count > 600 && count < 1000 ){ if(doit) { if(palstate%2) { pal1 = rand() % 16; pal2 = rand() % 16; twopal(bluePal,pal1,pal2); } else { pal1++; pal2++; if (pal1 > 15) pal1 = 1; if (pal2 > 15) pal2 = 1; twopal(bluePal,pal1,pal2); } } } if ( count > 1000){ palstate++; damage(bluePal); count=0; } } closeScreen(); } /* * drunkWalk * * implements drunken walk. * * i is integer index to indicate which mos channel * is requesting graphics * * CALLS: * rand - random number generator. * kplot - plot current drunken walk graphics */ static drunkWalk(i) { register int n,s,t; struct chaninfo *cpt; cpt = &ci[i]; cpt->opType = 1; /* pick starting delta x,y */ cpt->cx = rand() % 160; cpt->cy = rand() % 100; n = rand()%127; t = rand()%127; /* walk change according to note mod 8, mod 12?? */ switch(n % 8) { case 0: cpt->xdir = 1; break; case 1: cpt->xdir = 1; cpt->ydir = -1; break; case 2: cpt->xdir = -1; break; case 3: cpt->xdir = -1; cpt->ydir = -1; break; case 4: cpt->xdir = 1; cpt->ydir = 1; break; case 5: cpt->ydir = 1; break; case 6: cpt->ydir = -1; cpt->ydir = 1; break; case 7: cpt->xdir = -1; break; } kplot(t, i, cpt->cx += cpt->xdir, cpt->cy += cpt->ydir); kplot(t, i, cpt->cx += cpt->xdir, cpt->cy += cpt->ydir); /* boundary check. If at boundary, we rerandomize */ if ( cpt->cx >= 160 || cpt->cx < 0 ) cpt->cx = rand() % 30; if (cpt->cy >= 100 || cpt->cy < 0 ) cpt->cy = rand() % 40; } /* do graphics work on one pixel. four dots are drawn, * one per quadrant. */ static kplot(t, i, deltax,deltay) int t; /* event time */ register int i; /* per coroutine index */ register int deltax,deltay; { register int x,y; int chowfat; /* randomly switch pen thickness and color */ if ( (rand() % 80) == 20 ) { pi[i].howfat = (rand() >> 4) % 4; /* randomly choose pen color */ if ( (rand() % 2) == 0 ) color = t % 16; else color = rand() % 16; if ( color == 0 ) color++; } chowfat = pi[i].howfat; x = CENTERX+deltax; y = CENTERY+deltay; setpixel(x,y); switch(chowfat) { case 0: break; case 1: setpixel(x-1,y); setpixel(x+1,y); break; case 2: setpixel(x+1,y); setpixel(x+1,y+1); setpixel(x+1,y-1); setpixel(x,y+1); setpixel(x,y); setpixel(x-1,y); setpixel(x,y-1); setpixel(x,y-2); break; case 3: setpixel(x,y-1); setpixel(x,y-2); break; } x = CENTERX+deltax; y = CENTERY-deltay; setpixel(x,y); switch(chowfat) { case 0: break; case 1: setpixel(x-1,y); setpixel(x+1,y); break; case 2: setpixel(x+1,y); setpixel(x+1,y+1); setpixel(x+1,y-1); setpixel(x,y+1); setpixel(x,y); setpixel(x-1,y); setpixel(x,y-2); setpixel(x,y-1); break; case 3: setpixel(x,y-1); setpixel(x,y-2); break; } x = CENTERX-deltax; y = CENTERY+deltay; setpixel(x,y); switch(chowfat) { case 0: break; case 1: setpixel(x-1,y); setpixel(x+1,y); break; case 2: setpixel(x+1,y); setpixel(x+1,y+1); setpixel(x+1,y-1); setpixel(x,y+1); setpixel(x,y); setpixel(x-1,y); setpixel(x,y-2); setpixel(x,y-1); break; case 3: setpixel(x,y-1); setpixel(x,y-2); break; } x = CENTERX-deltax; y = CENTERY-deltay; setpixel(x,y); switch(chowfat) { case 0: break; case 1: setpixel(x-1,y); setpixel(x+1,y); break; case 2: setpixel(x+1,y); setpixel(x+1,y+1); setpixel(x+1,y-1); setpixel(x,y+1); setpixel(x,y); setpixel(x-1,y); setpixel(x,y-2); setpixel(x,y-1); break; case 3: setpixel(x,y-1); setpixel(x,y-2); break; } } openScreen() { linea0(); lineaa(); Cconws("\033E\033f"); /* erase screen */ } closeScreen() { Cconin(); Cconws("\033e\n"); } /* shift pallete positions. First position remains white. */ shufflePal(pal) int pal[]; { int first; int index; first = pal[1]; for ( index = 1; index < 15; index++) pal[index] = pal[index+1]; pal[15] = first; pal[0] = WHITE; newPal(pal); } twopal(pal,one,two) int pal[]; { int tmp; tmp = pal[one]; pal[one] = pal[two]; pal[two] = tmp; newPal(pal); } /* do something kinky to pal */ damage(pal) int pal[]; { register int n; register int r,g,b; n = rand() % 16; r = rand() % 0x7; g = rand() % 0x7; b = rand() % 0x7; pal[n] = b | (g << 4) | (r << 8 ); } /* get default pallete */ openPal() { register int i; /* get original pallete */ for (i = 0; i < 16; i++) gemPal[i] = Setcolor(i, -1); } /* restore original pallete */ closePal() { Setpallete(gemPal); } /* write new pallete */ newPal(pal) int pal[]; { Setpallete(pal); }