home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ABUSESRC.ZIP / AbuseSrc / macabuse / src / menu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-20  |  23.5 KB  |  922 lines

  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.  
  28. inline void MacKeyConfigMenu() { ; }
  29. inline void MacPreferences() { ; }
  30. #endif
  31.  
  32. #include "macgame.hpp"
  33.  
  34. extern net_protocol *prot;
  35. jwindow *volume_window=NULL;
  36. jwindow *macpref_window=NULL;
  37. jwindow *key_window=NULL;
  38. extern int confirm_quit();
  39. extern int registered;
  40.  
  41. //percent is 0..256
  42. void 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.  
  70. void 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.  
  96. void 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.  
  106. char *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.  
  124. void main_menu();
  125.  
  126. int 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.  
  268. static 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.  
  282. static 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.  
  288. static 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.  
  294. static 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.  
  420. FILE *open_FILE(char *filename, char *mode);
  421.  
  422. void 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.  
  446. void fade_out(int steps);
  447. void fade_in(image *im, int steps);
  448.  
  449.  
  450. #ifdef __MAC__
  451. void RestoreMac();
  452. void UnRestoreMac();
  453. #else
  454. inline void RestoreMac() { ; }
  455. inline void UnRestoreMac() { ; }
  456. #endif
  457.  
  458. int text_draw(int y, int x1, int y1, int x2, int y2, char *buf, JCFont *font, uchar *cmap, char color);
  459.  
  460. void 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.  
  562. void 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.  
  702. void *current_demo=NULL;
  703.  
  704. static 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.  
  723. ico_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.  
  794. ico_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.  
  816. void 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.  
  922.