/* fish.c */ /* Lloyd and Peter Linstrom */ #include "exec/types.h" #include "intuition/intuition.h" #include "graphics/sprite.h" #include "exec/memory.h" SHORT sprgot[8]; /* -1 means invalid sprite */ UWORD *sprdata[8]; /* eight pointers to sprite data */ SHORT xmove[8]; /* used for speed of x movement */ SHORT ymove[ ] = {1, 1, 30, 25, 20, 35, 35, 30}; /* used for speed of y movement */ SHORT count; /* Counter used in moving sprites */ struct SimpleSprite sprite[8]; /* seven simple sprites */ struct SimpleSprite *spr; /* pointer to a sprite */ short sheigth[ ] = {0, 10, 12, 11, 9, 15, 19, 10}; /* height of sprite */ short sdatasize[ ] = {0, 48, 56, 52, 44, 68, 84, 48}; /* size of sprite data */ short xstep[8]; /* Fish Movement increment for x */ short ystep[8]; /* Fish Movement increment for y */ short fishspeed[ ] = {0, 6, 4, 3, 2, 5, 4, 2}; /* Bias for fish speed */ short eventtime[8]; /* Counts until next scheduled movement change */ short eventtype[8]; /* Type of event to occur at eventtime */ short stopcode[ ] = {0, 0, 0, 0, 0, 0, 0, 0}; /* 1=fish stopped */ UWORD swtchex[ ] = { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 }; /* Bit reversed hex digits */ struct Window *w,*OpenWindow(); /* pointer to a window */ struct RastPort *rp; /* pointer to a RastPort */ struct Screen *s,*picture(); /* pointer to a screen */ struct ViewPort *vport; /* pointer to a ViewPort */ LONG GfxBase; LONG IntuitionBase; UWORD bottomfish[ ] = { 0, 0, /* position control */ 0x01c0, 0x0000, 0x07c1, 0x0001, 0x0443, 0x1ff3, 0x1217, 0x6fff, 0x848f, 0xffff, 0x2daf, 0xf7ff, 0xcd7f, 0x3bff, 0x3bd3, 0x1df3, 0x5101, 0x0001, 0x8800, 0x0000, 0, 0 }; UWORD bluefish[ ] = { 0, 0, /* position control */ 0x0080, 0x0080, 0x0380, 0x0381, 0x0001, 0x1ff2, 0x1003, 0x7ffc, 0x0003, 0xfffc, 0x0ff3, 0xf00c, 0x7ff1, 0x0002, 0x07c0, 0x07c1, 0x01c0, 0x01c0, 0, 0 /* end of structure */ }; UWORD bluetwo[ ] = { 0, 0, /* position */ 0x0060, 0x0020, 0x01e0, 0x00e0, 0x07e0, 0x03c0, 0x0fe1, 0x0021, 0x3ff1, 0x0002, 0x6ff5, 0x0003, 0xfdf7, 0x028b, 0xfbeb, 0x2635, 0x4eb7, 0xb9cb, 0x3765, 0x6ab3, 0x19c1, 0x0ea2, 0x0681, 0x0301, 0x0100, 0x0100, 0x0080, 0x0080, 0x0040, 0x0040, 0, 0 /* End of structure */ }; UWORD goldfish[ ] = { 0, 0, /* position control */ 0x0180, 0x0000, 0x03c0, 0x0000, 0x07c0, 0x0001, 0x0001, 0x1fe2, 0x0003, 0x7ff4, 0x1003, 0xeffc, 0x0407, 0xfbf8, 0x0403, 0xfbfc, 0x0c03, 0x73fc, 0x0001, 0x1fe2, 0x07c0, 0x0001, 0x00c0, 0x0000, 0, 0 /* end of structure */ }; UWORD goldtwo[ ] = { 0, 0, /* position control */ 0x01c0, 0x0000, 0x0781, 0x0000, 0x16c3, 0x0900, 0x16c7, 0x6920, 0x925b, 0x4da4, 0x9b6e, 0x6490, 0xcdab, 0x3254, 0x6da7, 0x1240, 0x0dc3, 0x1200, 0x0381, 0x0000, 0x01c0, 0x0000, 0, 0 /* End of structure */ }; UWORD angelfish[ ] = { 0, 0, /* position control */ 0x0000, 0x00c0, 0x0000, 0x0100, 0x0000, 0x0200, 0x0000, 0x0400, 0x0101, 0x0f80, 0x1203, 0x1fc0, 0x1247, 0x3fe1, 0x1495, 0x5ffa, 0xa4ae, 0x7ff4, 0xa4a2, 0x7ffc, 0xa4ae, 0x7ff4, 0x76d7, 0x2dba, 0x3fe7, 0x3241, 0x0f83, 0x0a40, 0x0601, 0x0780, 0x0200, 0x0200, 0x0100, 0x0100, 0x00c0, 0x00c0, 0x0030, 0x0030, 0, 0 /* end of structure */ }; UWORD brownfish[ ] = { 0, 0, /* Position control */ 0x0380, 0x0000, 0x0380, 0x0401, 0x1fe0, 0x1fe3, 0x7ff0, 0x7ff7, 0xcab9, 0xdffe, 0xb66a, 0xeddc, 0x5dd1, 0xa32e, 0x4a50, 0x7db7, 0x0180, 0x0ec3, 0x0100, 0x0001, 0, 0 /* End of Structure */ }; int rnum(d) /* Generate nonzero random number max d */ int d; { int t1; if(d <= 0) return(1); t1 = rand() % d + 1; return(t1); } void revsprite(dptr, nbytes) /* Bit reverse sprite data */ UWORD *dptr; /* Pointer to sprite data */ SHORT nbytes; /* Number of data bytes */ { short nlft; /* Number of words to reverse */ UWORD t1, t2; dptr++; /* Skip first two words of sprite data */ dptr++; nlft = nbytes/2 - 4; /* Number of words to reverse */ while(nlft > 0) { t1 = *dptr; /* Bit reverse word */ t2 = swtchex[t1 & 0xF] << 12; t2 += swtchex[(t1 & 0xF0) >> 4] << 8; t2 += swtchex[(t1 & 0xF00) >> 8] << 4; t2 += swtchex[(t1 & 0xF000) >> 12]; *dptr++ = t2; nlft--; } } void xevent(i) /* Handle events in fish movement */ short i; /* Fish number */ { switch(eventtype[i]) { case 1: /* Stop fish */ stopcode[i] = 1; ystep[i] = 0; eventtime[i] = rnum(30); eventtype[i] = 2; break; case 2: /* Start fish */ stopcode[i] = 0; eventtime[i] = 1; eventtype[i] = rnum(3) + 2; break; case 3: /* Reverse fish */ xstep[i] = -1 * xstep[i]; revsprite(sprdata[i], sdatasize[i]); eventtime[i] = 1; eventtype[i] = rnum(2) + 3; break; case 4: /* Change speed */ xmove[i] = rnum(3) + fishspeed[i]; eventtime[i] = 500 + rnum(1500); eventtype[i] = 1; break; case 5: /* Move in Y */ xmove[i] = rnum(3) + fishspeed[i]; ystep[i] = (rnum(2) == 1)? 1 : -1; if(spr->y < 50) ystep[i] = 1; if(spr->y >150) ystep[i] = -1; eventtype[i] = 1; eventtime[i] = 100 + rnum(500); break; default: break; } } movesprites() { short i; short newx, newy; spr = &sprite[0]; /* Point to first sprite */ for (i=0; i<8; i++) { if(sprgot[i] == -1) continue; if(--eventtime[i] == 0) xevent(i); /* Execute any events for fish */ if((count % xmove[i]) == 0) { if(stopcode[i] == 1) break; newx = spr->x + xstep[i];/* New sprite pos */ if((newx <= 0) || (newx >= 304)) { eventtime[i] = 1; eventtype[i] = 3; /* Reverse fish */ } MoveSprite(0, spr, newx, spr->y); } if((i != 1) && ((count % ymove[i]) == 0)) { if(stopcode[i] == 1) break; newy = spr->y + ystep[i]; if((newy <= 15) || (newy >= 185)) { eventtime[i] = 1; eventtype[i] = 5; /* Change Y movement */ } MoveSprite(0, spr, spr->x, newy); } spr++; /* Point to next sprite */ } count = ++count % 5040; /* 5040 = 7! */ } #define AZCOLOR 1 #define WHITECOLOR 2 struct NewWindow myWindow = { 0, 15, 300, 10, -1, -1, CLOSEWINDOW, WINDOWCLOSE | WINDOWDEPTH | WINDOWSIZING | WINDOWDRAG | ACTIVATE, NULL, NULL, (UBYTE *) "Fish Tank", NULL, NULL, 100, 30, 620, 200, WBENCHSCREEN }; #include "graphics/gfxmacros.h" int HandleEvent(code) LONG code; /* provided by main */ { switch (code) { case CLOSEWINDOW: return(0); break; default: return(1); break; } } void setspritecolors(vp) struct ViewPort *vp; { /* Goldfish colors for sprites 2 & 3 */ SetRGB4(vp, 22L, 15L, 8L, 2L); SetRGB4(vp, 21L, 15L, 11L, 7L); /* Bluefish colors for sprites 4 & 5 */ SetRGB4(vp, 26L, 0L, 7L, 12L); SetRGB4(vp, 25L, 7L, 9L, 15L); SetRGB4(vp, 27L, 13L, 14L, 14L); /* Angelfish colors for sprites 6 & 7 */ SetRGB4(vp, 30L, 15L, 12L, 9L); SetRGB4(vp, 29L, 15L, 13L, 11L); SetRGB4(vp, 31L, 7L, 5L, 2L); } int init() /* Open Libraries, Window, and set sprite colors */ { GfxBase = OpenLibrary("graphics.library", 0); if(GfxBase == NULL) return(0); IntuitionBase = OpenLibrary("intuition.library", 0); if(IntuitionBase == NULL) return(0); w = OpenWindow(&myWindow); if (w == 0) return(0); rp = w->RPort; vport = ViewPortAddress(w); /* ViewPort address of current screen */ setspritecolors(vport); return(1); /* Successful initialization */ } endit() /* Close screen, librarys and windows */ { if(s) s = picture(1,"background.ilbm"); /* Get rid of the background screen */ if(w) CloseWindow(w); if(GfxBase) CloseLibrary(GfxBase); if(IntuitionBase) CloseLibrary(IntuitionBase); exit(0); } cleanup() /* DeAllocate sprites and sprite memory */ { short k; for(k=0; k<8; k++) { if(sprgot[k] == -1) continue; FreeSprite(k); /* Free Sprite */ FreeMem(sprdata[k], sdatasize[k]); /* Free Sprite memory */ } } main() { struct IntuiMessage *msg; LONG k, result; SHORT j, jmax; UWORD *src, *dest; /* for copying data into ram */ if (init() == 0) endit(); /* Initailize everything */ srand(time(NULL)); /* Set PRN generator */ s = picture(0,"background.ilbm"); /* Load in background screen */ if(s != NULL) { vport = &(s->ViewPort); /* new viewport */ setspritecolors(vport); } count = 0; /* Initailize counter for movesprite()*/ spr = &sprite[0]; /* Point to first sprite */ sprgot[0] = -1; /* Ignore sprite 0 */ for(k=1; k<8; k++) { sprgot[k] = GetSprite(spr, k); /* Get a Sprite */ if(sprgot[k] == -1) continue; /* Skip if sprite unavailable */ xmove[k] = rnum(3) + fishspeed[k]; /* Set speed */ xstep[k] = (rnum(2) == 1)? -1 : 1; /* Set x direction */ ystep[k] = 0; /* Set y direction */ spr->x = 25 + rnum(250); /* Initialize position */ spr->y = 10 + rnum(170); if(k == 1) spr->y = 188; /* bottomfish on bottom */ eventtime[k] = rnum(800); /* time of event */ eventtype[k] = 1; /* stop */ spr->height = sheigth[k]; /* Initialize height */ switch(k) { case 1: src = bottomfish; break; case 2: src = goldfish; break; case 3: src = goldtwo; break; case 4: src = bluefish; break; case 5: src = bluetwo; break; case 6: src = angelfish; break; case 7: src = brownfish; break; } sprdata[k] = (UWORD *)AllocMem(sdatasize[k], MEMF_CHIP); if(sprdata[k] == NULL) /* No Chip Ram */ { FreeSprite(k); sprgot[k] = -1; /* Mark sprite as unavailable */ break; } dest = sprdata[k]; /* Copy sprite into Chip ram */ jmax = sdatasize[k] / 2; /* Num of words to copy */ for(j=0; jUserPort))!=NULL) { result = result * HandleEvent(msg->Class); ReplyMsg(msg); } if(result == 0) /* Close Window Flag */ { cleanup(); endit(); } movesprites(); } }