]> 4ch.mooo.com Git - 16.git/blob - 16/roads/ANIM.C
16_ca needs huge amounts of work and I should remember what needs to be done soon...
[16.git] / 16 / roads / ANIM.C
1 #define ANIM_C\r
2 \r
3 #include <fastgraf.h>\r
4 #include <stdlib.h>\r
5 #include "roads.h"\r
6 #include "tiles.h"\r
7 \r
8 extern int far *topography;      /* BACKGROUND TILE LIST (ARRAY) */\r
9 extern int far *terrain;      /* FOREGROUND TILE LIST (ARRAY) */\r
10 extern int view_x, view_y;     /* VIEW AREA (UPPER LEFT CORNER) */\r
11 extern int viewpage;           /* CURRENTLY VIEWED PAGE */\r
12 \r
13 int frogmode;\r
14 int frogwatchmode=0;\r
15 int animatemode=1;\r
16 \r
17 /* ANIMATION VARIABLES */\r
18 struct ANIMATION fire, water1, water2, uranium, frog;\r
19 struct ANIMATION *anim_list[ANIM_LIST_TOTAL];\r
20 \r
21 /*\r
22  *\r
23  * Animates all cells to the next frame.\r
24  *\r
25  */\r
26 void animate (void)\r
27 {\r
28     register int x, y;\r
29     int a, i, tile;\r
30     long time;\r
31     int total_updates=0;\r
32 \r
33     gogofrog();\r
34     time=fg_getclock();\r
35 \r
36     /* UPDATE ALL ANIM TYPES FOR NEXT FRAME IF TIME TO DO SO */\r
37     for (a=0; a<ANIM_LIST_TOTAL; a++) /* CHECK ALL ANIM TYPES */\r
38     {\r
39         if (anim_list[a]->next<1) /* EVENT_DRIVEN ANIMATION */\r
40         {\r
41             if (anim_list[a]->next==-1) /* EVENT OCCURING! */\r
42             {\r
43                 anim_list[a]->next=0; /* TURN EVENT OFF */\r
44                 total_updates++;\r
45             }\r
46         }\r
47 \r
48         else if (anim_list[a]->next<=time) /* IS ANIM READY FOR NEXT FRAME? */\r
49         {\r
50             anim_list[a]->next=time+anim_list[a]->delay; /* SET NEXT FRAME TIME */\r
51             anim_list[a]->current+=1;\r
52             if (anim_list[a]->current>=anim_list[a]->first+anim_list[a]->total)\r
53                 anim_list[a]->current=anim_list[a]->first;\r
54             total_updates++;\r
55         }\r
56     }\r
57 \r
58     if (total_updates==0) return; /* NO ANIMATION TODAY.  SORRY */\r
59 \r
60     /* VISUALLY UPDATE ALL VIEWABLE ANIMATIONS */\r
61     for (y=0; y<VIEW_HEIGHT; y++)\r
62     for (x=0; x<VIEW_WIDTH; x++)\r
63     {\r
64         i=VIEW_TO_WORLD(VIEW_TILE(x,y)); /* CONVERT VIEW COORDS TO WORLD */\r
65 \r
66         if (is_anim(terrain[i]))\r
67         {\r
68             a=0;\r
69             while (anim_list[a]->anm!=terrain[i]) a++;\r
70             tile=anim_list[a]->current;\r
71 \r
72                 /* COPY TILE TO MIX THEN TO CURRENT SCREEN */\r
73             pagecopy_tile_op (topography[i], MIXING_TILE, TILEPAGE, TILEPAGE);\r
74             pagecopy_tile_tr (tile, MIXING_TILE, TILEPAGE, TILEPAGE);\r
75             pagecopy_tile_op (MIXING_TILE, VIEW_TILE(x,y), TILEPAGE, viewpage);\r
76         }\r
77     }\r
78 }\r
79 \r
80 #define UP    1\r
81 #define DOWN  2\r
82 #define LEFT  3\r
83 #define RIGHT 4\r
84 #define CHANCE_FROG_NOT_TURN 95\r
85 \r
86 /*\r
87  *\r
88  * Move frog somewhere new.\r
89  *\r
90  */\r
91 void gogofrog (void)\r
92 {\r
93     int fails=0, r, suc;\r
94     int newx, newy;\r
95     static int x, y;\r
96     static int facing=RIGHT;\r
97     static int walking=FALSE;\r
98     static long nextfrog;\r
99 \r
100     if (frogmode==3) return; /* NO FROG!  GO AWAY */\r
101 \r
102     if (frogmode==2)\r
103     {\r
104         terrain[WORLD_TILE(x,y)]=EMPTY_TILE;\r
105         update_tile (WORLD_TILE(x,y));\r
106         frogmode=3;\r
107         return;\r
108     }\r
109 \r
110     if (frogmode==1)\r
111     {\r
112         if (nextfrog>fg_getclock())\r
113             return; /* NOT TIME TO ANIMATE OUR FROGGIE */\r
114 \r
115         frog.next=-1; /* TURN ON ANIMATION EVENT FLAG */\r
116 \r
117         /* DETERMINE IF FROG CHANGES FACING */\r
118         if (random(100)>CHANCE_FROG_NOT_TURN)\r
119         {\r
120             walking=FALSE;\r
121 \r
122             NEW_FACING:\r
123 \r
124             /* CHANGE FACING */\r
125             r=random(100);\r
126             switch (facing)\r
127             {\r
128                 case RIGHT:\r
129                 case LEFT:\r
130                 if (r<50) facing=UP;\r
131                 else facing=DOWN;\r
132                 break;\r
133 \r
134                 case DOWN:\r
135                 case UP:\r
136                 if (r<50) facing=RIGHT;\r
137                 else facing=LEFT;\r
138                 break;\r
139             }\r
140 \r
141             /* UPDATE FACING IMAGE */\r
142             switch (facing)\r
143             {\r
144                 case RIGHT: frog.current=FROG_FACE_RIGHT; break;\r
145                 case LEFT:  frog.current=FROG_FACE_LEFT;  break;\r
146                 case DOWN:  frog.current=FROG_FACE_DOWN;  break;\r
147                 case UP:    frog.current=FROG_FACE_UP;    break;\r
148             }\r
149             nextfrog=fg_getclock()+frog.delay;\r
150             return;\r
151         }\r
152 \r
153         /* DETERMINE IF FROG STARTS/STOPS WALKING */\r
154         if (walking==FALSE)\r
155         {\r
156             walking=TRUE;\r
157             switch (facing)\r
158             {\r
159                 case RIGHT: frog.current=FROG_WALK_RIGHT; break;\r
160                 case LEFT:  frog.current=FROG_WALK_LEFT;  break;\r
161                 case DOWN:  frog.current=FROG_WALK_DOWN;  break;\r
162                 case UP:    frog.current=FROG_WALK_UP;    break;\r
163             }\r
164 \r
165             frog.next=-1; /* TURN ON ANIMATION EVENT FLAG */\r
166             nextfrog=fg_getclock()+frog.delay;\r
167             return;\r
168         }\r
169 \r
170         /* DETERMINE IF WE CAN WALK OUR FROGGIE THIS WAY! */\r
171         newx=x;\r
172         newy=y;\r
173         switch (facing)\r
174         {\r
175             case RIGHT: newx++; break;\r
176             case LEFT:  newx--; break;\r
177             case DOWN:  newy++; break;\r
178             case UP:    newy--; break;\r
179         }\r
180 \r
181         /* CAN'T MOVE -- OBSTRUCTION OR END OF WORLD! */\r
182         if (newx<0 || newy<0 || newx>=WORLD_WIDTH || newy>=WORLD_HEIGHT\r
183             || terrain[WORLD_TILE(newx,newy)]!=EMPTY_TILE)\r
184         {\r
185             /* UPDATE FACING IMAGE TO REFLECT FROG STANDS FAST */\r
186             if (random(100)<50) switch (facing)\r
187             {\r
188                 case RIGHT: frog.current=FROG_FACE_RIGHT; break;\r
189                 case LEFT:  frog.current=FROG_FACE_LEFT;  break;\r
190                 case DOWN:  frog.current=FROG_FACE_DOWN;  break;\r
191                 case UP:    frog.current=FROG_FACE_UP;    break;\r
192             }\r
193             else\r
194             {\r
195                 frog.next=-1;\r
196                 goto NEW_FACING;\r
197             }\r
198             nextfrog=fg_getclock()+frog.delay;\r
199             return;\r
200         }\r
201 \r
202         /* CAN MOVE!  MOVE FROG ALONG */\r
203         switch (facing)\r
204         {\r
205             case RIGHT:\r
206             if (++frog.current>=FROG_NUM_WALKS+FROG_WALK_RIGHT)\r
207                 frog.current=FROG_WALK_RIGHT;\r
208             break;\r
209 \r
210             case LEFT:\r
211             if (++frog.current>=FROG_NUM_WALKS+FROG_WALK_LEFT)\r
212                 frog.current=FROG_WALK_LEFT;\r
213             break;\r
214 \r
215             case DOWN:\r
216             if (++frog.current>=FROG_NUM_WALKS+FROG_WALK_DOWN)\r
217                 frog.current=FROG_WALK_DOWN;\r
218             break;\r
219 \r
220             case UP:\r
221             if (++frog.current>=FROG_NUM_WALKS+FROG_WALK_UP)\r
222                 frog.current=FROG_WALK_UP;\r
223             break;\r
224 \r
225         }\r
226 \r
227             /* DON'T MOVE FROG'S X/Y AT CERTAIN FRAMES */\r
228         if (frog.current==FROG_WALK_UP+1 ||\r
229             frog.current==FROG_WALK_UP+3 ||\r
230             frog.current==FROG_WALK_LEFT+1 ||\r
231             frog.current==FROG_WALK_LEFT+3 ||\r
232             frog.current==FROG_WALK_RIGHT+1 ||\r
233             frog.current==FROG_WALK_RIGHT+3 ||\r
234             frog.current==FROG_WALK_DOWN+1 ||\r
235             frog.current==FROG_WALK_DOWN+3 )\r
236         {\r
237             frog.next=-1;\r
238             nextfrog=fg_getclock()+frog.delay;\r
239             return;\r
240         }\r
241 \r
242         terrain[WORLD_TILE(x,y)]=EMPTY_TILE;\r
243         terrain[WORLD_TILE(newx,newy)]=ANM_FROG;\r
244         frog.next=-1;\r
245 \r
246 /*\r
247  *\r
248  * Simply put, frog watch mode doesn't work.\r
249  * I got to the point where I said, gosh darnit, who needs\r
250  * to watch a stinking frog anyway?  It's left as is...\r
251  *\r
252  */\r
253         if (frogwatchmode)\r
254         {\r
255 \r
256             if (newx>x)      if (view_x<WORLD_WIDTH-view_x) view_x++;\r
257             else if (newx<x) if (view_x>0) view_x--;\r
258             else if (newy>y) if (view_y<WORLD_HEIGHT-view_y) view_y++;\r
259             else if (newy<y) if (view_y>0) view_y--;\r
260             redraw (NONFLIP_REFRESH);\r
261 /*            if (newx>x)      suc=redraw (NONFLIP_SCROLL_RIGHT);\r
262             else if (newx<x) suc=redraw (NONFLIP_SCROLL_LEFT);\r
263             else if (newy>y) suc=redraw (NONFLIP_SCROLL_DOWN);\r
264             else if (newy<y) suc=redraw (NONFLIP_SCROLL_UP);*/\r
265             viewpage=!viewpage; /* SWAP PAGES */\r
266             update_tile (WORLD_TILE(x,y));\r
267             fg_setvpage (viewpage); /* VIEW CORRECT PAGE */\r
268         } else update_tile (WORLD_TILE(x,y));\r
269 \r
270         x=newx;\r
271         y=newy;\r
272         nextfrog=fg_getclock()+frog.delay;\r
273         return;\r
274     }\r
275 \r
276 /********************* ADD NEW FROG ************************/\r
277 \r
278     /* LOCATE VIEWABLE TILE TO PLACE FROG */\r
279     do {\r
280         x=random(VIEW_WIDTH)+view_x;\r
281         y=random(VIEW_HEIGHT)+view_y;\r
282         fails++;\r
283     } while (terrain[WORLD_TILE(x,y)]!=EMPTY_TILE && fails<50);\r
284 \r
285     if (fails>=50) /* COULDN'T PLACE FROG */\r
286     {\r
287         fg_music ("L64EC.DE.C$");\r
288         frogmode=3;\r
289         frog.next=0;\r
290         return;\r
291     }\r
292 \r
293     terrain[WORLD_TILE(x,y)]=ANM_FROG; /* INSTALL FROG! */\r
294     frog.next=-1; /* UPDATE EVENT */\r
295     frogmode=1;\r
296     nextfrog=fg_getclock()+frog.delay;\r
297 \r
298     return;\r
299 }\r
300 \r
301 /*\r
302  *\r
303  * Initializes any animation information, as in at the program start.\r
304  *\r
305  */\r
306 void init_anim (void)\r
307 {\r
308     fire.first=fire.current=34;\r
309     fire.total=6;\r
310     fire.delay=1;\r
311     fire.next=fg_getclock()+fire.delay;\r
312     fire.anm=ANM_FIRE;\r
313 \r
314     water1.first=water1.current=60;\r
315     water1.total=3;\r
316     water1.delay=3;\r
317     water1.next=fg_getclock()+water1.delay;\r
318     water1.anm=ANM_WATER1;\r
319 \r
320     water2.first=water2.current=63;\r
321     water2.total=3;\r
322     water2.delay=4;\r
323     water2.next=fg_getclock()+water2.delay;\r
324     water2.anm=ANM_WATER2;\r
325 \r
326     uranium.first=uranium.current=66;\r
327     uranium.total=10;\r
328     uranium.delay=4;\r
329     uranium.next=fg_getclock()+uranium.delay;\r
330     uranium.anm=ANM_URANIUM;\r
331 \r
332     frog.first=frog.current=FROG_FACE_RIGHT;\r
333     frog.total=FROG_NUM_WALKS;\r
334     frog.delay=3;\r
335     frog.next=-1;\r
336     frog.anm=ANM_FROG;\r
337 \r
338     anim_list[0]=&fire;\r
339     anim_list[1]=&water1;\r
340     anim_list[2]=&water2;\r
341     anim_list[3]=&uranium;\r
342     anim_list[4]=&frog;\r
343 }\r
344 \r