DEADSOFTWARE

headers describes that c-files implements
[flatwaifu.git] / src / menu.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 <string.h>
26 #include <stdlib.h>
27 #include "files.h"
28 #include "memory.h"
29 #include "error.h"
30 #include "keyb.h"
31 #include "sound.h"
32 #include "view.h"
33 #include "player.h"
34 #include "switch.h"
35 #include "menu.h"
36 #include "misc.h"
37 #include "render.h"
38 #include "config.h"
39 #include "game.h"
40 #include "player.h"
41 #include "sound.h"
42 #include "music.h"
44 #include <SDL.h>
45 #include <sys/stat.h>
47 #define QSND_NUM 14
49 enum{HIT100,ARMOR,JUMP,WPNS,IMMORTAL,SPEED,OPEN,EXIT};
51 static byte panim[] = "BBDDAACCDDAABBDDAACCDDAABBDDAACCDDAAEEEEEFEFEFEFEFEFEFEFEFEFEEEEE";
52 byte *panimp = panim;
53 byte _warp;
55 byte pcolortab[PCOLORN] = {
56 0x18, 0x20, 0x40, 0x58, 0x60, 0x70, 0x80, 0xB0, 0xC0, 0xD0
57 };
58 int p1color = 5;
59 int p2color = 4;
61 char ibuf[24];
62 byte input=0;
63 static int icur;
65 enum{MENU,MSG};
66 enum{CANCEL,NEWGAME,LOADGAME,SAVEGAME,OPTIONS,QUITGAME,QUIT,ENDGAME,ENDGM,
67 PLR1,PLR2,COOP,DM,VOLUME,GAMMA,LOAD,SAVE,PLCOLOR,PLCEND,MUSIC,INTERP,
68 SVOLM,SVOLP,MVOLM,MVOLP,GAMMAM,GAMMAP,PL1CM,PL1CP,PL2CM,PL2CP};
70 #ifndef DEMO
71 static int qsnd[QSND_NUM];
72 #endif
74 static char *main_txt[]={
75 "NEW GAME","LOAD GAME","SAVE GAME","OPTIONS","EXIT"
76 },*opt_txt[]={
77 "RESTART","VOLUME","BRIGHTNESS","MUSIC","FULLSCREEN:"
78 },*ngplr_txt[]={
79 "ONE PLAYER","TWO PLAYERS"
80 },*ngdm_txt[]={
81 "COOPERATIVE","DEATHMATCH"
82 },*vol_txt[]={
83 "SOUND","MUSIC"
84 },*plcolor_txt[]={
85 "FIRST","SECOND"
86 },*gamma_txt[]={
87 ""
88 };
90 static byte main_typ[]={
91 NEWGAME,LOADGAME,SAVEGAME,OPTIONS,QUITGAME
92 },ngplr_typ[]={
93 PLR1,PLR2
94 },ngdm_typ[]={
95 COOP,DM
96 },opt_typ[]={
97 ENDGAME,VOLUME,GAMMA,MUSIC,INTERP
98 },quit_typ[]={
99 QUIT,CANCEL
100 },endgm_typ[]={
101 ENDGM,CANCEL
102 },vol_typ[]={
103 SVOLM,MVOLM
104 },plcolor_typ[]={
105 PL1CM,PL2CM
106 },gamma_typ[]={
107 GAMMAM
108 },load_typ[]={
109 LOAD,LOAD,LOAD,LOAD,LOAD,LOAD,LOAD
110 },save_typ[]={
111 SAVE,SAVE,SAVE,SAVE,SAVE,SAVE,SAVE
112 };
114 menu_t main_mnu={
115 MENU,5,0,80,"MENU",main_txt,main_typ
116 },opt_mnu={
117 MENU,5,0,75,"OPTIONS",opt_txt,opt_typ
118 },ngplr_mnu={
119 MENU,2,0,90,"NEW GAME",ngplr_txt,ngplr_typ
120 },ngdm_mnu={
121 MENU,2,0,90,"GAME TYPE",ngdm_txt,ngdm_typ
122 },vol_mnu={
123 MENU,2,0,40,"VOLUME",vol_txt,vol_typ
124 },plcolor_mnu={
125 MENU,2,0,90,"COLOR",plcolor_txt,plcolor_typ
126 },gamma_mnu={
127 MENU,1,0,85,"BRIGHTNESS",gamma_txt,gamma_typ
128 },load_mnu={
129 MENU,7,0,85,"LOAD GAME",NULL,load_typ
130 },save_mnu={
131 MENU,7,0,85,"SAVE GAME",NULL,save_typ
132 },quit1_msg={
133 MSG,0,0,0,"ARE YOU SURE?",NULL,quit_typ
134 },quit2_msg={
135 MSG,0,0,0,"ARE YOU SURE?",NULL,quit_typ
136 },quit3_msg={
137 MSG,0,0,0,"ARE YOU SURE?",NULL,quit_typ
138 },endgm_msg={
139 MSG,0,0,0,"RESTART LEVEL?",NULL,endgm_typ
140 };
142 static menu_t *qmsg[3]={&quit1_msg,&quit2_msg,&quit3_msg};
144 menu_t *mnu=NULL;
145 byte gm_redraw=0;
147 short lastkey=0;
148 static void *csnd1,*csnd2,*msnd1,*msnd2,*msnd3,*msnd4,*msnd5,*msnd6;
149 static int movsndt=0;
150 static byte cbuf[32];
152 static snd_t *voc=NULL;
153 static int voc_ch=0;
155 static void GMV_stop (void) {
156 if(voc) {
157 if(voc_ch) {S_stop(voc_ch);voc_ch=0;}
158 free(voc);voc=NULL;
162 void GMV_say (char *nm) {
163 int r,len;
164 snd_t *p;
165 byte *d;
167 if((r=F_findres(nm))==-1) return;
168 if(!(p=malloc((len=F_getreslen(r))+16))) return;
169 p->len=len;p->rate=11000;
170 p->lstart=p->llen=0;
171 GMV_stop();
172 F_loadres(r,p+1,0,len);
173 for(d=(byte*)(p+1);len;--len,++d) *d^=128;
174 voc=p;
175 voc_ch=S_play(voc,-1,1024,255);
178 static void GM_set (menu_t *m) {
179 mnu=m;gm_redraw=1;
180 if(g_st==GS_GAME) {
181 //V_setrect(0,SCRW,0,SCRH);V_clr(0,SCRW,0,SCRH,0);//V_setrect(0,320,0,200);V_clr(0,320,0,200,0);
182 //if(_2pl) {V_setrect(SCRW-120,120,0,SCRH);w_o=0;Z_clrst();w_o=SCRH/2;Z_clrst();}//if(_2pl) {V_setrect(200,120,0,200);w_o=0;Z_clrst();w_o=100;Z_clrst();}
183 //else {V_setrect(SCRW-120,120,0,SCRH);w_o=0;Z_clrst();}//else {V_setrect(200,120,50,100);w_o=50;Z_clrst();}
184 //pl1.drawst=pl2.drawst=0xFF;V_setrect(0,SCRW,0,SCRH);//V_setrect(0,320,0,200);
188 void G_code (void) {
189 void *s;
190 s=csnd2;
191 if(memcmp(cbuf+32-5,"IDDQD",5)==0) {
192 PL_hit(&pl1,400,0,HIT_SOME);
193 if(_2pl) PL_hit(&pl2,400,0,HIT_SOME);
194 s=csnd1;
195 }else if(memcmp(cbuf+32-4,"TANK",4)==0) {
196 pl1.life=pl1.armor=200;pl1.drawst|=PL_DRAWARMOR|PL_DRAWLIFE;
197 if(_2pl) {pl2.life=pl2.armor=200;pl2.drawst|=PL_DRAWARMOR|PL_DRAWLIFE;}
198 }else if(memcmp(cbuf+32-8,"BULLFROG",8)==0) {
199 PL_JUMP=(PL_JUMP==10)?20:10;
200 }else if(memcmp(cbuf+32-8,"FORMULA1",8)==0) {
201 PL_RUN=(PL_RUN==8)?24:8;
202 }else if(memcmp(cbuf+32-5,"RAMBO",5)==0) {
203 pl1.ammo=pl1.shel=pl1.rock=pl1.cell=pl1.fuel=30000;
204 pl1.wpns=0x7FF;pl1.drawst|=PL_DRAWWPN|PL_DRAWKEYS;
205 pl1.keys=0x70;
206 if(_2pl) {
207 pl2.ammo=pl2.shel=pl2.rock=pl2.cell=pl1.fuel=30000;
208 pl2.wpns=0x7FF;pl2.drawst|=PL_DRAWWPN|PL_DRAWKEYS;
209 pl2.keys=0x70;
211 }else if(memcmp(cbuf+32-5,"UJHTW",5)==0) {
212 p_immortal=!p_immortal;
213 }else if(memcmp(cbuf+32-9,",TKSQJHTK",9)==0) {
214 p_fly=!p_fly;
215 }else if(memcmp(cbuf+32-6,"CBVCBV",6)==0) {
216 SW_cheat_open();
217 }else if(memcmp(cbuf+32-7,"GOODBYE",7)==0) {
218 g_exit=1;
219 }else if(memcmp(cbuf+32-9,"GJITKYF",7)==0) {
220 if(cbuf[30]>='0' && cbuf[30]<='9' && cbuf[31]>='0' && cbuf[31]<='9') {
221 g_map=(cbuf[30]=='0')?0:(cbuf[30]-'0')*10;
222 g_map+=(cbuf[31]=='0')?0:(cbuf[31]-'0');
223 G_start();
225 }else return;
226 memset(cbuf,0,32);
227 Z_sound(s,128);
230 static void GM_command (int c) {
231 switch(c) {
232 case CANCEL:
233 GM_set(NULL);break;
234 case INTERP:
235 R_toggle_fullscreen();
236 GM_set(mnu);
237 break;
238 case MUSIC:
239 F_freemus();
240 F_nextmus(g_music);
241 F_loadmus(g_music);
242 S_startmusic(music_time*2);
243 GM_set(mnu);
244 break;
245 case NEWGAME:
246 GMV_say("_NEWGAME");
247 GM_set(&ngplr_mnu);break;
248 case PLR2:
249 GMV_say("_2PLAYER");
250 GM_set(&ngdm_mnu);break;
251 case PLR1:
252 GMV_say("_1PLAYER");
253 ngdm_mnu.cur=0;
254 case COOP: case DM:
255 if(c==COOP) GMV_say("_COOP");
256 else if(c==DM) GMV_say("_DM");
257 if(c!=PLR1) {GM_set(&plcolor_mnu);break;}
258 case PLCEND:
259 _2pl=ngplr_mnu.cur;
260 g_dm=ngdm_mnu.cur;
261 g_map=(_warp)?_warp:1;
262 PL_reset();
263 if(_2pl) {
264 pl1.color=pcolortab[p1color];
265 pl2.color=pcolortab[p2color];
266 }else pl1.color=0x70;
267 G_start();
268 GM_set(NULL);break;
269 case OPTIONS:
270 GMV_say("_RAZNOE");
271 GM_set(&opt_mnu);break;
272 case LOADGAME:
273 GMV_say("_OLDGAME");
274 F_getsavnames();GM_set(&load_mnu);break;
275 case SAVEGAME:
276 if(g_st!=GS_GAME) break;
277 GMV_say("_SAVEGAM");
278 F_getsavnames();GM_set(&save_mnu);break;
279 case SAVE:
280 input=1;memcpy(ibuf,savname[save_mnu.cur],24);icur=strlen(ibuf);
281 GM_set(mnu);break;
282 case LOAD:
283 if(!savok[load_mnu.cur]) break;
284 load_game(load_mnu.cur);
285 GM_set(NULL);break;
286 case VOLUME:
287 GMV_say("_VOLUME");
288 GM_set(&vol_mnu);break;
289 case GAMMA:
290 GMV_say("_GAMMA");
291 GM_set(&gamma_mnu);break;
292 case QUITGAME:
293 GMV_say((rand()&1)?"_EXIT1":"_EXIT2");
294 GM_set(qmsg[myrand(3)]);break;
295 case ENDGAME:
296 if(g_st!=GS_GAME) break;
297 GMV_say("_RESTART");
298 GM_set(&endgm_msg);break;
299 case QUIT:
300 F_freemus();
301 GMV_stop();
302 #ifndef DEMO
303 c=Z_sound(M_lock(qsnd[myrand(QSND_NUM)]),256);//for(c=(Z_sound(M_lock(qsnd[random2(QSND_NUM)]),256)+9)<<16,timer=0;timer<c;);
304 S_wait();
305 #endif
306 ERR_quit();break;
307 case ENDGM:
308 PL_reset();G_start();
309 GM_set(NULL);break;
310 case PL1CM:
311 if(--p1color<0) p1color=PCOLORN-1; break;
312 case PL1CP:
313 if(++p1color>=PCOLORN) p1color=0; break;
314 case PL2CM:
315 if(--p2color<0) p2color=PCOLORN-1; break;
316 case PL2CP:
317 if(++p2color>=PCOLORN) p2color=0; break;
318 case SVOLM:
319 S_volume(snd_vol-8);break;
320 case SVOLP:
321 S_volume(snd_vol+8);break;
322 case MVOLM:
323 S_volumemusic(mus_vol-8);break;
324 case MVOLP:
325 S_volumemusic(mus_vol+8);break;
326 case GAMMAM:
327 R_setgamma(R_getgamma() - 1);
328 break;
329 case GAMMAP:
330 R_setgamma(R_getgamma() + 1);
331 break;
335 struct {
336 int keysym;
337 byte ch;
338 } keychar[] = {
339 {SDLK_SPACE, ' '},
340 {SDLK_0, '0'},
341 {SDLK_1, '1'},
342 {SDLK_2, '2'},
343 {SDLK_3, '3'},
344 {SDLK_4, '4'},
345 {SDLK_5, '5'},
346 {SDLK_6, '6'},
347 {SDLK_7, '7'},
348 {SDLK_8, '8'},
349 {SDLK_9, '9'},
350 {SDLK_UNDERSCORE, '_'},
351 {SDLK_a, 'A'},
352 {SDLK_b, 'B'},
353 {SDLK_c, 'C'},
354 {SDLK_d, 'D'},
355 {SDLK_e, 'E'},
356 {SDLK_f, 'F'},
357 {SDLK_g, 'G'},
358 {SDLK_h, 'H'},
359 {SDLK_i, 'I'},
360 {SDLK_j, 'J'},
361 {SDLK_k, 'K'},
362 {SDLK_l, 'L'},
363 {SDLK_m, 'M'},
364 {SDLK_n, 'N'},
365 {SDLK_o, 'O'},
366 {SDLK_p, 'P'},
367 {SDLK_q, 'Q'},
368 {SDLK_r, 'R'},
369 {SDLK_s, 'S'},
370 {SDLK_t, 'T'},
371 {SDLK_u, 'U'},
372 {SDLK_v, 'V'},
373 {SDLK_w, 'W'},
374 {SDLK_x, 'X'},
375 {SDLK_y, 'Y'},
376 {SDLK_z, 'Z'},
377 {SDLK_COMMA,','},
378 {0}
379 };
381 static byte get_keychar (int keysym) {
382 int i = 0;
383 while (keychar[i].keysym) {
384 if (keychar[i].keysym == keysym) return keychar[i].ch;
385 i++;
387 return 0;
390 static void shot (void) {
391 /*
392 static int num=1;
393 char fn[100];//...
394 #ifndef WIN32
395 char *e = getenv("HOME");
396 strncpy(fn, e, 60);
397 sprintf(&fn[strlen(fn)],"/.doom2d-rembo",num);
398 mkdir(fn, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
399 sprintf(&fn[strlen(fn)],"/shot%04d.bmp",num);
400 #else
401 sprintf(fn,"shot%04d.bmp",num);
402 #endif
403 SDL_SaveBMP(screen, fn);
404 ++num;
405 */
408 int GM_act (void) {
409 byte c;
411 if(mnu==&plcolor_mnu) {
412 if(*(++panimp)==0) panimp=panim;
413 GM_set(mnu);
415 if(movsndt>0) --movsndt; else movsndt=0;
416 if(g_st==GS_TITLE) if(!mnu) if(lastkey) {
417 GM_set(&main_mnu);Z_sound(msnd3,128);
418 lastkey=0;
419 return 1;
421 if(input) switch(lastkey) {
422 case SDLK_RETURN: case SDLK_KP_ENTER://case 0x1C: case 0x9C:
423 F_savegame(save_mnu.cur,ibuf);
424 input=0;GM_set(NULL);break;
425 case 1: input=0;GM_set(mnu);break;
426 case SDLK_BACKSPACE://case 0x0E:
427 if(icur) {ibuf[--icur]=0;GM_set(mnu);} break;
428 default:
429 if(icur>=23) break;
430 c=get_keychar(lastkey);//c=keychar[(keys[0x2A] || keys[0x36])?1:0][lastkey];
431 if(!c) break;
432 ibuf[icur]=c;ibuf[++icur]=0;GM_set(mnu);
433 }else {
434 switch(lastkey) {
435 case SDLK_ESCAPE://case 1:
436 if(!mnu) {GM_set(&main_mnu);Z_sound(msnd3,128);}
437 else {GM_set(NULL);Z_sound(msnd4,128);}
438 break;
439 case SDLK_F5:
440 if(mnu) break;
441 Z_sound(msnd3,128);
442 GMV_say("_GAMMA");
443 GM_set(&gamma_mnu);break;
444 case SDLK_F4://case 0x3E:
445 if(mnu) break;
446 Z_sound(msnd3,128);
447 GMV_say("_VOLUME");
448 GM_set(&vol_mnu);break;
449 case SDLK_F2://case 0x3C:
450 if(mnu) break;
451 if(g_st!=GS_GAME) break;
452 Z_sound(msnd3,128);
453 F_getsavnames();GM_set(&save_mnu);break;
454 case SDLK_F3://case 0x3D:
455 if(mnu) break;
456 Z_sound(msnd3,128);
457 F_getsavnames();GM_set(&load_mnu);break;
458 case SDLK_F10://case 0x44:
459 if(mnu) break;
460 Z_sound(msnd3,128);
461 GM_command(QUITGAME);break;
462 case SDLK_UP: case SDLK_KP8://case 0x48: case 0xC8:
463 if(!mnu) break;
464 if(mnu->type!=MENU) break;
465 if(--mnu->cur<0) mnu->cur=mnu->n-1;
466 GM_set(mnu);
467 Z_sound(msnd1,128);break;
468 case SDLK_DOWN: case SDLK_KP5: case SDLK_KP2://case 0x50: case 0xD0: case 0x4C:
469 if(!mnu) break;
470 if(mnu->type!=MENU) break;
471 if(++mnu->cur>=mnu->n) mnu->cur=0;
472 GM_set(mnu);
473 Z_sound(msnd1,128);break;
474 case SDLK_LEFT: case SDLK_RIGHT: case SDLK_KP4: case SDLK_KP6://case 0x4B: case 0x4D: case 0xCB: case 0xCD:
475 if(!mnu) break;
476 if(mnu->type!=MENU) break;
477 if(mnu->t[mnu->cur]<SVOLM) break;
478 GM_command(mnu->t[mnu->cur]+((lastkey==SDLK_LEFT || lastkey==SDLK_KP4)?0:1));//GM_command(mnu->t[mnu->cur]+((lastkey==0x4B || lastkey==0xCB)?0:1));
479 GM_set(mnu);
480 if(!movsndt) movsndt=Z_sound((lastkey==SDLK_LEFT || lastkey==SDLK_KP4)?msnd5:msnd6,255);//if(!movsndt) movsndt=Z_sound((lastkey==0x4B || lastkey==0xCB)?msnd5:msnd6,255);
481 break;
482 case SDLK_RETURN: case SDLK_SPACE: case SDLK_KP_ENTER://case 0x1C: case 0x39: case 0x9C:
483 if(!mnu) break;
484 if(mnu->type!=MENU) break;
485 if(mnu->t[mnu->cur]>=PL1CM) {
486 Z_sound(msnd2,128);
487 GM_command(PLCEND);
488 break;
490 if(mnu->t[mnu->cur]>=SVOLM) break;
491 Z_sound(msnd2,128);
492 GM_command(mnu->t[mnu->cur]);
493 break;
494 case SDLK_y://case 0x15:
495 if(!mnu) break;
496 if(mnu->type!=MSG) break;
497 Z_sound(msnd3,128);
498 GM_command(mnu->t[0]);
499 break;
500 case SDLK_n://case 0x31:
501 if(!mnu) break;
502 if(mnu->type!=MSG) break;
503 Z_sound(msnd4,128);
504 GM_command(mnu->t[1]);
505 break;
506 case SDLK_F1://case 0x3B:
507 if(shot_vga) {shot();Z_sound(msnd4,128);}
508 break;
511 lastkey=0;
512 return((mnu)?1:0);
515 static void G_keyf (int k, int press) {
516 int i;
518 lastkey=k;
519 if(!_2pl || cheat) {
520 for(i=0;i<31;++i) cbuf[i]=cbuf[i+1];
521 cbuf[31]=get_keychar(k);
525 void GM_init (void) {
526 #ifndef DEMO
527 int i;
528 static char nm[QSND_NUM][6]={
529 "CYBSIT","KNTDTH","MNPAIN","PEPAIN","SLOP","MANSIT","BOSPN","VILACT",
530 "PLFALL","BGACT","BGDTH2","POPAIN","SGTATK","VILDTH"
531 };
532 char s[8];
534 s[0]='D';s[1]='S';
535 for(i=0;i<QSND_NUM;++i) {
536 memcpy(s+2,nm[i],6);
537 qsnd[i]=F_getresid(s);
539 #endif
540 csnd1=Z_getsnd("HAHA1");
541 csnd2=Z_getsnd("RADIO");
542 msnd1=Z_getsnd("PSTOP");
543 msnd2=Z_getsnd("PISTOL");
544 msnd3=Z_getsnd("SWTCHN");
545 msnd4=Z_getsnd("SWTCHX");
546 msnd5=Z_getsnd("SUDI");
547 msnd6=Z_getsnd("TUDI");
548 K_setkeyproc(G_keyf);