Path: utzoo!utgpu!water!watmath!clyde!att-cb!att-ih!ihnp4!inuxc!iuvax!pur-ee!j.cc.purdue.edu!ain From: ain@j.cc.purdue.edu (Patrick White) Newsgroups: comp.sources.amiga Subject: spheres (part 1 of 2) Message-ID: <6626@j.cc.purdue.edu> Date: 8 Mar 88 05:21:43 GMT Organization: PUCC Land, USA Lines: 1289 Approved: ain@j.cc.purdue.edu (Pat White) Program Name: spheres (part 1 of 2) Submitted By: guilford@csv.rpi.edu (Jim Guilford) Summary: Rotate spheres in 3-D according to mouse movements. Poster Boy: Pat White (ain@j.cc.purdue.edu) Untested. NOTES: Docs and data posted in separate shar. Reshared it. Didn't test compile it. -- Pat White (co-moderator comp.sources/binaries.amiga) UUCP: j.cc.purdue.edu!ain BITNET: PATWHITE@PURCCVM PHONE: (317) 743-8421 U.S. Mail: 320 Brown St. apt. 406, West Lafayette, IN 47906 ======================================== # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # animballs.c # globals.h # hamstuff.c # makedata.c # myblit.c # screen.c # This archive created: Mon Mar 7 19:28:18 1988 # By: Patrick White (PUCC Land, USA) echo shar: extracting animballs.c '(9992 characters)' cat << \SHAR_EOF > animballs.c /* animballs.c -- code to handle actual rotating images */ #include #include #include #include #include "globals.h" #include #include #include int woffset = WOFFSET; #define SETANDBOUND(ii,ff) {ii = 0.5 + ff * 15; \ if (ii > 15) ii = 15; \ else if (ii < 0) ii = 0;} float ka, kd, ks, lx, ly, lz, n, r; /* coloring parameters */ long int ix,iy,iz, jx,jy,jz, kx,ky,kz; static char title[81]; int bgcolor = 0; int scx = WIDTH / 2, scy = SMHEIGHT / 2; int xstart = -1; ystart = -1; #define ISIZE 14 #define FTOI(x) ((long int) (x * (1 << ISIZE))) #define MULT(x,y) ((x * y) >> ISIZE) #define LSIZE 10 #define MAKEL(x) ((long int) x * (1 << LSIZE)) struct Ball { long int x,y,z; float r,g,b,rad; long int xp,yp,zp; int y1,y2,intr,size; int dup; }; int nball; struct Ball **ballptr; struct Ball *balls; int maxsize = 0; int maskw = 0, maskh = 1; int maxextent = 0; long int intsin[360]; long int intcos[360]; void readballs(name) char *name; { int i, j, extent; int c; float x,y,z,rad,r,g,b; FILE *fp, *fopen(); int ir,ig,ib; if ((fp = fopen(name,"r")) == NULL) { fprintf(stderr,"Can't open balls file - '%s'",name); panic(""); } strcpy(title,"Drag Mouse to Rotate"); if ((c = getc(fp)) != '"') ungetc(c,fp); else { i = 0; c = getc(fp); while ((c != '"') && (c != EOF)) { if (i < 80) title[i++] = c; c = getc(fp); } if (c == EOF) panic("Error - title lacks final \""); title[i] = 0; } if ((c = fscanf(fp,"%f %f %f",&r,&g,&b)) != 3) { fprintf(stderr,"Error reading background color %d",c+1); panic(""); } else { SETANDBOUND(ir,r); SETANDBOUND(ig,g); SETANDBOUND(ib,b); bgcolor = match(ir,ig,ib); } if (fscanf(fp,"%d",&nball) != 1) panic("Error - Can't read number of balls"); balls = (struct Ball *) malloc(sizeof(struct Ball)*nball); if (balls == 0) panic("Not enough memory for balls"); ballptr = (struct Ball **) malloc(sizeof(long int)*nball); if (ballptr == 0) panic("Not enough memory for ballptr"); for (i = 0; i < nball; i++) { if ((c=fscanf(fp,"%f %f %f %f %f %f %f",&x,&y,&z,&rad,&r,&g,&b))!=7) {fprintf(stderr, "Error in reading item %d in ball description %d", c+1,i+1); panic(""); } balls[i].x = MAKEL(x); balls[i].y = MAKEL(y); balls[i].z = MAKEL(z); balls[i].rad = rad; balls[i].r = r; balls[i].g = g; balls[i].b = b; balls[i].intr = rad + 0.5; balls[i].size = 2 * balls[i].intr + 1; extent = 0.9 + sqrt(x*x + y*y +z*z) + balls[i].intr; if (extent > maxextent) maxextent = extent; if (balls[i].size > maxsize) maxsize = balls[i].size; balls[i].dup = -1; for (j = 0; j < i; j++) /* check for duplicate entries */ if ((balls[j].rad == rad) && (balls[j].r == r) && (balls[j].g == g) && (balls[j].b == b)) { balls[i].dup = j; break; } if (balls[i].dup != -1) { balls[i].y1 = balls[balls[i].dup].y1; balls[i].y2 = balls[balls[i].dup].y2; } else { balls[i].y1 = maskh; maskh += balls[i].size; if (!bw) { balls[i].y2 = maskh; maskh += balls[i].size; } else balls[i].y2 = 0; } } maskw = ((maxsize + 15) & ~15) + 16; fclose(fp); checkextent(); } void checkextent() { int largest,i; long int scale; double fscale; largest = scy - 10; if (scx < largest) largest = scx; if (maxextent > largest) { fprintf(stderr,"Warning, balls are too far apart, I will re-scale.\n"); Delay(250); fscale = (((double) largest) / ((double) maxextent)); scale = FTOI(fscale); maxsize = 0; maskw = 0; maskh = 1; for (i=0; i < nball; i++) { balls[i].x = MULT(balls[i].x,scale); balls[i].y = MULT(balls[i].y,scale); balls[i].z = MULT(balls[i].z,scale); balls[i].rad *= fscale; balls[i].intr = balls[i].rad + 0.5; balls[i].size = 2 * balls[i].intr + 1; if (balls[i].size > maxsize) maxsize = balls[i].size; if (balls[i].dup != -1 ) { balls[i].y1 = balls[balls[i].dup].y1; balls[i].y2 = balls[balls[i].dup].y2; } else { balls[i].y1 = maskh; maskh += balls[i].size; if (!bw) { balls[i].y2 = maskh; maskh += balls[i].size; } else balls[i].y2 = 0; } } maskw = ((maxsize + 15) & ~15) + 16; } } void initsin() { int i; float r,s; for (i=0; i < 360; i++) { r = i * (3.14159/180.0); s = sin(r); intsin[i] = FTOI(s); s = cos(r); intcos[i] = FTOI(s); } } void isin(x,c,s) int x; /* x is degrees */ long int *c,*s; { while (x >= 360) x -=360; while (x < 0) x += 360; *c = intcos[x]; *s = intsin[x]; } void initrender() { float m; initsin(); ka = .2; kd = .5; ks = .65; lx = ly = lz = 1; m = sqrt(lx*lx + ly*ly + lz*lz); lx /= m; ly /= m; lz /= m; n = 10; r = 9.5; ix = FTOI(1); iy = iz = 0; jy = FTOI(1); jx = jz = 0; kz = FTOI(1); kx = ky = 0; } void render() { int i; int x, y; int cont, MouseMoved; struct IntuiMessage *message; ULONG class; USHORT code,qual; for (i = 0; i < nball; i++) renderball(i); SetWindowTitles(mywindow,title,((char *)(-1))); mylinecopy(sbitmap,0,10,WOFFSET); showballs(); cont = 1; while(cont) { Wait(1 << (mywindow->UserPort->mp_SigBit)); MouseMoved = FALSE; while(message = (struct IntuiMessage *) GetMsg(mywindow->UserPort)) { class = message->Class; code = message->Code; x = message->MouseX; y = message->MouseY; qual = message->Qualifier; ReplyMsg((struct Message *)message); if (class == MOUSEMOVE) MouseMoved = TRUE; else if (class == CLOSEWINDOW) { cont = 0; break; } else if (class == MOUSEBUTTONS) mbutton(code,x,y); } if (MouseMoved && cont) mmove(x,y,qual); } } void showballs() { int i,j,sx,sy; struct Ball *ball; long int x,y; for (i = 0; i < nball; i++) { ball = ballptr[i] = &(balls[i]); ball->xp = ((ball->x)*ix + (ball->y)*jx + (ball->z)*kx) >> ISIZE; ball->yp = ((ball->x)*iy + (ball->y)*jy + (ball->z)*ky) >> ISIZE; ball->zp = ((ball->x)*iz + (ball->y)*jz + (ball->z)*kz) >> ISIZE; } for (i = nball-1; i > 0; i--) for (j = 0; j < i; j++) { if (ballptr[i]->zp < ballptr[j]->zp) { ball = ballptr[i]; ballptr[i]=ballptr[j]; ballptr[j]=ball; } } myblankc(sbitmap,10+woffset,190+woffset,bgcolor); if (!bw) myblankc(&tbitmap,0,SMHEIGHT-1,bgcolor); for (i = 0; i < nball; i++) { ball = ballptr[i]; x = (ball->xp + (1 << (LSIZE - 1))) >> LSIZE; y = (ball->yp + (1 << (LSIZE - 1))) >> LSIZE; sx = scx + x - ball->intr; sy = scy - y - ball->intr; BltBitMask(&ibitmap,0,ball->y1, sbitmap,sx,sy+woffset, &mbitmap,0,ball->y1,0, ball->size,ball->size); if (!bw) { BltBitMask(&ibitmap,0,ball->y2, &tbitmap,sx,sy, &mbitmap,0,ball->y1,0, ball->size,ball->size); BltBitMask(&tbitmap,sx+ball->intr+1,sy, sbitmap,sx+ball->intr+1,sy+woffset, &mbitmap,ball->intr,ball->y2,0, ball->intr+1,ball->size); } } flip(); } void scrollx(d) int d; { long int c,s; long int t; isin(-d,&c,&s); t = (c * ix - s * iz) >> ISIZE; iz = (s * ix + c * iz) >> ISIZE; ix = t; t = (c * jx - s * jz) >> ISIZE; jz = (s * jx + c * jz) >> ISIZE; jx = t; t = (c * kx - s * kz) >> ISIZE; kz = (s * kx + c * kz) >> ISIZE; kx = t; } void scrolly(d) int d; { long int c,s; long int t; isin(d,&c,&s); t = (c * iy - s * iz) >> ISIZE; iz = (s * iy + c * iz) >> ISIZE; iy = t; t = (c * jy - s * jz) >> ISIZE; jz = (s * jy + c * jz) >> ISIZE; jy = t; t = (c * ky - s * kz) >> ISIZE; kz = (s * ky + c * kz) >> ISIZE; ky = t; } void scrollz(d) int d; { long int c,s; long int t; isin(d,&c,&s); t = (c * iy - s * ix) >> ISIZE; ix = (s * iy + c * ix) >> ISIZE; iy = t; t = (c * jy - s * jx) >> ISIZE; jx = (s * jy + c * jx) >> ISIZE; jy = t; t = (c * ky - s * kx) >> ISIZE; kx = (s * ky + c * kx) >> ISIZE; ky = t; } void mbutton(code,x,y) int code, x, y; { if (code == SELECTDOWN) { xstart = x; ystart = y; } else if (code == SELECTUP) { xstart = ystart = -1; } } void mmove(x,y,qual) int x,y; USHORT qual; { register int shift; if (qual & 0x30) shift = 2; /* L-ALT, R-ALT */ else if (qual & 0x07) shift = 0; /* SHIFT */ else shift = 1; if (xstart != -1) { if (qual & 0x08) /* CNTL */ scrollz((x - xstart)<RasInfo->RyOffset = WOFFSET; } else { vp->RasInfo->RyOffset = 0; } ScrollVPort(vp); Enable(); Permit(); if (woffset) { woffset = 0; } else { woffset = WOFFSET; } } void renderball(j) int j; { struct Ball *ball; int intr, size, y1, y2; int x, y, xp, yp, ired, igreen, iblue; int start; float nx, ny, nz, rz, id, is; ball = balls+j; if (ball->dup != -1) return; y1 = ball->y1; y2 = ball->y2; intr = ball->intr; size = ball->size; /* special mask is offset -1 in x */ for (y = 0; y < size; y++) { start = 0; for (x = 0; x < size; x++) { xp = x - intr; yp = intr - y; nz = (ball->rad * ball->rad) - (xp * xp) - (yp * yp); if (nz >= 0.0) { mywritepixel1(&mbitmap,x,y+y1); nx = xp / ball->rad; ny = yp / ball->rad; nz = sqrt(nz) / ball->rad; id = lx*nx + ly*ny + lz*nz; /* diffuse intensity */ rz = (nz + nz) * id - lz; if (rz < 0) rz = 0; is = ks * pow(rz,n); id = ka + kd * id; SETANDBOUND(ired, (id * ball->r + is)); SETANDBOUND(igreen,(id * ball->g + is)); SETANDBOUND(iblue, (id * ball->b + is)); setcolor(x,y+y1,y+y2,ired,iblue,igreen,!start); if (start == 0) start = 1; } else if (start == 1) { dolast(); if (!bw) mywritepixel1(&mbitmap,x-1,y+y2); start = 2; } } if (start == 1) { dolast(); if (!bw) mywritepixel1(&mbitmap,x-1,y+y2); } } } SHAR_EOF if test 9992 -ne "`wc -c animballs.c`" then echo shar: error transmitting animballs.c '(should have been 9992 characters)' fi echo shar: extracting globals.h '(925 characters)' cat << \SHAR_EOF > globals.h /* structs.h structure and external definitions */ extern struct RastPort *rp; extern struct Window *mywindow; extern struct ViewPort *vp; extern struct Screen *myscreen; extern struct BitMap *sbitmap; extern struct BitMap tbitmap; extern struct BitMap ibitmap; extern struct BitMap mbitmap; extern int bw; extern int maxsize, maskw, maskh; extern int bgcolor; extern UWORD colortable[]; #define WOFFSET 200 #define HEIGHT 400 #define SMHEIGHT 200 #define WIDTH 192 void readballs(); void checkextent(); void initsin(); void isin(); void initrender(); void render(); void showballs(); void scrollx(); void scrolly(); void scrollz(); void mbutton(); void mmove(); void flip(); void renderball(); void panic(); void cleanup(); void setbw(); void dodefault(); void setcolor(); void dolast(); void BltBitMask(); void mywritepixel1(); void mywritepixel(); void myblank(); void mylinecopy(); void myblankc(); int match(); SHAR_EOF if test 925 -ne "`wc -c globals.h`" then echo shar: error transmitting globals.h '(should have been 925 characters)' fi echo shar: extracting hamstuff.c '(3628 characters)' cat << \SHAR_EOF > hamstuff.c /* hamstuff.c - routines to be given a set of colors. These will be plotted in ham mode. This is based on hamrtn.c */ #include #include #include #include "globals.h" extern UWORD colortable[]; extern UBYTE near[]; extern UWORD nearmc[]; /* near is 4096 long and is configured as a 16*16*16 array */ /* each byte gives the distance to the nearest colortable entry */ /* the high order nible is the index into the color table and the */ /* low order nible is the distance. */ /* color[16] - colormap containing rgb values fairly evenly */ /* spread throughout 16x16x16 space. */ /* near[4096] - table of distance. For each r,g,b */ /* address = (r<<8 | g<<4 | b) & 0xfff */ /* near>>4 gives the nearest color (index) and */ /* near & 0x0f gives the distance. */ /* nearmc[4096] - table of distance minus color */ /* This contains the nearest color ignoring a color */ /* (nearmc >> 8) & 0xf is for red, */ /* (nearmc >> 4) & 0xf is for green, */ /* and nearmc & 0xf is for blue */ #define INDEXNEAR(r,g,b) near[(((r)<<8) | ((g)<<4) | (b))&0xfff] #define PLOTABS(x,y,color) {mywritepixel(&ibitmap,x,y,color); \ i = colortable[color]; \ pr = i >> 8; \ pg = (i >> 4) & 0x0f; \ pb = i & 0x0f; \ if (!exact) \ mywritepixel(&ibitmap,ox,oy,near[oc]>>4);} #define RED 0x20 #define GREEN 0x30 #define BLUE 0x10 extern struct RastPort *rp; static short pr, pg, pb; static int ox, oy, oc; void setcolor(xpos,ypos,yepos,r,b,g,exact) int xpos,ypos,yepos,r,b,g,exact; { short d1, dr, dg, db; int i; r &= 0x0f; b &= 0x0f; g &= 0x0f; if (bw) mywritepixel(&ibitmap,xpos,ypos,(r+b+g)/3); else { d1 = INDEXNEAR(r,g,b); if (((d1 & 0x0f) == 0) || (exact)) { /* equals existing color */ PLOTABS(xpos,ypos,(d1>>4)); if (exact) mywritepixel(&ibitmap,xpos,yepos,d1>>4); } else { /* calculate nearest dist from prev */ dr = r - pr; if (dr < 0) dr = -dr; dg = g - pg; if (dg < 0) dg = -dg; db = b - pb; if (db < 0) db = -db; if (dr > dg) { if (dr > db) { /* dr is max */ if ((d1 & 0x0f) < (dg+db)) { PLOTABS(xpos,ypos,(d1>>4)); } else { mywritepixel(&ibitmap,xpos,ypos,RED | r); pr = r; mywritepixel(&ibitmap,ox,oy,(nearmc[oc]>>8)); } } else { /* if (dr > db) . . . */ /* db is max */ if ((d1 & 0x0f) < (dg+dr)) { PLOTABS(xpos,ypos,(d1>>4)); } else { mywritepixel(&ibitmap,xpos,ypos, BLUE | b); pb = b; mywritepixel(&ibitmap,ox,oy,(nearmc[oc] & 0xf)); } } } else { /* if (dr > dg) . . . */ if (dg > db) { /* dg is max */ if ((d1 & 0x0f) < (dr+db)) { PLOTABS(xpos,ypos,(d1>>4)); } else { mywritepixel(&ibitmap,xpos,ypos,GREEN | g); pg = g; mywritepixel(&ibitmap,ox,oy, (nearmc[oc]>>4)& 0xf); } } else { /* if (dg > db) . . . */ /* db is max */ if ((d1 & 0x0f) < (dg+dr)) { PLOTABS(xpos,ypos,(d1>>4)); } else { mywritepixel(&ibitmap,xpos,ypos,BLUE | b); pb = b; mywritepixel(&ibitmap,ox,oy,(nearmc[oc] & 0xf)); } } } /* end if (dr > dg) */ } /* end else for if ((d1 & 0x0f) == 0) */ oc = r<<8 | g<<4 | b; ox = xpos; oy = yepos; } } /* end setcolor */ void dolast() { if (!bw) mywritepixel(&ibitmap,ox,oy,near[oc]>>4); } int match(r,g,b) int r,g,b; { if (bw) return(0.5 + ((float)(r + g + b)) / 3.0); else return(INDEXNEAR(r,g,b) >> 4); } SHAR_EOF if test 3628 -ne "`wc -c hamstuff.c`" then echo shar: error transmitting hamstuff.c '(should have been 3628 characters)' fi echo shar: extracting makedata.c '(3045 characters)' cat << \SHAR_EOF > makedata.c /* makedata.c - enhancement to basic code to create data.c HAM file */ #include printcomments() { printf("/* data.c - table of data for HAM routines. */\n\n"); printf("/* color[16] - colormap containing rgb values fairly evenly */\n"); printf("/* spread throughout 16x16x16 space. */\n"); printf("/* near[4096] - table of distance. For each r,g,b */\n"); printf("/* address = (r<<8 | g<<4 | b) & 0xfff */\n"); printf("/* near>>4 gives the nearest color (index) and */\n"); printf("/* near & 0x0f gives the distance. */\n"); printf("/* nearmc[4096] - table of distance minus color */\n"); printf("/* This contains the nearest color ignoring a color */\n"); printf("/* (nearmc >> 8) & 0xf is for red, */\n"); printf("/* (nearmc >> 4) & 0xf is for green, */\n"); printf("/* and nearmc & 0xf is for blue */\n\n"); } struct color { int red, green, blue; }; struct color color[16] = { {0x0,0x0,0x0}, {0x4,0x6,0x6}, {0x3,0x7,0x2}, {0xc,0x2,0x3}, {0x3,0xd,0x3}, {0x3,0x2,0xc}, {0xc,0xc,0x2}, {0xc,0x3,0xd}, {0x3,0xc,0xd}, {0xc,0xd,0xc}, {0x0,0x8,0xa}, {0x8,0x0,0x8}, {0x8,0x8,0x0}, {0xf,0x7,0x7}, {0x8,0xf,0x8}, {0x8,0x8,0xf} }; main() { int r,g,b; int d,dd,n,i; int dr,dg,db, ddr,ddg,ddb, nr,ng,nb; printcomments(); printf("#include \n\n"); printf("UWORD colortable[16] = {\n"); for (i=0; i<15; i++) printf("\t0x%01x%01x%01x,\n", color[i].red,color[i].green,color[i].blue); printf("\t0x%01x%01x%01x\n", color[i].red,color[i].green,color[i].blue); printf("};\n\n"); printf("UBYTE near[4096] = {\n"); for (r = 0; r < 16; r++) { for (g = 0; g < 16; g++) { printf("\t"); for (b = 0; b < 16; b++) { d = 10000; for (i = 0; i < 16; i++) { dd = abs(r - color[i].red) + abs(g - color[i].green) + abs(b - color[i].blue); if (dd < d) { d = dd; n = i; } } printf("0x%01x%01x",n,d); if (b < 15) printf(", "); else if ((r < 15) || (g < 15)) printf(",\n"); else printf("\n"); if (b == 7) printf("\n\t"); } } } printf("};\n\n"); printf("UWORD nearmc[4096] = {\n"); for (r = 0; r < 16; r++) { for (g = 0; g < 16; g++) { printf("\t"); for (b = 0; b < 16; b++) { dr = 10000; dg = 10000; db = 10000; for (i = 0; i < 16; i++) { ddr = abs(g -color[i].green) + abs(b - color[i].blue ); ddg = abs(r -color[i].red ) + abs(b - color[i].blue ); ddb = abs(r -color[i].red ) + abs(g - color[i].green); if (ddr < dr) { dr = ddr; nr = i;} if (ddg < dg) { dg = ddg; ng = i;} if (ddb < db) { db = ddb; nb = i;} } printf("0x%01x%01x%01x",nr,ng,nb); if (b < 15) printf(", "); else if ((r < 15) || (g < 15)) printf(",\n"); else printf("\n"); if (b == 7) printf("\n\t"); } } } printf("};\n"); } SHAR_EOF if test 3045 -ne "`wc -c makedata.c`" then echo shar: error transmitting makedata.c '(should have been 3045 characters)' fi echo shar: extracting myblit.c '(5261 characters)' cat << \SHAR_EOF > myblit.c /* myblit.c - definition of my blitter code */ /* It will blit from a source through a mask to a destination bitmap */ /* The mask must have the word before and after it clear */ #include #ifdef BLTDEBUG #include #endif #include #include #include #define BLTADD (0xdff040) /* * This structure contains everything we need to know. * Do not do a structure copy into this! Instead, assign * each field. The last field assigned must be bltsize; that * starts up the blitter. Also note that all of these are * write only, and you can't read them. */ struct BltStruct { WORD con0; WORD con1; WORD afwm; WORD alwm; WORD *csource, *bsource, *asource, *dsource; WORD bltsize; WORD dmy1, dmy2, dmy3; WORD cmod, bmod, amod, dmod; }; static struct BltStruct *Blitter = (struct BltStruct *)BLTADD; static UBYTE boffset[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; void BltBitMask(sbm,sx,sy,dbm,dx,dy,mbm,mx,my,mpno,xsize,ysize) struct BitMap *sbm, *dbm, *mbm; int sx,sy,dx,dy,mx,my,mpno,xsize,ysize; { WORD *splane, *dplane, *mplane; WORD *aaddr,*baddr,*daddr; int ashft, bshft; UWORD afwm,alwm; int smodulo, dmodulo, mmodulo; int i; smodulo = ((sbm->BytesPerRow) + 1) >> 1; dmodulo = ((dbm->BytesPerRow) + 1) >> 1; mmodulo = ((mbm->BytesPerRow) + 1) >> 1; splane = (WORD *) (sbm->Planes[0]); dplane = (WORD *) (dbm->Planes[0]); mplane = (WORD *) (mbm->Planes[mpno]); daddr = dplane + dmodulo * dy + (dx >> 4); dx &= 15; aaddr = mplane + mmodulo * my + (mx >> 4); mx &= 15; baddr = splane + smodulo * sy + (sx >> 4); sx &= 15; #ifdef BLTDEBUG printf("new - spl = %x, dpl = %x, mpl = %x\n",splane,dplane,mplane); printf("smod = %x, dmod = %x, mmod = %x\n",smodulo,dmodulo,mmodulo); printf("aa=%x, ba=%x, da=%x, (a)mx=%d, (b)sx=%d, dx=%d, xs=%d\n", (aaddr - mplane - mmodulo * my), (baddr - splane - smodulo * sy), (daddr - dplane - dmodulo * dy),mx,sx,dx,xsize); #endif ashft = dx - mx; bshft = dx - sx; afwm = ((unsigned) 0xffff) >> mx; alwm = 0xffff << (16 - ((mx + xsize) & 15)); xsize = (xsize + dx + 15) >> 4; if ((ashft < 0) || (bshft < 0)) { daddr--; xsize++; if (ashft < 0) ashft += 16; else aaddr--; if (bshft < 0) bshft += 16; else baddr--; } #ifdef BLTDEBUG printf("aaddr = %x, baddr = %x, daddr = %x\n",aaddr,baddr,daddr); printf("aa=%x, ba=%x, da=%x, fw=%x, lw=%x, as=%d, bs=%d, xs=%d\n", (aaddr - mplane - mmodulo * my), (baddr - splane - smodulo * sy), (daddr - dplane - dmodulo * dy),afwm,alwm,ashft,bshft,xsize); #endif OwnBlitter(); WaitBlit(); Blitter->asource = aaddr; Blitter->bsource = baddr; Blitter->csource = Blitter->dsource = daddr; Blitter->amod = (mmodulo - xsize) << 1; Blitter->bmod = (smodulo - xsize) << 1; Blitter->cmod = Blitter->dmod = (dmodulo - xsize) << 1; Blitter->afwm = afwm; Blitter->alwm = alwm; Blitter->con0 = (ashft << 12) | (0xf << 8) | 0xca; Blitter->con1 = (bshft << 12); Blitter->bltsize = (ysize << 6) | xsize; for (i = 1; i < dbm->Depth; i++) { WaitBlit(); Blitter->asource = aaddr; Blitter->bsource = baddr + (((WORD *)sbm->Planes[i]) - ((WORD *)sbm->Planes[0])); Blitter->csource = Blitter->dsource = daddr + (((WORD *)dbm->Planes[i]) - ((WORD *)dbm->Planes[0])); Blitter->bltsize = (ysize << 6) | xsize; } DisownBlitter(); } void mywritepixel1(bm,x,y) struct BitMap *bm; int x,y; { register int offset; register UBYTE bits; offset = y * bm->BytesPerRow + (x >> 3); bits = boffset[x & 7]; bm->Planes[0][offset] |= bits; } void mywritepixel(bm,x,y,color) struct BitMap *bm; int x,y; { register int offset; register int i; UBYTE bits,nbits; offset = y * bm->BytesPerRow + (x >> 3); bits = boffset[x & 7]; nbits = ~bits; for (i=0; i < bm->Depth; i++) { if (color & 0x01) bm->Planes[i][offset] |= bits; else bm->Planes[i][offset] &= nbits; color >>= 1; } } void myblank(bm,y1,y2) struct BitMap *bm; int y1,y2; { register int offset, bytes; register int i; offset = y1 * bm->BytesPerRow; bytes = (y2 - y1) * bm->BytesPerRow; for (i=0; i < bm->Depth; i++) BltClear(&(bm->Planes[i][offset]),bytes,0); } void mylinecopy(bm,starty,len,delta) struct BitMap *bm; int starty, len, delta; { UBYTE *loc1, *loc2, *stop; int i; for(i=0; i < bm->Depth; i++) { loc1 = &(bm->Planes[i][starty*bm->BytesPerRow]); stop = loc1 + len*bm->BytesPerRow; loc2 = loc1 + delta*bm->BytesPerRow; while (loc1 < stop) *(loc2++) = *(loc1++); } } void myblankc(bm,y1,y2,color) struct BitMap *bm; int y1,y2,color; { register int i; WORD *daddr; int dmodulo; dmodulo = ((bm->BytesPerRow) + 1) >> 1; daddr = (WORD *) (bm->Planes[0]); daddr += dmodulo * y1; OwnBlitter(); WaitBlit(); Blitter->dsource = daddr; Blitter->dmod = 0; if (color & 1) Blitter->con0 = (1 << 8) | (0xff); else Blitter->con0 = (1 << 8); Blitter->bltsize = ((y2-y1) << 6) | dmodulo; color >>= 1; for (i = 1; i < bm->Depth; i++) { WaitBlit(); Blitter->dsource = daddr + (((WORD *)bm->Planes[i]) - ((WORD *)bm->Planes[0])); if (color & 1) Blitter->con0 = (1 << 8) | (0xff); else Blitter->con0 = (1 << 8); color >>= 1; Blitter->bltsize = ((y2 - y1) << 6) | dmodulo; } DisownBlitter(); } SHAR_EOF if test 5261 -ne "`wc -c myblit.c`" then echo shar: error transmitting myblit.c '(should have been 5261 characters)' fi echo shar: extracting screen.c '(5319 characters)' cat << \SHAR_EOF > screen.c /* screen.c -- code to open a screen and then call render */ #include #include #include #include #include "globals.h" #include #include #include #include struct IntuitionBase *IntuitionBase = NULL; struct GfxBase *GfxBase = NULL; struct LayersBase *LayersBase = NULL; #define IREV 29 #define GREV 29 char defaultfile[] = "balls.default.dat"; #define DEPTH 6 int depth = DEPTH; struct BitMap pbitmap = { /* picture (screen) bitmap (*sbitmap) */ 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; struct BitMap tbitmap = { /* temp (exact) bitmap */ 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; struct BitMap ibitmap = { /* image bitmap */ 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; struct BitMap mbitmap = { /* mask bitmap */ 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; struct NewScreen mynewscreen = { 0, 0, WIDTH, 200, DEPTH, 0, 15, HAM, CUSTOMSCREEN | CUSTOMBITMAP, NULL, "B & W Low Res Screen", NULL, &pbitmap, }; struct Screen *myscreen = NULL; struct ViewPort *vp; struct BitMap *sbitmap = NULL; struct NewWindow mynewwindow = { 0, 1, WIDTH, 199, 0, 15, MOUSEBUTTONS | MOUSEMOVE | CLOSEWINDOW, WINDOWCLOSE | SIMPLE_REFRESH | /* BACKDROP | */ BORDERLESS | REPORTMOUSE | ACTIVATE, NULL, NULL, " Please Wait . . . ", NULL, NULL, 0, 0, 0, 0, CUSTOMSCREEN, }; struct Window *mywindow = NULL; int bw = 0; UWORD bwcolortable[16] = { 0x000, 0x111, 0x222, 0x333, 0x444, 0x555, 0x666, 0x777, 0x888, 0x999, 0xaaa, 0xbbb, 0xccc, 0xddd, 0xeee, 0xfff}; void main(argc,argv) int argc; char *argv[]; { int i; void cleanup(); switch (argc) { case 0: readballs(defaultfile); break; case 2: readballs(argv[1]); break; case 3: if (strcmp(argv[1],"-bw") == 0) { setbw(); readballs(argv[2]); break; } default:dodefault(); } onbreak(&cleanup); initrender(); IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",IREV); if (IntuitionBase == NULL) panic("Can't open intuition"); GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",GREV); if (GfxBase == NULL) panic("Can't open GfxBase"); InitBitMap(&pbitmap,depth,WIDTH,HEIGHT); for (i=0; i < depth; i++) { pbitmap.Planes[i] = (PLANEPTR)AllocRaster(WIDTH,HEIGHT); if (pbitmap.Planes[i] == NULL) panic("Not enough memory for screen"); BltClear(pbitmap.Planes[i],RASSIZE(WIDTH,HEIGHT),0); } if (!bw) { InitBitMap(&tbitmap,depth,WIDTH,SMHEIGHT); for (i=0; i < depth; i++) { tbitmap.Planes[i] = (PLANEPTR)AllocRaster(WIDTH,SMHEIGHT); if (tbitmap.Planes[i] == NULL) panic("Not enough memory for temp bit map"); BltClear(tbitmap.Planes[i],RASSIZE(WIDTH,SMHEIGHT),0); } } InitBitMap(&ibitmap,depth,maskw,maskh); for (i=0; i < depth; i++) { ibitmap.Planes[i] = (PLANEPTR)AllocRaster(maskw,maskh); if (ibitmap.Planes[i] == NULL) panic("Not enough memory for image bit map"); BltClear(ibitmap.Planes[i],RASSIZE(maskw,maskh),0); } InitBitMap(&mbitmap,1,maskw,maskh); mbitmap.Planes[0] = (PLANEPTR)AllocRaster(maskw,maskh); if (mbitmap.Planes[0] == NULL) panic("Not enough memory for mask bit map"); BltClear(mbitmap.Planes[0],RASSIZE(maskw,maskh),0); myscreen = (struct Screen *) OpenScreen(&mynewscreen); if (myscreen == NULL) panic("Can't open screen"); vp = &(myscreen->ViewPort); sbitmap = &(myscreen->BitMap); mynewwindow.Screen = myscreen; mywindow = (struct Window *) OpenWindow(&mynewwindow); if (mywindow == NULL) panic("Can't open window"); if (bw) LoadRGB4(&myscreen->ViewPort,bwcolortable,16); else LoadRGB4(&myscreen->ViewPort,colortable,16); RethinkDisplay(); render(); cleanup(); } void panic(str) char *str; { fprintf(stderr,"%s\n",str); fflush(stderr); cleanup(); } void cleanup() { int i; if (mywindow) CloseWindow(mywindow); if (myscreen) CloseScreen(myscreen); if (mbitmap.Planes[0]) FreeRaster(mbitmap.Planes[0],maskw,maskh); for (i = depth-1; i >= 0; i--) if (ibitmap.Planes[i]) FreeRaster(ibitmap.Planes[i],maskw,maskh); for (i = depth-1; i >= 0; i--) if (tbitmap.Planes[i]) FreeRaster(tbitmap.Planes[i],WIDTH,SMHEIGHT); for (i = depth-1; i >= 0; i--) if (pbitmap.Planes[i]) FreeRaster(pbitmap.Planes[i],WIDTH,HEIGHT); if (GfxBase) CloseLibrary((struct Library *)GfxBase); if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase); exit(0); } void setbw() { bw = TRUE; mynewscreen.Depth = depth = 4; mynewscreen.ViewModes &= ~HAM; } void dodefault() { printf(" %c33manimballs%c31m - An animation hack by JimG\n\n",0x9b,0x9b); printf("Usage: animballs [-bw] ballsfile\n\n"); printf(" You have invoked animballs without parameters. I will use\n"); printf("a default balls file (balls.default.dat). You should read the\n"); printf("README file to see how to run this program. As a quick intro,\n"); printf("there will be a delay and then you will see some balls appear.\n"); printf("Press and hold the left mouse button, then drag the mouse to\n"); printf("rotate the balls in 3-space. Click on the close gadget to end.\n\n"); printf("Press to continue:"); (void) getc(stdin); readballs(defaultfile); } SHAR_EOF if test 5319 -ne "`wc -c screen.c`" then echo shar: error transmitting screen.c '(should have been 5319 characters)' fi # End of shell archive exit 0