install: add install sources and resources
[doom2d-restoration.git] / GAME / GAME.C
blob333f82eb48e7fbbc85c3c5edd60f3f510f2c56e2
1 #include "glob.h"
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include "files.h"
6 #include "memory.h"
7 #include "vga.h"
8 #include "error.h"
9 #include "keyb.h"
10 #include "sound.h"
11 #include "view.h"
12 #include "bmap.h"
13 #include "fx.h"
14 #include "switch.h"
15 #include "weapons.h"
16 #include "items.h"
17 #include "dots.h"
18 #include "smoke.h"
19 #include "player.h"
20 #include "monster.h"
21 #include "menu.h"
22 #include "misc.h"
23 #include "map.h"
25 #define LT_DELAY 8
26 #define LT_HITTIME 6
28 #define GETIME 1092
30 int A8_start(char*);
31 int A8_nextframe(void);
32 void A8_close(void);
34 void FX_trans1(int t);
35 extern unsigned char fx_scr1[64000],fx_scr2[64000];
37 extern short lastkey;
39 //extern word chk;
41 extern int hit_xv,hit_yv;
43 extern vgapal std_pal;
44 void setgamma(int);
46 extern int sw_secrets;
48 #define PL_FLASH 90
50 void Z_clrst(void);
52 extern int PL_JUMP;
54 extern map_block_t blk;
56 extern byte clrmap[256*12];
58 void V_maptoscr(int,int,int,int,void *);
60 void F_loadgame(int);
62 extern byte cheat;
64 byte _2pl=0,g_dm=0,g_st=GS_TITLE,g_exit=0,g_map=1,_warp=0,g_music[8]="MENU";
65 byte _net=0;
66 int g_sttm=1092;
67 dword g_time;
68 int dm_pnum,dm_pl1p,dm_pl2p;
69 pos_t dm_pos[100];
71 static void *telepsnd;
72 static void *scrnh[3];
73 void *cd_scr;
75 extern int sky_type;
76 void *ltn[2][2];
77 int lt_time,lt_type,lt_side,lt_ypos,lt_force;
78 void *ltnsnd[2];
80 int g_trans=0,g_transt;
82 static void set_trans(int st) {
83   switch(g_st) {
84     case GS_ENDANIM: case GS_END2ANIM: case GS_DARKEN:
85     case GS_BVIDEO: case GS_EVIDEO: case GS_END3ANIM:
86       g_st=st;return;
87   }
88   switch(g_st=st) {
89     case GS_ENDANIM: case GS_END2ANIM: case GS_DARKEN:
90     case GS_BVIDEO: case GS_EVIDEO: case GS_END3ANIM:
91       return;
92   }
93   g_trans=1;g_transt=0;
97 static void chk_exit(void) {
98   static char msg[]={'П'^85,'о'^85,'ж'^85,'а'^85,'л'^85,'у'^85,'й'^85,'с'^85,
99     'т'^85,'а'^85,' '^85,
100     'п'^85,'е'^85,'р'^85,'е'^85,'у'^85,'с'^85,'т'^85,'а'^85,'н'^85,'о'^85,
101     'в'^85,'и'^85,'т'^85,'е'^85,' '^85,'и'^85,'г'^85,'р'^85,'у'^85,0};
102   int i;
104   for(i=0;msg[i];++i) msg[i]^=85;
105   ERR_fatal("%s",msg);
109 void G_savegame(int h) {
110   write(h,&_2pl,1);write(h,&g_dm,1);write(h,&g_exit,1);write(h,&g_map,1);
111   write(h,&g_time,4);write(h,&dm_pl1p,4);write(h,&dm_pl2p,4);
112   write(h,&dm_pnum,4);write(h,dm_pos,dm_pnum*sizeof(pos_t));
113   write(h,&cheat,1);
114   write(h,g_music,8);
117 void G_loadgame(int h) {
118   read(h,&_2pl,1);read(h,&g_dm,1);read(h,&g_exit,1);read(h,&g_map,1);
119   read(h,&g_time,4);read(h,&dm_pl1p,4);read(h,&dm_pl2p,4);
120   read(h,&dm_pnum,4);read(h,dm_pos,dm_pnum*sizeof(pos_t));
121   read(h,&cheat,1);
122   read(h,g_music,8);F_loadmus(g_music);
125 int G_load(int h) {
126   switch(blk.t) {
127         case MB_MUSIC:
128           read(h,g_music,8);
129           F_loadmus(g_music);
130           return 1;
131   }return 0;
134 void load_game(int n) {
135   F_freemus();
136   W_init();
137   F_loadgame(n);
138   set_trans(GS_GAME);
139   V_setscr((g_trans)?fx_scr2:scrbuf);V_setrect(0,320,0,200);
140   V_clr(0,320,0,200,0);
141   if(_2pl) {w_o=0;Z_clrst();w_o=100;Z_clrst();}
142   else {w_o=50;Z_clrst();}
143 //  V_copytoscr(0,320,0,200);
144   V_setscr(scrbuf);
145   pl1.drawst=0xFF;
146   if(_2pl) pl2.drawst=0xFF;
147   BM_remapfld();
148   BM_clear(BM_PLR1|BM_PLR2|BM_MONSTER);
149   BM_mark(&pl1.o,BM_PLR1);
150   if(_2pl) BM_mark(&pl2.o,BM_PLR2);
151   MN_mark();
152   S_startmusic();
155 void G_start(void) {
156   char s[8];
158   F_freemus();
159   sprintf(s,"MAP%02u",(word)g_map);
160   F_loadmap(s);
161   set_trans(GS_GAME);
162   V_setscr((g_trans)?fx_scr2:scrbuf);V_setrect(0,320,0,200);
163   V_clr(0,320,0,200,0);
164   if(_2pl) {w_o=0;Z_clrst();w_o=100;Z_clrst();}
165   else {w_o=50;Z_clrst();}
166 //  V_copytoscr(0,320,0,200);
167   V_setscr(scrbuf);
168   pl1.drawst=0xFF;
169   if(_2pl) pl2.drawst=0xFF;
170   g_exit=0;
171   itm_rtime=(g_dm)?1092:0;
172   p_immortal=0;PL_JUMP=10;
173   g_time=0;
174   lt_time=1000;
175   lt_force=1;
176   if(!_2pl) pl1.lives=3;
177   BM_remapfld();
178   BM_clear(BM_PLR1|BM_PLR2|BM_MONSTER);
179   BM_mark(&pl1.o,BM_PLR1);
180   if(_2pl) BM_mark(&pl2.o,BM_PLR2);
181   MN_mark();
182   S_startmusic();
185 #define GGAS_TOTAL (MN__LAST-MN_DEMON+16+10)
187 void G_init(void) {
188   int i,j;
189   char s[9];
191   logo("G_init: настройка ресурсов игры ");
192   logo_gas(5,GGAS_TOTAL);
193   telepsnd=Z_getsnd("TELEPT");
194   scrnh[0]=M_lock(F_getresid("TITLEPIC"));
195   scrnh[1]=M_lock(F_getresid("INTERPIC"));
196   scrnh[2]=M_lock(F_getresid("ENDPIC"));
197   cd_scr=M_lock(F_getresid("CD1PIC"));
198   for(i=0;i<2;++i) {
199     sprintf(s,"LTN%c",i+'1');
200     for(j=0;j<2;++j)
201       ltn[i][j]=Z_getspr(s,j,0,NULL);
202   }
203   ltnsnd[0]=Z_getsnd("THUND1");
204   ltnsnd[1]=Z_getsnd("THUND2");
205   DOT_alloc();
206   SMK_alloc();
207   FX_alloc();
208   WP_alloc();
209   IT_alloc();
210   SW_alloc();
211   PL_alloc();
212   MN_alloc();
213   Z_initst();
214   logo_gas(GGAS_TOTAL,GGAS_TOTAL);
215   logo("\n");
216 //  GM_init();
217   pl1.color=0x70;
218   pl2.color=0x60;
219   g_trans=0;
222 int G_beg_video(void) {
223   switch(g_map) {
224     case 3: return A8_start("FALL");
225     case 4: return A8_start("KORIDOR");
226     case 5: return A8_start("SKULL");
227     case 6: return A8_start("TORCHES");
228     case 7: return A8_start("CACO");
229     case 8: return A8_start("DARTS");
230     case 9: return A8_start("FISH");
231     case 10: return A8_start("TRAP");
232     case 11: return A8_start("JAIL");
233     case 12: return A8_start("MMON1");
234     case 13: return A8_start("TOWER");
235     case 14: return A8_start("SAPOG");
236     case 15: return A8_start("SWITCH");
237     case 16: return A8_start("ACCEL");
238     case 17: return A8_start("MEAT");
239     case 18: return A8_start("LEGION");
240     case 19: return A8_start("CLOUDS");
241 //    case : return A8_start("");
242   }
243   return 0;
246 int G_end_video(void) {
247   switch(g_map) {
248     case 1: return A8_start("TRUBA");
249     case 10: return A8_start("GOTCHA");
250 //    case : return A8_start("");
251   }
252   return 0;
255 static byte transdraw=0;
257 void G_act(void) {
258   static byte pcnt=0;
260   if(g_trans) {
261     if(g_transt==0) {
262       V_setscr(NULL);memcpy(fx_scr1,scra,64000);
263       V_setscr(fx_scr2);transdraw=1;G_draw();transdraw=0;
264       V_setscr(scrbuf);
265     }
266     FX_trans1(g_transt*2);
267     V_copytoscr(0,320,0,200);
268     if(++g_transt>32) {
269       g_trans=0;
270     }
271     return;
272   }
273   if(g_st==GS_BVIDEO || g_st==GS_EVIDEO) {
274 //    V_setscr(NULL);
275     if(!A8_nextframe() || lastkey==1) {
276       if(lastkey==1) lastkey=0;
277       A8_close();
278 //      V_setscr(scrbuf);
279       if(g_st==GS_BVIDEO) G_start();
280       else goto inter;
281     }
282     V_copytoscr(0,320,0,200);
283 //    V_setscr(scrbuf);
284     return;
285   }else if(g_st==GS_ENDANIM || g_st==GS_END2ANIM || g_st==GS_END3ANIM) {
286 //    V_setscr(NULL);
287     if(!A8_nextframe()) {
288       switch(g_st) {
289         case GS_ENDANIM: g_st=GS_DARKEN;break;
290         case GS_END2ANIM: g_st=GS_END3ANIM;A8_start("KONEC");break;
291         case GS_END3ANIM: g_st=GS_ENDSCR;lastkey=0;break;
292       }g_sttm=0;return;
293     }
294     V_copytoscr(0,320,0,200);
295 //    V_setscr(scrbuf);
296     return;
297   }else if(g_st==GS_DARKEN) {
298 //    if(++g_sttm>=105) {
299 //      V_setscr(NULL);V_clr(0,320,0,200,0);V_setscr(scrbuf);
300 //      setgamma(gamma);
301       g_st=GS_END2ANIM;A8_start("CREDITS");
302 //    }
303 //    if(g_sttm>64) return;
304 //    VP_tocolor(std_pal,0,0,0,64,g_sttm);VP_setall(pal_tmp);
305     return;
306   }
307   if(GM_act()) return;
308   switch(g_st) {
309         case GS_TITLE: case GS_ENDSCR:
310           return;
311         case GS_INTER:
312 #ifdef DEMO
313           if(keys[0x39] || keys[0x1C] || keys[0x9C]) {
314             set_trans(GS_TITLE);
315           }
316 #else
317           if(keys[0x39] || keys[0x1C] || keys[0x9C])
318             if(!G_beg_video()) G_start(); else {
319               g_st=GS_BVIDEO;F_freemus();
320             }
321 #endif
322           return;
323   }
324   if(sky_type==2) {
325     if(lt_time>LT_DELAY || lt_force) {
326       if(!(rand()&31) || lt_force) {
327         lt_force=0;
328         lt_time=-LT_HITTIME;
329         lt_type=rand()%2;
330         lt_side=rand()&1;
331         lt_ypos=rand()&31;
332         Z_sound(ltnsnd[rand()&1],128);
333       }
334     }else ++lt_time;
335   }
336   ++g_time;
337   pl1.hit=0;pl1.hito=-3;
338   if(_2pl) {pl2.hit=0;pl2.hito=-3;}
339   G_code();
341   if(chk==1)
342     if(g_time>GETIME) {
343       p_immortal=0;
344       hit_xv=0;hit_yv=-10;
345       PL_hit(&pl1,1,0,HIT_SOME);
346       if(_2pl) PL_hit(&pl2,1,0,HIT_SOME);
347       if(!_2pl) {
348         if(PL_isdead(&pl1)) chk_exit();
349       }else if(PL_isdead(&pl1) && PL_isdead(&pl2)) chk_exit();
350     }
352   W_act();
353   IT_act();
354   SW_act();
355   if(_2pl) {
356         if(pcnt) {PL_act(&pl1);PL_act(&pl2);}
357         else {PL_act(&pl2);PL_act(&pl1);}
358         pcnt^=1;
359   }else PL_act(&pl1);
360   MN_act();
361   if(fld_need_remap) BM_remapfld();
362   BM_clear(BM_PLR1|BM_PLR2|BM_MONSTER);
363   BM_mark(&pl1.o,BM_PLR1);
364   if(_2pl) BM_mark(&pl2.o,BM_PLR2);
365   MN_mark();
366   WP_act();
367   DOT_act();
368   SMK_act();
369   FX_act();
370   if(_2pl) {
371         PL_damage(&pl1);PL_damage(&pl2);
372         if(!(pl1.f&PLF_PNSND) && pl1.pain) PL_cry(&pl1);
373         if(!(pl2.f&PLF_PNSND) && pl2.pain) PL_cry(&pl2);
374         if((pl1.pain-=5) < 0) {pl1.pain=0;pl1.f&=(0xFFFF-PLF_PNSND);}
375         if((pl2.pain-=5) < 0) {pl2.pain=0;pl2.f&=(0xFFFF-PLF_PNSND);}
376   }else{
377         PL_damage(&pl1);
378         if(!(pl1.f&PLF_PNSND) && pl1.pain) PL_cry(&pl1);
379         if((pl1.pain-=5) < 0) {pl1.pain=0;pl1.f&=(0xFFFF-PLF_PNSND);}
380   }
381   if(g_exit==1) {
382         if(G_end_video()) {
383           F_freemus();
384           g_st=GS_EVIDEO;
385           return;
386         }
387 inter:
388         switch(g_map) {
389           case 19: g_st=GS_ENDANIM;A8_start("FINAL");break;
390           case 31: case 32: g_map=16;set_trans(GS_INTER);break;
391           default: ++g_map;set_trans(GS_INTER);break;
392         }
393         F_freemus();
394         if(g_st==GS_INTER) {
395           F_loadmus("INTERMUS");
396         }else {F_loadmus("КОНЕЦ");if(mus_vol>0) mus_vol=128;}
397         S_startmusic();
398   }else if(g_exit==2) {
399         switch(g_map) {
400           case 31: g_map=32;set_trans(GS_INTER);break;
401           case 32: g_map=16;set_trans(GS_INTER);break;
402           default: g_map=31;set_trans(GS_INTER);break;
403         }
404         F_freemus();
405         F_loadmus("INTERMUS");
406         S_startmusic();
407   }
408 #ifdef DEMO
409   if(g_dm && g_time>10920) {set_trans(GS_INTER);}
410 #endif
413 static void drawview(player_t *p) {
414   if(p->looky<-50) p->looky=-50;
415   else if(p->looky>50) p->looky=50;
416   w_x=p->o.x;w_y=p->o.y-12+p->looky;W_draw();PL_drawst(p);
419 static int get_pu_st(int t) {
420   if(t>=PL_FLASH) return 1;
421   if((t/9)&1) return 0;
422   return 1;
425 static void pl_info(player_t *p,int y) {
426   dword t;
428   t=p->kills*10920/g_time;
429   Z_gotoxy(25,y);Z_printbf("УБИЛ");
430   Z_gotoxy(25,y+15);Z_printbf("УБИЙСТВ В МИНУТУ");
431   Z_gotoxy(25,y+30);Z_printbf("НАШЕЛ СЕКРЕТОВ %u ИЗ %u",p->secrets,sw_secrets);
432   Z_gotoxy(255,y);Z_printbf("%u",p->kills);
433   Z_gotoxy(255,y+15);Z_printbf("%u.%u",t/10,t%10);
436 void G_draw(void) {
437   int h;
438   word hr,mn,sc;
440   if(g_trans && !transdraw) return;
441   switch(g_st) {
442     case GS_ENDANIM: case GS_END2ANIM: case GS_DARKEN:
443     case GS_BVIDEO: case GS_EVIDEO: case GS_END3ANIM:
444       return;
445     case GS_TITLE:
446       V_pic(0,0,scrnh[0]);
447       break;
448     case GS_ENDSCR:
449       V_clr(0,320,0,200,0);V_pic(0,0,scrnh[2]);
450       break;
451     case GS_INTER:
452           V_pic(0,0,scrnh[1]);
453           Z_gotoxy(60,20);Z_printbf("УРОВЕНЬ ПРОЙДЕН");
454           Z_calc_time(g_time,&hr,&mn,&sc);
455           Z_gotoxy(115,40);Z_printbf("ЗА %u:%02u:%02u",hr,mn,sc);
456           h=60;
457           if(_2pl) {
458                 Z_gotoxy(80,h);Z_printbf("ПЕРВЫЙ ИГРОК");
459                 Z_gotoxy(80,h+70);Z_printbf("ВТОРОЙ ИГРОК");
460                 h+=20;
461           }
462           pl_info(&pl1,h);
463           if(_2pl) pl_info(&pl2,h+70);
464           break;
465   }
466   if(g_st!=GS_GAME) {
467     if(g_trans) return;
468     GM_draw();
469     V_copytoscr(0,320,0,200);
470     return;
471   }
472   if(_2pl) {
473         w_o=0;drawview(&pl1);
474         w_o=100;drawview(&pl2);
475   }else{
476         w_o=50;drawview(&pl1);
477   }
478   if(g_trans) return;
479   if(GM_draw()) {
480     pl1.drawst=pl2.drawst=0;
481     V_copytoscr(0,320,0,200);
482     return;
483   }
484   if(pl1.invl) h=get_pu_st(pl1.invl)*6;
485   else if(pl1.pain<15) h=0;
486   else if(pl1.pain<35) h=1;
487   else if(pl1.pain<55) h=2;
488   else if(pl1.pain<75) h=3;
489   else if(pl1.pain<95) h=4;
490   else h=5;
491   if(h) V_maptoscr(0,200,(_2pl)?1:51,98,clrmap+h*256);
492   else V_copytoscr(0,200,(_2pl)?1:51,98);
493   if(pl1.drawst) V_copytoscr(200,120,(_2pl)?0:50,100);
494   pl1.drawst=0;
495   if(_2pl) {
496         if(pl2.invl) h=get_pu_st(pl2.invl)*6;
497         else if(pl2.pain<15) h=0;
498     else if(pl2.pain<35) h=1;
499     else if(pl2.pain<55) h=2;
500     else if(pl2.pain<75) h=3;
501     else if(pl2.pain<95) h=4;
502     else h=5;
503     if(h) V_maptoscr(0,200,101,98,clrmap+h*256);
504     else V_copytoscr(0,200,101,98);
505     if(pl2.drawst) V_copytoscr(200,120,100,100);
506     pl2.drawst=0;
507   }
510 void G_respawn_player(player_t *p) {
511   int i;
513   if(dm_pnum==2) {
514     if(p==&pl1) i=dm_pl1p^=1;
515     else i=dm_pl2p^=1;
516     p->o.x=dm_pos[i].x;p->o.y=dm_pos[i].y;p->d=dm_pos[i].d;
517     FX_tfog(dm_pos[i].x,dm_pos[i].y);Z_sound(telepsnd,128);
518     return;
519   }
520   do{i=random(dm_pnum);}while(i==dm_pl1p || i==dm_pl2p);
521   p->o.x=dm_pos[i].x;p->o.y=dm_pos[i].y;p->d=dm_pos[i].d;
522   if(p==&pl1) dm_pl1p=i; else dm_pl2p=i;
523   FX_tfog(dm_pos[i].x,dm_pos[i].y);Z_sound(telepsnd,128);