DEADSOFTWARE

menu: add controls settings via menu
[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 "my.h"
39 #include "game.h"
40 #include "config.h"
41 #include "music.h"
42 #include "a8.h"
43 #include "error.h"
44 #include "input.h"
46 #include "save.h"
48 #define LT_DELAY 8
49 #define LT_HITTIME 6
51 #define GETIME 1092
53 byte transdraw;
54 byte _2pl;
55 byte g_dm;
56 byte g_st = GS_TITLE;
57 byte g_exit;
58 byte g_map = 1;
59 char g_music[8] = "MENU";
60 dword g_time;
61 int dm_pnum;
62 int dm_pl1p;
63 int dm_pl2p;
64 pos_t dm_pos[100];
65 byte cheat;
67 static void *telepsnd;
69 int lt_time;
70 int lt_type;
71 int lt_side;
72 int lt_ypos;
73 static int lt_force;
74 static void *ltnsnd[2];
76 int g_trans;
77 static int g_transt;
79 static void set_trans(int st) {
80 switch(g_st) {
81 case GS_ENDANIM: case GS_END2ANIM: case GS_DARKEN:
82 case GS_BVIDEO: case GS_EVIDEO: case GS_END3ANIM:
83 g_st=st;return;
84 }
85 switch(g_st=st) {
86 case GS_ENDANIM: case GS_END2ANIM: case GS_DARKEN:
87 case GS_BVIDEO: case GS_EVIDEO: case GS_END3ANIM:
88 return;
89 }
90 g_trans=1;g_transt=0;
91 }
93 void load_game (int n) {
94 MUS_free();
95 W_init();
96 F_loadgame(n);
97 set_trans(GS_GAME);
98 pl1.drawst=0xFF;
99 if(_2pl) pl2.drawst=0xFF;
100 BM_remapfld();
101 BM_clear(BM_PLR1|BM_PLR2|BM_MONSTER);
102 BM_mark(&pl1.o,BM_PLR1);
103 if(_2pl) BM_mark(&pl2.o,BM_PLR2);
104 MN_mark();
105 //MUS_start(music_time);
106 MUS_start(0);
109 void G_start (void) {
110 char s[8];
111 MUS_free();
112 sprintf(s,"MAP%02u",(word)g_map);
113 F_loadmap(s);
114 set_trans(GS_GAME);
115 pl1.drawst=0xFF;
116 if(_2pl) pl2.drawst=0xFF;
117 g_exit=0;
118 itm_rtime=(g_dm)?1092:0;
119 p_immortal=0;PL_JUMP=10;
120 g_time=0;
121 lt_time=1000;
122 lt_force=1;
123 if(!_2pl) pl1.lives=3;
124 BM_remapfld();
125 BM_clear(BM_PLR1|BM_PLR2|BM_MONSTER);
126 BM_mark(&pl1.o,BM_PLR1);
127 if(_2pl) BM_mark(&pl2.o,BM_PLR2);
128 MN_mark();
129 //MUS_start(music_time);
130 MUS_start(0);
133 #define GGAS_TOTAL (MN__LAST-MN_DEMON+16+10)
135 void G_init (void) {
136 int i,j;
137 char s[9];
139 logo("G_init: настройка ресурсов игры ");
140 logo_gas(5,GGAS_TOTAL);
141 telepsnd=Z_getsnd("TELEPT");
142 ltnsnd[0]=Z_getsnd("THUND1");
143 ltnsnd[1]=Z_getsnd("THUND2");
144 DOT_alloc();
145 SMK_alloc();
146 FX_alloc();
147 WP_alloc();
148 IT_alloc();
149 SW_alloc();
150 PL_alloc();
151 MN_alloc();
152 Z_initst();
153 logo_gas(GGAS_TOTAL,GGAS_TOTAL);
154 logo("\n");
155 GM_init();
156 pl1.color=0x70;
157 pl2.color=0x60;
158 g_trans=0;
161 static int G_beg_video (void) {
162 /*
163 switch(g_map) {
164 case 3: return A8_start("FALL");
165 case 4: return A8_start("KORIDOR");
166 case 5: return A8_start("SKULL");
167 case 6: return A8_start("TORCHES");
168 case 7: return A8_start("CACO");
169 case 8: return A8_start("DARTS");
170 case 9: return A8_start("FISH");
171 case 10: return A8_start("TRAP");
172 case 11: return A8_start("JAIL");
173 case 12: return A8_start("MMON1");
174 case 13: return A8_start("TOWER");
175 case 14: return A8_start("SAPOG");
176 case 15: return A8_start("SWITCH");
177 case 16: return A8_start("ACCEL");
178 case 17: return A8_start("MEAT");
179 case 18: return A8_start("LEGION");
180 case 19: return A8_start("CLOUDS");
182 */
183 return 0;
187 static int G_end_video (void) {
188 /*
189 switch(g_map) {
190 case 1: return A8_start("TRUBA");
191 case 10: return A8_start("GOTCHA");
193 */
194 return 0;
197 void G_act (void) {
198 static byte pcnt=0;
199 /*
200 if(g_trans) {
201 if(g_transt==0) {
202 V_setscr(NULL);memcpy(fx_scr1,scra,64000);
203 V_setscr(fx_scr2);
204 transdraw=1;G_draw();transdraw=0;
205 V_setscr(scrbuf);
207 FX_trans1(g_transt*2);
208 V_copytoscr(0,320,0,200);
209 if(++g_transt>32) {
210 g_trans=0;
212 return;
213 g_trans=0;
215 */ g_trans=0;
218 if(g_st==GS_BVIDEO || g_st==GS_EVIDEO) {
219 if (!A8_nextframe() || lastkey == KEY_ESCAPE) {
220 if (lastkey == KEY_ESCAPE) lastkey = KEY_UNKNOWN;
221 A8_close();
222 if(g_st==GS_BVIDEO) G_start();
223 else goto inter;
225 // V_copytoscr(0,SCRW,0,SCRH);//V_copytoscr(0,320,0,200);
226 return;
227 }else if(g_st==GS_ENDANIM || g_st==GS_END2ANIM || g_st==GS_END3ANIM) {
228 if(!A8_nextframe()) {
229 switch(g_st) {
230 case GS_ENDANIM: g_st=GS_DARKEN;break;
231 case GS_END2ANIM: g_st=GS_END3ANIM;A8_start("KONEC");break;
232 case GS_END3ANIM: g_st=GS_ENDSCR;lastkey=0;break;
234 return;
236 // V_copytoscr(0,SCRW,0,SCRH);//V_copytoscr(0,320,0,200);
237 return;
238 }else if(g_st==GS_DARKEN) {
239 g_st=GS_END2ANIM;A8_start("CREDITS");
240 return;
243 if(GM_act()) return;
247 switch(g_st) {
248 case GS_TITLE: case GS_ENDSCR:
250 return;
251 case GS_INTER:
252 #ifdef DEMO
253 if(keys[0x39] || keys[0x1C] || keys[0x9C]) {
254 set_trans(GS_TITLE);
256 #else
257 if (I_pressed(KEY_SPACE) || I_pressed(KEY_RETURN) || I_pressed(KEY_KP_ENTER)) {
258 if (!G_beg_video()) {
259 G_start();
260 } else {
261 g_st = GS_BVIDEO;
262 MUS_free();
265 #endif
266 return;
270 if(sky_type==2) {
271 if(lt_time>LT_DELAY || lt_force) {
272 if(!(rand()&31) || lt_force) {
273 lt_force=0;
274 lt_time=-LT_HITTIME;
275 lt_type=rand()%2;
276 lt_side=rand()&1;
277 lt_ypos=rand()&31;
278 Z_sound(ltnsnd[rand()&1],128);
280 }else ++lt_time;
282 ++g_time;
283 pl1.hit=0;pl1.hito=-3;
284 if(_2pl) {pl2.hit=0;pl2.hito=-3;}
285 G_code();
287 IT_act();
288 SW_act();
289 if(_2pl) {
290 if(pcnt) {PL_act(&pl1);PL_act(&pl2);}
291 else {PL_act(&pl2);PL_act(&pl1);}
292 pcnt^=1;
293 }else PL_act(&pl1);
294 MN_act();
295 if(fld_need_remap) BM_remapfld();
296 BM_clear(BM_PLR1|BM_PLR2|BM_MONSTER);
297 BM_mark(&pl1.o,BM_PLR1);
298 if(_2pl) BM_mark(&pl2.o,BM_PLR2);
299 MN_mark();
300 WP_act();
301 DOT_act();
302 SMK_act();
303 FX_act();
304 if(_2pl) {
305 PL_damage(&pl1);PL_damage(&pl2);
306 if(!(pl1.f&PLF_PNSND) && pl1.pain) PL_cry(&pl1);
307 if(!(pl2.f&PLF_PNSND) && pl2.pain) PL_cry(&pl2);
308 if((pl1.pain-=5) < 0) {pl1.pain=0;pl1.f&=(0xFFFF-PLF_PNSND);}
309 if((pl2.pain-=5) < 0) {pl2.pain=0;pl2.f&=(0xFFFF-PLF_PNSND);}
310 }else{
311 PL_damage(&pl1);
312 if(!(pl1.f&PLF_PNSND) && pl1.pain) PL_cry(&pl1);
313 if((pl1.pain-=5) < 0) {pl1.pain=0;pl1.f&=(0xFFFF-PLF_PNSND);}
315 if(g_exit==1) {
317 if(G_end_video()) {
318 MUS_free();
319 g_st=GS_EVIDEO;
320 return;
323 inter:
324 switch(g_map) {
325 case 19: g_st=GS_ENDANIM;A8_start("FINAL");break;
326 case 31: case 32: g_map=16;set_trans(GS_INTER);break;
327 default: ++g_map;set_trans(GS_INTER);break;
329 MUS_free();
330 if (g_st == GS_INTER) {
331 MUS_load("INTERMUS");
332 } else {
333 MUS_load("\x8a\x8e\x8d\x85\x96\x0");
334 MUS_volume(128);
336 MUS_start(0);
337 }else if(g_exit==2) {
338 switch(g_map) {
339 case 31: g_map=32;set_trans(GS_INTER);break;
340 case 32: g_map=16;set_trans(GS_INTER);break;
341 default: g_map=31;set_trans(GS_INTER);break;
343 MUS_free();
344 MUS_load("INTERMUS");
345 MUS_start(0);
348 #ifdef DEMO
349 if(g_dm && g_time>10920) {set_trans(GS_INTER);}
350 #endif
353 void G_respawn_player (player_t *p) {
354 int i;
356 if(dm_pnum==2) {
357 if(p==&pl1) i=dm_pl1p^=1;
358 else i=dm_pl2p^=1;
359 p->o.x=dm_pos[i].x;p->o.y=dm_pos[i].y;p->d=dm_pos[i].d;
360 FX_tfog(dm_pos[i].x,dm_pos[i].y);Z_sound(telepsnd,128);
361 return;
363 do{i=myrand(dm_pnum);}while(i==dm_pl1p || i==dm_pl2p);
364 p->o.x=dm_pos[i].x;p->o.y=dm_pos[i].y;p->d=dm_pos[i].d;
365 if(p==&pl1) dm_pl1p=i; else dm_pl2p=i;
366 FX_tfog(dm_pos[i].x,dm_pos[i].y);Z_sound(telepsnd,128);