source: abuse/tags/pd/macabuse/src/menu.c @ 49

Last change on this file since 49 was 49, checked in by Sam Hocevar, 12 years ago
  • Imported original public domain release, for future reference.
  • Property svn:keywords set to Id
File size: 22.6 KB
Line 
1#include "menu.hpp"
2#include "lisp.hpp"
3#include "game.hpp"
4#include "timing.hpp"
5#include "game.hpp"
6#include "id.hpp"
7#include "pmenu.hpp"
8#include "gui.hpp"
9#include "property.hpp"
10#include "dev.hpp"
11#include "clisp.hpp"
12#include "gamma.hpp"
13#include "dprint.hpp"
14#include "demo.hpp"
15#include "loadgame.hpp"
16#include "scroller.hpp"
17#include "netcfg.hpp"
18#include "key_cfg.hpp"
19#include "mono_cfg.hpp"
20#include <math.h>
21#include "sock.hpp"
22
23#ifdef __MAC__
24#include "hack.hpp"
25#else
26#include "../imlib/port/mac/hack.hpp"
27
28inline void MacKeyConfigMenu() { ; }
29inline void MacPreferences() { ; }
30#endif
31
32#include "macgame.hpp"
33
34extern net_protocol *prot;
35jwindow *volume_window=NULL;
36jwindow *macpref_window=NULL;
37jwindow *key_window=NULL;
38extern int confirm_quit();
39extern int registered;
40
41//percent is 0..256
42void tint_area(int x1, int y1, int x2, int y2, int r_to, int g_to, int b_to, int percent)
43{
44  int x,y;
45  short cx1,cy1,cx2,cy2;
46  screen->get_clip(cx1,cy1,cx2,cy2);
47  if (x1<cx1) x1=cx1;
48  if (y1<cy1) y1=cy1;
49  if (x2>cx2) x2=cx2;
50  if (y2>cy2) y2=cy2;
51  if (x2<x1 || y2<y1) return ;
52
53  percent=256-percent;
54
55  for (y=y1;y<=y2;y++)
56  {
57    unsigned char *sl=screen->scan_line(y)+x1;
58    for (x=x1;x<=x2;x++,sl++)
59    {
60      unsigned char *paddr=(unsigned char *)pal->addr()+(*sl)*3;
61      unsigned char r=((*(paddr++))-r_to)*percent/256+r_to;
62      unsigned char g=((*(paddr++))-g_to)*percent/256+g_to;
63      unsigned char b=((*(paddr++))-b_to)*percent/256+b_to;
64      *sl=color_table->lookup_color((r)>>3,(g)>>3,(b)>>3);
65    }
66  }
67  screen->add_dirty(x1,y1,x2,y2); 
68}
69
70void darken_area(int x1, int y1, int x2, int y2, int amount)
71{
72  int x,y;
73  short cx1,cy1,cx2,cy2;
74  screen->get_clip(cx1,cy1,cx2,cy2);
75  if (x1<cx1) x1=cx1;
76  if (y1<cy1) y1=cy1;
77  if (x2>cx2) x2=cx2;
78  if (y2>cy2) y2=cy2;
79  if (x2<x1 || y2<y1) return ;
80
81  for (y=y1;y<=y2;y++)
82  {
83    unsigned char *sl=screen->scan_line(y)+x1;
84    for (x=x1;x<=x2;x++,sl++)
85    {
86      unsigned char *paddr=(unsigned char *)pal->addr()+(*sl)*3;
87      unsigned char r=(*(paddr++))*amount/256;
88      unsigned char g=(*(paddr++))*amount/256;
89      unsigned char b=(*(paddr++))*amount/256;
90      *sl=color_table->lookup_color((r)>>3,(g)>>3,(b)>>3);
91    }
92  }
93  screen->add_dirty(x1,y1,x2,y2);
94}
95
96void dark_wiget(int x1, int y1, int x2, int y2, int br, int dr, int amount)
97{
98  screen->add_dirty(x1,y1,x2,y2);
99  screen->line(x1,y1,x1,y2,br);
100  screen->line(x1+1,y1,x2,y1,br);
101  screen->line(x2,y1+1,x2,y2,dr);
102  screen->line(x1+1,y2,x2,y2,dr);
103  darken_area(x1+1,y1+1,x2-1,y2-1,amount); 
104}
105
106char *men_str(void *arg)
107{
108  switch (item_type(arg))
109  {
110    case L_STRING :
111    { return lstring_value(arg); } break;
112    case L_CONS_CELL :
113    { return lstring_value(CAR(arg)); } break;
114    default :
115    {
116      lprint(arg);
117      dprintf(" is not a valid menu option\n");
118      exit(0);
119    }
120  }
121  return NULL;
122}
123
124void main_menu();
125
126int menu(void *args, JCFont *font)             // reurns -1 on esc
127{
128  main_menu();
129  char *title=NULL;
130  if (!NILP(CAR(args)))
131    title=lstring_value(CAR(args));
132  Cell *def=lcar(lcdr(lcdr(args)));
133  args=CAR(CDR(args));
134
135  int options=list_length(args);
136  int mh=(font->height()+1)*options+10,maxw=0;
137
138  Cell *c=(Cell *)args;
139  for (;!NILP(c);c=CDR(c))
140  {
141    if (strlen(men_str(CAR(c)))>maxw)
142      maxw=strlen(men_str(CAR(c)));
143  }
144 
145  int mw=(font->width())*maxw+20;
146  int mx=screen->width()/2-mw/2,
147      my=screen->height()/2-mh/2;
148 
149
150  screen->add_dirty(mx,my,mx+mw-1,my+mh-1);
151
152  if (title)
153  {
154    int tl=strlen(title)*font->width();
155    int tx=screen->width()/2-tl/2;
156    dark_wiget(tx-2,my-font->height()-4,tx+tl+2,my-2,eh->medium_color(),eh->dark_color(),180);
157    font->put_string(screen,tx+1,my-font->height()-2,title,eh->bright_color());
158  }
159 
160  dark_wiget(mx,my,mx+mw-1,my+mh-1,eh->medium_color(),eh->dark_color(),200);
161
162
163  int y=my+5;
164  for (c=(Cell *)args;!NILP(c);c=CDR(c))
165  {
166    char *ms=men_str(CAR(c));
167    font->put_string(screen,mx+10+1,y+1,ms,eh->black());
168    font->put_string(screen,mx+10,y,ms,eh->bright_color());
169    y+=font->height()+1;
170  }
171 
172
173  eh->flush_screen();
174  event ev;
175  int choice=0,done=0;
176  int bh=font->height()+3;
177  image *save=new image(mw-2,bh);
178  int color=128,cdir=50;
179 
180  time_marker *last_color_time=NULL;
181  if (!NILP(def))
182    choice=lnumber_value(def);
183  do
184  {
185    eh->flush_screen();
186    if (eh->event_waiting())
187    {
188      eh->get_event(ev);
189      if (ev.type==EV_KEY)
190      {
191                                switch (ev.key)
192                                {
193                                  case JK_ESC :
194                                  { choice=-1; done=1; } break;
195                                  case JK_ENTER :
196                                  { done=1; } break;
197                                  case JK_DOWN :
198                                  { if (choice<options-1)
199                                    choice++;
200                                  else choice=0;
201                                  } break;
202                                  case JK_UP :
203                                  {
204                                    if (choice>0)
205                                    choice--;
206                                    else choice=options-1;
207                                  } break;                   
208                                }
209      } else if (ev.type==EV_MOUSE_BUTTON && ev.mouse_button)
210      {
211                                if (ev.mouse_move.x>mx && ev.mouse_move.x<mx+mw && ev.mouse_move.y>my &&
212                                    ev.mouse_move.y<my+mh)
213                                {
214                                  int msel=(ev.mouse_move.y-my)/(font->height()+1);
215                                  if (msel>=options) msel=options-1;
216                                  if (msel==choice)                    // clicked on already selected item, return it
217                                    done=1;
218                                  else choice=msel;                    // selects an item
219                                }
220      }
221    }
222
223    time_marker cur_time;
224    if (!last_color_time || (int)(cur_time.diff_time(last_color_time)*1000)>120)
225    {       
226      if (last_color_time)
227        delete last_color_time;
228      last_color_time=new time_marker;
229
230      int by1=(font->height()+1)*choice+my+5-2;
231      int by2=by1+bh-1;
232
233      screen->put_part(save,0,0,mx+1,by1,mx+mw-2,by2);
234      tint_area(mx+1,by1,mx+mw-2,by2,63,63,63,color);
235
236      char *cur=men_str(nth(choice,args));
237      font->put_string(screen,mx+10+1,by1+3,cur,eh->black());
238      font->put_string(screen,mx+10,by1+2,cur,eh->bright_color());
239      screen->rectangle(mx+1,by1,mx+mw-2,by2,eh->bright_color());
240
241      color+=cdir;
242
243      if (color<12 || color>256)
244      {
245                                cdir=-cdir;
246                                color+=cdir;
247      }
248      eh->flush_screen();
249      save->put_image(screen,mx+1,by1);
250    } else milli_wait(10);
251
252  } while (!done);
253  if (last_color_time)
254    delete last_color_time;
255  delete save;
256  the_game->draw(the_game->state==SCENE_STATE);
257
258  if (choice!=-1)
259  {
260    void *val=nth(choice,args);
261    if (item_type(val)==L_CONS_CELL)   // is there another value that the user want us to return?
262      return lnumber_value(lcdr(val)); 
263  }
264  return choice;
265}
266
267
268static void draw_vol(image *screen, int x1, int y1, int x2, int y2, int t, int max, int c1, int c2, int slider)
269{
270  int dx=x1+t*(x2-x1)/max;
271  if (t!=0)
272  {
273    cash.img(slider)->put_image(screen,x1,y1);   
274//    screen->bar(x1,y1,dx,y2,c1);
275  }
276  else dx--;
277
278  if (dx<x2)
279    screen->bar(dx+1,y1,x2,y2,c2);
280}
281
282static void draw_sfx_vol(int slider)
283{
284  draw_vol(volume_window->screen,16,75,99,88,sfx_volume,127,pal->find_closest(200,75,19),
285           pal->find_closest(40,0,0),slider);
286}
287
288static void draw_music_vol(int slider)
289{
290  draw_vol(volume_window->screen,6,61,34,67,music_volume,127,pal->find_closest(255,0,0),
291           pal->find_closest(40,0,0),slider);
292}
293
294static void create_volume_window()
295{
296/*  int vx=WINDOW_FRAME_LEFT,vy=WINDOW_FRAME_TOP+eh->font()->height()*2,scroller_height=130,bh=eh->font()->height()+5;
297
298  volume_window=eh->new_window(prop->getd("volume_x",xres/2-20),
299                               prop->getd("volume_y",yres/2-50),
300                               -1,
301                               -1,
302                               new scroller(vx,vy,LOWER_SFX,0,scroller_height,0,127,
303                               new scroller(vx+30,vy,LOWER_MUSIC,0,scroller_height,0,127,NULL)),symbol_str("VOLUME"));
304  event ev;
305  int done=0;
306  do
307  {
308    eh->flush_screen();
309    eh->get_event(ev);
310    if (ev.type==EV_CLOSE_WINDOW && ev.window==volume_window) done=1;   
311  } while (!done);
312  eh->close_window(volume_window);
313  volume_window=NULL; */
314
315
316  char *ff="art/frame.spe";
317  int t=SPEC_IMAGE;
318  int u_u=cash.reg(ff,"u_u",t,1),
319      u_d=cash.reg(ff,"u_u",t,1),
320      u_ua=cash.reg(ff,"u_ua",t,1),
321      u_da=cash.reg(ff,"u_da",t,1),
322
323      d_u=cash.reg(ff,"d_u",t,1),
324      d_d=cash.reg(ff,"d_u",t,1),
325      d_ua=cash.reg(ff,"d_ua",t,1),
326      d_da=cash.reg(ff,"d_da",t,1),
327      slider=cash.reg(ff,"volume_slide",t,1);
328
329  image *ok_image=cash.img(cash.reg("art/frame.spe","dev_ok",SPEC_IMAGE,1))->copy();
330 
331  volume_window=eh->new_window(prop->getd("volume_x",xres-185),
332                               prop->getd("volume_y",yres/2-50),
333                               120-WINDOW_FRAME_LEFT-WINDOW_FRAME_RIGHT-2,
334                               163-WINDOW_FRAME_TOP-WINDOW_FRAME_BOTTOM,
335                             new ico_button(62,112,ID_SFX_DOWN,d_u,d_d,d_ua,d_da,
336                             new ico_button(24,18,ID_SFX_UP,u_u,u_d,u_ua,u_da,
337                             new button(17,127,ID_QUIT_OK,ok_image,
338                             new info_field(35,0,0,symbol_str("SFXv"),0)))));
339
340  /*                         new ico_button(10,72,ID_MUSIC_DOWN,d_u,d_d,d_ua,d_da,
341                             new ico_button(21,72,ID_MUSIC_UP,u_u,u_d,u_ua,u_da,
342                             new info_field(3,86,0,symbol_str("MUSICv"),
343                                            NULL))))))); */
344
345  cash.img(cash.reg(ff,"vcontrol",t,1))->put_image(volume_window->screen,0,0);
346  //  draw_music_vol(slider);
347  draw_sfx_vol(slider);
348  volume_window->inm->redraw();
349  eh->grab_focus(volume_window);
350  eh->flush_screen();
351
352  volume_window->inm->allow_no_selections();
353  volume_window->inm->clear_current();
354
355  event ev;
356  do
357  {
358    do { eh->get_event(ev); } while (ev.type==EV_MOUSE_MOVE && eh->event_waiting());
359    eh->flush_screen();
360    if (ev.type==EV_MESSAGE)
361    {
362      switch (ev.message.id)
363      {
364        case ID_SFX_UP :
365        { if (volume_window)
366        {
367          sfx_volume+=16;
368          if (sfx_volume>127) sfx_volume=127;
369          draw_sfx_vol(slider);
370          char *s="sfx/ambtech1.wav";
371          if (sound_avail&SFX_INITIALIZED)
372            cash.sfx(cash.reg(s,s,SPEC_EXTERN_SFX,1))->play(sfx_volume);
373        }
374        } break;
375        case ID_SFX_DOWN :
376        { if (volume_window)
377        {
378          sfx_volume-=16;
379          if (sfx_volume<0) sfx_volume=0;
380          draw_sfx_vol(slider);
381          char *s="sfx/ambtech1.wav";
382          if (sound_avail&SFX_INITIALIZED)
383            cash.sfx(cash.reg(s,s,SPEC_EXTERN_SFX,1))->play(sfx_volume);
384        }
385        } break;
386
387        case ID_MUSIC_UP :
388        { if (volume_window)
389        {
390          music_volume+=16;
391          if (music_volume>127) music_volume=127;
392          draw_music_vol(slider);
393          if (current_song) current_song->set_volume(music_volume);
394        }
395        } break;
396        case ID_MUSIC_DOWN :
397        { if (volume_window)
398        {
399          music_volume-=16;
400          if (music_volume<0) music_volume=0;
401          draw_music_vol(slider);
402          if (current_song) current_song->set_volume(music_volume);
403        }
404        } break;
405        case ID_QUIT_OK :
406        {
407          eh->close_window(volume_window);
408          volume_window=NULL;     
409        }
410      }
411    } else if (ev.type==EV_CLOSE_WINDOW || (ev.type==EV_KEY && ev.key==JK_ESC))
412    {
413      eh->close_window(volume_window);
414      volume_window=NULL;
415    }
416  } while (volume_window);
417  delete ok_image;
418}
419
420FILE *open_FILE(char *filename, char *mode);
421
422void save_difficulty()
423{
424  FILE *fp=open_FILE("hardness.lsp","wb");
425  if (!fp)
426    dprintf("Unable to write to file hardness.lsp\n");
427  else
428  {
429    fprintf(fp,"(setf difficulty '");
430    if (DEFINEDP(symbol_value(l_difficulty)))
431    {
432      if (symbol_value(l_difficulty)==l_extreme)
433        fprintf(fp,"extreme)\n");
434      else if (symbol_value(l_difficulty)==l_hard)
435        fprintf(fp,"hard)\n");
436      else if (symbol_value(l_difficulty)==l_easy)
437        fprintf(fp,"easy)\n");
438      else
439        fprintf(fp,"medium)\n");
440    } else
441       fprintf(fp,"medium)\n");
442    fclose(fp);
443  }
444}
445
446void fade_out(int steps);
447void fade_in(image *im, int steps);
448
449
450#ifdef __MAC__
451void RestoreMac();
452void UnRestoreMac();
453#else
454inline void RestoreMac() { ; }
455inline void UnRestoreMac() { ; }
456#endif
457
458int text_draw(int y, int x1, int y1, int x2, int y2, char *buf, JCFont *font, uchar *cmap, char color);
459
460void show_sell(int abortable)
461{
462#if 0
463  void *ss=make_find_symbol("sell_screens");
464  if (!DEFINEDP(symbol_value(ss)))
465  {
466    int sp=current_space;
467    current_space=PERM_SPACE;
468//    char *prog="((\"art/help.spe\" . \"sell2\")(\"art/help.spe\" . \"sell4\")(\"art/help.spe\" . \"sell3\")(\"art/endgame.spe\" . \"credit\"))";
469    char *prog="((\"art/endgame.spe\" . \"credit\") (\"art/help.spe\" . \"sell6\"))";
470    set_symbol_value(ss,compile(prog));
471    current_space=sp;
472  }
473
474  if (DEFINEDP(symbol_value(ss)))
475  {
476    image blank(2,2); blank.clear();
477    eh->set_mouse_shape(blank.copy(),0,0);      // don't show mouse
478
479    ss=symbol_value(ss);
480    int quit=0;
481    while (ss && !quit)
482    {
483      int im=cash.reg_object("art/help.spe",CAR(ss),SPEC_IMAGE,1);
484      fade_in(cash.img(im),16);
485
486      event ev;
487      do
488      {
489        eh->flush_screen();
490                                eh->get_event(ev);
491      } while (ev.type!=EV_KEY);
492      if (ev.key==JK_ESC && abortable)
493        quit=1;
494      fade_out(16);
495      ss=CDR(ss);
496    }
497    eh->set_mouse_shape(cash.img(c_normal)->copy(),1,1);
498  }
499#else
500        image blank(2,2); blank.clear();
501  eh->set_mouse_shape(blank.copy(),0,0);      // don't show mouse
502        screen->clear();
503
504  image *im;
505  event ev;
506        int i;
507 
508  im=cash.img(cash.reg("art/endgame.spe","credit",SPEC_IMAGE,1));
509  char *str=lstring_value(eval(make_find_symbol("thanks_text")));
510
511        int dx=(xres+1)/2-im->width()/2,dy=(yres+1)/2-im->height()/2;
512        im->put_image(screen,dx,dy);
513
514  fade_in(0,16);       
515
516  uchar cmap[32];
517  for (i=0;i<32;i++)
518    cmap[i]=pal->find_closest(i*256/32,i*256/32,i*256/32);
519
520        i = 0;
521
522        int tx = 300, ty = 350, twx = 319, twy = 119;   
523       
524  while (eh->event_waiting()) eh->get_event(ev);
525        ev.type = EV_SPURIOUS;
526
527        time_marker start;
528        int txti = 0;
529  do
530  {
531        im->put_part(screen,dx+tx,dy+ty,tx,ty,tx+twx,ty+twy);
532                txti++;
533    text_draw(twy+5-txti,dx+tx+15,dy+ty,dx+tx+twx-15,dy+ty+twy,str,eh->font(),cmap,eh->bright_color());                 
534        eh->flush_screen();
535               
536                time_marker now;
537    while (now.diff_time(&start)<0.10)
538      now.get_time();
539    start.get_time();
540
541    while (eh->event_waiting() && ev.type!=EV_KEY) eh->get_event(ev);
542  } while (txti<600 && ev.type!=EV_KEY && ev.type!=EV_MOUSE_BUTTON);
543  fade_out(16);
544
545        if (!abortable || !(ev.type==EV_KEY && ev.key==JK_ESC))
546        {
547          im=cash.img(cash.reg("art/help.spe","sell6",SPEC_IMAGE,1));
548          fade_in(im,16);       
549       
550          do
551          {
552                eh->flush_screen();
553                        eh->get_event(ev);
554          } while (ev.type!=EV_KEY && ev.type!=EV_MOUSE_BUTTON);
555          fade_out(16);
556        }
557  eh->set_mouse_shape(cash.img(c_normal)->copy(),1,1);
558#endif
559}
560
561
562void menu_handler(event &ev, input_manager *inm)
563{
564  switch (ev.type)
565  {
566    case EV_MESSAGE :
567    {
568      switch (ev.message.id)
569      {
570                                case ID_LIGHT_OFF :
571                                if (!volume_window)
572                                {
573                                  screen->clear();
574                                  eh->flush_screen();
575                                  gamma_correct(pal,1);
576                                  fade_in(cash.img(title_screen),8);
577                                  inm->redraw();
578                                  eh->flush_screen();
579                                } break;
580                                case ID_RETURN :
581                                if (!volume_window)
582                                {
583                                  the_game->set_state(RUN_STATE);
584                                } break;
585                                case ID_START_GAME :
586                                if (!volume_window)
587                                {       
588                                  the_game->load_level(level_file);
589                                  the_game->set_state(RUN_STATE);
590                                  view *v;
591                                  for (v=player_list;v;v=v->next)
592                                    if (v->focus)
593                                      v->reset_player();
594                                   
595                                } break;
596
597   
598        case ID_LOAD_PLAYER_GAME :
599                                if (!volume_window)
600                                {
601                                  int got_level=load_game(0,symbol_str("LOAD"));
602                                  the_game->reset_keymap();
603                                  if (got_level)
604                                  {
605                                    char name[50];
606                                    sprintf(name,"save%04d.spe",got_level);
607                                    the_game->load_level(name);
608                                    the_game->set_state(RUN_STATE);         
609                                  }
610                                } break;
611                       
612                       
613                                case ID_VOLUME :
614                                if (!volume_window)
615                                { create_volume_window(); } break;
616                       
617                                case ID_MEDIUM :
618                                {
619                                  set_symbol_value(l_difficulty,l_medium);
620                                  save_difficulty();
621                                } break;
622                                case ID_HARD :
623                                {
624                                  set_symbol_value(l_difficulty,l_hard);
625                                  save_difficulty();
626                                } break;
627                                case ID_EXTREME :
628                                {
629                                  set_symbol_value(l_difficulty,l_extreme);
630                                  save_difficulty();
631                                } break;
632                                case ID_EASY :
633                                {
634                                  set_symbol_value(l_difficulty,l_easy);
635                                  save_difficulty();
636                                } break;
637                       
638                                case ID_NETWORKING :
639                                {
640                                  if (!volume_window)
641                                  {
642                                    net_configuration *cfg=new net_configuration;
643                                    if (cfg->input())
644                                    {
645                                      if (main_net_cfg) delete main_net_cfg;
646                                      main_net_cfg=cfg;
647                                    } else delete cfg;
648                                    the_game->draw(0);
649                                    inm->redraw();
650                                  }
651                                } break;
652                                             
653                                case ID_SHOW_SELL :
654                                if (!volume_window)
655                                {
656                                  show_sell(1);
657                                  screen->clear();
658                                  if (title_screen>=0)
659                                  {
660                                    image *tit=cash.img(title_screen);
661                                      tit->put_image(screen,screen->width()/2-tit->width()/2,
662                                                                      screen->height()/2-tit->height()/2);
663                                  }
664                                  inm->redraw();
665                                  fade_in(NULL,8);
666                                  eh->flush_screen();
667                       
668                                } break;
669                                             
670                                case ID_MACKEYS :
671                                  do_key_config(eh);
672
673                                  /*
674                                        fade_out(8);
675                                        RestoreMac();
676                                        MacKeyConfigMenu();
677
678                                        UnRestoreMac(); */
679
680                                    fade_in(cash.img(title_screen),8);
681                                    inm->redraw();
682                                    eh->flush_screen();
683                                        break;
684
685                                case ID_MACCONF :
686                                  do_monitor_config(eh);
687
688                                  fade_in(cash.img(title_screen),8);
689                                  inm->redraw();
690                                  eh->flush_screen();
691                                  break;
692      } break;
693    } break;
694    case EV_CLOSE_WINDOW :
695    {
696      if (ev.window==volume_window)
697      { eh->close_window(volume_window); volume_window=NULL; }
698    } break;
699  }
700}
701
702void *current_demo=NULL;
703
704static ico_button *load_icon(int num, int id, int x, int y, int &h, ifield *next, char *key)
705{
706  char name[20];
707  char *base="newi";
708  int a,b,c;
709  sprintf(name,"%s%04d.pcx",base,num*3+1);
710  a=cash.reg("art/icons.spe",name,SPEC_IMAGE,1);
711
712  sprintf(name,"%s%04d.pcx",base,num*3+2);
713  b=cash.reg("art/icons.spe",name,SPEC_IMAGE,1);
714
715  sprintf(name,"%s%04d.pcx",base,num*3+3);
716  c=cash.reg("art/icons.spe",name,SPEC_IMAGE,1);
717
718  h=cash.img(a)->height();
719
720  return new ico_button(x,y,id,b,b,a,c,next,-1,key);
721}
722
723ico_button *make_default_buttons(int x,int &y, ico_button *append_list)
724{
725  int h;
726  int diff_on;
727
728  if (DEFINEDP(symbol_value(l_difficulty)))
729  {
730    if (symbol_value(l_difficulty)==l_extreme)
731      diff_on=3;
732    else if (symbol_value(l_difficulty)==l_hard)
733      diff_on=2;
734    else if (symbol_value(l_difficulty)==l_easy)
735      diff_on=0;
736    else
737      diff_on=1;
738  } else  diff_on=3;
739
740
741  ico_button *start;
742
743  ifield **cur=(ifield **)&start;
744 
745  if (!player_list->next)
746  {
747    *cur=load_icon(0,ID_START_GAME,x,y,h,NULL,"ic_start");   cur=&((*cur)->next);  y+=h;
748  }
749
750
751  ico_switch_button *set=NULL;
752  if (!main_net_cfg || (main_net_cfg->state!=net_configuration::SERVER && main_net_cfg->state!=net_configuration::CLIENT))
753  {
754    *cur=new ico_switch_button(x,y,ID_NULL,diff_on,
755                                                 load_icon(3,ID_EASY,x,y,h,
756                                                 load_icon(8,ID_MEDIUM,x,y,h,
757                                                 load_icon(9,ID_HARD,x,y,h,
758                                                 load_icon(10,ID_EXTREME,x,y,h,NULL,"ic_extreme"),
759                                                     "ic_hard"),"ic_medium"),"ic_easy"),NULL);     
760    cur=&((*cur)->next);  y+=h; 
761  }
762
763  *cur=load_icon(4,ID_LIGHT_OFF,x,y,h,NULL,"ic_gamma");    cur=&((*cur)->next);  y+=h; 
764  *cur=load_icon(5,ID_VOLUME,x,y,h,NULL,"ic_volume");      cur=&((*cur)->next);  y+=h; 
765
766  if (registered && prot)
767  {
768    *cur = load_icon(11,ID_NETWORKING,x,y,h,NULL,"ic_networking"); cur=&((*cur)->next);  y+=h;     
769  }
770
771  *cur = load_icon(2,ID_SHOW_SELL,x,y,h,NULL,"ic_sell");   cur=&((*cur)->next);  y+=h;     
772
773  *cur = load_icon(12,ID_MACCONF,x,y,h,NULL,"ic_macconf"); cur=&((*cur)->next);  y+=h;   
774
775  *cur = load_icon(13,ID_MACKEYS,x,y,h,NULL,"ic_mackeys"); cur=&((*cur)->next);  y+=h; 
776
777
778
779  *cur=load_icon(6,ID_QUIT,x,y,h,NULL,"ic_quit"); cur=&((*cur)->next);  y+=h; 
780
781  ico_button *list=append_list;
782
783  if (append_list)
784  {
785    while (append_list->next)
786      append_list=(ico_button *)append_list->next;
787    append_list->next=start;
788  } else list=start;
789 
790  return list; 
791}
792
793
794ico_button *make_conditional_buttons(int x,int &y)
795
796  ico_button *start_list=NULL;
797  int h;
798  if (current_level)       // should we include a return icon?
799  {
800    start_list=load_icon(7,ID_RETURN,x,y,h,NULL,"ic_return");
801    y+=h;
802  }
803   
804 
805  ico_button *load;
806  if (!player_list->next && show_load_icon())
807  { load= load_icon(1,ID_LOAD_PLAYER_GAME,x,y,h,NULL,"ic_load");                     y+=h;}
808  else load=NULL;
809
810  if (start_list) start_list->next=load;
811  else start_list=load;
812
813  return start_list;   
814}
815
816void main_menu()
817{
818  int y=yres/2-210;
819  ico_button *list=make_conditional_buttons(xres-51,y);
820  list=make_default_buttons(xres-51,y,list);
821
822
823  input_manager *inm=new input_manager(screen,eh,list);
824  inm->allow_no_selections();
825  inm->clear_current();
826
827  time_marker old_time;
828
829  screen->add_dirty(0,0,xres-1,yres-1);
830
831  int eoff=0,coff=0;
832  event ev;
833 
834#ifdef __MAC__
835        int command = 0;
836#endif
837
838  int state=0,stop_menu=0;
839  time_marker start;
840  eh->flush_screen();
841  do
842  {
843    time_marker new_time;
844
845    if (eh->event_waiting())
846    {
847      do { eh->get_event(ev); } while (ev.type==EV_MOUSE_MOVE && eh->event_waiting());
848      inm->handle_event(ev,NULL,eh);
849
850#ifdef __MAC__
851      if ((ev.type==EV_KEY || ev.type==EV_KEYRELEASE) && ev.key==JK_COMMAND)
852        command = (ev.type == EV_KEY);
853      if (ev.type==EV_KEY && ev.key=='q' && command)
854        eh->push_event(new event(ID_QUIT,NULL));
855#else
856      if (ev.type==EV_KEY && ev.key==JK_ESC)
857        eh->push_event(new event(ID_QUIT,NULL));
858#endif
859
860      menu_handler(ev,inm);
861      start.get_time();
862     
863      eh->flush_screen();
864    }
865
866    if (new_time.diff_time(&start)>22)
867    {
868      if (volume_window)
869        start.get_time();
870      else
871      {
872                                if (!current_demo)
873                                {
874                                  void *d=make_find_symbol("demos");
875                                  if (DEFINEDP(symbol_value(d)))
876                                  current_demo=symbol_value(d);
877                                }
878                                if (current_demo)
879                                {
880                                  demo_man.set_state(demo_manager::PLAYING,lstring_value(CAR(current_demo)));
881                                  stop_menu=1;
882                                  current_demo=CDR(current_demo);
883                                }
884      }
885    }
886
887    if (volume_window) stop_menu=0;  // can't exit with colume window open
888    else if (main_net_cfg && main_net_cfg->restart_state()) stop_menu=1;
889    else if (the_game->state==RUN_STATE) stop_menu=1;
890    else if (ev.type==EV_MESSAGE)
891    {
892      if (ev.message.id==ID_START_GAME || ev.message.id==ID_RETURN) stop_menu=1;
893      else if (ev.message.id==ID_QUIT)
894      {
895#ifdef __MAC__
896                                stop_menu=1;
897#else
898                                if (confirm_quit())
899                                        stop_menu=1;
900                                else
901                                {
902                                        ev.type=EV_SPURIOUS;
903                                        start.get_time();
904                                }
905#endif
906      }
907    }
908
909  } while (!stop_menu);
910
911  delete inm;
912
913
914  if (ev.type==EV_MESSAGE && ev.message.id==ID_QUIT)   // propogate the quit message
915    the_game->end_session();
916}
917
918
919
920
921
Note: See TracBrowser for help on using the repository browser.