OSDN Git Service

wwww
[proj16/16.git] / 16 / v2 / source / ENGINE / ENGINE.C
1 /*\r
2 Copyright (C) 1998 BJ Eirich (aka vecna)\r
3 This program is free software; you can redistribute it and/or\r
4 modify it under the terms of the GNU General Public License\r
5 as published by the Free Software Foundation; either version 2\r
6 of the License, or (at your option) any later version.\r
7 This program is distributed in the hope that it will be useful,\r
8 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\r
10 See the GNU General Public Lic\r
11 See the GNU General Public License for more details.\r
12 You should have received a copy of the GNU General Public License\r
13 along with this program; if not, write to the Free Software\r
14 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
15 */\r
16 \r
17 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\r
18 // CHANGELOG:\r
19 // <zero 5.7.99>\r
20 // + added ScreenShot() on F11\r
21 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\r
22 \r
23 \r
24 #define ENGINE_H\r
25 #include "verge.h"\r
26 \r
27 // ================================= Data ====================================\r
28 \r
29 typedef struct\r
30 {\r
31   word start;                        // strand start\r
32   word finish;                       // strand end\r
33   word delay;                        // tile-switch delay\r
34   word mode;                         // tile-animation mode\r
35 } vspanim_r;\r
36 \r
37 typedef struct\r
38 {\r
39   char pmultx,pdivx;                 // parallax multiplier/divisor for X\r
40   char pmulty,pdivy;                 // parallax multiplier/divisor for Y\r
41   unsigned short sizex, sizey;       // layer dimensions.\r
42   unsigned char trans, hline;        // transparency flag | hline (raster fx)\r
43 } layer_r;\r
44 \r
45 typedef struct\r
46 {\r
47   char name[40];                     // zone name/desc\r
48   unsigned short script;             // script to call thingy\r
49   unsigned short percent;            // chance of executing\r
50   unsigned short delay;              // step-delay\r
51   unsigned short aaa;                // Accept Adjacent Activation\r
52   unsigned short entityscript;       // script to call for entities\r
53 } zoneinfo;\r
54 \r
55 zoneinfo zones[256];                 // zone data records\r
56 layer_r layer[6];                    // Array of layer data\r
57 vspanim_r vspanim[100];              // tile animation data\r
58 unsigned short vadelay[100];         // Tile animation delay ctr\r
59 \r
60 char mapname[60];                    // MAP filename\r
61 char vspname[60];                    // VSP filemap\r
62 char musname[60];                    // MAP bkgrd music default filename\r
63 char rstring[20];                    // render-order string\r
64 char numlayers;                      // number of layers in map\r
65 byte *obstruct, *zone;               // obstruction and zone buffers\r
66 char layertoggle[8];                 // layer visible toggles\r
67 word xstart, ystart;                 // MAP start x/y location\r
68 int bufsize;                         // how many bytes need to be written\r
69 int numzones;                        // number of active zones\r
70 \r
71 word *layers[6];                     // Raw layer data\r
72 int xwin=0, ywin=0;                  // camera offset\r
73 \r
74 // -- vsp data --\r
75 \r
76 byte *vsp=0,*vspmask;                // VSP data buffer.\r
77 unsigned short numtiles;             // number of tiles in VSP.\r
78 unsigned short *tileidx;             // tile index thingamajig\r
79 char *flipped;                       // bi-direction looping flag\r
80 \r
81 // entity stuffs\r
82 \r
83 char *msbuf[100];                    // ptr-table to script offset\r
84 char *ms;                            // script text buffer\r
85 byte nms;                            // number of movescripts\r
86 \r
87 char numfollowers=0;                 // number of party followers\r
88 byte follower[10];                   // maximum of 10 followers.\r
89 char laststeps[10]={ 0 };            // record of last movements\r
90 int lastent;\r
91 \r
92 // -- stuff --\r
93 \r
94 byte movegranularity; // means nothing now, please remove\r
95 byte movectr=0;\r
96 \r
97 byte phantom=0;                      // walk-through-walls\r
98 byte speeddemon=0;                   // doublespeed cheat\r
99 int bindarray[128];                  // bind script offset\r
100 \r
101 // ================================= Code ====================================\r
102 \r
103 void ReadCompressedLayer1(byte *dest, int len, char *buf)\r
104 {\r
105   int j,n;\r
106   byte run, w;\r
107 \r
108   n=0;\r
109   do\r
110   {\r
111      w=*buf; buf++;\r
112      if (w==0xFF)\r
113      {\r
114         run=*buf; buf++;\r
115         w=*buf; buf++;\r
116         for (j=0; j<run; j++)\r
117              dest[n+j]=w;\r
118         n+=run;\r
119      }\r
120      else\r
121      {\r
122          dest[n]=w;\r
123          n++;\r
124      }\r
125   } while (n<len);\r
126 }\r
127 \r
128 void ReadCompressedLayer2(word *dest, int len, word *buf)\r
129 {\r
130   int j,n;\r
131   byte run;\r
132   word w;\r
133 \r
134   n=0;\r
135   do\r
136   {\r
137     w=*buf; buf++;\r
138     if ((w & 0xFF00)==0xFF00)\r
139     {\r
140       run=(w & 0x00FF);\r
141       w=*buf; buf++;\r
142       for(j=0; j<run; j++)\r
143         dest[n+j]=w;\r
144       n+=run;\r
145     }\r
146     else\r
147     {\r
148       dest[n]=w;\r
149       n++;\r
150     }\r
151   } while(n<len);\r
152 }\r
153 \r
154 void LoadVSP(char *fname)\r
155 {\r
156   VFILE *f;\r
157   int i;\r
158   word ver;\r
159   char *cb;\r
160 \r
161 // Mwahaha! The Indefatigable Grue has snuck into the V2 source code! It is forever corrupted by his evil touch! Cower in fear, oh yes, FEAR! MwahahaHA..ha...hem...\r
162 \r
163   if (!(f=vopen(fname))) err("*error* Could not open VSP file %s.",fname);\r
164   vread(&ver, 2, f);\r
165   vread(&pal, 768, f);\r
166   vread(&numtiles, 2, f);\r
167 \r
168   vsp=(byte *) valloc(numtiles*256, "vsp", OID_IMAGE);\r
169   if (ver==2)\r
170   {\r
171     vread(vsp, (256*numtiles), f);\r
172   }\r
173   else\r
174   {\r
175     vread(&i, 4, f);\r
176     cb=(char *) valloc(i, "LoadVSP:cb", OID_TEMP);\r
177     vread(cb, i, f);\r
178     ReadCompressedLayer1(vsp, 256*numtiles, cb);\r
179     vfree(cb);\r
180   }\r
181   vread(&vspanim, sizeof vspanim, f);\r
182   vclose(f);\r
183 \r
184   // Now calculate VSP transparency mask.\r
185 \r
186   vspmask=(byte *) valloc(numtiles*256, "vspmask", OID_MISC);\r
187   for (i=0; i<(numtiles*256); i++)\r
188   {\r
189     if (vsp[i]) vspmask[i]=0;\r
190     else vspmask[i]=255;\r
191   }\r
192 \r
193   // Allocate and build tileidx.\r
194 \r
195   tileidx=(unsigned short *) valloc(numtiles*2, "tileidx", OID_MISC);\r
196   for (i=0; i<numtiles; i++)\r
197       tileidx[i]=i;\r
198 \r
199   flipped=(char *) valloc(numtiles, "flipped", OID_MISC);\r
200   animate=TRUE;\r
201 }\r
202 \r
203 void FreeVSP()\r
204 {\r
205   animate=FALSE;\r
206   vfree(vsp);\r
207   vfree(vspmask);\r
208   vfree(tileidx);\r
209   vfree(flipped);\r
210   vfree(mapvc);\r
211 }\r
212 \r
213 void LoadMAP(char *fname)\r
214 {\r
215   VFILE *f;\r
216   char *cb;\r
217   int i;\r
218 \r
219 // No matter where you go, you're there.\r
220 \r
221   Logp("Loading MAP %s.",fname);\r
222   memcpy(mapname, fname, strlen(fname)+1);\r
223   memcpy(strbuf, "MAPù5", 6);\r
224   if (!(f=vopen(fname))) err("Could not find %s.",fname);\r
225   vread(strbuf, 6, f);\r
226   if (strcmp(strbuf,"MAPù5"))\r
227       err("%s is not a recognized MAP file.",fname);\r
228 \r
229 // Lalala! Can you find Waldo hiding in the code? Here's a hint, he likes to dress like a candy-cane.\r
230 \r
231   vread(&i, 4, f);\r
232   vread(vspname, 60, f);\r
233   vread(musname, 60, f);\r
234   vread(rstring, 20, f);\r
235   vread(&xstart, 2, f);\r
236   vread(&ystart, 2, f);\r
237   vread(strbuf, 51, f);\r
238   vread(&numlayers, 1, f);\r
239   for (i=0; i<numlayers; i++)\r
240       vread(&layer[i], 12, f);\r
241 \r
242   memset(&layertoggle, 0, 8);\r
243   for (i=0; i<numlayers; i++)\r
244   {\r
245      vread(&bufsize, 4, f);\r
246      layers[i]=(unsigned short *) valloc(layer[i].sizex*(layer[i].sizey+2)*2, "LoadMAP:layers[i]", OID_MAP);\r
247      cb=(char *) valloc(bufsize, "LoadMAP:cb", OID_TEMP);\r
248      vread(cb, bufsize, f);\r
249      ReadCompressedLayer2(layers[i],(layer[i].sizex * layer[i].sizey), (word *) cb);\r
250      vfree(cb);\r
251      layertoggle[i]=1;\r
252   }\r
253   obstruct=(byte *) valloc(layer[0].sizex*(layer[0].sizey+2), "obstruct", OID_MAP);\r
254   zone=(byte *) valloc(layer[0].sizex*(layer[0].sizey+2), "zone", OID_MAP);\r
255 \r
256   vread(&bufsize, 4, f);\r
257   cb=(char *) valloc(bufsize, "LoadMAP:cb (2)", OID_TEMP);\r
258   vread(cb, bufsize, f);\r
259   ReadCompressedLayer1(obstruct,(layer[0].sizex * layer[0].sizey), cb);\r
260   vfree(cb);\r
261   vread(&bufsize, 4, f);\r
262   cb=(char *) valloc(bufsize, "LoadMAP:cb (3)", OID_TEMP);\r
263   vread(cb, bufsize, f);\r
264   ReadCompressedLayer1(zone,(layer[0].sizex * layer[0].sizey), cb);\r
265   vfree(cb);\r
266   memset(&zones, 0, sizeof zones);\r
267   vread(&numzones, 4, f);\r
268   vread(&zones, numzones*50, f);\r
269 \r
270   memset(&chrlist, 0, sizeof chrlist);\r
271   vread(&nmchr, 1, f);\r
272   vread(&chrlist, 60*nmchr, f);\r
273 \r
274 // Cheese is good, cheese is nice. Cheese is better, than body lice.\r
275 \r
276   memset(&entity, 0, sizeof entity);\r
277   vread(&entities, 1, f);\r
278   vread(&entity, (sizeof(entity)/256*entities), f);\r
279   for (i=0; i<entities; i++)\r
280   {\r
281     entity[i].tx=entity[i].x;\r
282     entity[i].ty=entity[i].y;\r
283     entity[i].x*=16;\r
284     entity[i].y*=16;\r
285   }\r
286 \r
287   vread(&nms, 1, f);\r
288   vread(&i, 4, f);\r
289   vread(&msbuf, nms*4, f);\r
290   if (nms)\r
291   {\r
292     ms=(char *) valloc(i, "LoadMAP:ms", OID_MAP);\r
293     vread(ms, i, f);\r
294   }\r
295   else\r
296   {\r
297     vseek(f, i, 0);\r
298     ms=(char *) malloc(16);\r
299   }\r
300   vread(&i, 4, f); // # of things\r
301   LoadMapVC(f);\r
302   vclose(f);\r
303 \r
304   memset(&chr, 0, sizeof chr);\r
305   LoadVSP(vspname);\r
306   LoadCHRList();\r
307   Logp(" [%d] ",mapevents);\r
308   if (strlen(musname))\r
309     PlayMusic(musname);\r
310   LogDone();\r
311   ExecuteEvent(0);\r
312 }\r
313 \r
314 void FreeMAP()\r
315 {\r
316   int i;\r
317 \r
318   vfree(obstruct);\r
319   vfree(zone);\r
320   for (i=0; i<numlayers; i++)\r
321     vfree(layers[i]);\r
322   vfree(ms);\r
323   player=0;\r
324   memset(&entity, 0, sizeof entity);\r
325   entities=0; nmchr=0; numchrs=0;\r
326   xwin=0; ywin=0;\r
327   vfree(mapvc);\r
328 }\r
329 \r
330 void MAPswitch()\r
331 {\r
332   hookretrace=0;\r
333   hooktimer=0;\r
334   kill=1;\r
335   memcpy(startmap, (char *) args[1], strlen((char *) args[1]));\r
336   key[SCAN_RQUOTA]=1;\r
337   conlines=2;\r
338 }\r
339 \r
340 // The_Edge rules. Really. I mean it. Wyrdwad too. They're as cool as Omniphile!\r
341 \r
342 void MAPstats()\r
343 { int a;\r
344 \r
345   Con_NextLine();\r
346   Con_Printf("{||||||||||||||||||||}");\r
347   sprintf(strbuf,"MAP stats for \80%s~ - \81%d~ layers",mapname,numlayers); Con_Printf(strbuf);\r
348   sprintf(strbuf,"Base dimensions \81%d~ x \81%d~", layer[0].sizex, layer[0].sizey);\r
349   Con_Printf(strbuf);  a=layer[0].sizex*layer[0].sizey;\r
350   sprintf(strbuf,"MAP using \81%d~ bytes of memory",\r
351           a*(2+(numlayers*2))); Con_Printf(strbuf);\r
352   sprintf(strbuf,"\81%d~ active zones.",numzones); Con_Printf(strbuf);\r
353   Con_Printf("{||||||||||||||||||||}");\r
354   sprintf(strbuf,"VSP file: \80%s~",vspname); Con_Printf(strbuf);\r
355   sprintf(strbuf,"VSP has \81%d~ tiles using \81%d~ bytes",numtiles,\r
356           (numtiles*256)+800+(numtiles*3)); Con_Printf(strbuf);\r
357   Con_Printf("{||||||||||||||||||||}");\r
358 }\r
359 \r
360 int PlayerObstructed(char dir)\r
361 {\r
362   if (phantom) return 0;\r
363   switch (dir)\r
364   {\r
365     case 0: if (ObstructionAt(player->tx, player->ty+1)) return 1; break;\r
366     case 1: if (ObstructionAt(player->tx, player->ty-1)) return 1; break;\r
367     case 2: if (ObstructionAt(player->tx-1, player->ty)) return 1; break;\r
368     case 3: if (ObstructionAt(player->tx+1, player->ty)) return 1; break;\r
369   }\r
370   switch (dir)\r
371   {\r
372     case 0: if (EntityObsAt(player->tx, player->ty+1)) return 1; break;\r
373     case 1: if (EntityObsAt(player->tx, player->ty-1)) return 1; break;\r
374     case 2: if (EntityObsAt(player->tx-1, player->ty)) return 1; break;\r
375     case 3: if (EntityObsAt(player->tx+1, player->ty)) return 1; break;\r
376   }\r
377   return 0;\r
378 }\r
379 \r
380 void CheckZone()\r
381 {\r
382   int curzone;\r
383   static int lz=0, zonedelay=0;\r
384 \r
385   curzone=zone[(player->ty * layer[0].sizex) + player->tx];\r
386   if (lz!=curzone)\r
387   {\r
388     zonedelay=0;\r
389     lz=curzone;\r
390   }\r
391   if (!zones[curzone].percent) return;\r
392   if (zonedelay < zones[curzone].delay)\r
393   {\r
394     zonedelay++;\r
395     return;\r
396   }\r
397   if (curzone)\r
398     if (zones[curzone].script &&\r
399         zones[curzone].percent >= rnd(0,255))\r
400     {\r
401        ExecuteEvent(zones[curzone].script);\r
402        zonedelay=0;\r
403     }\r
404 }\r
405 \r
406 int InvFace()\r
407 {\r
408   switch(player -> facing)\r
409   {\r
410     case 0: return 1;\r
411     case 1: return 0;\r
412     case 2: return 3;\r
413     case 3: return 2;\r
414   }\r
415   return -1;\r
416 }\r
417 \r
418 void Activate()\r
419 {\r
420   byte tz;\r
421   int ax=0, ay=0;\r
422 \r
423   switch(player->facing)\r
424   {\r
425     case 0: ax=player->tx; ay=player->ty+1; break;\r
426     case 1: ax=player->tx; ay=player->ty-1; break;\r
427     case 2: ax=player->tx-1; ay=player->ty; break;\r
428     case 3: ax=player->tx+1; ay=player->ty; break;\r
429   }\r
430   tz=zone[(ay*layer[0].sizex)+ax];\r
431   if (zones[tz].aaa)\r
432   {\r
433     ExecuteEvent(zones[tz].script);\r
434     return;\r
435   }\r
436   if ((tz=EntityAt(ax, ay)))\r
437   {\r
438     tz--;\r
439     if (entity[tz].face)\r
440     {\r
441       entity[tz].facing=InvFace();\r
442       AnimateEntity(&entity[tz]);\r
443     }\r
444     if (entity[tz].actscript)\r
445     {\r
446       lastent=tz;\r
447       ExecuteEvent(entity[tz].actscript);\r
448     }\r
449   }\r
450 }\r
451 \r
452 void ResetFollowers()\r
453 {\r
454   int i;\r
455 \r
456   player->x=player->tx<<4;\r
457   player->y=player->ty<<4;\r
458   player->moving=0;\r
459   player->movecnt=0;\r
460   player->reset=1;\r
461   for (i=0; i<numfollowers; i++)\r
462   {\r
463     entity[follower[i]].x=player->x;\r
464     entity[follower[i]].y=player->y;\r
465     entity[follower[i]].tx=player->tx;\r
466     entity[follower[i]].ty=player->ty;\r
467     entity[follower[i]].facing=player->facing;\r
468     entity[follower[i]].reset=1;\r
469   }\r
470   memset(laststeps, 0, 10);\r
471 }\r
472 \r
473 void MoveFollowers()\r
474 {\r
475   int i;\r
476 \r
477   for (i=0; i<numfollowers; i++)\r
478   {\r
479     entity[follower[i]].moving=laststeps[i+1];\r
480     entity[follower[i]].movecnt=15;\r
481     if (entity[follower[i]].reset ||\r
482         entity[follower[i]].facing != laststeps[i+1]-1)\r
483     {\r
484       //player->animofs=chr[player->chrindex].uanim;\r
485       entity[follower[i]].delayct=0;\r
486       entity[follower[i]].reset=0;\r
487     }\r
488     entity[follower[i]].facing=laststeps[i+1]-1;\r
489   }\r
490 }\r
491 \r
492 //--- zero 5.7.99\r
493 \r
494 void WritePalette(FILE *f)\r
495 { char b;\r
496   int i;\r
497   byte pal3[768];\r
498 \r
499   for (i=0; i<768; i++)\r
500       pal3[i]=pal2[i] << 2;\r
501 \r
502   b=12; fwrite(&b, 1, 1, f);\r
503   fwrite(pal3, 1, 768, f);\r
504 }\r
505 \r
506 void WritePCXLine(unsigned char *p,int len,FILE *pcxf)\r
507 { int i;\r
508   unsigned char byt, samect, repcode;\r
509 \r
510   i=0;\r
511   do\r
512   {   byt=p[i++];\r
513       samect=1;\r
514       while (samect<(unsigned) 63 && i<len && byt==p[i])\r
515       {\r
516          samect++;\r
517          i++;\r
518       }\r
519       if (samect>1 || (byt & 0xC0) != 0)\r
520       {\r
521          repcode=0xC0 | samect;\r
522          fwrite(&repcode,1,1,pcxf);\r
523       }\r
524       fwrite(&byt,1,1,pcxf);\r
525   } while (i<len);\r
526 }\r
527 \r
528 \r
529 void ScreenShot()\r
530 {\r
531   unsigned char b1;\r
532   unsigned short int w1;\r
533   int i,n;\r
534   char fnamestr[13];\r
535   static int ss=0;\r
536   FILE *pcxf;\r
537 \r
538   n=0;\r
539   do\r
540   {\r
541     sprintf(fnamestr,"%d.pcx",n);\r
542     pcxf=fopen(fnamestr,"r");\r
543     i=(int)pcxf;\r
544     if(pcxf) fclose(pcxf);\r
545     n++;\r
546   } while(i);\r
547   n--;\r
548 \r
549   // Takes a snapshot of the current screen.\r
550 \r
551    sprintf(fnamestr,"%d.pcx",n);\r
552 \r
553    pcxf=fopen(fnamestr,"wb");\r
554    ss++;\r
555 \r
556 // Write PCX header\r
557 \r
558    b1=10; fwrite(&b1, 1, 1, pcxf); // manufacturer always = 10\r
559    b1=5; fwrite(&b1, 1, 1, pcxf);  // version = 3.0, >16 colors\r
560    b1=1; fwrite(&b1, 1, 1, pcxf);  // encoding always = 1\r
561    b1=8; fwrite(&b1, 1, 1, pcxf);  // 8 bits per pixel, for 256 colors\r
562    w1=0; fwrite(&w1, 1, 2, pcxf);  // xmin = 0;\r
563    w1=0; fwrite(&w1, 1, 2, pcxf);  // ymin = 0;\r
564  w1=sx-1; fwrite(&w1, 1, 2, pcxf);  // xmax = 319;\r
565  w1=sy-1; fwrite(&w1, 1, 2, pcxf);  // ymax = 199;\r
566  w1=sx; fwrite(&w1, 1, 2, pcxf);  // hres = 320;\r
567  w1=sy; fwrite(&w1, 1, 2, pcxf);  // vres = 200;\r
568 \r
569  fwrite(screen,1,48,pcxf);\r
570 \r
571  b1=0; fwrite(&b1, 1, 1, pcxf);   // reserved always = 0.\r
572  b1=1; fwrite(&b1, 1, 1, pcxf);   // number of color planes. Just 1 for 8bit.\r
573  w1=sx; fwrite(&w1, 1, 2, pcxf); // number of bytes per line\r
574 \r
575  w1=0; fwrite(&w1, 1, 1, pcxf);\r
576  fwrite(screen, 1, 59, pcxf);          // filler\r
577 \r
578  for (w1=0; w1<sy; w1++)\r
579      WritePCXLine(screen+w1*tsx, sx, pcxf);\r
580 \r
581  WritePalette(pcxf);\r
582  fclose(pcxf);\r
583 // timer_count=0;\r
584 }\r
585 //---\r
586 \r
587 \r
588 void LastMove(char dir)\r
589 {\r
590   laststeps[9]=laststeps[8];\r
591   laststeps[8]=laststeps[7];\r
592   laststeps[7]=laststeps[6];\r
593   laststeps[6]=laststeps[5];\r
594   laststeps[5]=laststeps[4];\r
595   laststeps[4]=laststeps[3];\r
596   laststeps[3]=laststeps[2];\r
597   laststeps[2]=laststeps[1];\r
598   laststeps[1]=laststeps[0];\r
599   laststeps[0]=dir;\r
600 \r
601   MoveFollowers();\r
602 }\r
603 \r
604 void ProcessControls1()\r
605 {\r
606   if (!player->moving)\r
607   {\r
608     if (down && !PlayerObstructed(0))\r
609     {\r
610       player->ty++;\r
611       player->moving=1;\r
612       player->movecnt=15;\r
613       player->y++;\r
614       if (player->reset || player->facing != 0)\r
615       {\r
616         player->animofs=chr[player->chrindex].danim;\r
617         player->delayct=0;\r
618         player->reset=0;\r
619       }\r
620       player->facing=0;\r
621       LastMove(1);\r
622       return;\r
623     }\r
624     if (up && !PlayerObstructed(1))\r
625     {\r
626       player->ty--;\r
627       player->moving=2;\r
628       player->movecnt=15;\r
629       player->y--;\r
630       if (player->reset || player->facing != 1)\r
631       {\r
632         player->animofs=chr[player->chrindex].uanim;\r
633         player->delayct=0;\r
634         player->reset=0;\r
635       }\r
636       player->facing=1;\r
637       LastMove(2);\r
638       return;\r
639     }\r
640     if (left && !PlayerObstructed(2))\r
641     {\r
642       player->tx--;\r
643       player->moving=3;\r
644       player->movecnt=15;\r
645       player->x--;\r
646       if (player->reset || player->facing != 2)\r
647       {\r
648         player->animofs=chr[player->chrindex].lanim;\r
649         player->delayct=0;\r
650         player->reset=0;\r
651       }\r
652       player->facing=2;\r
653       LastMove(3);\r
654       return;\r
655     }\r
656     if (right && !PlayerObstructed(3))\r
657     {\r
658       player->tx++;\r
659       player->moving=4;\r
660       player->movecnt=15;\r
661       player->x++;\r
662       if (player->reset || player->facing != 3)\r
663       {\r
664         player->animofs=chr[player->chrindex].ranim;\r
665         player->delayct=0;\r
666         player->reset=0;\r
667       }\r
668       player->facing=3;\r
669       LastMove(4);\r
670       return;\r
671     }\r
672     if (down) player->facing=0;\r
673     if (up) player->facing=1;\r
674     if (left) player->facing=2;\r
675     if (right) player->facing=3;\r
676   }\r
677 \r
678   switch (player->moving)\r
679   {\r
680     case 0: player->reset=1; player->animofs=0; player->delayct=0; break;\r
681     case 1: player->y++; player->movecnt--; break;\r
682     case 2: player->y--; player->movecnt--; break;\r
683     case 3: player->x--; player->movecnt--; break;\r
684     case 4: player->x++; player->movecnt--; break;\r
685   }\r
686   if (!player->movecnt && player->moving)\r
687   {\r
688     player->moving=0;\r
689     CheckZone();\r
690   }\r
691   if (!player->movecnt && b1) Activate();\r
692 }\r
693 \r
694 void ProcessControls()\r
695 { int i;\r
696 \r
697   if (key[SCAN_RQUOTA])\r
698   {\r
699     key[SCAN_RQUOTA]=0; last_pressed=0;\r
700     ActivateConsole();\r
701   }\r
702   if (key[SCAN_ALT] && key[SCAN_X]) err("Exiting: ALT-X pressed.");\r
703 //--- zero 5.7.99\r
704   if (key[SCAN_F11])\r
705   {\r
706     Message("ss",50);\r
707     ScreenShot();\r
708     key[SCAN_F11]=0;\r
709   }\r
710 //---\r
711   if (!player) return;\r
712 \r
713   if (player->speed<4)\r
714   {\r
715     switch (player->speed)\r
716     {\r
717       case 1: if (player->speedct<3) { player->speedct++; return; } break;\r
718       case 2: if (player->speedct<2) { player->speedct++; return; } break;\r
719       case 3: if (player->speedct<1) { player->speedct++; return; } break;\r
720     }\r
721   }\r
722   if (player->speed<5)\r
723   {\r
724     ProcessControls1();\r
725     player->speedct=0;\r
726     AnimateEntity(player);\r
727   }\r
728   switch (player->speed)\r
729   {\r
730     case 5: for (i=0; i<2; i++) { ProcessControls1(); AnimateEntity(player); } return;\r
731     case 6: for (i=0; i<3; i++) { ProcessControls1(); AnimateEntity(player); } return;\r
732     case 7: for (i=0; i<4; i++) { ProcessControls1(); AnimateEntity(player); } return;\r
733   }\r
734 }\r
735 \r
736 void GameTick()\r
737 {\r
738   UpdateControls();\r
739   CheckMessages();\r
740   if (bindarray[last_pressed])\r
741     HookKey(bindarray[last_pressed]);\r
742   ProcessControls();\r
743   if (speeddemon && key[SCAN_CTRL]) ProcessControls();\r
744   ProcessEntities();\r
745 }\r
746 \r