#define ANIM_C #include #include #include "roads.h" #include "tiles.h" extern int far *topography; /* BACKGROUND TILE LIST (ARRAY) */ extern int far *terrain; /* FOREGROUND TILE LIST (ARRAY) */ extern int view_x, view_y; /* VIEW AREA (UPPER LEFT CORNER) */ extern int viewpage; /* CURRENTLY VIEWED PAGE */ int frogmode; int frogwatchmode=0; int animatemode=1; /* ANIMATION VARIABLES */ struct ANIMATION fire, water1, water2, uranium, frog; struct ANIMATION *anim_list[ANIM_LIST_TOTAL]; /* * * Animates all cells to the next frame. * */ void animate (void) { register int x, y; int a, i, tile; long time; int total_updates=0; gogofrog(); time=fg_getclock(); /* UPDATE ALL ANIM TYPES FOR NEXT FRAME IF TIME TO DO SO */ for (a=0; anext<1) /* EVENT_DRIVEN ANIMATION */ { if (anim_list[a]->next==-1) /* EVENT OCCURING! */ { anim_list[a]->next=0; /* TURN EVENT OFF */ total_updates++; } } else if (anim_list[a]->next<=time) /* IS ANIM READY FOR NEXT FRAME? */ { anim_list[a]->next=time+anim_list[a]->delay; /* SET NEXT FRAME TIME */ anim_list[a]->current+=1; if (anim_list[a]->current>=anim_list[a]->first+anim_list[a]->total) anim_list[a]->current=anim_list[a]->first; total_updates++; } } if (total_updates==0) return; /* NO ANIMATION TODAY. SORRY */ /* VISUALLY UPDATE ALL VIEWABLE ANIMATIONS */ for (y=0; yanm!=terrain[i]) a++; tile=anim_list[a]->current; /* COPY TILE TO MIX THEN TO CURRENT SCREEN */ pagecopy_tile_op (topography[i], MIXING_TILE, TILEPAGE, TILEPAGE); pagecopy_tile_tr (tile, MIXING_TILE, TILEPAGE, TILEPAGE); pagecopy_tile_op (MIXING_TILE, VIEW_TILE(x,y), TILEPAGE, viewpage); } } } #define UP 1 #define DOWN 2 #define LEFT 3 #define RIGHT 4 #define CHANCE_FROG_NOT_TURN 95 /* * * Move frog somewhere new. * */ void gogofrog (void) { int fails=0, r, suc; int newx, newy; static int x, y; static int facing=RIGHT; static int walking=FALSE; static long nextfrog; if (frogmode==3) return; /* NO FROG! GO AWAY */ if (frogmode==2) { terrain[WORLD_TILE(x,y)]=EMPTY_TILE; update_tile (WORLD_TILE(x,y)); frogmode=3; return; } if (frogmode==1) { if (nextfrog>fg_getclock()) return; /* NOT TIME TO ANIMATE OUR FROGGIE */ frog.next=-1; /* TURN ON ANIMATION EVENT FLAG */ /* DETERMINE IF FROG CHANGES FACING */ if (random(100)>CHANCE_FROG_NOT_TURN) { walking=FALSE; NEW_FACING: /* CHANGE FACING */ r=random(100); switch (facing) { case RIGHT: case LEFT: if (r<50) facing=UP; else facing=DOWN; break; case DOWN: case UP: if (r<50) facing=RIGHT; else facing=LEFT; break; } /* UPDATE FACING IMAGE */ switch (facing) { case RIGHT: frog.current=FROG_FACE_RIGHT; break; case LEFT: frog.current=FROG_FACE_LEFT; break; case DOWN: frog.current=FROG_FACE_DOWN; break; case UP: frog.current=FROG_FACE_UP; break; } nextfrog=fg_getclock()+frog.delay; return; } /* DETERMINE IF FROG STARTS/STOPS WALKING */ if (walking==FALSE) { walking=TRUE; switch (facing) { case RIGHT: frog.current=FROG_WALK_RIGHT; break; case LEFT: frog.current=FROG_WALK_LEFT; break; case DOWN: frog.current=FROG_WALK_DOWN; break; case UP: frog.current=FROG_WALK_UP; break; } frog.next=-1; /* TURN ON ANIMATION EVENT FLAG */ nextfrog=fg_getclock()+frog.delay; return; } /* DETERMINE IF WE CAN WALK OUR FROGGIE THIS WAY! */ newx=x; newy=y; switch (facing) { case RIGHT: newx++; break; case LEFT: newx--; break; case DOWN: newy++; break; case UP: newy--; break; } /* CAN'T MOVE -- OBSTRUCTION OR END OF WORLD! */ if (newx<0 || newy<0 || newx>=WORLD_WIDTH || newy>=WORLD_HEIGHT || terrain[WORLD_TILE(newx,newy)]!=EMPTY_TILE) { /* UPDATE FACING IMAGE TO REFLECT FROG STANDS FAST */ if (random(100)<50) switch (facing) { case RIGHT: frog.current=FROG_FACE_RIGHT; break; case LEFT: frog.current=FROG_FACE_LEFT; break; case DOWN: frog.current=FROG_FACE_DOWN; break; case UP: frog.current=FROG_FACE_UP; break; } else { frog.next=-1; goto NEW_FACING; } nextfrog=fg_getclock()+frog.delay; return; } /* CAN MOVE! MOVE FROG ALONG */ switch (facing) { case RIGHT: if (++frog.current>=FROG_NUM_WALKS+FROG_WALK_RIGHT) frog.current=FROG_WALK_RIGHT; break; case LEFT: if (++frog.current>=FROG_NUM_WALKS+FROG_WALK_LEFT) frog.current=FROG_WALK_LEFT; break; case DOWN: if (++frog.current>=FROG_NUM_WALKS+FROG_WALK_DOWN) frog.current=FROG_WALK_DOWN; break; case UP: if (++frog.current>=FROG_NUM_WALKS+FROG_WALK_UP) frog.current=FROG_WALK_UP; break; } /* DON'T MOVE FROG'S X/Y AT CERTAIN FRAMES */ if (frog.current==FROG_WALK_UP+1 || frog.current==FROG_WALK_UP+3 || frog.current==FROG_WALK_LEFT+1 || frog.current==FROG_WALK_LEFT+3 || frog.current==FROG_WALK_RIGHT+1 || frog.current==FROG_WALK_RIGHT+3 || frog.current==FROG_WALK_DOWN+1 || frog.current==FROG_WALK_DOWN+3 ) { frog.next=-1; nextfrog=fg_getclock()+frog.delay; return; } terrain[WORLD_TILE(x,y)]=EMPTY_TILE; terrain[WORLD_TILE(newx,newy)]=ANM_FROG; frog.next=-1; /* * * Simply put, frog watch mode doesn't work. * I got to the point where I said, gosh darnit, who needs * to watch a stinking frog anyway? It's left as is... * */ if (frogwatchmode) { if (newx>x) if (view_x0) view_x--; else if (newy>y) if (view_y0) view_y--; redraw (NONFLIP_REFRESH); /* if (newx>x) suc=redraw (NONFLIP_SCROLL_RIGHT); else if (newxy) suc=redraw (NONFLIP_SCROLL_DOWN); else if (newy=50) /* COULDN'T PLACE FROG */ { fg_music ("L64EC.DE.C$"); frogmode=3; frog.next=0; return; } terrain[WORLD_TILE(x,y)]=ANM_FROG; /* INSTALL FROG! */ frog.next=-1; /* UPDATE EVENT */ frogmode=1; nextfrog=fg_getclock()+frog.delay; return; } /* * * Initializes any animation information, as in at the program start. * */ void init_anim (void) { fire.first=fire.current=34; fire.total=6; fire.delay=1; fire.next=fg_getclock()+fire.delay; fire.anm=ANM_FIRE; water1.first=water1.current=60; water1.total=3; water1.delay=3; water1.next=fg_getclock()+water1.delay; water1.anm=ANM_WATER1; water2.first=water2.current=63; water2.total=3; water2.delay=4; water2.next=fg_getclock()+water2.delay; water2.anm=ANM_WATER2; uranium.first=uranium.current=66; uranium.total=10; uranium.delay=4; uranium.next=fg_getclock()+uranium.delay; uranium.anm=ANM_URANIUM; frog.first=frog.current=FROG_FACE_RIGHT; frog.total=FROG_NUM_WALKS; frog.delay=3; frog.next=-1; frog.anm=ANM_FROG; anim_list[0]=&fire; anim_list[1]=&water1; anim_list[2]=&water2; anim_list[3]=&uranium; anim_list[4]=&frog; }