DEADSOFTWARE

streams: new method: getlen
[flatwaifu.git] / src / game.c
1 /* Copyright (C) 1996-1997 Aleksey Volynskov
2 * Copyright (C) 2011 Rambo
3 * Copyright (C) 2020 SovietPony
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License ONLY.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
18 #include "glob.h"
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include "files.h"
23 #include "memory.h"
24 #include "sound.h"
25 #include "view.h"
26 #include "bmap.h"
27 #include "fx.h"
28 #include "switch.h"
29 #include "weapons.h"
30 #include "items.h"
31 #include "dots.h"
32 #include "smoke.h"
33 #include "player.h"
34 #include "monster.h"
35 #include "menu.h"
36 #include "misc.h"
37 #include "map.h"
38 #include "game.h"
39 #include "config.h"
40 #include "music.h"
41 #include "a8.h"
42 #include "error.h"
43 #include "input.h"
45 #include "save.h"
47 #define LT_DELAY 8
48 #define LT_HITTIME 6
50 #define GETIME 1092
52 byte transdraw;
53 byte _2pl;
54 byte g_dm;
55 byte g_st = GS_TITLE;
56 byte g_exit;
57 byte g_map = 1;
58 char g_music[8] = "MENU";
59 dword g_time;
60 int dm_pnum;
61 int dm_pl1p;
62 int dm_pl2p;
63 pos_t dm_pos[100];
64 byte cheat;
66 static void *telepsnd;
68 int lt_time;
69 int lt_type;
70 int lt_side;
71 int lt_ypos;
72 static int lt_force;
73 static void *ltnsnd[2];
75 int g_trans;
76 static int g_transt;
78 static void set_trans(int st) {
79 switch(g_st) {
80 case GS_ENDANIM: case GS_END2ANIM: case GS_DARKEN:
81 case GS_BVIDEO: case GS_EVIDEO: case GS_END3ANIM:
82 g_st=st;return;
83 }
84 switch(g_st=st) {
85 case GS_ENDANIM: case GS_END2ANIM: case GS_DARKEN:
86 case GS_BVIDEO: case GS_EVIDEO: case GS_END3ANIM:
87 return;
88 }
89 g_trans=1;g_transt=0;
90 }
92 void load_game (int n) {
93 MUS_free();
94 W_init();
95 F_loadgame(n);
96 set_trans(GS_GAME);
97 pl1.drawst=0xFF;
98 if(_2pl) pl2.drawst=0xFF;
99 BM_remapfld();
100 BM_clear(BM_PLR1|BM_PLR2|BM_MONSTER);
101 BM_mark(&pl1.o,BM_PLR1);
102 if(_2pl) BM_mark(&pl2.o,BM_PLR2);
103 MN_mark();
104 //MUS_start(music_time);
105 MUS_start(0);
108 void G_start (void) {
109 char s[8];
110 MUS_free();
111 sprintf(s,"MAP%02u",(word)g_map);
112 F_loadmap(s);
113 set_trans(GS_GAME);
114 pl1.drawst=0xFF;
115 if(_2pl) pl2.drawst=0xFF;
116 g_exit=0;
117 itm_rtime=(g_dm)?1092:0;
118 p_immortal=0;PL_JUMP=10;
119 g_time=0;
120 lt_time=1000;
121 lt_force=1;
122 if(!_2pl) pl1.lives=3;
123 BM_remapfld();
124 BM_clear(BM_PLR1|BM_PLR2|BM_MONSTER);
125 BM_mark(&pl1.o,BM_PLR1);
126 if(_2pl) BM_mark(&pl2.o,BM_PLR2);
127 MN_mark();
128 //MUS_start(music_time);
129 MUS_start(0);
132 #define GGAS_TOTAL (MN__LAST-MN_DEMON+16+10)
134 void G_init (void) {
135 int i,j;
136 char s[9];
138 logo("G_init: setup game resources ");
139 logo_gas(5,GGAS_TOTAL);
140 telepsnd=Z_getsnd("TELEPT");
141 ltnsnd[0]=Z_getsnd("THUND1");
142 ltnsnd[1]=Z_getsnd("THUND2");
143 DOT_alloc();
144 SMK_alloc();
145 FX_alloc();
146 WP_alloc();
147 IT_alloc();
148 SW_alloc();
149 PL_alloc();
150 MN_alloc();
151 Z_initst();
152 logo_gas(GGAS_TOTAL,GGAS_TOTAL);
153 logo("\n");
154 GM_init();
155 pl1.color=0x70;
156 pl2.color=0x60;
157 g_trans=0;
160 static int G_beg_video (void) {
161 /*
162 switch(g_map) {
163 case 3: return A8_start("FALL");
164 case 4: return A8_start("KORIDOR");
165 case 5: return A8_start("SKULL");
166 case 6: return A8_start("TORCHES");
167 case 7: return A8_start("CACO");
168 case 8: return A8_start("DARTS");
169 case 9: return A8_start("FISH");
170 case 10: return A8_start("TRAP");
171 case 11: return A8_start("JAIL");
172 case 12: return A8_start("MMON1");
173 case 13: return A8_start("TOWER");
174 case 14: return A8_start("SAPOG");
175 case 15: return A8_start("SWITCH");
176 case 16: return A8_start("ACCEL");
177 case 17: return A8_start("MEAT");
178 case 18: return A8_start("LEGION");
179 case 19: return A8_start("CLOUDS");
181 */
182 return 0;
186 static int G_end_video (void) {
187 /*
188 switch(g_map) {
189 case 1: return A8_start("TRUBA");
190 case 10: return A8_start("GOTCHA");
192 */
193 return 0;
196 void G_act (void) {
197 static byte pcnt=0;
198 /*
199 if(g_trans) {
200 if(g_transt==0) {
201 V_setscr(NULL);memcpy(fx_scr1,scra,64000);
202 V_setscr(fx_scr2);
203 transdraw=1;G_draw();transdraw=0;
204 V_setscr(scrbuf);
206 FX_trans1(g_transt*2);
207 V_copytoscr(0,320,0,200);
208 if(++g_transt>32) {
209 g_trans=0;
211 return;
212 g_trans=0;
214 */ g_trans=0;
217 if(g_st==GS_BVIDEO || g_st==GS_EVIDEO) {
218 if (!A8_nextframe() || lastkey == KEY_ESCAPE) {
219 if (lastkey == KEY_ESCAPE) lastkey = KEY_UNKNOWN;
220 A8_close();
221 if(g_st==GS_BVIDEO) G_start();
222 else goto inter;
224 // V_copytoscr(0,SCRW,0,SCRH);//V_copytoscr(0,320,0,200);
225 return;
226 }else if(g_st==GS_ENDANIM || g_st==GS_END2ANIM || g_st==GS_END3ANIM) {
227 if(!A8_nextframe()) {
228 switch(g_st) {
229 case GS_ENDANIM: g_st=GS_DARKEN;break;
230 case GS_END2ANIM: g_st=GS_END3ANIM;A8_start("KONEC");break;
231 case GS_END3ANIM: g_st=GS_ENDSCR;lastkey=0;break;
233 return;
235 // V_copytoscr(0,SCRW,0,SCRH);//V_copytoscr(0,320,0,200);
236 return;
237 }else if(g_st==GS_DARKEN) {
238 g_st=GS_END2ANIM;A8_start("CREDITS");
239 return;
242 if(GM_act()) return;
246 switch(g_st) {
247 case GS_TITLE: case GS_ENDSCR:
249 return;
250 case GS_INTER:
251 #ifdef DEMO
252 if(keys[0x39] || keys[0x1C] || keys[0x9C]) {
253 set_trans(GS_TITLE);
255 #else
256 if (I_pressed(KEY_SPACE) || I_pressed(KEY_RETURN) || I_pressed(KEY_KP_ENTER)) {
257 if (!G_beg_video()) {
258 G_start();
259 } else {
260 g_st = GS_BVIDEO;
261 MUS_free();
264 #endif
265 return;
269 if(sky_type==2) {
270 if(lt_time>LT_DELAY || lt_force) {
271 if(!(rand()&31) || lt_force) {
272 lt_force=0;
273 lt_time=-LT_HITTIME;
274 lt_type=rand()%2;
275 lt_side=rand()&1;
276 lt_ypos=rand()&31;
277 Z_sound(ltnsnd[rand()&1],128);
279 }else ++lt_time;
281 ++g_time;
282 pl1.hit=0;pl1.hito=-3;
283 if(_2pl) {pl2.hit=0;pl2.hito=-3;}
284 G_code();
286 IT_act();
287 SW_act();
288 if(_2pl) {
289 if(pcnt) {PL_act(&pl1);PL_act(&pl2);}
290 else {PL_act(&pl2);PL_act(&pl1);}
291 pcnt^=1;
292 }else PL_act(&pl1);
293 MN_act();
294 if(fld_need_remap) BM_remapfld();
295 BM_clear(BM_PLR1|BM_PLR2|BM_MONSTER);
296 BM_mark(&pl1.o,BM_PLR1);
297 if(_2pl) BM_mark(&pl2.o,BM_PLR2);
298 MN_mark();
299 WP_act();
300 DOT_act();
301 SMK_act();
302 FX_act();
303 if(_2pl) {
304 PL_damage(&pl1);PL_damage(&pl2);
305 if(!(pl1.f&PLF_PNSND) && pl1.pain) PL_cry(&pl1);
306 if(!(pl2.f&PLF_PNSND) && pl2.pain) PL_cry(&pl2);
307 if((pl1.pain-=5) < 0) {pl1.pain=0;pl1.f&=(0xFFFF-PLF_PNSND);}
308 if((pl2.pain-=5) < 0) {pl2.pain=0;pl2.f&=(0xFFFF-PLF_PNSND);}
309 }else{
310 PL_damage(&pl1);
311 if(!(pl1.f&PLF_PNSND) && pl1.pain) PL_cry(&pl1);
312 if((pl1.pain-=5) < 0) {pl1.pain=0;pl1.f&=(0xFFFF-PLF_PNSND);}
314 if(g_exit==1) {
316 if(G_end_video()) {
317 MUS_free();
318 g_st=GS_EVIDEO;
319 return;
322 inter:
323 switch(g_map) {
324 case 19: g_st=GS_ENDANIM;A8_start("FINAL");break;
325 case 31: case 32: g_map=16;set_trans(GS_INTER);break;
326 default: ++g_map;set_trans(GS_INTER);break;
328 MUS_free();
329 if (g_st == GS_INTER) {
330 MUS_load("INTERMUS");
331 } else {
332 MUS_load("\x8a\x8e\x8d\x85\x96\x0");
333 MUS_volume(128);
335 MUS_start(0);
336 }else if(g_exit==2) {
337 switch(g_map) {
338 case 31: g_map=32;set_trans(GS_INTER);break;
339 case 32: g_map=16;set_trans(GS_INTER);break;
340 default: g_map=31;set_trans(GS_INTER);break;
342 MUS_free();
343 MUS_load("INTERMUS");
344 MUS_start(0);
347 #ifdef DEMO
348 if(g_dm && g_time>10920) {set_trans(GS_INTER);}
349 #endif
352 void G_respawn_player (player_t *p) {
353 int i;
355 if(dm_pnum==2) {
356 if(p==&pl1) i=dm_pl1p^=1;
357 else i=dm_pl2p^=1;
358 p->o.x=dm_pos[i].x;p->o.y=dm_pos[i].y;p->d=dm_pos[i].d;
359 FX_tfog(dm_pos[i].x,dm_pos[i].y);Z_sound(telepsnd,128);
360 return;
362 do{i=myrand(dm_pnum);}while(i==dm_pl1p || i==dm_pl2p);
363 p->o.x=dm_pos[i].x;p->o.y=dm_pos[i].y;p->d=dm_pos[i].d;
364 if(p==&pl1) dm_pl1p=i; else dm_pl2p=i;
365 FX_tfog(dm_pos[i].x,dm_pos[i].y);Z_sound(telepsnd,128);