DEADSOFTWARE

3d797fc944cbf019c0df7addc2153ce89118fbf9
[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 "sound.h"
31 #include "view.h"
32 #include "player.h"
33 #include "switch.h"
34 #include "menu.h"
35 #include "misc.h"
36 #include "render.h"
37 #include "config.h"
38 #include "game.h"
39 #include "player.h"
40 #include "sound.h"
41 #include "music.h"
42 #include "input.h"
44 #include <sys/stat.h>
46 #define QSND_NUM 14
48 enum{HIT100,ARMOR,JUMP,WPNS,IMMORTAL,SPEED,OPEN,EXIT};
50 static byte panim[] = "BBDDAACCDDAABBDDAACCDDAABBDDAACCDDAAEEEEEFEFEFEFEFEFEFEFEFEFEEEEE";
51 byte *panimp = panim;
52 byte _warp;
54 byte pcolortab[PCOLORN] = {
55 0x18, 0x20, 0x40, 0x58, 0x60, 0x70, 0x80, 0xB0, 0xC0, 0xD0
56 };
57 int p1color = 5;
58 int p2color = 4;
60 char ibuf[24];
61 byte input=0;
62 static int icur;
64 enum{MENU,MSG};
65 enum{CANCEL,NEWGAME,LOADGAME,SAVEGAME,OPTIONS,QUITGAME,QUIT,ENDGAME,ENDGM,
66 PLR1,PLR2,COOP,DM,VOLUME,GAMMA,LOAD,SAVE,PLCOLOR,PLCEND,MUSIC,INTERP,
67 SVOLM,SVOLP,MVOLM,MVOLP,GAMMAM,GAMMAP,PL1CM,PL1CP,PL2CM,PL2CP};
69 #ifndef DEMO
70 static int qsnd[QSND_NUM];
71 #endif
73 static char *main_txt[]={
74 "NEW GAME","LOAD GAME","SAVE GAME","OPTIONS","EXIT"
75 },*opt_txt[]={
76 "RESTART","VOLUME","BRIGHTNESS","MUSIC","FULLSCREEN:"
77 },*ngplr_txt[]={
78 "ONE PLAYER","TWO PLAYERS"
79 },*ngdm_txt[]={
80 "COOPERATIVE","DEATHMATCH"
81 },*vol_txt[]={
82 "SOUND","MUSIC"
83 },*plcolor_txt[]={
84 "FIRST","SECOND"
85 },*gamma_txt[]={
86 ""
87 };
89 static byte main_typ[]={
90 NEWGAME,LOADGAME,SAVEGAME,OPTIONS,QUITGAME
91 },ngplr_typ[]={
92 PLR1,PLR2
93 },ngdm_typ[]={
94 COOP,DM
95 },opt_typ[]={
96 ENDGAME,VOLUME,GAMMA,MUSIC,INTERP
97 },quit_typ[]={
98 QUIT,CANCEL
99 },endgm_typ[]={
100 ENDGM,CANCEL
101 },vol_typ[]={
102 SVOLM,MVOLM
103 },plcolor_typ[]={
104 PL1CM,PL2CM
105 },gamma_typ[]={
106 GAMMAM
107 },load_typ[]={
108 LOAD,LOAD,LOAD,LOAD,LOAD,LOAD,LOAD
109 },save_typ[]={
110 SAVE,SAVE,SAVE,SAVE,SAVE,SAVE,SAVE
111 };
113 menu_t main_mnu={
114 MENU,5,0,80,"MENU",main_txt,main_typ
115 },opt_mnu={
116 MENU,5,0,75,"OPTIONS",opt_txt,opt_typ
117 },ngplr_mnu={
118 MENU,2,0,90,"NEW GAME",ngplr_txt,ngplr_typ
119 },ngdm_mnu={
120 MENU,2,0,90,"GAME TYPE",ngdm_txt,ngdm_typ
121 },vol_mnu={
122 MENU,2,0,40,"VOLUME",vol_txt,vol_typ
123 },plcolor_mnu={
124 MENU,2,0,90,"COLOR",plcolor_txt,plcolor_typ
125 },gamma_mnu={
126 MENU,1,0,85,"BRIGHTNESS",gamma_txt,gamma_typ
127 },load_mnu={
128 MENU,7,0,85,"LOAD GAME",NULL,load_typ
129 },save_mnu={
130 MENU,7,0,85,"SAVE GAME",NULL,save_typ
131 },quit1_msg={
132 MSG,0,0,0,"ARE YOU SURE?",NULL,quit_typ
133 },quit2_msg={
134 MSG,0,0,0,"ARE YOU SURE?",NULL,quit_typ
135 },quit3_msg={
136 MSG,0,0,0,"ARE YOU SURE?",NULL,quit_typ
137 },endgm_msg={
138 MSG,0,0,0,"RESTART LEVEL?",NULL,endgm_typ
139 };
141 static menu_t *qmsg[3]={&quit1_msg,&quit2_msg,&quit3_msg};
143 menu_t *mnu=NULL;
144 byte gm_redraw=0;
146 short lastkey=0;
147 static void *csnd1,*csnd2,*msnd1,*msnd2,*msnd3,*msnd4,*msnd5,*msnd6;
148 static int movsndt=0;
149 static byte cbuf[32];
151 static snd_t *voc=NULL;
152 static int voc_ch=0;
154 static void GMV_stop (void) {
155 if(voc) {
156 if(voc_ch) {S_stop(voc_ch);voc_ch=0;}
157 free(voc);voc=NULL;
161 void GMV_say (char *nm) {
162 int r,len;
163 snd_t *p;
164 byte *d;
166 if((r=F_findres(nm))==-1) return;
167 if(!(p=malloc((len=F_getreslen(r))+16))) return;
168 p->len=len;p->rate=11000;
169 p->lstart=p->llen=0;
170 GMV_stop();
171 F_loadres(r,p+1,0,len);
172 for(d=(byte*)(p+1);len;--len,++d) *d^=128;
173 voc=p;
174 voc_ch=S_play(voc,-1,1024,255);
177 static void GM_set (menu_t *m) {
178 mnu=m;gm_redraw=1;
179 if(g_st==GS_GAME) {
180 //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);
181 //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();}
182 //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();}
183 //pl1.drawst=pl2.drawst=0xFF;V_setrect(0,SCRW,0,SCRH);//V_setrect(0,320,0,200);
187 void G_code (void) {
188 void *s;
189 s=csnd2;
190 if(memcmp(cbuf+32-5,"IDDQD",5)==0) {
191 PL_hit(&pl1,400,0,HIT_SOME);
192 if(_2pl) PL_hit(&pl2,400,0,HIT_SOME);
193 s=csnd1;
194 }else if(memcmp(cbuf+32-4,"TANK",4)==0) {
195 pl1.life=pl1.armor=200;pl1.drawst|=PL_DRAWARMOR|PL_DRAWLIFE;
196 if(_2pl) {pl2.life=pl2.armor=200;pl2.drawst|=PL_DRAWARMOR|PL_DRAWLIFE;}
197 }else if(memcmp(cbuf+32-8,"BULLFROG",8)==0) {
198 PL_JUMP=(PL_JUMP==10)?20:10;
199 }else if(memcmp(cbuf+32-8,"FORMULA1",8)==0) {
200 PL_RUN=(PL_RUN==8)?24:8;
201 }else if(memcmp(cbuf+32-5,"RAMBO",5)==0) {
202 pl1.ammo=pl1.shel=pl1.rock=pl1.cell=pl1.fuel=30000;
203 pl1.wpns=0x7FF;pl1.drawst|=PL_DRAWWPN|PL_DRAWKEYS;
204 pl1.keys=0x70;
205 if(_2pl) {
206 pl2.ammo=pl2.shel=pl2.rock=pl2.cell=pl1.fuel=30000;
207 pl2.wpns=0x7FF;pl2.drawst|=PL_DRAWWPN|PL_DRAWKEYS;
208 pl2.keys=0x70;
210 }else if(memcmp(cbuf+32-5,"UJHTW",5)==0) {
211 p_immortal=!p_immortal;
212 }else if(memcmp(cbuf+32-9,",TKSQJHTK",9)==0) {
213 p_fly=!p_fly;
214 }else if(memcmp(cbuf+32-6,"CBVCBV",6)==0) {
215 SW_cheat_open();
216 }else if(memcmp(cbuf+32-7,"GOODBYE",7)==0) {
217 g_exit=1;
218 }else if(memcmp(cbuf+32-9,"GJITKYF",7)==0) {
219 if(cbuf[30]>='0' && cbuf[30]<='9' && cbuf[31]>='0' && cbuf[31]<='9') {
220 g_map=(cbuf[30]=='0')?0:(cbuf[30]-'0')*10;
221 g_map+=(cbuf[31]=='0')?0:(cbuf[31]-'0');
222 G_start();
224 }else return;
225 memset(cbuf,0,32);
226 Z_sound(s,128);
229 static void GM_command (int c) {
230 switch(c) {
231 case CANCEL:
232 GM_set(NULL);break;
233 case INTERP:
234 R_toggle_fullscreen();
235 GM_set(mnu);
236 break;
237 case MUSIC:
238 F_freemus();
239 F_nextmus(g_music);
240 F_loadmus(g_music);
241 S_startmusic(music_time*2);
242 GM_set(mnu);
243 break;
244 case NEWGAME:
245 GMV_say("_NEWGAME");
246 GM_set(&ngplr_mnu);break;
247 case PLR2:
248 GMV_say("_2PLAYER");
249 GM_set(&ngdm_mnu);break;
250 case PLR1:
251 GMV_say("_1PLAYER");
252 ngdm_mnu.cur=0;
253 case COOP: case DM:
254 if(c==COOP) GMV_say("_COOP");
255 else if(c==DM) GMV_say("_DM");
256 if(c!=PLR1) {GM_set(&plcolor_mnu);break;}
257 case PLCEND:
258 _2pl=ngplr_mnu.cur;
259 g_dm=ngdm_mnu.cur;
260 g_map=(_warp)?_warp:1;
261 PL_reset();
262 if(_2pl) {
263 pl1.color=pcolortab[p1color];
264 pl2.color=pcolortab[p2color];
265 }else pl1.color=0x70;
266 G_start();
267 GM_set(NULL);break;
268 case OPTIONS:
269 GMV_say("_RAZNOE");
270 GM_set(&opt_mnu);break;
271 case LOADGAME:
272 GMV_say("_OLDGAME");
273 F_getsavnames();GM_set(&load_mnu);break;
274 case SAVEGAME:
275 if(g_st!=GS_GAME) break;
276 GMV_say("_SAVEGAM");
277 F_getsavnames();GM_set(&save_mnu);break;
278 case SAVE:
279 input=1;memcpy(ibuf,savname[save_mnu.cur],24);icur=strlen(ibuf);
280 GM_set(mnu);break;
281 case LOAD:
282 if(!savok[load_mnu.cur]) break;
283 load_game(load_mnu.cur);
284 GM_set(NULL);break;
285 case VOLUME:
286 GMV_say("_VOLUME");
287 GM_set(&vol_mnu);break;
288 case GAMMA:
289 GMV_say("_GAMMA");
290 GM_set(&gamma_mnu);break;
291 case QUITGAME:
292 GMV_say((rand()&1)?"_EXIT1":"_EXIT2");
293 GM_set(qmsg[myrand(3)]);break;
294 case ENDGAME:
295 if(g_st!=GS_GAME) break;
296 GMV_say("_RESTART");
297 GM_set(&endgm_msg);break;
298 case QUIT:
299 F_freemus();
300 GMV_stop();
301 #ifndef DEMO
302 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;);
303 S_wait();
304 #endif
305 ERR_quit();break;
306 case ENDGM:
307 PL_reset();G_start();
308 GM_set(NULL);break;
309 case PL1CM:
310 if(--p1color<0) p1color=PCOLORN-1; break;
311 case PL1CP:
312 if(++p1color>=PCOLORN) p1color=0; break;
313 case PL2CM:
314 if(--p2color<0) p2color=PCOLORN-1; break;
315 case PL2CP:
316 if(++p2color>=PCOLORN) p2color=0; break;
317 case SVOLM:
318 S_volume(snd_vol-8);break;
319 case SVOLP:
320 S_volume(snd_vol+8);break;
321 case MVOLM:
322 S_volumemusic(mus_vol-8);break;
323 case MVOLP:
324 S_volumemusic(mus_vol+8);break;
325 case GAMMAM:
326 R_setgamma(R_getgamma() - 1);
327 break;
328 case GAMMAP:
329 R_setgamma(R_getgamma() + 1);
330 break;
334 struct {
335 int keysym;
336 byte ch;
337 } keychar[] = {
338 {KEY_SPACE, ' '},
339 {KEY_0, '0'},
340 {KEY_1, '1'},
341 {KEY_2, '2'},
342 {KEY_3, '3'},
343 {KEY_4, '4'},
344 {KEY_5, '5'},
345 {KEY_6, '6'},
346 {KEY_7, '7'},
347 {KEY_8, '8'},
348 {KEY_9, '9'},
349 //{KEY_UNDERSCORE, '_'},
350 {KEY_A, 'A'},
351 {KEY_B, 'B'},
352 {KEY_C, 'C'},
353 {KEY_D, 'D'},
354 {KEY_E, 'E'},
355 {KEY_F, 'F'},
356 {KEY_G, 'G'},
357 {KEY_H, 'H'},
358 {KEY_I, 'I'},
359 {KEY_J, 'J'},
360 {KEY_K, 'K'},
361 {KEY_L, 'L'},
362 {KEY_M, 'M'},
363 {KEY_N, 'N'},
364 {KEY_O, 'O'},
365 {KEY_P, 'P'},
366 {KEY_Q, 'Q'},
367 {KEY_R, 'R'},
368 {KEY_S, 'S'},
369 {KEY_T, 'T'},
370 {KEY_U, 'U'},
371 {KEY_V, 'V'},
372 {KEY_W, 'W'},
373 {KEY_X, 'X'},
374 {KEY_Y, 'Y'},
375 {KEY_Z, 'Z'},
376 {KEY_COMMA,','},
377 {0}
378 };
380 static byte get_keychar (int keysym) {
381 int i = 0;
382 while (keychar[i].keysym) {
383 if (keychar[i].keysym == keysym) return keychar[i].ch;
384 i++;
386 return 0;
389 static void shot (void) {
390 /*
391 static int num=1;
392 char fn[100];//...
393 #ifndef WIN32
394 char *e = getenv("HOME");
395 strncpy(fn, e, 60);
396 sprintf(&fn[strlen(fn)],"/.doom2d-rembo",num);
397 mkdir(fn, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
398 sprintf(&fn[strlen(fn)],"/shot%04d.bmp",num);
399 #else
400 sprintf(fn,"shot%04d.bmp",num);
401 #endif
402 SDL_SaveBMP(screen, fn);
403 ++num;
404 */
407 int GM_act (void) {
408 byte c;
410 if(mnu==&plcolor_mnu) {
411 if(*(++panimp)==0) panimp=panim;
412 GM_set(mnu);
414 if(movsndt>0) --movsndt; else movsndt=0;
415 if(g_st==GS_TITLE) if(!mnu) if(lastkey) {
416 GM_set(&main_mnu);Z_sound(msnd3,128);
417 lastkey=0;
418 return 1;
420 if (input) {
421 switch (lastkey) {
422 case KEY_RETURN:
423 case KEY_KP_ENTER:
424 F_savegame(save_mnu.cur, ibuf);
425 input = 0;
426 GM_set(NULL);
427 break;
428 case KEY_ESCAPE:
429 input = 0;
430 GM_set(mnu);
431 break;
432 case KEY_BACKSPACE:
433 if (icur) {
434 icur -= 1;
435 ibuf[icur] = 0;
436 GM_set(mnu);
438 break;
439 default:
440 if (icur < 23) {
441 c = get_keychar(lastkey);
442 if (c != 0) {
443 ibuf[icur] = c;
444 icur += 1;
445 ibuf[icur] = 0;
446 GM_set(mnu);
449 break;
451 } else {
452 switch (lastkey) {
453 case KEY_ESCAPE:
454 if (mnu == NULL) {
455 GM_set(&main_mnu);
456 Z_sound(msnd3, 128);
457 } else {
458 GM_set(NULL);
459 Z_sound(msnd4, 128);
461 break;
462 case KEY_F5:
463 if (mnu == NULL) {
464 Z_sound(msnd3, 128);
465 GMV_say("_GAMMA");
466 GM_set(&gamma_mnu);
468 break;
469 case KEY_F4:
470 if (mnu == NULL) {
471 Z_sound(msnd3, 128);
472 GMV_say("_VOLUME");
473 GM_set(&vol_mnu);
475 break;
476 case KEY_F2:
477 if (mnu == NULL && g_st == GS_GAME) {
478 Z_sound(msnd3, 128);
479 F_getsavnames();
480 GM_set(&save_mnu);
482 break;
483 case KEY_F3:
484 if (mnu == NULL) {
485 Z_sound(msnd3, 128);
486 F_getsavnames();
487 GM_set(&load_mnu);
489 break;
490 case KEY_F10:
491 if (mnu == NULL) {
492 Z_sound(msnd3, 128);
493 GM_command(QUITGAME);
495 break;
496 case KEY_UP:
497 case KEY_KP_8:
498 if (mnu != NULL && mnu->type == MENU) {
499 mnu->cur -= 1;
500 if (mnu->cur < 0) {
501 mnu->cur = mnu->n - 1;
503 GM_set(mnu);
504 Z_sound(msnd1, 128);
506 break;
507 case KEY_DOWN:
508 case KEY_KP_5:
509 case KEY_KP_2:
510 if (mnu != NULL && mnu->type == MENU) {
511 mnu->cur += 1;
512 if (mnu->cur >= mnu->n) {
513 mnu->cur = 0;
515 GM_set(mnu);
516 Z_sound(msnd1, 128);
518 break;
519 case KEY_LEFT:
520 case KEY_RIGHT:
521 case KEY_KP_4:
522 case KEY_KP_6:
523 if (mnu != NULL && mnu->type == MENU && mnu->t[mnu->cur] >= SVOLM) {
524 GM_command(mnu->t[mnu->cur] + (lastkey == KEY_LEFT || lastkey == KEY_KP_4));
525 GM_set(mnu);
526 if (!movsndt) {
527 movsndt = Z_sound(lastkey == KEY_LEFT || lastkey == KEY_KP_4 ? msnd5 : msnd6, 255);
530 break;
531 case KEY_RETURN:
532 case KEY_SPACE:
533 case KEY_KP_ENTER:
534 if (mnu != NULL && mnu->type == MENU) {
535 if (mnu->t[mnu->cur] >= PL1CM) {
536 Z_sound(msnd2, 128);
537 GM_command(PLCEND);
538 break;
539 } else if (mnu->t[mnu->cur] < SVOLM) {
540 Z_sound(msnd2,128);
541 GM_command(mnu->t[mnu->cur]);
544 break;
545 case KEY_Y:
546 if (mnu != NULL && mnu->type == MSG) {
547 Z_sound(msnd3, 128);
548 GM_command(mnu->t[0]);
550 break;
551 case KEY_N:
552 if (mnu != NULL && mnu->type == MSG) {
553 Z_sound(msnd4, 128);
554 GM_command(mnu->t[1]);
556 break;
557 case KEY_F1:
558 if (shot_vga) {
559 shot();
560 Z_sound(msnd4, 128);
562 break;
565 lastkey = KEY_UNKNOWN;
566 return mnu ? 1 : 0;
569 void G_keyf (int key, int down) {
570 int i;
571 if (down) {
572 lastkey = key;
573 if (!_2pl || cheat) {
574 for (i = 0; i < 31; ++i) {
575 cbuf[i] = cbuf[i + 1];
577 cbuf[31] = get_keychar(key);
582 void GM_init (void) {
583 #ifndef DEMO
584 int i;
585 static char nm[QSND_NUM][6]={
586 "CYBSIT","KNTDTH","MNPAIN","PEPAIN","SLOP","MANSIT","BOSPN","VILACT",
587 "PLFALL","BGACT","BGDTH2","POPAIN","SGTATK","VILDTH"
588 };
589 char s[8];
591 s[0]='D';s[1]='S';
592 for(i=0;i<QSND_NUM;++i) {
593 memcpy(s+2,nm[i],6);
594 qsnd[i]=F_getresid(s);
596 #endif
597 csnd1=Z_getsnd("HAHA1");
598 csnd2=Z_getsnd("RADIO");
599 msnd1=Z_getsnd("PSTOP");
600 msnd2=Z_getsnd("PISTOL");
601 msnd3=Z_getsnd("SWTCHN");
602 msnd4=Z_getsnd("SWTCHX");
603 msnd5=Z_getsnd("SUDI");
604 msnd6=Z_getsnd("TUDI");