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);
}