DEADSOFTWARE

194365ecc3a739663131a9eedb7c5f5b87a8705c
[flatwaifu.git] / src / game.c
1 /*
2 Copyright (C) Prikol Software 1996-1997
3 Copyright (C) Aleksey Volynskov 1996-1997
4 Copyright (C) <ARembo@gmail.com> 2011
6 This file is part of the Doom2D:Rembo project.
8 Doom2D:Rembo is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License version 2 as
10 published by the Free Software Foundation.
12 Doom2D:Rembo is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, see <http://www.gnu.org/licenses/> or
19 write to the Free Software Foundation, Inc.,
20 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
23 #include "glob.h"
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include "files.h"
28 #include "memory.h"
29 #include "vga.h"
30 #include "error.h"
31 #include "keyb.h"
32 #include "sound.h"
33 #include "view.h"
34 #include "bmap.h"
35 #include "fx.h"
36 #include "switch.h"
37 #include "weapons.h"
38 #include "items.h"
39 #include "dots.h"
40 #include "smoke.h"
41 #include "player.h"
42 #include "monster.h"
43 #include "menu.h"
44 #include "misc.h"
45 #include "map.h"
47 #include <SDL_keysym.h>
49 #define LT_DELAY 8
50 #define LT_HITTIME 6
52 #define GETIME 1092
55 int A8_start(char*);
56 int A8_nextframe(void);
57 void A8_close(void);
60 void FX_trans1(int t);
61 extern unsigned char fx_scr1[64000],fx_scr2[64000];
63 extern short lastkey;
66 extern int hit_xv,hit_yv;
68 extern vgapal std_pal;
69 void setgamma(int);
71 extern int sw_secrets;
73 #define PL_FLASH 90
75 extern int PL_JUMP;
77 extern map_block_t blk;
79 extern byte clrmap[256*12];
81 extern byte cheat;
83 byte _2pl=0,g_dm=0,g_st=GS_TITLE,g_exit=0,g_map=1,_warp=0,g_music[8]="MENU";
84 byte _net=0;
85 int g_sttm=1092;
86 dword g_time;
87 int dm_pnum,dm_pl1p,dm_pl2p;
88 pos_t dm_pos[100];
90 static void *telepsnd;
91 static void *scrnh[3];
92 void *cd_scr;
94 extern int sky_type;
95 void *ltn[2][2];
96 int lt_time,lt_type,lt_side,lt_ypos,lt_force;
97 void *ltnsnd[2];
99 int g_trans=0,g_transt;
101 static void set_trans(int st) {
102 switch(g_st) {
103 case GS_ENDANIM: case GS_END2ANIM: case GS_DARKEN:
104 case GS_BVIDEO: case GS_EVIDEO: case GS_END3ANIM:
105 g_st=st;return;
107 switch(g_st=st) {
108 case GS_ENDANIM: case GS_END2ANIM: case GS_DARKEN:
109 case GS_BVIDEO: case GS_EVIDEO: case GS_END3ANIM:
110 return;
112 g_trans=1;g_transt=0;
115 void G_savegame(FILE* h) {
116 myfwrite(&_2pl,1,1,h);myfwrite(&g_dm,1,1,h);myfwrite(&g_exit,1,1,h);myfwrite(&g_map,1,1,h);
117 myfwrite(&g_time,1,4,h);myfwrite(&dm_pl1p,1,4,h);myfwrite(&dm_pl2p,1,4,h);
118 myfwrite(&dm_pnum,1,4,h);myfwrite(dm_pos,1,dm_pnum*sizeof(pos_t),h);
119 myfwrite(&cheat,1,1,h);
120 myfwrite(g_music,1,8,h);
123 void G_loadgame(FILE* h) {
124 myfread(&_2pl,1,1,h);myfread(&g_dm,1,1,h);myfread(&g_exit,1,1,h);myfread(&g_map,1,1,h);
125 myfread(&g_time,1,4,h);myfread(&dm_pl1p,1,4,h);myfread(&dm_pl2p,1,4,h);
126 myfread(&dm_pnum,1,4,h);myfread(dm_pos,1,dm_pnum*sizeof(pos_t),h);
127 myfread(&cheat,1,1,h);
128 myfread(g_music,1,8,h);F_loadmus(g_music);
131 int G_load(FILE* h) {
132 switch(blk.t) {
133 case MB_MUSIC:
134 myfread(g_music,1,8,h);
135 if (music_random) F_randmus(g_music);
136 F_loadmus(g_music);
137 return 1;
138 }return 0;
141 void load_game(int n) {
142 F_freemus();
143 W_init();
144 F_loadgame(n);
145 set_trans(GS_GAME);
146 V_setscr((g_trans)?fx_scr2:scrbuf);V_setrect(0,SCRW,0,SCRH);//V_setrect(0,320,0,200);
147 V_clr(0,SCRW,0,SCRH,0);//V_clr(0,320,0,200,0);
148 if(_2pl) {w_o=0;Z_clrst();w_o=SCRH/2;Z_clrst();}//if(_2pl) {w_o=0;Z_clrst();w_o=100;Z_clrst();}
149 else {w_o=0;Z_clrst();}//else {w_o=50;Z_clrst();}
150 V_setscr(scrbuf);
151 pl1.drawst=0xFF;
152 if(_2pl) pl2.drawst=0xFF;
153 BM_remapfld();
154 BM_clear(BM_PLR1|BM_PLR2|BM_MONSTER);
155 BM_mark(&pl1.o,BM_PLR1);
156 if(_2pl) BM_mark(&pl2.o,BM_PLR2);
157 MN_mark();
158 S_startmusic(music_time);
161 void G_start(void) {
162 char s[8];
164 F_freemus();
165 sprintf(s,"MAP%02u",(word)g_map);
166 F_loadmap(s);
167 set_trans(GS_GAME);
168 V_setscr((g_trans)?fx_scr2:scrbuf);V_setrect(0,SCRW,0,SCRH);//V_setrect(0,320,0,200);
169 V_clr(0,SCRW,0,SCRH,0);//V_clr(0,320,0,200,0);
170 if(_2pl) {w_o=0;Z_clrst();w_o=SCRH/2;Z_clrst();}//if(_2pl) {w_o=0;Z_clrst();w_o=100;Z_clrst();}
171 else {w_o=0;Z_clrst();}//else {w_o=50;Z_clrst();}
172 V_setscr(scrbuf);
173 pl1.drawst=0xFF;
174 if(_2pl) pl2.drawst=0xFF;
175 g_exit=0;
176 itm_rtime=(g_dm)?1092:0;
177 p_immortal=0;PL_JUMP=10;
178 g_time=0;
179 lt_time=1000;
180 lt_force=1;
181 if(!_2pl) pl1.lives=3;
182 BM_remapfld();
183 BM_clear(BM_PLR1|BM_PLR2|BM_MONSTER);
184 BM_mark(&pl1.o,BM_PLR1);
185 if(_2pl) BM_mark(&pl2.o,BM_PLR2);
186 MN_mark();
187 S_startmusic(music_time);
190 #define GGAS_TOTAL (MN__LAST-MN_DEMON+16+10)
192 void G_init(void) {
193 int i,j;
194 char s[9];
196 logo("G_init: настройка ресурсов игры ");
197 logo_gas(5,GGAS_TOTAL);
198 telepsnd=Z_getsnd("TELEPT");
199 scrnh[0]=M_lock(F_getresid("TITLEPIC"));
200 scrnh[1]=M_lock(F_getresid("INTERPIC"));
201 scrnh[2]=M_lock(F_getresid("ENDPIC"));
202 cd_scr=M_lock(F_getresid("CD1PIC"));
203 for(i=0;i<2;++i) {
204 sprintf(s,"LTN%c",i+'1');
205 for(j=0;j<2;++j)
206 ltn[i][j]=Z_getspr(s,j,0,NULL);
208 ltnsnd[0]=Z_getsnd("THUND1");
209 ltnsnd[1]=Z_getsnd("THUND2");
210 DOT_alloc();
211 SMK_alloc();
212 FX_alloc();
213 WP_alloc();
214 IT_alloc();
215 SW_alloc();
216 PL_alloc();
217 MN_alloc();
218 Z_initst();
219 logo_gas(GGAS_TOTAL,GGAS_TOTAL);
220 logo("\n");
221 GM_init();
222 pl1.color=0x70;
223 pl2.color=0x60;
224 g_trans=0;
227 int G_beg_video(void) {
228 /*
229 switch(g_map) {
230 case 3: return A8_start("FALL");
231 case 4: return A8_start("KORIDOR");
232 case 5: return A8_start("SKULL");
233 case 6: return A8_start("TORCHES");
234 case 7: return A8_start("CACO");
235 case 8: return A8_start("DARTS");
236 case 9: return A8_start("FISH");
237 case 10: return A8_start("TRAP");
238 case 11: return A8_start("JAIL");
239 case 12: return A8_start("MMON1");
240 case 13: return A8_start("TOWER");
241 case 14: return A8_start("SAPOG");
242 case 15: return A8_start("SWITCH");
243 case 16: return A8_start("ACCEL");
244 case 17: return A8_start("MEAT");
245 case 18: return A8_start("LEGION");
246 case 19: return A8_start("CLOUDS");
248 */
249 return 0;
253 int G_end_video(void) {
254 /*
255 switch(g_map) {
256 case 1: return A8_start("TRUBA");
257 case 10: return A8_start("GOTCHA");
259 */
260 return 0;
264 static byte transdraw=0;
266 void G_act(void) {
267 static byte pcnt=0;
268 /*
269 if(g_trans) {
270 if(g_transt==0) {
271 V_setscr(NULL);memcpy(fx_scr1,scra,64000);
272 V_setscr(fx_scr2);
273 transdraw=1;G_draw();transdraw=0;
274 V_setscr(scrbuf);
276 FX_trans1(g_transt*2);
277 V_copytoscr(0,320,0,200);
278 if(++g_transt>32) {
279 g_trans=0;
281 return;
282 g_trans=0;
284 */ g_trans=0;
287 if(g_st==GS_BVIDEO || g_st==GS_EVIDEO) {
288 if(!A8_nextframe() || lastkey==SDLK_ESCAPE) {
289 if(lastkey==SDLK_ESCAPE) lastkey=0;
290 A8_close();
291 if(g_st==GS_BVIDEO) G_start();
292 else goto inter;
294 V_copytoscr(0,SCRW,0,SCRH);//V_copytoscr(0,320,0,200);
295 return;
296 }else if(g_st==GS_ENDANIM || g_st==GS_END2ANIM || g_st==GS_END3ANIM) {
297 if(!A8_nextframe()) {
298 switch(g_st) {
299 case GS_ENDANIM: g_st=GS_DARKEN;break;
300 case GS_END2ANIM: g_st=GS_END3ANIM;A8_start("KONEC");break;
301 case GS_END3ANIM: g_st=GS_ENDSCR;lastkey=0;break;
302 }g_sttm=0;return;
304 V_copytoscr(0,SCRW,0,SCRH);//V_copytoscr(0,320,0,200);
305 return;
306 }else if(g_st==GS_DARKEN) {
307 g_st=GS_END2ANIM;A8_start("CREDITS");
308 return;
311 if(GM_act()) return;
315 switch(g_st) {
316 case GS_TITLE: case GS_ENDSCR:
318 return;
319 case GS_INTER:
320 #ifdef DEMO
321 if(keys[0x39] || keys[0x1C] || keys[0x9C]) {
322 set_trans(GS_TITLE);
324 #else
325 if(keys[SDLK_SPACE] || keys[SDLK_RETURN] || keys[SDLK_KP_ENTER])//if(keys[0x39] || keys[0x1C] || keys[0x9C])
326 if(!G_beg_video()) G_start(); else {
327 g_st=GS_BVIDEO;F_freemus();
329 #endif
330 return;
334 if(sky_type==2) {
335 if(lt_time>LT_DELAY || lt_force) {
336 if(!(rand()&31) || lt_force) {
337 lt_force=0;
338 lt_time=-LT_HITTIME;
339 lt_type=rand()%2;
340 lt_side=rand()&1;
341 lt_ypos=rand()&31;
342 Z_sound(ltnsnd[rand()&1],128);
344 }else ++lt_time;
346 ++g_time;
347 pl1.hit=0;pl1.hito=-3;
348 if(_2pl) {pl2.hit=0;pl2.hito=-3;}
349 G_code();
351 W_act();
352 IT_act();
353 SW_act();
354 if(_2pl) {
355 if(pcnt) {PL_act(&pl1);PL_act(&pl2);}
356 else {PL_act(&pl2);PL_act(&pl1);}
357 pcnt^=1;
358 }else PL_act(&pl1);
359 MN_act();
360 if(fld_need_remap) BM_remapfld();
361 BM_clear(BM_PLR1|BM_PLR2|BM_MONSTER);
362 BM_mark(&pl1.o,BM_PLR1);
363 if(_2pl) BM_mark(&pl2.o,BM_PLR2);
364 MN_mark();
365 WP_act();
366 DOT_act();
367 SMK_act();
368 FX_act();
369 if(_2pl) {
370 PL_damage(&pl1);PL_damage(&pl2);
371 if(!(pl1.f&PLF_PNSND) && pl1.pain) PL_cry(&pl1);
372 if(!(pl2.f&PLF_PNSND) && pl2.pain) PL_cry(&pl2);
373 if((pl1.pain-=5) < 0) {pl1.pain=0;pl1.f&=(0xFFFF-PLF_PNSND);}
374 if((pl2.pain-=5) < 0) {pl2.pain=0;pl2.f&=(0xFFFF-PLF_PNSND);}
375 }else{
376 PL_damage(&pl1);
377 if(!(pl1.f&PLF_PNSND) && pl1.pain) PL_cry(&pl1);
378 if((pl1.pain-=5) < 0) {pl1.pain=0;pl1.f&=(0xFFFF-PLF_PNSND);}
380 if(g_exit==1) {
382 if(G_end_video()) {
383 F_freemus();
384 g_st=GS_EVIDEO;
385 return;
388 inter:
389 switch(g_map) {
390 case 19: g_st=GS_ENDANIM;A8_start("FINAL");break;
391 case 31: case 32: g_map=16;set_trans(GS_INTER);break;
392 default: ++g_map;set_trans(GS_INTER);break;
394 F_freemus();
395 if(g_st==GS_INTER) {
396 F_loadmus("INTERMUS");
397 }else {F_loadmus("\x8a\x8e\x8d\x85\x96\x0");if(mus_vol>0) {S_volumemusic(128);} }
398 S_startmusic(0);
399 }else if(g_exit==2) {
400 switch(g_map) {
401 case 31: g_map=32;set_trans(GS_INTER);break;
402 case 32: g_map=16;set_trans(GS_INTER);break;
403 default: g_map=31;set_trans(GS_INTER);break;
405 F_freemus();
406 F_loadmus("INTERMUS");
407 S_startmusic(0);
410 #ifdef DEMO
411 if(g_dm && g_time>10920) {set_trans(GS_INTER);}
412 #endif
415 /*
416 static void drawview(player_t *p) {
417 if(p->looky<-50) p->looky=-50;
418 else if(p->looky>50) p->looky=50;
419 w_x=p->o.x;w_y=p->o.y-12+p->looky;W_draw();PL_drawst(p);
421 */
422 static void drawview(player_t *p) {
423 if(p->looky<-SCRH/4) p->looky=-SCRH/4;
424 else if(p->looky>SCRH/4) p->looky=SCRH/4;
425 w_x=p->o.x;w_y=p->o.y-12+p->looky;
426 W_draw();
427 PL_drawst(p);
430 static int get_pu_st(int t) {
431 if(t>=PL_FLASH) return 1;
432 if((t/9)&1) return 0;
433 return 1;
436 static void pl_info(player_t *p,int y) {
437 dword t;
439 t=p->kills*10920/g_time;
440 Z_gotoxy(25,y);Z_printbf("KILLS");//Z_gotoxy(25,y);Z_printbf("KILLS");
441 Z_gotoxy(25,y+15);Z_printbf("KPM");//Z_gotoxy(25,y+15);Z_printbf("KPM");
442 Z_gotoxy(25,y+30);Z_printbf("SECRETS %u / %u",p->secrets,sw_secrets);//Z_gotoxy(25,y+30);Z_printbf("SECRETS %u / %u",p->secrets,sw_secrets);
443 Z_gotoxy(255,y);Z_printbf("%u",p->kills);//Z_gotoxy(255,y);Z_printbf("%u",p->kills);
444 Z_gotoxy(255,y+15);Z_printbf("%u.%u",t/10,t%10);//Z_gotoxy(255,y+15);Z_printbf("%u.%u",t/10,t%10);
447 void G_draw(void) {
448 int h;
449 word hr,mn,sc;
451 if(g_trans && !transdraw) return;
452 switch(g_st) {
453 case GS_ENDANIM: case GS_END2ANIM: case GS_DARKEN:
454 case GS_BVIDEO: case GS_EVIDEO: case GS_END3ANIM:
455 return;
456 case GS_TITLE:
457 V_center(1);//
458 V_pic(0,0,scrnh[0]);
459 V_center(0);//
460 break;
461 case GS_ENDSCR:
462 V_center(1);//
463 V_clr(0,SCRW,0,SCRH,0);V_pic(0,0,scrnh[2]);//V_clr(0,320,0,200,0);V_pic(0,0,scrnh[2]);
464 V_center(0);//
465 break;
466 case GS_INTER:
467 V_center(1);//
468 V_clr(0,SCRW,0,SCRH,0);//
469 V_pic(0,0,scrnh[1]);
470 Z_gotoxy(60,20);Z_printbf("LEVEL COMPLETE");
471 Z_calc_time(g_time,&hr,&mn,&sc);
472 Z_gotoxy(115,40);Z_printbf("TIME %u:%02u:%02u",hr,mn,sc);
473 h=60;
474 if(_2pl) {
475 Z_gotoxy(80,h);Z_printbf("PLAYER ONE");
476 Z_gotoxy(80,h+70);Z_printbf("PLAYER TWO");
477 h+=SCRH/10;//h+=20;
479 pl_info(&pl1,h);
480 if(_2pl) pl_info(&pl2,h+70);
481 V_center(0);//
482 break;
484 V_center(1);//
485 if(g_st!=GS_GAME) {
486 if(g_trans) return;
487 GM_draw();
488 V_copytoscr(0,SCRW,0,SCRH);//V_copytoscr(0,320,0,200);
489 return;
491 V_center(0);//
493 if(_2pl) {
494 w_o=0;WD=SCRW-120;HT=SCRH/2-2;drawview(&pl1);//w_o=0;drawview(&pl1);
495 w_o=SCRH/2;WD=SCRW-120;HT=SCRH/2-2;drawview(&pl2);//w_o=100;drawview(&pl2);
496 }else{
497 w_o=0;WD=SCRW-120;HT=SCRH-2;drawview(&pl1);//w_o=50;drawview(&pl1);
499 if(g_trans) return;
500 V_center(1);//
501 if(GM_draw()) {
502 pl1.drawst=pl2.drawst=0xFF;//pl1.drawst=pl2.drawst=0;
503 V_copytoscr(0,SCRW,0,SCRH);//V_copytoscr(0,320,0,200);
504 return;
506 V_center(0);//
507 if(pl1.invl) h=get_pu_st(pl1.invl)*6;
508 else if(pl1.pain<15) h=0;
509 else if(pl1.pain<35) h=1;
510 else if(pl1.pain<55) h=2;
511 else if(pl1.pain<75) h=3;
512 else if(pl1.pain<95) h=4;
513 else h=5;
514 if(h) V_maptoscr(0,SCRW-120,1,(_2pl)?(SCRH/2-2):(SCRH-2),clrmap+h*256);//if(h) V_maptoscr(0,200,(_2pl)?1:51,98,clrmap+h*256);
515 else V_copytoscr(0,SCRW-120,1,(_2pl)?(SCRH/2-2):(SCRH-2)); //else V_copytoscr(0,200,(_2pl)?1:51,98);
516 if(pl1.drawst) V_copytoscr(SCRW-120,120,0,_2pl?(SCRH/2):SCRH);//if(pl1.drawst) V_copytoscr(200,120,(_2pl)?0:50,100);
517 pl1.drawst=0xFF;//pl1.drawst=0;
518 if(_2pl) {
519 if(pl2.invl) h=get_pu_st(pl2.invl)*6;
520 else if(pl2.pain<15) h=0;
521 else if(pl2.pain<35) h=1;
522 else if(pl2.pain<55) h=2;
523 else if(pl2.pain<75) h=3;
524 else if(pl2.pain<95) h=4;
525 else h=5;
526 if(h) V_maptoscr(0,SCRW-120,SCRH/2+1,SCRH/2-2,clrmap+h*256);//if(h) V_maptoscr(0,200,101,98,clrmap+h*256);
527 else V_copytoscr(0,SCRW-120,SCRH/2+1,SCRH/2-2);//else V_copytoscr(0,200,101,98);
528 if(pl2.drawst) V_copytoscr(SCRW-120,120,SCRH/2,SCRH/2);//if(pl2.drawst) V_copytoscr(200,120,100,100);
529 pl2.drawst=0xFF;//pl2.drawst=0;
533 void G_respawn_player(player_t *p) {
534 int i;
536 if(dm_pnum==2) {
537 if(p==&pl1) i=dm_pl1p^=1;
538 else i=dm_pl2p^=1;
539 p->o.x=dm_pos[i].x;p->o.y=dm_pos[i].y;p->d=dm_pos[i].d;
540 FX_tfog(dm_pos[i].x,dm_pos[i].y);Z_sound(telepsnd,128);
541 return;
543 do{i=myrand(dm_pnum);}while(i==dm_pl1p || i==dm_pl2p);
544 p->o.x=dm_pos[i].x;p->o.y=dm_pos[i].y;p->d=dm_pos[i].d;
545 if(p==&pl1) dm_pl1p=i; else dm_pl2p=i;
546 FX_tfog(dm_pos[i].x,dm_pos[i].y);Z_sound(telepsnd,128);