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

  1. #include "dev.hpp"
  2. #include "input.hpp"
  3. #include "objects.hpp"
  4. #include "id.hpp"
  5. #include "lisp.hpp"
  6. #include "light.hpp"
  7. #include "devsel.hpp"
  8. #include "dprint.hpp"
  9. #include "property.hpp"
  10. #include "pmenu.hpp"
  11. #include "filesel.hpp"
  12. #include "tools.hpp"
  13. #include "game.hpp"
  14. #include "pcxread.hpp"
  15. #include "lisp_gc.hpp"
  16. #include "demo.hpp"
  17. #include "profile.hpp"
  18. #include "sbar.hpp"
  19. #include "compiled.hpp"
  20. #include "chat.hpp"
  21. #include <ctype.h>
  22.  
  23. #define make_above_tile(x) ((x)|0x4000)
  24. extern int registered;
  25. char backw_on=0,forew_on=0,show_menu_on=0,ledit_on=0,pmenu_on=0,omenu_on=0,commandw_on=0,tbw_on=0,
  26.   searchw_on=0,small_render_on=0,interpolate_draw=0,disable_autolight=0,fps_on=0,profile_on=0,
  27.   show_names=0,fg_reversed=0,
  28.   raise_all;
  29.  
  30. char *symbol_str(char *name)
  31. {
  32.   void *sym=make_find_symbol(name);
  33.   if (symbol_value(sym) && item_type(symbol_value(sym))==L_STRING)
  34.     return lstring_value(symbol_value(sym));
  35.  
  36.  
  37.   // maybe english.lsp was not loaded yet, let's try to do that
  38.   int sp=current_space;
  39.   current_space=PERM_SPACE;
  40.  
  41.   
  42.   char prog[50]; 
  43.   char *cs=prog;
  44.   strcpy(prog,"(setq section 'game_section)\n");
  45.   eval(compile(cs));
  46.   strcpy(prog,"(load \"lisp/english.lsp\")\n");
  47.   cs=prog;
  48.   if (!eval(compile(cs)))
  49.   {
  50.     dprintf("unable to open file '%s'\n",lsf);
  51.     exit(0);
  52.   }
  53.   current_space=sp;
  54.  
  55.  
  56.   // check again to see if the symbol is there
  57.   sym=make_find_symbol(name);
  58.   if (symbol_value(sym) && item_type(symbol_value(sym))==L_STRING)
  59.     return lstring_value(symbol_value(sym));
  60.  
  61.  
  62.   // check to see if there is a missing symbol definition
  63.   sym=make_find_symbol("missing_sym");
  64.   if (symbol_value(sym) && item_type(symbol_value(sym))==L_STRING)
  65.     return lstring_value(symbol_value(sym));
  66.  
  67.   // last resort, return english string
  68.   return "Missing language symbol!";
  69. }
  70.  
  71.  
  72. static game_object *copy_object=NULL;
  73.  
  74. pmenu *dev_menu=NULL;
  75. jwindow *mess_win=NULL,*warn_win=NULL;
  76.  
  77. game_object *edit_object;
  78. dev_controll *dev_cont=NULL;
  79. image *small_render=NULL;
  80.  
  81. int scale_mult,scale_div,dlastx,dlasty;
  82. int last_created_type=-1;
  83. char level_file[100]="levels/level00.spe";
  84.  
  85. void make_edit_mode_menu();
  86.  
  87. class cached_image : public visual_object
  88. {
  89.   int id;
  90.   public :
  91.   cached_image(int Id) { id=Id; }
  92.   virtual void draw(image *screen, int x, int y, 
  93.       window_manager *wm, filter *f)
  94.   {
  95.     if (f)
  96.       f->put_image(screen,cash.img(id),x,y,1);
  97.     else
  98.       cash.img(id)->put_image(screen,x,y); 
  99.   }
  100.   virtual int width(window_manager *wm) { return cash.img(id)->width(); }
  101.   virtual int height(window_manager *wm) { return cash.img(id)->height(); }
  102. } ;
  103.  
  104.  
  105. #define DEV_MODES 3
  106. cached_image *dev_mode_pict[DEV_MODES];
  107.  
  108. int dev_del,dev_move, dev_char_left,dev_char_right,dev_back,dev_front,dev_ok,dev_copy,dev_brain,
  109.   dev_lights,dev_objects,dev_ai,dev_mode_icon[DEV_MODES],
  110.   dev_forward,dev_backward;
  111.  
  112. char *dev_mode_icon_names[DEV_MODES]={"pixel_mode","pick_mode", /* "fill_mode",
  113.                                                                    "line_mode","rect_mode","bar_mode", */ "area_select"};
  114.  
  115. int dev_mode_ids[DEV_MODES]={ID_DMODE_DRAW,ID_DMODE_PICK, ID_DMODE_AREA};
  116.  
  117. int edit_mode=ID_DMODE_DRAW;
  118.  
  119.  
  120. dev_term *dev_console=NULL;
  121. int ldef_width=0,ldef_height=0,ldef_r1=1,ldef_r2=100;
  122.  
  123. void make_screen_size(int w, int h);
  124.  
  125. class amb_cont : public scroller
  126. {
  127.   public :
  128.   amb_cont(int X, int Y, ifield *Next) : scroller(X,Y,ID_NULL,100,eh->font()->height()+2,0,64,Next) 
  129.   { if (player_list) sx=player_list->ambient; }
  130.   virtual void scroll_event(int newx, image *screen, window_manager *wm)
  131.   {
  132.     screen->bar(x,y,x+l-1,y+h-1,wm->dark_color());
  133.     char st[100];
  134.     sprintf(st,"%d",newx);
  135.     wm->font()->put_string(screen,x+30,y+1,st,eh->bright_color());
  136.     if (player_list)
  137.       player_list->ambient=newx;
  138.     the_game->need_refresh();
  139.   }
  140. } ;
  141.  
  142.  
  143. int confirm_quit()
  144. {
  145.   image *ok_image=cash.img(cash.reg("art/frame.spe","dev_ok",SPEC_IMAGE,1))->copy(),
  146.     *cancel_image=cash.img(cash.reg("art/frame.spe","cancel",SPEC_IMAGE,1))->copy();
  147.  
  148.  
  149.   jwindow *quitw=eh->new_window(xres/2+40,yres/2,90,-1,
  150.       new button(WINDOW_FRAME_LEFT+10,WINDOW_FRAME_TOP+20,ID_QUIT_OK,ok_image,
  151.           new button(WINDOW_FRAME_LEFT+38,WINDOW_FRAME_TOP+20,ID_CANCEL,cancel_image,
  152.               new info_field(WINDOW_FRAME_LEFT,WINDOW_FRAME_TOP,ID_NULL,symbol_str("sure?"),NULL))),
  153.       symbol_str("quit_title"));
  154.   eh->grab_focus(quitw);
  155.   int fin=0,quit=0;
  156.   do
  157.   {
  158.     eh->flush_screen();
  159.  
  160.     event ev;
  161.     eh->get_event(ev);
  162.     if (ev.type==EV_MESSAGE && ev.message.id==ID_QUIT_OK)
  163.       fin=quit=1;
  164.     else if (ev.type==EV_MESSAGE && ev.message.id==ID_CANCEL)
  165.       fin=1;
  166.     else if (ev.type==EV_KEY && toupper(ev.key)==toupper(*symbol_str("YES")))
  167.       fin=quit=1;
  168.     else if (ev.type==EV_KEY && toupper(ev.key)==toupper(*symbol_str("NO")))
  169.       fin=1;
  170.     if ((ev.type==EV_KEY && ev.key==JK_ESC) || ev.type==EV_CLOSE_WINDOW) fin=1;
  171.  
  172.   } while (!fin);
  173.   delete ok_image;
  174.   delete cancel_image;
  175.  
  176.   the_game->reset_keymap();
  177.  
  178.   eh->close_window(quitw);
  179.   eh->flush_screen();
  180.   return quit;
  181. }
  182.  
  183. void show_object_number (game_object *who)
  184. {
  185.   int total=0,number=0;
  186.   game_object *c;  
  187.   for (c=current_level->first_object();c;c=c->next)
  188.   {
  189.     if (c->otype==who->otype)
  190.       total++;
  191.     if (c==who) number=total;
  192.   }
  193.   char msg[100];
  194.   sprintf(msg,"%s : %d of %d",object_names[who->otype],number,total);
  195. }
  196.  
  197. void dev_controll::search_backward()
  198. { ;
  199.  
  200.  
  201. void single_render()
  202. {
  203.   // enlarge clip area
  204.   the_game->first_view->cx2=the_game->first_view->cx1+
  205.     (the_game->first_view->cx2-the_game->first_view->cx1+1)*2;
  206.   the_game->first_view->cy2=the_game->first_view->cy1+
  207.     (the_game->first_view->cy2-the_game->first_view->cy1+1)*2;                
  208.   delete small_render;
  209.   small_render=NULL;
  210.   small_render_on=0;
  211. }
  212.  
  213. void double_render()
  214. {
  215.   small_render_on=1;
  216.   // reduce clip area
  217.   the_game->first_view->cx2=the_game->first_view->cx1+
  218.     (the_game->first_view->cx2-the_game->first_view->cx1+1)/2;
  219.   the_game->first_view->cy2=the_game->first_view->cy1+
  220.     (the_game->first_view->cy2-the_game->first_view->cy1+1)/2;
  221.  
  222.   small_render=new image((the_game->first_view->cx2-the_game->first_view->cx1+1),
  223.       (the_game->first_view->cy2-the_game->first_view->cy1+1),NULL,2);
  224. }
  225.  
  226.  
  227. void dev_controll::search_forward()
  228. {
  229.   if (search_window) // if no window then we can't get the object name
  230.   {
  231.     char *name=search_window->read(ID_SEARCH_TEXT);
  232.     int type=-1;    // see if this type exsists
  233.     int i;
  234.     for (i=0;i<total_objects;i++)
  235.       if (!strcmp(object_names[i],name))
  236.         type=i;
  237.     if (type==-1)
  238.     {
  239.       char msg[60];
  240.       sprintf(msg,"Object type '%s' does not exsists!\n",name);
  241.       the_game->show_help(msg);
  242.       the_game->need_refresh();
  243.     } else
  244.     {
  245.       game_object *first,*find=NULL;      
  246.       if (!search_object || search_object->otype!=type)
  247.         first=current_level->first_object();
  248.       else
  249.         first=search_object->next;
  250.       for (;!find && first;first=first->next)
  251.         if (first->otype==type)
  252.       find=first;
  253.       int loop=0;
  254.       if (!find)
  255.       {
  256.     for (first=current_level->first_object();first && !find;first=first->next)
  257.     {
  258.       if (first->otype==type)
  259.         find=first;
  260.     }
  261.     loop=1;
  262.       }
  263.       if (find)
  264.       {
  265.         search_object=find;
  266.     show_object_number(search_object);
  267.       }
  268.       else
  269.       {
  270.     the_game->show_help("No object matching name exsist in level\n");
  271.     
  272.       }
  273.     }
  274.   }
  275. }
  276.  
  277.  
  278. long dev_controll::snap_x(long x)
  279. {
  280.   if (eh->key_pressed(JK_CTRL_L) || eh->key_pressed(JK_CTRL_R))
  281.     return x-(x%the_game->ftile_width());
  282.   else if (eh->key_pressed(JK_ALT_L) || eh->key_pressed(JK_ALT_R))
  283.     return x-(x%the_game->ftile_width())+the_game->ftile_width()/2;
  284.   else return x;  
  285. }
  286.  
  287. long dev_controll::snap_y(long y)
  288. {
  289.   if (eh->key_pressed(JK_CTRL_L) || eh->key_pressed(JK_CTRL_R))
  290.     return y-(y%the_game->ftile_height())-1;
  291.   else if (eh->key_pressed(JK_ALT_L) || eh->key_pressed(JK_ALT_R))
  292.     return y-(y%the_game->ftile_height())+the_game->ftile_height()/2-1;
  293.   else return y;
  294. }
  295.  
  296. void dev_controll::make_ambient()
  297. {
  298.   if (!ambw)
  299.     ambw=eh->new_window(prop->getd("ambient x",-1),
  300.         prop->getd("ambient y",-1),-1,-1,
  301.         new amb_cont(WINDOW_FRAME_LEFT,WINDOW_FRAME_TOP,NULL),"ambient");
  302. }
  303.  
  304. void dev_term::execute(char *st)
  305. {
  306.   if (!strcmp(st,"?"))
  307.   {
  308.     put_string("unchop x y, size x y,\n"
  309.         "load, esave, name\n");
  310.   } else 
  311.   {
  312.     event ev;
  313.     dv->do_command(st,ev);
  314.   }
  315. }
  316.  
  317. void load_dev_icons()
  318. {
  319.   char *artf="art/dev.spe";
  320.   dev_del=cash.reg(artf,"dev_del",SPEC_IMAGE,0);
  321.   dev_move=cash.reg(artf,"dev_move",SPEC_IMAGE,0);
  322.   dev_char_left=cash.reg(artf,"dev_char_left",SPEC_IMAGE,0);
  323.   dev_char_right=cash.reg(artf,"dev_char_right",SPEC_IMAGE,0);
  324.   dev_back=cash.reg(artf,"dev_back",SPEC_IMAGE,0);
  325.   dev_front=cash.reg(artf,"dev_front",SPEC_IMAGE,0);
  326.   dev_ok=cash.reg(artf,"dev_ok",SPEC_IMAGE,0);
  327.   dev_copy=cash.reg(artf,"dev_copy",SPEC_IMAGE,0);
  328.   dev_brain=cash.reg(artf,"brain",SPEC_IMAGE,0);
  329.   dev_lights=cash.reg(artf,"lights",SPEC_IMAGE,0);
  330.   dev_objects=cash.reg(artf,"objects",SPEC_IMAGE,0);
  331.   dev_ai=cash.reg(artf,"ai",SPEC_IMAGE,0);
  332.   dev_forward=cash.reg(artf,"forward",SPEC_IMAGE,0);
  333.   dev_backward=cash.reg(artf,"backward",SPEC_IMAGE,0);
  334.  
  335.   for (int i=0;i<DEV_MODES;i++)
  336.     dev_mode_icon[i]=cash.reg(artf,dev_mode_icon_names[i],SPEC_IMAGE,0);
  337.   
  338. }
  339.  
  340. void scale_put(image *im, image *screen, int x, int y, short new_width, short new_height)
  341. {
  342.   unsigned char *sl1,*sl2;
  343.   long xstep=(im->width()<<16)/new_width,
  344.     ystep=(im->height()<<16)/new_height,iy,ix,sx,ix_start,iy_start;
  345.   screen->add_dirty(x,y,x+new_width-1,y+new_height-1);
  346.  
  347.  
  348.   short cx1,cy1,cx2,cy2;
  349.   screen->get_clip(cx1,cy1,cx2,cy2);
  350.   if (cx1>cx2 || cy1>cy2 || x>cx2 || y>cy2 || x+new_width<=cx1 || y+new_height<=cy1) return ;
  351.   if (x<cx1)
  352.   {
  353.     ix_start=(cx1-x)*xstep;
  354.     new_width-=(cx1-x);
  355.     x=cx1;
  356.   } else ix_start=0;
  357.   if (x+new_width>=cx2)
  358.     new_width-=x+new_width-1-cx2;
  359.   if (y<cy1)
  360.   {
  361.     iy_start=(cy1-y)*ystep;
  362.     new_height-=(cy1-y);
  363.     y=cy1;
  364.   } else iy_start=0;
  365.   if (y+new_height>cy2)
  366.     new_height-=y+new_height-cy2;
  367.   
  368.  
  369.   for (iy=iy_start;new_height>0;new_height--,y++,iy+=ystep)
  370.   {
  371.     sl1=im->scan_line(iy>>16);
  372.     sl2=screen->scan_line(y)+x;
  373.     for (ix=ix_start,sx=0;sx<new_width;sx++,ix+=xstep,sl2++)
  374.       *sl2=sl1[ix>>16];    
  375.   }
  376. }
  377.  
  378.  
  379. void scale_put_trans(image *im, image *screen, int x, int y, short new_width, short new_height)
  380. {
  381.   unsigned char *sl1,*sl2;
  382.   long xstep=(im->width()<<16)/new_width,
  383.     ystep=(im->height()<<16)/new_height,iy,ix,sx,ix_start,iy_start;
  384.   screen->add_dirty(x,y,x+new_width-1,y+new_height-1);
  385.  
  386.  
  387.   short cx1,cy1,cx2,cy2;
  388.   screen->get_clip(cx1,cy1,cx2,cy2);
  389.   if (cx1>cx2 || cy1>cy2 || x>cx2 || y>cy2 || x+new_width<=cx1 || y+new_height<=cy1) return ;
  390.   if (x<cx1)
  391.   {
  392.     ix_start=(cx1-x)*xstep;
  393.     new_width-=(cx1-x);
  394.     x=cx1;
  395.   } else ix_start=0;
  396.   if (x+new_width>=cx2)
  397.     new_width-=x+new_width-1-cx2;
  398.   if (y<cy1)
  399.   {
  400.     iy_start=(cy1-y)*ystep;
  401.     new_height-=(cy1-y);
  402.     y=cy1;
  403.   } else iy_start=0;
  404.   if (y+new_height>cy2)
  405.     new_height-=y+new_height-cy2;
  406.   
  407.   uchar d;
  408.   for (iy=iy_start;new_height>0;new_height--,y++,iy+=ystep)
  409.   {
  410.     sl1=im->scan_line(iy>>16);
  411.     sl2=screen->scan_line(y)+x;
  412.     for (ix=ix_start,sx=0;sx<new_width;sx++,ix+=xstep,sl2++)
  413.     {
  414.       d=sl1[ix>>16];
  415.       if (d)
  416.         *sl2=d;
  417.     }
  418.   }
  419. }
  420.  
  421. int dev_controll::need_plus_minus()
  422. {
  423.   if (state==DEV_MOVE_LIGHT) return 1; else return 0;
  424. }
  425.  
  426. int dev_controll::need_arrows()
  427. {
  428.   if (state==DEV_MOVE_LIGHT) return 1; else return 0;
  429. }
  430.  
  431. int dev_controll::repeat_key_mode()
  432. {
  433.   if (state==DEV_MOVE_LIGHT) return 1; else return 0;
  434. }
  435.  
  436. int last_link_x=0,last_link_y=0;
  437.  
  438. void dev_controll::dev_draw(view *v)
  439. {
  440.   long x1,y1,x2,y2;
  441.   if (dev&EDIT_MODE)
  442.   {
  443.     long vx=v->xoff(),vy=v->yoff();
  444.   
  445.     if (dev&DRAW_LINKS)
  446.     {
  447.       for (light_source *f=first_light_source;f;f=f->next)
  448.       {
  449.     if (f->x-vx>=0 && f->x-vx<=(v->cx2-v->cx1+1) && f->y-vy>=0 && f->y-vy<=(v->cy2-v->cy1+1))
  450.     {
  451.       image *im=cash.img(light_buttons[f->type]);
  452.       im->put_image(screen,f->x-vx+v->cx1-im->width()/2,f->y-vy+v->cy1-im->height()/2,1);
  453.       screen->rectangle(f->x1-vx+v->cx1,f->y1-vy+v->cy1,f->x2-vx+v->cx1,f->y2-vy+v->cy1,
  454.               eh->medium_color());
  455.     }
  456.       }
  457.     }
  458.  
  459.     if (link_object)
  460.     {
  461.       long rx1,ry1;
  462.       the_game->game_to_mouse(link_object->x,link_object->y,v,rx1,ry1);      
  463.       screen->line(rx1,ry1,dlastx,dlasty,yellow);            
  464.     }
  465.  
  466.     if (selected_light)
  467.     {
  468.       image *i=cash.img(light_buttons[0]);
  469.       int l=i->width()/2,h=i->height()/2;
  470.       long rx1,ry1;
  471.       the_game->game_to_mouse(selected_light->x,selected_light->y,v,rx1,ry1);      
  472.       screen->rectangle(rx1-l,ry1-h,rx1+l,ry1+h,eh->bright_color());
  473.     }
  474.  
  475.     game_object *o;
  476.     if (show_names)
  477.       for (o=current_level->first_object();o;o=o->next)
  478.       {
  479.     the_game->game_to_mouse(o->x,o->y,current_view,x1,y1);
  480.     char *nm=object_names[o->otype];
  481.     console_font->put_string(screen,x1-strlen(nm)*console_font->width()/2,y1+2,nm);
  482.       }
  483.     
  484.     if (dev&DRAW_LINKS)
  485.     {
  486.       // draw connections between objects
  487.       for (o=current_level->first_object();o;o=o->next)
  488.       {
  489.     the_game->game_to_mouse(o->x,o->y,current_view,x1,y1);
  490.  
  491.     int i=0;
  492.     for (;i<o->total_objects();i++)
  493.     {
  494.       game_object *other=o->get_object(i);
  495.       the_game->game_to_mouse(other->x,other->y,current_view,x2,y2);    
  496.       screen->line(x1,y1,x2,y2,eh->bright_color());
  497.     }
  498.  
  499.     for (i=0;i<o->total_lights();i++)
  500.     {
  501.       light_source *l=o->get_light(i);
  502.       the_game->game_to_mouse(l->x,l->y,current_view,x2,y2);
  503.       screen->line(x1,y1,x2,y2,light_connection_color);
  504.     }
  505.  
  506.       }
  507.     }
  508.  
  509.     if (selected_object)
  510.     {    
  511.       selected_object->picture_space(x1,y1,x2,y2);    
  512.       long rx1,ry1,rx2,ry2;
  513.       the_game->game_to_mouse(x1,y1,v,rx1,ry1);
  514.       the_game->game_to_mouse(x2,y2,v,rx2,ry2);
  515.       screen->rectangle(rx1,ry1,rx2,ry2,eh->bright_color());
  516.  
  517.       the_game->game_to_mouse(selected_object->x,selected_object->y,current_view,x1,y1);
  518.       for (int i=0;i<selected_object->total_objects();i++)
  519.       {
  520.     game_object *other=selected_object->get_object(i);
  521.     the_game->game_to_mouse(other->x,other->y,current_view,x2,y2);
  522.     screen->line(x1,y1,x2,y2,light_connection_color);
  523.       }
  524.     }  
  525.  
  526.  
  527.   }
  528.  
  529.   update_memprof();
  530. }
  531.  
  532. light_source *find_light(long x, long y)
  533. {
  534.   image *i=cash.img(light_buttons[0]);
  535.   int l=i->width()/2,h=i->height()/2;
  536.   for (light_source *f=first_light_source;f;f=f->next)
  537.   {
  538.     if (x>=f->x-l && x<=f->x+l && y>=f->y-h && y<=f->y+h)
  539.       return f;
  540.   }
  541.   return NULL;
  542. }
  543.  
  544.  
  545. extern void small_static_allocation_summary(int &total, int *&static_list, int *&cache_list);
  546.  
  547. void dev_controll::update_memprof()
  548. {
  549.   if (memprof)
  550.   {
  551.     int i,largest=0;
  552.     int total,*st,*ch;
  553.     small_static_allocation_summary(total,st,ch); 
  554.  
  555.     int x=WINDOW_FRAME_LEFT;
  556.     int y=WINDOW_FRAME_TOP;
  557.     memprof->clear();
  558.  
  559.     for (i=0;i<total;i++)
  560.     {
  561.       int h=st[i]*100/3000;  x++;
  562.       memprof->screen->bar(x,y,x,y+h,eh->bright_color());
  563.       h=ch[i]*100/3000;
  564.       memprof->screen->bar(x,y,x,y+h,eh->medium_color());
  565.       x++;
  566.     }
  567.     jfree(st);
  568.     jfree(ch);
  569.     char buf[100];
  570.     sprintf(buf,"%8d %8d",j_allocated(),j_available());
  571.     eh->font()->put_string(memprof->screen,memprof->x1(),memprof->y2()-eh->font()->height(),buf);
  572.  
  573.   }
  574.   
  575. }
  576.  
  577. void dev_controll::toggle_memprof()
  578. {
  579.   if (memprof)
  580.   {
  581.     prop->setd("memprof x",memprof->x);
  582.     prop->setd("memprof y",memprof->y);
  583.     eh->close_window(memprof);
  584.     memprof=NULL;
  585.   } else
  586.   {
  587.     int total,*st,*ch;
  588.     small_static_allocation_summary(total,st,ch);
  589.     jfree(st);
  590.     jfree(ch);
  591.     memprof=eh->new_window(0,0,total*2+20,100,NULL);
  592.     update_memprof();   
  593.   }
  594. }
  595.  
  596. void dev_controll::toggle_toolbar()
  597. {
  598.   if (tbw)
  599.   {
  600.     tbw_on=0;
  601.     prop->setd("toolbar x",tbw->x);
  602.     prop->setd("toolbar y",tbw->y);
  603.     eh->close_window(tbw);
  604.     tbw=NULL;
  605.   } else
  606.   {
  607.     tbw_on=1;
  608.     int setx=0;
  609.     for (int i=0;i<DEV_MODES;i++)
  610.     {
  611.       if (edit_mode==dev_mode_ids[i])
  612.         setx=i;
  613.       dev_mode_pict[i]=new cached_image(dev_mode_icon[i]);
  614.     }
  615.  
  616.     tool_picker *tp=new tool_picker(WINDOW_FRAME_LEFT,WINDOW_FRAME_TOP, 
  617.         ID_NULL,
  618.         5,(visual_object **)dev_mode_pict,dev_mode_ids,DEV_MODES,
  619.         pal,pal,eh,NULL);
  620.     int sx=WINDOW_FRAME_LEFT,sy=WINDOW_FRAME_TOP;
  621.     tbw=eh->new_window(prop->getd("toolbar x",-1),
  622.         prop->getd("toolbar y",-1),-1,-1,tp);
  623.     tp->set_x(setx,tbw->screen,eh);
  624.   }
  625. }
  626.  
  627. void dev_controll::toggle_show_menu()
  628. {
  629.   if (show_menu)
  630.   {
  631.     show_menu_on=0;
  632.     prop->setd("layer x",show_menu->x);
  633.     prop->setd("layer y",show_menu->y);
  634.     eh->close_window(show_menu);
  635.     show_menu=NULL;
  636.   } else
  637.   {
  638.     show_menu_on=1;
  639.     int sx=WINDOW_FRAME_LEFT,sy=WINDOW_FRAME_TOP;
  640.  
  641.     button *lnb=new button(sx,sy+100,SHOW_LINKS,            symbol_str("l_links"),NULL);           if (dev&DRAW_LINKS)          lnb->push();
  642.     button *lb=new button(sx,sy+80,  SHOW_LIGHT,            symbol_str("l_light"),lnb);          if (dev&DRAW_LIGHTS)         lb->push();
  643.     button *cb=new button(sx,sy+60,  SHOW_CHARACTERS,       symbol_str("l_char"),lb);       if (dev&DRAW_PEOPLE_LAYER)   cb->push();
  644.     button *bb=new button(sx,sy+40,  SHOW_BACKGROUND,       symbol_str("l_back"),cb);       if (dev&DRAW_BG_LAYER)       bb->push();
  645.     button *bdb=new button(sx,sy+20, SHOW_FOREGROUND_BOUND, symbol_str("l_bound"),bb); if (dev&DRAW_FG_BOUND_LAYER) bdb->push();
  646.     button *fb=new button(sx,sy+ 0,  SHOW_FOREGROUND,       symbol_str("l_fore"),bdb);      if (dev&DRAW_FG_LAYER)       fb->push();
  647.  
  648.     show_menu=eh->new_window(prop->getd("layer x",-1),
  649.         prop->getd("layer y",-1),
  650.         -1,-1,fb,symbol_str(symbol_str("SHOW?")));
  651.   }
  652. }
  653.  
  654.  
  655. char **listable_objs=NULL;
  656. int total_listable;
  657.  
  658. void dev_controll::toggle_omenu()
  659. {
  660.   if (omenu)
  661.   {
  662.     omenu_on=0;
  663.     prop->setd("objects x",omenu->x);
  664.     prop->setd("objects y",omenu->y);
  665.     eh->close_window(omenu);
  666.     omenu=NULL;
  667.     jfree(listable_objs);
  668.     listable_objs=NULL;
  669.   }
  670.   else
  671.   {
  672.     omenu_on=1;
  673.     total_listable=0;
  674.     int i=0;
  675.     for (;i<total_objects;i++)
  676.       if (!figures[i]->get_cflag(CFLAG_UNLISTABLE))
  677.         total_listable++;
  678.     listable_objs=(char **)jmalloc(sizeof(char *)*total_listable,"omenu list");
  679.     int c=0;   
  680.     for (i=0;i<total_objects;i++)
  681.       if (!figures[i]->get_cflag(CFLAG_UNLISTABLE))
  682.       {
  683.     listable_objs[c]=object_names[i];
  684.     c++;
  685.       }
  686.           
  687.     omenu=eh->new_window(prop->getd("objects x",0),
  688.         prop->getd("objects y",0),-1,-1,
  689.         new pick_list(WINDOW_FRAME_LEFT,
  690.             WINDOW_FRAME_TOP,DEV_CREATE,yres/eh->font()->height()/2,
  691.             listable_objs,total_listable,0,NULL,cash.img(window_texture)));
  692.   }  
  693.  
  694. int get_omenu_item(int x)
  695. {
  696.   for (int i=0;i<total_objects;i++)
  697.     if (listable_objs[x]==object_names[i])
  698.       return i;
  699.   return 0;
  700. }
  701.  
  702. void dev_controll::toggle_pmenu()
  703. {
  704.   if (pmenu)
  705.   {
  706.     pmenu_on=0;
  707.     prop->setd("pal x",pmenu->x);
  708.     prop->setd("pal y",pmenu->y);
  709.     eh->close_window(pmenu);
  710.     pmenu=NULL;
  711.     jfree(pwin_list);
  712.   }
  713.   else if (total_pals)
  714.   {
  715.     pmenu_on=1;
  716.     pwin_list=(char **)jmalloc(total_pals*sizeof(char *),"pal pick list");
  717.     int i;
  718.     for (i=0;i<total_pals;i++)
  719.       pwin_list[i]=pal_wins[i]->name;
  720.  
  721.     pmenu=eh->new_window(prop->getd("pal x",0),
  722.         prop->getd("pal y",-1),
  723.         -1,-1,
  724.         new pick_list(WINDOW_FRAME_LEFT,
  725.             WINDOW_FRAME_TOP,DEV_PALETTE,yres/eh->font()->height()/2,
  726.             pwin_list,total_pals,0,NULL,cash.img(window_texture)));
  727.   } else the_game->show_help(symbol_str("no_pals"));
  728.  
  729.  
  730. void dev_controll::toggle_fgw()
  731. {
  732.   if (!forew)
  733.   {
  734.     forew_on=0;
  735.     int maxh=(yres-25)/(the_game->ftile_height()/fg_scale);
  736.     int tw=the_game->ftile_width()*fg_w/fg_scale,
  737.       th=the_game->ftile_height()/fg_scale;
  738.  
  739.     tile_picker *f_tp=new tile_picker(WINDOW_FRAME_LEFT+1,WINDOW_FRAME_TOP+1,
  740.         DEV_FG_PICKER,SPEC_FORETILE,eh,fg_scale,maxh,fg_w,NULL);
  741.     f_tp->reverse();
  742.  
  743.     forew=eh->new_window(prop->getd("fore x",-30),
  744.         prop->getd("fore y",0),
  745.         -1,-1,
  746.         f_tp,symbol_str("l_fg"));
  747.   } else
  748.   { 
  749.     forew_on=1;
  750.     prop->setd("fore x",forew->x);
  751.     prop->setd("fore y",forew->y);
  752.     eh->close_window(forew);
  753.     forew=NULL;
  754.   }
  755. }
  756.  
  757. void dev_controll::toggle_music_window()
  758. {
  759.   /*  if (!music_window)
  760.       {
  761.       music_window=eh->new_window(-1,30,0,0,
  762.       new pick_list(WINDOW_FRAME_LEFT,WINDOW_FRAME_TOP,
  763.       DEV_MUSIC_PICKLIST,10,song_list,total_songs,0,NULL));
  764.       eh->fnt->put_string(music_window->screen,WINDOW_FRAME_LEFT,1,"songs");
  765.       } else
  766.       { 
  767.       eh->close_window(music_window);
  768.       music_window=NULL;
  769.       }*/
  770. }
  771.  
  772. void dev_controll::toggle_bgw()
  773. {
  774.   if (!backw)
  775.   {
  776.     backw_on=0;
  777.     int maxh=(yres-25)/(the_game->btile_height()/bg_scale);
  778.     int tw=the_game->btile_width()*bg_w/bg_scale,
  779.       th=the_game->btile_height()/bg_scale;
  780.  
  781.     backw=eh->new_window(prop->getd("back x",-30),
  782.         prop->getd("back y",0),
  783.         -1,-1,
  784.         new tile_picker(WINDOW_FRAME_LEFT+1,WINDOW_FRAME_TOP+1,
  785.             DEV_BG_PICKER,SPEC_BACKTILE,eh,bg_scale,maxh,bg_w,NULL),symbol_str("l_bg"));
  786.   } else
  787.   { 
  788.     backw_on=1;
  789.     prop->setd("back x",backw->x);
  790.     prop->setd("back y",backw->y);
  791.     eh->close_window(backw);
  792.     backw=NULL;
  793.   }
  794. }
  795.  
  796. void dev_controll::toggle_search_window()
  797. {
  798.   if (!search_window)
  799.   {
  800.     int wl=WINDOW_FRAME_LEFT+1,
  801.       wh=WINDOW_FRAME_TOP+1;
  802.     int bh=cash.img(dev_forward)->height(),
  803.       bw=cash.img(dev_forward)->width();
  804.     search_window=eh->new_window(prop->getd("searchw x",-30),
  805.         prop->getd("searchw y",0),
  806.         -1,-1,
  807.         new text_field(wl,wh,ID_SEARCH_TEXT,"object name>",
  808.             "***************************",
  809.             prop->get("search name",""),
  810.             new button(wl+bw*1,wh+eh->font()->height()+5,ID_SEARCH_BACKWARD,
  811.                 cash.img(dev_backward),
  812.                 new button(wl+bw*3,wh+eh->font()->height()+5,ID_SEARCH_FOREWARD,
  813.                     cash.img(dev_forward),NULL))),"SEARCH");
  814.     searchw_on=0;
  815.   } else
  816.   {
  817.     searchw_on=1; 
  818.     prop->setd("searchw x",search_window->x);
  819.     prop->setd("searchw y",search_window->y);
  820.     prop->set("search name",search_window->read(ID_SEARCH_TEXT));
  821.     eh->close_window(search_window);
  822.     search_window=NULL;
  823.     search_object=NULL;
  824.   }
  825. }
  826.  
  827. int open_owin=0,open_fwin=0,open_bwin=0,start_edit=0,start_nodelay=0,start_doubled=0,start_mem=0;
  828.  
  829.  
  830. int get_option(char *name);
  831.  
  832.  
  833. void dev_init(int argc, char **argv)
  834. {
  835.   scale_mult=1;
  836.   scale_div=1; 
  837.   dev=0;
  838.   int i;
  839.   prop=new property_manager;
  840.   prop->load("defaults.prp");
  841.  
  842.   for (i=1;i<argc;i++)
  843.   {    
  844.     if (!strcmp(argv[i],"-edit"))
  845.     {
  846.       if (!registered)
  847.         dprintf("%s\n",symbol_str("no_edit"));
  848.       else
  849.       {
  850.         dev|=EDIT_MODE;    
  851.         start_edit=1;
  852.         start_running=1;
  853.         disable_autolight=1;
  854.         if (get_option("-2"))
  855.         {
  856.           dprintf("%s\n",symbol_str("no2"));
  857.           exit(0);
  858.         }
  859.       }
  860.     }
  861.     else if (!strcmp(argv[i],"-fwin"))
  862.       open_fwin=1;    
  863.     else if (!strcmp(argv[i],"-show_mem"))
  864.       start_mem=1;    
  865.     else if (!strcmp(argv[i],"-bwin"))
  866.       open_bwin=1;          
  867.     else if (!strcmp(argv[i],"-owin"))
  868.       open_owin=1;        
  869.     else if (!strcmp(argv[i],"-nodelay"))
  870.       start_nodelay=1;        
  871.     else if (!strcmp(argv[i],"-scale"))
  872.     {
  873.       i++;      
  874.       scale_mult=atoi(argv[i++]);
  875.       scale_div=atoi(argv[i]);
  876.     } else if (!strcmp(argv[i],"-f"))
  877.     {
  878.       i++;
  879.       strcpy(level_file,argv[i]);
  880.     } else if (!strcmp(argv[i],"-2"))
  881.       start_doubled=1;
  882.     else if (!strcmp(argv[i],"-demo"))
  883.       demo_start=1;
  884.  
  885.   }  
  886.  
  887.   if (get_option("-no_autolight"))
  888.     disable_autolight=0;
  889.  
  890.   if ((get_option("-size") || get_option("-vmode")) && !start_edit)
  891.   {
  892.     dprintf("%s\n",symbol_str("no_hirez"));
  893.     exit(0);
  894.   }
  895.  
  896.   fg_reversed=prop->getd("fg_reversed",0);
  897.   mouse_scrolling=prop->getd("mouse_scrolling",0);
  898.   palettes_locked=prop->getd("palettes_locked",0);
  899.   view_shift_disabled=prop->getd("view_shift_disabled",0);
  900.   fps_on=prop->getd("fps_on",0);
  901.   show_names=prop->getd("show_names",0);
  902.   raise_all=prop->getd("raise_all",0);
  903. }
  904.  
  905. static pmenu *make_menu(int x, int y);
  906.  
  907.  
  908. dev_controll::dev_controll()
  909. {
  910.   area_win=NULL;
  911.   current_area=NULL;
  912.   fg_w=bg_w=1;
  913.   commandw=NULL;
  914.   bg_scale=fg_scale=1;
  915.   pal_wins=NULL;
  916.   total_pals=0;
  917.   state=DEV_SELECT;
  918.   aiw=NULL;
  919.   edit_light=NULL;
  920.   selected_light=NULL;
  921.  
  922.   tbw=NULL;
  923.   modew=NULL;
  924.   link_object=NULL;
  925.   selected_object=NULL;
  926.   edit_object=NULL;
  927.   ai_object=NULL;
  928.   memprof=NULL;
  929.   oedit=NULL;  
  930.   forew=NULL;
  931.   backw=NULL;  
  932.   omenu=NULL;  
  933.   ledit=NULL;
  934.   pmenu=NULL;
  935.   lightw=NULL;
  936.   search_window=NULL;
  937.   show_menu=NULL;
  938.   music_window=NULL;
  939.   ambw=NULL;
  940.   load_dev_icons();
  941.  
  942.   if (open_owin) toggle_omenu();
  943.   if (open_fwin) toggle_fgw();
  944.   if (open_bwin) toggle_bgw();
  945.   if (start_nodelay) the_game->toggle_delay();
  946.   yellow=pal->find_closest(255,255,0);
  947.   if (start_edit)
  948.   {
  949.     the_game->load_level(level_file);
  950.     the_game->draw();
  951.   }
  952.   
  953.   dev_console=new dev_term(50,18,this);
  954.  
  955.  
  956.   if (start_edit)
  957.     make_edit_mode_menu();
  958.  
  959.  
  960.   if (get_option("-nolight"))
  961.     dev=dev^DRAW_LIGHTS;
  962.   if (start_mem)
  963.     toggle_memprof();
  964. }
  965.  
  966.  
  967. void dev_controll::set_state(int new_state)
  968. {
  969.   if (start_doubled && new_state==RUN_STATE && !small_render)
  970.     double_render();
  971. }
  972.  
  973. void dev_controll::load_stuff()
  974. {  
  975.   if (dev & EDIT_MODE)
  976.   {
  977.     char prog[100],*cs;
  978.     strcpy(prog,"(compile-file \"edit.lsp\")");
  979.     cs=prog;
  980.     void *p=compile(cs);
  981.     l_user_stack.push(p);
  982.     eval(p);
  983.     l_user_stack.pop(1);
  984.     for (int i=0;i<total_pals;i++)
  985.       pal_wins[i]->close_window();
  986.   }
  987.  
  988. }
  989.  
  990. void dev_controll::do_command(char *command, event &ev)
  991. {
  992.   char fword[50],*st;
  993.   int l,h,x,y,i;
  994.   if (command[0]=='(')            // is this a lisp command?
  995.   {
  996.     eval(compile(command));  
  997.     return ;
  998.   }
  999.  
  1000.   sscanf(command,"%s",fword);
  1001.   for (st=command;*st && *st!=' ';st++);
  1002.   if (*st) st++;
  1003.   if (!strcmp(fword,"active"))
  1004.   {
  1005.     if (current_level && current_level->first_active_object())
  1006.     {
  1007.       game_object *o=current_level->first_active_object();
  1008.       while (o)
  1009.       {
  1010.         dprintf("%s %d %d %d %d\n",object_names[o->otype],o->x,o->y,
  1011.             figures[o->otype]->rangex,
  1012.             figures[o->otype]->rangey
  1013.                 );
  1014.         o=o->next_active;
  1015.       }
  1016.     }
  1017.   }
  1018.  
  1019.   if (!strcmp(fword,"clear_weapons"))
  1020.   {
  1021.     view *f=NULL;
  1022.     for (f=player_list;f;f=f->next)
  1023.     {
  1024.       int i;
  1025.       for (i=0;i<total_weapons;i++)
  1026.     f->weapons[i]=-1;
  1027.  
  1028.       if (total_weapons)
  1029.         f->weapons[0]=0;
  1030.     }
  1031.   }
  1032.  
  1033.   if (!strcmp(fword,"reload"))
  1034.   {
  1035.     if (current_level && player_list && player_list->focus)
  1036.     {
  1037.       edit_object=selected_object=NULL;
  1038.       long cx=player_list->focus->x,cy=player_list->focus->y;
  1039.  
  1040.       // save the old weapon array
  1041.       long *w=(long *)jmalloc(total_weapons*sizeof(long),"tmp weapon array");
  1042.       memcpy(w,player_list->weapons,total_weapons*sizeof(long));
  1043.       
  1044.       char tmp[100];
  1045.       strcpy(tmp,current_level->name());
  1046.       the_game->load_level(tmp);
  1047.       current_level->unactivate_all();
  1048.  
  1049.       if (screen)  // don't draw if graphics haven't been setup yet.
  1050.         the_game->draw();
  1051.       player_list->reset_player();
  1052.       player_list->focus->x=cx;
  1053.       player_list->focus->y=cy;
  1054.  
  1055.       memcpy(player_list->weapons,w,total_weapons*sizeof(long));     
  1056.       jfree(w);
  1057.  
  1058.       the_game->need_refresh();
  1059.     }    
  1060.   }
  1061.  
  1062.   if (!strcmp(fword,"unchop"))
  1063.   {
  1064.     long rx,ry;
  1065.     the_game->btile_on(dlastx,dlasty,rx,ry);
  1066.     if (rx>=0 && ry>=0)
  1067.     {
  1068.       if (sscanf(command,"%s%d%d",fword,&l,&h)==3)
  1069.       {
  1070.         dprintf("unchopped %dx%d to ",l,h);
  1071.         l=(l+the_game->btile_width()-1)/the_game->btile_width();
  1072.         h=(h+the_game->btile_height()-1)/the_game->btile_height();
  1073.         for (y=0,i=cur_bg;y<h;y++)
  1074.           for (x=0;x<l;x++)
  1075.             the_game->put_bg(rx+x,ry+y,i++); 
  1076.         dprintf("%dx%d\n",l,h);
  1077.       } else dprintf(symbol_str("unchop1"));
  1078.  
  1079.     }      
  1080.   } 
  1081.   if (!strcmp(fword,"center"))
  1082.   {
  1083.     view *v=the_game->first_view;
  1084.     for (;v;v=v->next)
  1085.     {
  1086.       v->pan_x=0;
  1087.       v->pan_y=0;
  1088.     }
  1089.     the_game->need_refresh();
  1090.   }
  1091.  
  1092.   if (!strcmp(fword,"size"))
  1093.   {
  1094.     int l,w;    
  1095.     if (sscanf(command,"%s%d%d",fword,&l,&w)==3)
  1096.     {
  1097.       current_level->set_size(l,w);    
  1098.       dprintf("level is now %dx%d\n",l,w);
  1099.     } else dprintf(symbol_str("size1"));
  1100.  
  1101.  
  1102.   }
  1103.   if (!strcmp(fword,"name"))
  1104.   {
  1105.     while (*command && *command!=' ') command++;
  1106.     if (*command)
  1107.       current_level->set_name(command+1);    
  1108.     dprintf(symbol_str("name_now"),current_level->name());
  1109.   }
  1110.   if (!strcmp(fword,"set_first_level"))
  1111.   {
  1112.     strcpy(level_file,st);
  1113.     dprintf("first level will be '%s'\n",level_file);       
  1114.   }
  1115.  
  1116.   if (!strcmp(fword,"load"))
  1117.   {
  1118.     if (!strcmp(st,"STARTING_LEVEL"))
  1119.       st=level_file;
  1120.  
  1121.     dprintf("loading '%s'\n",st);
  1122.     the_game->load_level(st);    
  1123.     current_level->unactivate_all();
  1124.  
  1125.     the_game->need_refresh();
  1126.   }
  1127.  
  1128.   if (!strcmp(fword,"mem"))
  1129.   {
  1130.     if (st[0])    
  1131.       show_char_mem(st);
  1132.     else show_mem();
  1133.   }
  1134.  
  1135.   if (!strcmp(fword,"esave"))
  1136.   {
  1137.     dprintf(symbol_str("esave"));
  1138.     save();
  1139.   }
  1140.  
  1141.   if (!strcmp(fword,"delete"))
  1142.   {      
  1143.     if (selected_object)
  1144.     {
  1145.       if (!(dev&EDIT_MODE) && current_level->is_attacker(selected_object))
  1146.         the_game->show_help(symbol_str("nd_player"));
  1147.       else
  1148.       {      
  1149.     if (selected_object->controller())
  1150.       the_game->show_help(symbol_str("nd_player"));
  1151.     else
  1152.     {
  1153.       current_level->delete_object(selected_object);
  1154.       if (S_DELETE_SND>0) cash.sfx(S_DELETE_SND)->play(sfx_volume/2);
  1155.       selected_object=NULL;    
  1156.     }
  1157.       }
  1158.     } else if (selected_light)
  1159.     {
  1160.       if (!edit_light)
  1161.       {
  1162.     if (current_level)
  1163.     {
  1164.           current_level->remove_light(selected_light);
  1165.       if (S_DELETE_SND>0) cash.sfx(S_DELETE_SND)->play(sfx_volume/2);
  1166.     }
  1167.     else
  1168.           delete_light(selected_light);
  1169.     selected_light=NULL;
  1170.       }      
  1171.     } else the_game->show_help(symbol_str("d_nosel"));
  1172.     the_game->need_refresh();
  1173.   }
  1174.  
  1175.   if (!strcmp(fword,"create"))
  1176.   {
  1177.     char oname[100];
  1178.     sscanf(command,"%s%s",fword,oname);       // read the type of object to create
  1179.     int x,t=-1;
  1180.     for (x=0;x<total_objects;x++)             // find the object type by name
  1181.       if (!strcmp(object_names[x],oname))
  1182.         t=x;
  1183.  
  1184.     if (t>=0)                                 // did we find it?
  1185.     {
  1186.       long rx,ry;
  1187.       the_game->mouse_to_game(dlastx,dlasty,rx,ry);
  1188.       edit_object=create(t,rx,ry);
  1189.       current_level->add_object(edit_object);
  1190.       the_game->need_refresh();
  1191.       last_created_type=t;
  1192.     } else
  1193.     {
  1194.       sprintf(fword,"No such object type : %s\n",oname);
  1195.       the_game->show_help(fword);
  1196.     }
  1197.   }
  1198.  
  1199.   if (!strcmp(fword,"move"))
  1200.   {
  1201.     if (selected_object)   
  1202.       edit_object=selected_object;      
  1203.  
  1204.     if (edit_object)
  1205.       state=DEV_MOVE_OBJECT;
  1206.     else the_game->show_help("No object selected");
  1207.       
  1208.   }
  1209.   if (!strcmp(fword,"move_light"))
  1210.   {
  1211.     if (selected_light)   
  1212.       edit_light=selected_light;      
  1213.  
  1214.     if (edit_light)
  1215.       state=DEV_MOVE_LIGHT;
  1216.     else the_game->show_help("No light selected");
  1217.       
  1218.   }
  1219.  
  1220.   
  1221.   if (!strcmp(fword,"clear_auto"))
  1222.   {
  1223.     long i,j;
  1224.     for (i=0;i<current_level->foreground_width();i++)
  1225.       for (j=0;j<current_level->foreground_height();j++)
  1226.         current_level->clear_fg(i,j);
  1227.   }
  1228.  
  1229.   if (!strcmp(fword,"fg_select"))
  1230.   {
  1231.     long x,y;
  1232.     the_game->ftile_on(dlastx,dlasty,x,y);
  1233.     if (x>=0 && y>=0 && x<current_level->foreground_width() &&
  1234.     y<current_level->foreground_height())
  1235.     {
  1236.       cur_fg=current_level->get_fg(x,y);
  1237.       if (forew)      
  1238.     ((tile_picker *)forew->read(DEV_FG_PICKER))->recenter(forew->screen,eh);      
  1239.       the_game->need_refresh();
  1240.     }
  1241.   }
  1242.  
  1243.   if (!strcmp(fword,"toggle_fg_raise"))
  1244.   {
  1245.     long x,y;
  1246.     the_game->ftile_on(dlastx,dlasty,x,y);
  1247.     if (x>=0 && y>=0 && x<current_level->foreground_width() &&
  1248.     y<current_level->foreground_height())    
  1249.       current_level->fg_set_raised(x,y,!current_level->fg_raised(x,y));    
  1250.   }
  1251.   
  1252.   if (!strcmp(fword,"fg_add"))
  1253.   {
  1254.     int x;
  1255.     if (sscanf(st,"%d",&x))
  1256.     {
  1257.       cur_fg++;
  1258.       if (cur_fg<0) cur_fg=0;
  1259.       if (cur_fg>=nforetiles) cur_fg=nforetiles-1;
  1260.  
  1261.       if (forew)      
  1262.     ((tile_picker *)forew->read(DEV_FG_PICKER))->recenter(forew->screen,eh);      
  1263.     }   
  1264.   }
  1265.  
  1266.   if (!strcmp(fword,"mem_report"))
  1267.     mem_report("memory.report");
  1268.  
  1269.   if (!strcmp(fword,"restart"))
  1270.   {
  1271.     current_level->restart();
  1272.   }
  1273.   if (!strcmp(fword,"quit"))
  1274.   {
  1275.     the_game->end_session();
  1276.   }
  1277.  
  1278.   if (!strcmp(fword,"to_front"))
  1279.   {
  1280.     game_object *which=selected_object;
  1281.     if (!selected_object) which=edit_object;
  1282.     if (which)    
  1283.       current_level->to_front(which);
  1284.     else the_game->show_help(symbol_str("forward?"));
  1285.   }
  1286.  
  1287.   if (!strcmp(fword,"to_back"))
  1288.   {
  1289.     game_object *which=selected_object;
  1290.     if (!selected_object) which=edit_object;
  1291.     if (which)    
  1292.       current_level->to_back(which);
  1293.     else the_game->show_help(symbol_str("back?")); 
  1294.   }
  1295.  
  1296.   if (!strcmp(fword,"set_aitype"))
  1297.   {
  1298.     game_object *which=selected_object;
  1299.     if (!selected_object) which=edit_object;
  1300.     if (which)    
  1301.     {
  1302.       int x;
  1303.       if (*st && sscanf(st,"%d",&x)!=EOF)
  1304.         which->change_aitype(x);
  1305.       else 
  1306.       {
  1307.     switch (ev.key)
  1308.     {
  1309.       case '0' : which->change_aitype(0); break;
  1310.       case '1' : which->change_aitype(1); break;
  1311.       case '2' : which->change_aitype(2); break;
  1312.       case '3' : which->change_aitype(3); break;
  1313.       case '4' : which->change_aitype(4); break;
  1314.       case '5' : which->change_aitype(5); break;
  1315.       case '6' : which->change_aitype(6); break;
  1316.       case '7' : which->change_aitype(7); break;
  1317.       case '8' : which->change_aitype(8); break;
  1318.       case '9' : which->change_aitype(9); break;
  1319.       case ')' : which->change_aitype(10); break;
  1320.       case '!' : which->change_aitype(11); break;
  1321.       case '@' : which->change_aitype(12); break;
  1322.       case '#' : which->change_aitype(13); break;
  1323.       case '$' : which->change_aitype(14); break;
  1324.       case '%' : which->change_aitype(15); break;
  1325.       case '^' : which->change_aitype(16); break;
  1326.       case '&' : which->change_aitype(17); break;
  1327.       case '*' : which->change_aitype(18); break;
  1328.       case '(' : which->change_aitype(19); break;
  1329.     }
  1330.       }     
  1331.       the_game->need_refresh();
  1332.     }
  1333.     else the_game->show_help(symbol_str("aitype"));
  1334.   }
  1335.  
  1336.  
  1337. }
  1338.  
  1339.  
  1340. void dev_controll::toggle_light_window()
  1341. {
  1342.   if (!lightw)
  1343.   {
  1344.     int wl=WINDOW_FRAME_LEFT,wh=WINDOW_FRAME_TOP,bh=16+6,bw=20+6,th=eh->font()->height()+4;    
  1345.     lightw=eh->new_window(prop->getd("light create x",0),
  1346.         prop->getd("light create y",0),
  1347.         -1,-1,new button_box(wl,wh,DEV_LIGHT_BUTTON_BOX,1,
  1348.             new button(wl+bw*0,wh+bh*0,DEV_LIGHT0,cash.img(light_buttons[0]),
  1349.                 new button(wl+bw*1,wh+bh*0,DEV_LIGHT1,cash.img(light_buttons[1]),
  1350.                     new button(wl+bw*2,wh+bh*0,DEV_LIGHT2,cash.img(light_buttons[2]),
  1351.  
  1352.                         new button(wl+bw*0,wh+bh*1,DEV_LIGHT3,cash.img(light_buttons[3]),
  1353.                             new button(wl+bw*1,wh+bh*1,DEV_LIGHT4,cash.img(light_buttons[4]),
  1354.                                 new button(wl+bw*2,wh+bh*1,DEV_LIGHT5,cash.img(light_buttons[5]),
  1355.  
  1356.                     new button(wl+bw*0,wh+bh*2,DEV_LIGHT6,cash.img(light_buttons[6]),
  1357.                                         new button(wl+bw*1,wh+bh*2,DEV_LIGHT7,cash.img(light_buttons[7]),
  1358.                                             new button(wl+bw*2,wh+bh*2,DEV_LIGHT8,cash.img(light_buttons[8]),
  1359.  
  1360.                                                 new button(wl+bw*0,wh+bh*3,DEV_LIGHT9,cash.img(light_buttons[9]),
  1361.                                                     new button(wl+bw*1,wh+bh*3,DEV_AMBIENT,cash.img(light_buttons[11]),
  1362.                                                         NULL))))))))))),
  1363.  
  1364.             new text_field(wl,wh+bh*4,DEV_LIGHTW,      "W ","******",
  1365.                 prop->getd("light create w",0),
  1366.                 new text_field(wl,wh+bh*4+th*1,DEV_LIGHTH, "H ","******",
  1367.                     prop->getd("light create h",0),
  1368.                     new text_field(wl,wh+bh*4+th*2,DEV_LIGHTR1,"R1","******",
  1369.                         prop->getd("light create r1",1),
  1370.                         new text_field(wl,wh+bh*4+th*3,DEV_LIGHTR2,"R2","******",
  1371.                             prop->getd("light create r2",100),
  1372.                             NULL))))),
  1373.         symbol_str("l_light"));
  1374.                            
  1375.   } else
  1376.   {
  1377.     prop->setd("light create x",lightw->x);
  1378.     prop->setd("light create y",lightw->y);
  1379.     prop->setd("light create w",atoi(lightw->read(DEV_LIGHTW)));
  1380.     prop->setd("light create h",atoi(lightw->read(DEV_LIGHTH)));
  1381.     prop->setd("light create r1",atoi(lightw->read(DEV_LIGHTR1)));
  1382.     prop->setd("light create r2",atoi(lightw->read(DEV_LIGHTR2)));
  1383.     eh->close_window(lightw);
  1384.     lightw=NULL;
  1385.   }
  1386. }
  1387.  
  1388. void dev_controll::make_ai_window(game_object *o)
  1389. {
  1390.   ai_object=o;
  1391.   int th=eh->font()->height()+4,wl=WINDOW_FRAME_LEFT,wh=WINDOW_FRAME_TOP+20;
  1392.   if (figures[o->otype]->total_fields)
  1393.   {
  1394.     ifield *next=NULL;
  1395.     int maxl=0;
  1396.     int i=0;
  1397.     for (;i<figures[o->otype]->total_fields;i++)
  1398.       if (strlen(figures[o->otype]->fields[i]->descript_name)>maxl)
  1399.         maxl=strlen(figures[o->otype]->fields[i]->descript_name);
  1400.   
  1401.     int owh=wh;
  1402.     ifield *first,*last=NULL;
  1403.     for (i=0;i<figures[o->otype]->total_fields;i++)
  1404.     {
  1405.       char tmp[200];
  1406.       strcpy(tmp,figures[o->otype]->fields[i]->descript_name);
  1407.       for (int j=maxl-strlen(figures[o->otype]->fields[i]->descript_name);j;j--)
  1408.         strcat(tmp," ");      
  1409.       int er;
  1410.       ifield *p=new text_field(wl,wh,ID_NULL,tmp,"######",
  1411.           (double)o->get_var_by_name(figures[o->otype]->fields[i]->real_name,er),
  1412.           NULL);
  1413.       if (last)
  1414.         last->next=p;
  1415.       else
  1416.         first=p;
  1417.       last=p;
  1418.       wh+=th;
  1419.     }         
  1420.     aiw=eh->new_window(prop->getd("ai x",0),
  1421.         prop->getd("ai y",0),
  1422.         -1,-1,             
  1423.         new button(wl,owh-20,DEV_AI_OK,cash.img(dev_ok),first),"ai");
  1424.  
  1425.   }
  1426.   else
  1427.   {
  1428.     aiw=eh->new_window(prop->getd("ai x",0),
  1429.         prop->getd("ai y",0),
  1430.         -1,-1,
  1431.         new button(wl,wh-20,DEV_AI_OK,cash.img(dev_ok),
  1432.             new text_field(wl,wh+th*0, DEV_AI_XVEL,    symbol_str("ai_xvel"),"#####",(double)o->xvel(),
  1433.                 new text_field(wl,wh+th*1, DEV_AI_YVEL,    symbol_str("ai_yvel"),"#####",(double)o->yvel(),
  1434.                     new text_field(wl,wh+th*2, DEV_AI_XACEL,   symbol_str("ai_xacel"),"#####",(double)o->xacel(),
  1435.                         new text_field(wl,wh+th*3, DEV_AI_YACEL,   symbol_str("ai_yacel"),"#####",(double)o->yacel(),
  1436.                             new text_field(wl,wh+th*4, DEV_AI_STTIME,  symbol_str("ai_stime"),"####",(double)o->aistate_time(),
  1437.                                 new text_field(wl,wh+th*5, DEV_AI_GRAVITY, symbol_str("ai_gravity"),"####",(double)o->gravity(),
  1438.                                     new text_field(wl,wh+th*6, DEV_AI_HEALTH,  symbol_str("ai_health"),"####",(double)o->hp(),
  1439.                                         new text_field(wl,wh+th*7, DEV_AI_MORPHPR, symbol_str("ai_morph"),"####",(double)o->mp(),
  1440.                                             new text_field(wl,wh+th*8, DEV_AI_TYPE,    symbol_str("ai_type"),"####",(double)o->aitype(),
  1441.                                                 new text_field(wl,wh+th*9,DEV_AI_STATE,    symbol_str("ai_state"),"####",(double)o->aistate(),
  1442.                                                     new text_field(wl,wh+th*10,DEV_AI_FADE,    symbol_str("ai_fade"),"####",(double)o->fade_count(),
  1443.                                                         NULL)))))))))))),"ai");
  1444.   }
  1445.  
  1446.   eh->grab_focus(aiw);
  1447. }
  1448.  
  1449. void dev_controll::notify_deleted_light(light_source *l)
  1450. {
  1451.   if (l==edit_light)
  1452.   {
  1453.     if (ledit)
  1454.     {
  1455.       prop->setd("ledit x",ledit->x);
  1456.       prop->setd("ledit y",ledit->y);
  1457.       eh->close_window(ledit); ledit=NULL;
  1458.     }
  1459.     edit_light=NULL;
  1460.   }
  1461.   if (l==selected_light)  
  1462.     selected_light=NULL;
  1463. }
  1464.  
  1465. void dev_controll::notify_deleted_object(game_object *o)
  1466. {
  1467.   if (o==edit_object)
  1468.   {
  1469.     state=DEV_SELECT;
  1470.     close_oedit_window();
  1471.   }
  1472.  
  1473.   if (o==ai_object)
  1474.     close_ai_window();
  1475.   if (o==search_object)
  1476.   { if (search_window)
  1477.     toggle_search_window();
  1478.   search_object=NULL;
  1479.   }
  1480.   if (o==link_object)
  1481.     link_object=NULL;
  1482.   if (o==selected_object)
  1483.   {
  1484.     selected_object=NULL;
  1485.     state=DEV_SELECT;
  1486.   }
  1487.  
  1488. }
  1489.  
  1490. void dev_controll::close_ai_window()
  1491. {
  1492.   if (aiw)
  1493.   {    
  1494.     game_object *o=ai_object;
  1495.     long x;
  1496.     if (o)
  1497.     {
  1498.       if (figures[o->otype]->total_fields)
  1499.       {
  1500.     ifield *f=aiw->inm->get(DEV_AI_OK)->next;
  1501.     for (int i=0;i<figures[o->otype]->total_fields;i++)
  1502.     {
  1503.       x=atoi(f->read());
  1504.       char *v=figures[o->otype]->fields[i]->real_name;
  1505.       int er;
  1506.       if (o->get_var_by_name(v,er)!=x)
  1507.             o->set_var_by_name(v,x);
  1508.       f=f->next;
  1509.     }
  1510.       }
  1511.       else
  1512.       {
  1513.     x=atoi(aiw->read(DEV_AI_XVEL)); if (x!=o->xvel()) o->set_xvel(x);
  1514.     x=atoi(aiw->read(DEV_AI_YVEL)); if (x!=o->yvel()) o->set_yvel(x);
  1515.  
  1516.     x=atoi(aiw->read(DEV_AI_XACEL)); if (x!=o->xacel()) o->set_xacel(x);
  1517.     x=atoi(aiw->read(DEV_AI_YACEL)); if (x!=o->yacel()) o->set_yacel(x);
  1518.  
  1519.     x=atoi(aiw->read(DEV_AI_STTIME)); if (x!=o->aistate_time()) o->set_aistate_time(x);
  1520.     x=atoi(aiw->read(DEV_AI_GRAVITY)); if (x!=o->gravity()) o->set_gravity(x);
  1521.  
  1522.     x=atoi(aiw->read(DEV_AI_HEALTH)); if (x!=o->hp()) o->set_hp(x);
  1523.     x=atoi(aiw->read(DEV_AI_MORPHPR)); if (x!=o->mp()) o->set_mp(x);
  1524.  
  1525.     x=atoi(aiw->read(DEV_AI_TYPE)); if (x!=o->aitype()) o->set_aitype(x);
  1526.     x=atoi(aiw->read(DEV_AI_STATE)); if (x!=o->aistate()) o->set_aistate(x);
  1527.     x=atoi(aiw->read(DEV_AI_FADE)); if (x!=o->fade_count()) o->set_fade_count(x);
  1528.       }
  1529.     }
  1530.     prop->setd("ai x",aiw->x);
  1531.     prop->setd("ai y",aiw->y);
  1532.     eh->close_window(aiw);
  1533.     aiw=NULL;
  1534.     ai_object=NULL;
  1535.     the_game->need_refresh();
  1536.   }
  1537. }
  1538.  
  1539.  
  1540. void dev_controll::area_handle_input(event &ev)
  1541. {
  1542.  
  1543.   if (ev.type==EV_MOUSE_BUTTON && ev.mouse_button)
  1544.   {
  1545.     long gx,gy;
  1546.     the_game->mouse_to_game(last_demo_mx,last_demo_my,gx,gy);
  1547.     if (!current_level) return ;
  1548.     current_area=current_level->area_list=new area_controller(gx,gy,
  1549.         the_game->ftile_width(),
  1550.         the_game->ftile_height(),
  1551.         current_level->area_list); 
  1552.     the_game->need_refresh();
  1553.     state=DEV_DRAG_AREA_BOTTOM;
  1554.   }
  1555. }
  1556.  
  1557. void dev_controll::close_area_win(int read_values)
  1558. {
  1559.   if (area_win)
  1560.   {
  1561.     prop->setd("area_box x",area_win->x);
  1562.     prop->setd("area_box y",area_win->y);
  1563.  
  1564.     if (current_area && read_values)
  1565.     {      
  1566.       current_area->ambient=atoi(area_win->read(DEV_AREA_AMBIENT));
  1567.       current_area->ambient_speed=atoi(area_win->read(DEV_AREA_AMBIENT_SPEED));
  1568.       current_area->view_xoff=atoi(area_win->read(DEV_AREA_VIEW_XOFF));
  1569.       current_area->view_yoff=atoi(area_win->read(DEV_AREA_VIEW_YOFF));
  1570.       current_area->view_xoff_speed=atoi(area_win->read(DEV_AREA_VIEW_XOFF_SPEED));
  1571.       current_area->view_yoff_speed=atoi(area_win->read(DEV_AREA_VIEW_YOFF_SPEED));
  1572.     }    
  1573.     eh->close_window(area_win);
  1574.     area_win=NULL;
  1575.   }
  1576. }
  1577.  
  1578. void dev_controll::pick_handle_input(event &ev)
  1579. {
  1580.   area_controller *find=NULL;
  1581.   int find_top=0;
  1582.   if (!current_level) return;
  1583.   if (ev.type==EV_MOUSE_BUTTON && ev.mouse_button)
  1584.   {
  1585.     long mx=last_demo_mx,my=last_demo_my;
  1586.     view *v=the_game->view_in(mx,my);
  1587.     for (area_controller *a=current_level->area_list;a;a=a->next)
  1588.     {
  1589.       long x1,y1,x2,y2;
  1590.       the_game->game_to_mouse(a->x,a->y,v,x1,y1);
  1591.       the_game->game_to_mouse(a->x+a->w,a->y+a->h,v,x2,y2);
  1592.       if (abs(x1-mx)<2 && abs(y1-my)<2)
  1593.       { find=a;    find_top=1; }
  1594.       else if (abs(x2-mx)<2 && abs(y2-my)<2)
  1595.       { find=a;    find_top=0; }
  1596.     }  
  1597.  
  1598.     time_marker now;
  1599.     int dc=now.diff_time(&last_area_click)<0.5;
  1600.     last_area_click.get_time();
  1601.     if (find && current_area && dc)
  1602.     {         
  1603.       if (area_win) close_area_win(0);
  1604.       int wl=WINDOW_FRAME_LEFT;
  1605.       int wh=WINDOW_FRAME_TOP,th=eh->font()->height()+12,bw=cash.img(dev_ok)->width()+10;
  1606.       area_win=eh->new_window(prop->getd("area_box x",0),
  1607.           prop->getd("area_box y",0),
  1608.           -1,-1,
  1609.  
  1610.           new button(wl+bw*0,wh-8,DEV_AREA_OK,cash.img(dev_ok),
  1611.               new button(wl+bw*1,wh-8,DEV_AREA_DELETE,cash.img(dev_del), 
  1612.  
  1613.                   new text_field(wl,wh+th*1,DEV_AREA_AMBIENT,         symbol_str("a_ambient"),"******",current_area->ambient,
  1614.                       new text_field(wl,wh+th*2,DEV_AREA_AMBIENT_SPEED,   symbol_str("a_aspeed"),"******",current_area->ambient_speed,
  1615.                           new text_field(wl,wh+th*3,DEV_AREA_VIEW_XOFF,       symbol_str("a_view_xoff"),"******",current_area->view_xoff,
  1616.                               new text_field(wl,wh+th*4,DEV_AREA_VIEW_YOFF,       symbol_str("a_view_yoff"),"******",current_area->view_yoff,
  1617.                                   new text_field(wl,wh+th*5,DEV_AREA_VIEW_XOFF_SPEED, symbol_str("a_view_xspd"),"******",current_area->view_xoff_speed,
  1618.                                       new text_field(wl,wh+th*6,DEV_AREA_VIEW_YOFF_SPEED, symbol_str("a_view_yspd"),"******",current_area->view_yoff_speed,
  1619.                                           NULL)))))))));
  1620.     } else if (find)
  1621.     {
  1622.       current_area=find;
  1623.       current_area->active=1;
  1624.       if (find_top)
  1625.         state=DEV_DRAG_AREA_TOP;
  1626.       else state=DEV_DRAG_AREA_BOTTOM;
  1627.       the_game->need_refresh();
  1628.     } else if (current_area)
  1629.     {
  1630.       current_area->active=0;
  1631.       current_area=NULL;
  1632.       the_game->need_refresh();
  1633.     }
  1634.   }
  1635. }
  1636.  
  1637. void dev_controll::close_oedit_window()
  1638. {
  1639.   if (oedit)
  1640.   {
  1641.     prop->setd("oedit x",oedit->x);
  1642.     prop->setd("oedit y",oedit->y);
  1643.     eh->close_window(oedit);
  1644.     oedit=NULL;         
  1645.     edit_object=NULL;
  1646.   }
  1647. }
  1648.  
  1649. int screen_shot_on=1;
  1650. int sshot_fcount=-1;
  1651.  
  1652. void dev_controll::event_move_object(event &ev)
  1653. {
  1654.   if (!edit_object)
  1655.   { state=DEV_SELECT; }
  1656.   else
  1657.   {
  1658.     if (ev.type==EV_MOUSE_MOVE)
  1659.     {
  1660.       the_game->mouse_to_game(last_demo_mx,last_demo_my,edit_object->x,edit_object->y);      
  1661.       edit_object->x=snap_x(edit_object->x);
  1662.       edit_object->y=snap_y(edit_object->y);
  1663.       the_game->need_refresh();
  1664.     }
  1665.     else if (ev.mouse_button==1 && ev.window==NULL)
  1666.     {
  1667.       state=DEV_MOUSE_RELEASE;
  1668.       selected_object=edit_object=NULL;    
  1669.     }
  1670.     if (ev.window==NULL && ev.type==EV_KEY && ev.key=='d')
  1671.     {
  1672.       long xv=0,yv=100;
  1673.       edit_object->try_move(edit_object->x,edit_object->y,xv,yv,1);
  1674.       edit_object->y+=yv;
  1675.       state=DEV_SELECT;
  1676.       selected_object=edit_object=NULL;    
  1677.     }
  1678.   }
  1679. }
  1680.  
  1681. void dev_controll::event_move_light(event &ev)
  1682. {
  1683.   if (edit_light)
  1684.   {
  1685.     if (ev.type==EV_MOUSE_MOVE)
  1686.     {
  1687.       the_game->mouse_to_game(last_demo_mx,last_demo_my,edit_light->x,edit_light->y);
  1688.       edit_light->x=snap_x(edit_light->x);
  1689.       edit_light->y=snap_y(edit_light->y);
  1690.  
  1691.       edit_light->calc_range();
  1692.       the_game->need_refresh();
  1693.     } else if (ev.type==EV_KEY)
  1694.     {
  1695.       int rd=0;
  1696.       switch (ev.key)
  1697.       {
  1698.         case '+' :
  1699.         { 
  1700.           if (edit_light->type==9)
  1701.           {
  1702.             if (edit_light->inner_radius<64)
  1703.             { edit_light->inner_radius++; rd=1; }
  1704.           } else { edit_light->outer_radius++; rd=1; }
  1705.         } break;
  1706.         case '-' :
  1707.         {
  1708.           if (edit_light->type==9)
  1709.           {
  1710.             if (edit_light->inner_radius>0)
  1711.             { edit_light->inner_radius--; rd=1; }
  1712.           } else if (edit_light->outer_radius>edit_light->inner_radius+1)
  1713.           { edit_light->outer_radius--; rd=1; }
  1714.         } break;
  1715.         case JK_RIGHT :
  1716.         {
  1717.           if (edit_light->type==9)
  1718.           { edit_light->xshift++; rd=1; }
  1719.           else if (edit_light->xshift>0) 
  1720.           { edit_light->xshift--; rd=1; }
  1721.         } break;
  1722.         case JK_LEFT :
  1723.         {
  1724.           if (edit_light->type==9)
  1725.           {
  1726.             if (edit_light->xshift>1)
  1727.             { edit_light->xshift--; rd=1; }
  1728.           }
  1729.           else
  1730.           { edit_light->xshift++; rd=1; }
  1731.         } break;
  1732.         case JK_UP :
  1733.         {
  1734.           if (edit_light->type==9)
  1735.           { edit_light->yshift++; rd=1; }
  1736.           else if (edit_light->yshift>0) 
  1737.           { edit_light->yshift--; rd=1; }
  1738.         } break;
  1739.         case JK_DOWN :
  1740.         {
  1741.           if (edit_light->type==9)
  1742.           {
  1743.             if (edit_light->yshift>1)
  1744.             { edit_light->yshift--; rd=1; }
  1745.           }
  1746.           else
  1747.           { edit_light->yshift++; rd=1; }
  1748.         } break;
  1749.         
  1750.       }      
  1751.       if (rd)
  1752.       {
  1753.         edit_light->calc_range();
  1754.         the_game->need_refresh();
  1755.       }
  1756.  
  1757.     }
  1758.   }
  1759.  
  1760.   if ((ev.mouse_button==1 && ev.window==NULL) || !edit_light)
  1761.     state=DEV_MOUSE_RELEASE;
  1762. }
  1763.  
  1764. void dev_controll::event_drag_area_bottom(event &ev)
  1765. {
  1766.   if (current_area)
  1767.   {
  1768.     long gx,gy;
  1769.     the_game->mouse_to_game(last_demo_mx,last_demo_my,gx,gy);
  1770.     if (gx>current_area->x && gy>current_area->y)
  1771.     {       
  1772.       if (gx-current_area->x!=current_area->w || gy-current_area->y!=current_area->h)
  1773.       {
  1774.         the_game->need_refresh();
  1775.         current_area->w=gx-current_area->x;
  1776.         current_area->h=gy-current_area->y;      
  1777.       }
  1778.     }
  1779.     if (ev.type==EV_MOUSE_BUTTON && !ev.mouse_button)
  1780.     {
  1781.       current_area->active=0;
  1782.       state=DEV_SELECT;
  1783.     }
  1784.   }
  1785. }
  1786.  
  1787. void dev_controll::event_drag_area_top(event &ev)
  1788. {
  1789.   if (current_area)
  1790.   {
  1791.     long gx,gy;
  1792.     the_game->mouse_to_game(last_demo_mx,last_demo_my,gx,gy);
  1793.     if (gx<current_area->x+current_area->w && gy<current_area->y+current_area->h)
  1794.     {       
  1795.       if (gx!=current_area->x || gy!=current_area->y)
  1796.       {
  1797.         the_game->need_refresh();
  1798.         current_area->x=gx;
  1799.         current_area->y=gy;
  1800.       }
  1801.     }
  1802.     if (ev.type==EV_MOUSE_BUTTON && !ev.mouse_button)
  1803.     {
  1804.       current_area->active=0;
  1805.       state=DEV_SELECT;
  1806.     }
  1807.   }
  1808. }
  1809.  
  1810. void dev_controll::event_select(event &ev)
  1811. {
  1812.   long x,y;
  1813.   if (dev&EDIT_MODE)
  1814.   {
  1815.     game_object *old=selected_object;      
  1816.     selected_object=NULL;
  1817.     if (ev.window==NULL)
  1818.     {    
  1819.       long rx,ry;
  1820.       the_game->mouse_to_game(last_demo_mx,last_demo_my,rx,ry);
  1821.  
  1822.       if (!(dev & MAP_MODE))
  1823.       {
  1824.         if (dev&DRAW_PEOPLE_LAYER)
  1825.           selected_object=current_level->find_object(rx,ry);
  1826.         light_source *old_light=selected_light;
  1827.         if (selected_object)
  1828.           selected_light=NULL;
  1829.         else
  1830.           selected_light=find_light(rx,ry);
  1831.         if (selected_light!=old_light)
  1832.           the_game->need_refresh();            
  1833.       } else { selected_light=NULL; }
  1834.  
  1835.       if (edit_mode==ID_DMODE_DRAW)
  1836.       {
  1837.         if (ev.mouse_button==1 && !selected_object && !selected_light)
  1838.         {
  1839.           long xs,ys;
  1840.           the_game->ftile_on(last_demo_mx,last_demo_my,xs,ys);
  1841.           if (xs>=0 && ys>=0 && xs<current_level->foreground_width() && 
  1842.               ys<current_level->foreground_height())          
  1843.             current_level->put_fg(xs,ys,raise_all ? make_above_tile(cur_fg) : cur_fg);
  1844.           the_game->need_refresh();
  1845.         } else if (ev.mouse_button==1 && !selected_object && !selected_light)
  1846.         {
  1847.           long xs,ys;
  1848.           the_game->btile_on(last_demo_mx,last_demo_my,xs,ys);
  1849.           if (xs>=0 && ys>=0 && xs<current_level->background_width() && 
  1850.               ys<current_level->background_height())
  1851.             current_level->put_bg(xs,ys,cur_fg);
  1852.           the_game->need_refresh();
  1853.         }
  1854.       } else if (edit_mode==ID_DMODE_AREA)
  1855.         area_handle_input(ev);
  1856.       else if (edit_mode==ID_DMODE_PICK)
  1857.         pick_handle_input(ev);                   
  1858.     }
  1859.     
  1860.     if (old!=selected_object)
  1861.       the_game->need_refresh();            
  1862.  
  1863.  
  1864.     if (ev.mouse_button)
  1865.     {
  1866.       if (selected_object)
  1867.       {
  1868.         if (edit_object && edit_object!=selected_object)      
  1869.           edit_object->add_object(selected_object);
  1870.  
  1871.         if (oedit)
  1872.           close_oedit_window();
  1873.          
  1874.         int bw=20+6,bh=16+6,wl=WINDOW_FRAME_LEFT,wh=WINDOW_FRAME_TOP,th=eh->font()->height()+4;
  1875.  
  1876.         oedit=eh->new_window(prop->getd("oedit x",0),
  1877.             prop->getd("oedit y",0),
  1878.             -1,-1,new button_box(wl,wh,ID_NULL,1,
  1879.                 new button(wl+bw*0,wh,DEV_OEDIT_OK,cash.img(dev_ok),
  1880.                     new button(wl+bw*1,wh,DEV_OEDIT_MOVE,cash.img(dev_move),
  1881.                         new button(wl+bw*2,wh,DEV_OEDIT_FRONT,cash.img(dev_front),
  1882.                             new button(wl+bw*3,wh,DEV_OEDIT_BACK,cash.img(dev_back),
  1883.                                 new button(wl+bw*4,wh,DEV_OEDIT_COPY,cash.img(dev_copy),
  1884.                                     new button(wl+bw*0,wh+bh*1,DEV_OEDIT_DELETE,cash.img(dev_del),
  1885.                                         NULL)))))),
  1886.                 new button(wl+bw*5,wh+bh*0,DEV_OEDIT_AI,cash.img(dev_ai),
  1887.  
  1888.                     new button_box(wl+bw*1,wh+bh*1,DEV_OEDIT_CHAR_BOX,0,
  1889.                         new button(wl+bw*1,wh+bh*1,DEV_OEDIT_LEFT,cash.img(dev_char_left),
  1890.                             new button(wl+bw*2,wh+bh*1,DEV_OEDIT_RIGHT,cash.img(dev_char_right),NULL)),
  1891.  
  1892.                         new button(wl+bw*3,wh+bh*1,DEV_OBJECTS_DELETE,cash.img(dev_objects),
  1893.                             new button(wl+bw*4,wh+bh*1,DEV_LIGHTS_DELETE,cash.img(dev_lights),NULL))))),
  1894.             symbol_str("l_EDIT"));
  1895.  
  1896.         
  1897.         edit_object=selected_object;    
  1898.       } else if (selected_light)
  1899.       {
  1900.         if (ledit)
  1901.         {
  1902.           prop->setd("ledit x",ledit->x);
  1903.           prop->setd("ledit x",ledit->y);
  1904.           eh->close_window(ledit);
  1905.         }
  1906.         int bw=20+6,bh=16+6,wl=WINDOW_FRAME_LEFT,wh=WINDOW_FRAME_TOP,th=eh->font()->height()+4;
  1907.         edit_light=selected_light;
  1908.         if (edit_object)
  1909.         {
  1910.           edit_object->add_light(edit_light);
  1911.           edit_light->known=1;
  1912.         }
  1913.         ledit=eh->new_window(prop->getd("ledit x",0),
  1914.             prop->getd("ledit y",0),
  1915.             -1,-1,
  1916.             new button_box(wl,wh,ID_NULL,1,
  1917.                 new button(wl+bw*0,wh,DEV_LEDIT_OK,cash.img(dev_ok),
  1918.                     new button(wl+bw*1,wh,DEV_LEDIT_MOVE,cash.img(dev_move),
  1919.                         new button(wl+bw*2,wh,DEV_LEDIT_COPY,cash.img(dev_copy),
  1920.                             new button(wl+bw*3,wh,DEV_LEDIT_DEL,cash.img(dev_del),NULL)))),
  1921.                 new text_field(wl,wh+bh,DEV_LEDIT_W,      "W ","******",edit_light->xshift,
  1922.                     new text_field(wl,wh+bh+th*1,DEV_LEDIT_H, "H ","******",edit_light->yshift,
  1923.                         new text_field(wl,wh+bh+th*2,DEV_LEDIT_R1,"R1","******",(int)(edit_light->inner_radius),
  1924.                             new text_field(wl,wh+bh+th*3,DEV_LEDIT_R2,"R2","******",(int)(edit_light->outer_radius),
  1925.                                 NULL))))));
  1926.       }
  1927.       else if (ev.window==NULL)
  1928.       {
  1929.         if (dlastx>=0 && dlasty>=0 && edit_mode==ID_DMODE_DRAW)
  1930.         {
  1931.           if ((dev & DRAW_FG_LAYER) && ev.mouse_button==1)
  1932.           {    
  1933.             the_game->ftile_on(last_demo_mx,last_demo_my,x,y);
  1934.             if (x>=0 && y>=0 && x<current_level->foreground_width() &&
  1935.                 y<current_level->foreground_height())
  1936.               the_game->put_fg(x,y,raise_all ? make_above_tile(cur_fg) : cur_fg);
  1937.           }       
  1938.           if ((dev & DRAW_BG_LAYER) && ev.mouse_button==2)
  1939.           {      
  1940.             the_game->btile_on(last_demo_mx,last_demo_my,x,y);
  1941.             if (x>=0 && y>=0 && x<current_level->background_width() &&
  1942.                 y<current_level->background_height())
  1943.               the_game->put_bg(x,y,cur_bg);
  1944.           }    
  1945.         } 
  1946.       }
  1947.     }
  1948.   }
  1949. }
  1950.  
  1951. void dev_controll::event_key(event &ev)
  1952. {
  1953.   long x,y;
  1954.   if (backw && ev.window==backw)
  1955.   { if (ev.key=='-' && bg_scale<the_game->btile_height()/2)
  1956.   { toggle_bgw();
  1957.   bg_scale++;
  1958.   toggle_bgw();
  1959.   } else if (ev.key=='+' && bg_scale>1)
  1960.   { toggle_bgw();
  1961.   bg_scale--;
  1962.   toggle_bgw();
  1963.   } else if (ev.key=='b') toggle_bgw();
  1964.   else if (ev.key=='B') { toggle_bgw(); bg_w++; if (bg_w>6) bg_w=1; toggle_bgw(); }
  1965.   }
  1966.   if (forew && ev.window==forew)
  1967.   { if (ev.key=='-' && fg_scale<the_game->ftile_height()/2)
  1968.   { toggle_fgw();
  1969.   fg_scale++;
  1970.   toggle_fgw();
  1971.   } else if (ev.key=='+' && fg_scale>1)
  1972.   { toggle_fgw();
  1973.   fg_scale--;
  1974.   toggle_fgw();
  1975.   } else if (ev.key=='i')
  1976.   {
  1977.     toggle_fgw();
  1978.     fg_reversed=!fg_reversed;
  1979.     prop->setd("fg_reversed",fg_reversed);
  1980.     toggle_fgw();
  1981.   } else if (ev.key=='f') toggle_fgw();
  1982.             
  1983.   else if (ev.key=='F') { toggle_fgw(); fg_w++; if (fg_w>6) fg_w=1; toggle_fgw(); }
  1984.   }
  1985.   if (ev.window==NULL || ev.window==pmenu ||
  1986.       ev.window==forew || is_pal_win(ev.window))  // main window actions
  1987.   {          
  1988.     switch (ev.key)
  1989.     {
  1990.       case JK_CTRL_L : if (!edit_object && !link_object) { link_object=selected_object; }
  1991.       case 'n' : current_level->next_focus(); break;                       
  1992.         //      case '/' : if (dev_console) dev_console->toggle(); break;      
  1993.       case 't' :
  1994.       {
  1995.         if (ev.window==NULL || ev.window==forew)
  1996.         {
  1997.           the_game->ftile_on(last_demo_mx,last_demo_my,x,y);
  1998.           fg_fill(cur_fg,x,y,NULL);
  1999.         }
  2000.       } break;
  2001.       case 'f' : toggle_fgw(); break;
  2002.       case 'M' : toggle_music_window(); break;                      
  2003.             
  2004.       case 'b' : toggle_bgw(); break;
  2005.       case 'a' : toggle_toolbar(); break;
  2006.       case 'A' : { if (selected_object)
  2007.       {
  2008.         if (oedit) eh->push_event(new event(DEV_OEDIT_OK,NULL));               
  2009.         make_ai_window(selected_object);
  2010.       }
  2011.       } break;
  2012.                          
  2013.       case 'o' : toggle_omenu(); break;                
  2014.             
  2015.       case '<' : do_command("to_back",ev); break;
  2016.             
  2017.       case '>' : do_command("to_front",ev); break;
  2018.       case 'p' : toggle_pmenu(); break;                
  2019.       case 'P' : profile_toggle(); break;
  2020.       case '|' : toggle_memprof(); break;
  2021.       case '.' : 
  2022.       { 
  2023.         if (last_created_type>=0)
  2024.         {
  2025.           int val=last_created_type;
  2026.           char cmd[100];
  2027.           sprintf(cmd,"create %s",object_names[val]);
  2028.           do_command(cmd,ev);
  2029.           state=DEV_CREATE_OBJECT;
  2030.           dev|=(EDIT_MODE | DRAW_PEOPLE_LAYER);        
  2031.         }
  2032.       }             
  2033.       break;    
  2034.             
  2035.             
  2036.       case 'd' : { do_command("delete",ev);  the_game->need_refresh(); } break;
  2037.       case 'i' : 
  2038.       {       
  2039.         fg_reversed=!fg_reversed;
  2040.         prop->setd("fg_reversed",fg_reversed);
  2041.         if (forew)
  2042.         {
  2043.           toggle_fgw();
  2044.           toggle_fgw();
  2045.         }
  2046.       } break;
  2047.       case 'l' : toggle_light_window(); break;
  2048.       case '!' :
  2049.       case '@' :
  2050.       case '#' :
  2051.       case '$' :
  2052.       case '%' :
  2053.       case '^' :
  2054.       case '&' :
  2055.       case '*' :
  2056.       case '(' :
  2057.       case ')' :
  2058.             
  2059.       case '0' :
  2060.       case '1' :
  2061.       case '2' :
  2062.       case '3' :
  2063.       case '4' :
  2064.       case '5' :
  2065.       case '6' :
  2066.       case '7' :
  2067.       case '8' :
  2068.       case '9' : do_command("set_aitype",ev); break;
  2069.       case 'c' : do_command("center",ev); break;
  2070.       case 'C' :  
  2071.         if (selected_object && selected_object->controller()==NULL)
  2072.         { copy_object=selected_object;
  2073.         eh->push_event(new event(DEV_OEDIT_COPY,NULL)); } break;
  2074.                   
  2075.       case 'D' : the_game->toggle_delay(); break;
  2076.       case 'L' : toggle_show_menu(); break;
  2077.       case '`' : do_command("fg_select",ev); break;
  2078.       case 'r' : { do_command("toggle_fg_raise",ev); the_game->need_refresh(); }  break;
  2079.       case '[' : do_command("fg_add -1",ev); break;
  2080.       case ']' : do_command("fg_add 1",ev); break;
  2081.       case 'R' : do_command("reload",ev); break;
  2082.       case 'w' : 
  2083.       {       
  2084.         long rx,ry;
  2085.         the_game->mouse_to_game(dlastx,dlasty,rx,ry);
  2086.         char msg[100]; sprintf(msg,symbol_str("mouse_at"),rx,ry);
  2087.         the_game->show_help(msg);
  2088.         the_game->need_refresh();
  2089.       } break;
  2090.       case 'k' :
  2091.       {
  2092.         if (selected_object && selected_object->total_objects()) 
  2093.           selected_object->remove_object(selected_object->get_object(0));
  2094.         the_game->need_refresh();
  2095.       } break;
  2096.       case 'K' :
  2097.       {
  2098.         if (selected_object && selected_object->total_objects()) 
  2099.           selected_object->remove_object(selected_object->get_object(selected_object->total_objects()-1));
  2100.         the_game->need_refresh();
  2101.       } break;
  2102.       case 'j' :
  2103.       {
  2104.         if (current_level && player_list && player_list->focus)
  2105.         {
  2106.           long rx,ry;
  2107.           the_game->mouse_to_game(dlastx,dlasty,rx,ry);
  2108.           player_list->focus->x=rx;
  2109.           player_list->focus->y=ry;
  2110.           do_command("center",ev);
  2111.           the_game->need_refresh();
  2112.         }
  2113.       } break;
  2114.       case 'z' : do_command("clear_weapons",ev); break;      
  2115.       case 'Z' : if (dev&EDIT_MODE)
  2116.       { view *v=the_game->view_in(last_demo_mx,last_demo_my);
  2117.       if (v)
  2118.       {
  2119.         v->god=!v->god;
  2120.         sbar.redraw(screen);
  2121.       }
  2122.       } break;
  2123.       case ' ' : 
  2124.       {
  2125.         if (dev & EDIT_MODE)
  2126.         {
  2127.           if (selected_object)
  2128.           {
  2129.             if (oedit)
  2130.               close_oedit_window();
  2131.             edit_object=selected_object;
  2132.             do_command("move",ev);
  2133.           } else if (selected_light)
  2134.           {
  2135.             if (ledit)
  2136.             {
  2137.               eh->close_window(ledit);
  2138.               ledit=NULL;
  2139.             }
  2140.             edit_light=selected_light;
  2141.             do_command("move_light",ev);
  2142.           }
  2143.                       
  2144.         } break;        
  2145.       }      
  2146.       case 'x' : 
  2147.       {
  2148.         if (selected_object) 
  2149.         { if (selected_object->direction>0)
  2150.           selected_object->direction=-1;
  2151.         else selected_object->direction=1;
  2152.         }
  2153.       } break;
  2154.                   
  2155.     }      
  2156.   }
  2157. }
  2158.  
  2159. void dev_controll::event_close_window(event &ev)
  2160. {
  2161.   if (ev.window)
  2162.   {      
  2163.     if (ev.window==commandw)
  2164.     {
  2165.       prop->setd("commandw x",commandw->x);
  2166.       prop->setd("commandw y",commandw->y);      
  2167.       eh->close_window(commandw); 
  2168.       commandw=NULL;    
  2169.     } else if (ev.window==oedit)
  2170.       close_oedit_window();
  2171.     else if (ev.window==ambw)
  2172.     { eh->close_window(ambw); ambw=NULL; }
  2173.     else if (ev.window==backw) toggle_bgw();
  2174.     else if (ev.window==forew) toggle_fgw();
  2175.     else if (ev.window==lightw) toggle_light_window();
  2176.     else if (ev.window==show_menu) toggle_show_menu();
  2177.     else if (ev.window==pmenu) toggle_pmenu();
  2178.     else if (ev.window==tbw) toggle_toolbar();
  2179.     else if (ev.window==omenu) toggle_omenu();
  2180.     else if (ev.window==memprof) toggle_memprof();
  2181.     else if (ev.window==search_window) toggle_search_window();
  2182.     else if (profile_handle_event(ev))  profile_on=!profile_on;
  2183.     else if (chat->chat_event(ev)) chat->toggle();
  2184.     
  2185.   }
  2186. }
  2187.  
  2188. void dev_controll::event_oedit_copy(event &ev)
  2189. {
  2190.   game_object *use=copy_object;
  2191.   if (!use) use=edit_object;
  2192.   if (use)
  2193.   {        
  2194.     game_object *old=use;
  2195.     close_oedit_window();
  2196.     if (use->controller())
  2197.       the_game->show_help(symbol_str("no_clone"));
  2198.     else
  2199.     {
  2200.       edit_object=old->copy();
  2201.  
  2202.       current_level->add_object(edit_object);
  2203.       the_game->need_refresh();
  2204.       state=DEV_MOVE_OBJECT; 
  2205.  
  2206.       close_oedit_window();
  2207.       copy_object=NULL;
  2208.     }
  2209.   }
  2210. }
  2211.  
  2212. void dev_controll::event_ledit_ok(event &ev)
  2213. {
  2214.   edit_light->xshift=atoi(ledit->read(DEV_LEDIT_W));
  2215.   edit_light->yshift=atoi(ledit->read(DEV_LEDIT_H));
  2216.   edit_light->inner_radius=atoi(ledit->read(DEV_LEDIT_R1));
  2217.   edit_light->outer_radius=atoi(ledit->read(DEV_LEDIT_R2));
  2218.   if (edit_light->outer_radius<=edit_light->inner_radius)
  2219.   {
  2220.     edit_light->inner_radius=edit_light->outer_radius-1;
  2221.     if (edit_light->inner_radius<1)
  2222.     {
  2223.       edit_light->inner_radius=1;
  2224.       edit_light->outer_radius=2;
  2225.     }
  2226.   }
  2227.  
  2228.   edit_light->calc_range();
  2229.   edit_light=NULL;
  2230.   prop->setd("ledit x",ledit->x);
  2231.   prop->setd("ledit y",ledit->y);
  2232.   eh->close_window(ledit); ledit=NULL;
  2233.   the_game->need_refresh();      
  2234. }
  2235.  
  2236. void dev_controll::event_ledit_del(event &ev)
  2237. {
  2238.   prop->setd("ledit x",ledit->x);
  2239.   prop->setd("ledit y",ledit->y);
  2240.   eh->close_window(ledit); ledit=NULL;
  2241.   if (current_level)
  2242.     current_level->remove_light(edit_light);
  2243.   else
  2244.     delete_light(edit_light);
  2245.   edit_light=NULL;
  2246.   the_game->need_refresh();
  2247. }
  2248.  
  2249. void dev_controll::handle_event(event &ev)
  2250. {
  2251.   long x,y;
  2252.   if (link_object && (dlastx!=last_link_x || dlasty!=last_link_y))
  2253.   {
  2254.     last_link_x=dlastx;
  2255.     last_link_y=dlasty;
  2256.     the_game->need_refresh();
  2257.   }
  2258.  
  2259.   if (dev_menu && dev_menu->handle_event(ev,screen,eh)) return ;
  2260.  
  2261.   if (!current_level) return ;
  2262.  
  2263.   for (x=0;x<total_pals;x++)
  2264.     pal_wins[x]->handle_event(ev);
  2265.   if (ev.type==EV_MOUSE_MOVE)
  2266.   {
  2267.     dlastx=last_demo_mx;
  2268.     dlasty=last_demo_my;    
  2269.   }
  2270.   if (dev_console && dev_console->handle_event(ev,eh))
  2271.     return;
  2272.  
  2273.   if (ev.type==EV_KEY && ev.key==JK_F2)
  2274.     write_PCX(screen,pal,"scrnshot.pcx");
  2275.   else if (ev.type==EV_KEY && ev.key==JK_F3)
  2276.   {
  2277.     char name[100];
  2278.     sprintf(name,"shot%04d.pcx",screen_shot_on++);
  2279.     write_PCX(screen,pal,name);
  2280.   } else if (ev.type==EV_KEY && ev.key==JK_F5)
  2281.   {
  2282.     if (sshot_fcount!=-1)
  2283.     {
  2284.       sshot_fcount=-1;
  2285.       the_game->show_help(symbol_str("seqs_off"));
  2286.     }
  2287.     else
  2288.     {
  2289.       sshot_fcount=0;
  2290.       the_game->show_help(symbol_str("seqs_on"));
  2291.     }    
  2292.   }
  2293.  
  2294.   switch (state)
  2295.   {
  2296.     case DEV_MOUSE_RELEASE :
  2297.     {
  2298.       if (!ev.mouse_button)
  2299.         state=DEV_SELECT;    
  2300.     } break;
  2301.  
  2302.     case DEV_CREATE_OBJECT :
  2303.     {
  2304.       if (!ev.mouse_button)    
  2305.         state=DEV_MOVE_OBJECT;
  2306.     } break;
  2307.  
  2308.  
  2309.     case DEV_MOVE_OBJECT :
  2310.     { event_move_object(ev); } break;
  2311.     
  2312.  
  2313.     case DEV_MOVE_LIGHT :    
  2314.     { event_move_light(ev); } break;
  2315.  
  2316.  
  2317.     case DEV_DRAG_AREA_BOTTOM :
  2318.     {
  2319.       event_drag_area_bottom(ev);
  2320.     } break;
  2321.  
  2322.     case DEV_DRAG_AREA_TOP :
  2323.     {
  2324.       event_drag_area_top(ev);
  2325.     } break;
  2326.  
  2327.     case DEV_SELECT :
  2328.     {  event_select(ev);  }
  2329.   }
  2330.  
  2331.   switch (ev.type)
  2332.   {
  2333.     case EV_MESSAGE :
  2334.     {
  2335.       switch (ev.message.id)
  2336.       { 
  2337.     case ID_DMODE_DRAW :
  2338.     case ID_DMODE_PICK :
  2339.     case ID_DMODE_FILL :
  2340.     case ID_DMODE_LINE : 
  2341.     case ID_DMODE_RECT :
  2342.     case ID_DMODE_BAR  : 
  2343.     case ID_DMODE_AREA :
  2344.     {
  2345.       edit_mode=ev.message.id;
  2346.     } break;
  2347.         /*    case ID_ENLARGE_RENDER :
  2348.                 {
  2349.                 if (!small_render)
  2350.                 double_render();
  2351.                 else       
  2352.                 single_render();
  2353.       
  2354.                 view_shift_disabled=!view_shift_disabled;
  2355.                 } break; */
  2356.  
  2357.     case ID_SEARCH :
  2358.     {
  2359.       toggle_search_window();
  2360.     } break;
  2361.     case ID_SEARCH_FOREWARD :
  2362.     { search_forward();
  2363.     } break;
  2364.     case ID_SEARCH_BACKWARD :
  2365.     { search_forward();
  2366.     } break;
  2367.     case ID_CANCEL :
  2368.     {
  2369.       if (mess_win)
  2370.       {
  2371.         eh->close_window(mess_win);
  2372.         mess_win=NULL;
  2373.       } break;
  2374.     } break;
  2375.     case ID_LEVEL_LOAD :
  2376.     {     
  2377.       if (!mess_win)
  2378.       {
  2379.         mess_win=file_dialog(eh,symbol_str("level_name"),current_level ? current_level->name() : "",
  2380.                 ID_LEVEL_LOAD_OK,symbol_str("ok_button"),ID_CANCEL,symbol_str("cancel_button"),
  2381.                 symbol_str("FILENAME"),ID_MESS_STR1);
  2382.         eh->grab_focus(mess_win);
  2383.       }
  2384.     } break;
  2385.     case ID_LEVEL_LOAD_OK :
  2386.     {
  2387.       char cmd[100];
  2388.       sprintf(cmd,"load %s",mess_win->read(ID_MESS_STR1));
  2389.       dev_cont->do_command(cmd,ev);
  2390.       eh->push_event(new event(ID_CANCEL,NULL));        // close window
  2391.     } break;    
  2392.     case ID_GAME_SAVE :
  2393.     {
  2394.       current_level->save("savegame.spe",1);
  2395.       the_game->show_help(symbol_str("saved_game"));
  2396.       the_game->need_refresh();      
  2397.     } break;
  2398.     case ID_LEVEL_SAVE :
  2399.     { if (current_level)
  2400.         {
  2401.           if (current_level->save(current_level->name(),0))
  2402.           {
  2403.             char msg[100];
  2404.             sprintf(msg,symbol_str("saved_level"),current_level->name());
  2405.             the_game->show_help(msg);
  2406.             the_game->need_refresh();
  2407.           }
  2408.         }
  2409.         else the_game->show_help("no current level, cannot save");
  2410.     } break;
  2411.     case ID_LEVEL_SAVEAS :
  2412.     {
  2413.       if (!mess_win)
  2414.       {
  2415.         mess_win=file_dialog(eh,symbol_str("saveas_name"),current_level ? current_level->name() : "untitled.spe",
  2416.                 ID_LEVEL_SAVEAS_OK,symbol_str("ok_button"),
  2417.                 ID_CANCEL,symbol_str("cancel_button"),
  2418.                 symbol_str("FILENAME"),ID_MESS_STR1);
  2419.         eh->grab_focus(mess_win);
  2420.       }
  2421.     } break;
  2422.     case ID_LEVEL_SAVEAS_OK :
  2423.     {
  2424.       if (current_level)
  2425.       {
  2426.         current_level->set_name(mess_win->read(ID_MESS_STR1));
  2427.         eh->push_event(new event(ID_CANCEL,NULL));        // close window after save
  2428.         eh->push_event(new event(ID_LEVEL_SAVE,NULL));        
  2429.       }
  2430.     } break;
  2431.     case ID_EDIT_SAVE :
  2432.     {
  2433.       do_command("esave",ev);
  2434.       the_game->show_help(symbol_str("edit_saved"));
  2435.     } break;
  2436.     case ID_CACHE_PROFILE :
  2437.     {
  2438.       if (current_level && !cash.prof_is_on())
  2439.       {
  2440.         cash.prof_init();
  2441.         the_game->show_help("Cache profiling is now on.");
  2442.       }
  2443.       else the_game->show_help("Cache profiling is already on!");
  2444.     } break;
  2445.  
  2446.     case ID_CACHE_PROFILE_END :  // ask the user for a file name to save as
  2447.     {
  2448.       if (cash.prof_is_on())
  2449.       {
  2450.         cash.prof_uninit();
  2451.         the_game->show_help(symbol_str("prof_off"));
  2452.       } else the_game->show_help(symbol_str("prof"));
  2453.     } break;
  2454.  
  2455.     case ID_LEVEL_NEW :
  2456.     {
  2457.       if (!mess_win)
  2458.       {
  2459.         mess_win=eh->new_window(xres/2,yres/2,-1,-1,
  2460.                 new button(WINDOW_FRAME_LEFT+10,WINDOW_FRAME_TOP+20,ID_LEVEL_NEW_OK,symbol_str("YES"),
  2461.                     new button(WINDOW_FRAME_LEFT+40,WINDOW_FRAME_TOP+20,ID_CANCEL,symbol_str("NO"),
  2462.                         new info_field(WINDOW_FRAME_LEFT,WINDOW_FRAME_TOP,ID_NULL,symbol_str("sure?"),NULL))),symbol_str("New?"));
  2463.         eh->grab_focus(mess_win);
  2464.       }
  2465.     } break;
  2466.     case ID_LEVEL_NEW_OK :
  2467.     {
  2468.       eh->push_event(new event(ID_CANCEL,NULL));  // close_window
  2469.       if (current_level)      
  2470.         delete current_level;     
  2471.       current_level=new level(100,100,"untitled.spe");
  2472.     } break;
  2473.     case ID_LEVEL_RESIZE :
  2474.     {
  2475.       if (!mess_win)
  2476.       {
  2477.         int wl=WINDOW_FRAME_LEFT,wt=WINDOW_FRAME_TOP,h=eh->font()->height()+8;
  2478.         mess_win=eh->new_window(xres/2,yres/2,-1,-1,
  2479.                 new text_field(wl,wt+h*0,ID_MESS_STR1,symbol_str("width_"),"****",
  2480.                     current_level ? current_level->foreground_width() : 100,
  2481.             new text_field(wl,wt+h*1,ID_MESS_STR2,symbol_str("height_"),"****",
  2482.                         current_level ? current_level->foreground_height() : 100,
  2483.                         new button(wl+10,wt+h*4,ID_LEVEL_RESIZE_OK,symbol_str("ok_button"),
  2484.                             new button(wt+40,wt+h*4,ID_CANCEL,symbol_str("cancel_button"),NULL)))),symbol_str("_scroll"));
  2485.       } 
  2486.     } break;
  2487.     case ID_LEVEL_RESIZE_OK :
  2488.     {
  2489.       if (current_level)
  2490.       {
  2491.         current_level->set_size(atoi(mess_win->read(ID_MESS_STR1)),
  2492.                 atoi(mess_win->read(ID_MESS_STR2)));
  2493.       } else the_game->show_help("Create a level first!");
  2494.       eh->push_event(new event(ID_CANCEL,NULL));  // close_window
  2495.     } break;
  2496.  
  2497.     case ID_SUSPEND :
  2498.     {
  2499.       dev^=SUSPEND_MODE;
  2500.       if (dev&SUSPEND_MODE)
  2501.         the_game->show_help(symbol_str("suspend_on"));
  2502.       else
  2503.             the_game->show_help(symbol_str("suspend_off"));
  2504.     } break;
  2505.     case ID_PLAY_MODE :
  2506.     {
  2507.       dev^=EDIT_MODE;
  2508.     } break;
  2509.     case ID_QUIT :
  2510.     {
  2511.       if (confirm_quit())
  2512.         do_command("quit",ev);
  2513.     } ;
  2514.     case ID_TOGGLE_MAP :
  2515.     {
  2516.       if (dev&MAP_MODE) dev-=MAP_MODE;
  2517.       else dev|=MAP_MODE;
  2518.       the_game->need_refresh();     
  2519.     } break;
  2520.     case ID_TOGGLE_LIGHT :
  2521.     {
  2522.       dev^=DRAW_LIGHTS;
  2523.       the_game->need_refresh();
  2524.     } break;
  2525.     case ID_RECORD_DEMO :
  2526.     {
  2527.       if (!mess_win)
  2528.       {
  2529.         int wl=WINDOW_FRAME_LEFT,wt=WINDOW_FRAME_TOP,h=eh->font()->height()+8;
  2530.         mess_win=eh->new_window(xres/2,yres/2,-1,-1,
  2531.                 new text_field(wl,wt+h*0,ID_RECORD_DEMO_FILENAME,
  2532.                     "demo filename","*******************",
  2533.                     "demo.dat",
  2534.                     new button(wl+10,wt+h*2,ID_RECORD_DEMO_OK,symbol_str("ok_button"),
  2535.                         new button(wt+40,wt+h*2,ID_CANCEL,symbol_str("cancel_button"),NULL))));
  2536.       }
  2537.     } break;
  2538.  
  2539.         case ID_RECORD_DEMO_OK :
  2540.     {
  2541.       demo_man.set_state(demo_manager::RECORDING,mess_win->read(ID_RECORD_DEMO_FILENAME));
  2542.       eh->push_event(new event(ID_CANCEL,NULL));        // close window      
  2543.     } break;
  2544.  
  2545.     case ID_PLAY_DEMO :
  2546.     {
  2547.       if (!mess_win)
  2548.       {
  2549.         int wl=WINDOW_FRAME_LEFT,wt=WINDOW_FRAME_TOP,h=eh->font()->height()+8;
  2550.         mess_win=eh->new_window(xres/2,yres/2,-1,-1,
  2551.                 new text_field(wl,wt+h*0,ID_PLAY_DEMO_FILENAME,
  2552.                     "demo filename","*******************",
  2553.                     "demo.dat",
  2554.                     new button(wl+10,wt+h*2,ID_PLAY_DEMO_OK,symbol_str("ok_button"),
  2555.                         new button(wt+40,wt+h*2,ID_CANCEL,symbol_str("cancel_button"),NULL))));
  2556.       }
  2557.     } break;
  2558.  
  2559.         case ID_PLAY_DEMO_OK :
  2560.     {
  2561.       demo_man.set_state(demo_manager::PLAYING,mess_win->read(ID_PLAY_DEMO_FILENAME));
  2562.       eh->close_window(mess_win);
  2563.       mess_win=NULL;
  2564.     } break; 
  2565.  
  2566.     case ID_SET_SCROLL :
  2567.     {
  2568.       if (!mess_win)
  2569.       {
  2570.         int wl=WINDOW_FRAME_LEFT,wt=WINDOW_FRAME_TOP,h=eh->font()->height()+8;
  2571.         mess_win=eh->new_window(xres/2,yres/2,-1,-1,
  2572.                 new text_field(wl,wt+h*0,ID_MESS_STR1,symbol_str("x_mul"),"****",bg_xmul,
  2573.             new text_field(wl,wt+h*1,ID_MESS_STR2,symbol_str("x_div"),"****",bg_xdiv,
  2574.                         new text_field(wl,wt+h*2,ID_MESS_STR3,symbol_str("y_mul"),"****",bg_ymul,
  2575.                             new text_field(wl,wt+h*3,ID_MESS_STR4,symbol_str("y_div"),"****",bg_ydiv,
  2576.                                 new button(wl+10,wt+h*4,ID_SET_SCROLL_CHECK,symbol_str("ok_button"),
  2577.                                     new button(wt+40,wt+h*4,ID_CANCEL,symbol_str("cancel_button"),NULL)))))),symbol_str("_scroll"));
  2578.       } 
  2579.     } break;
  2580.     case ID_SET_SCROLL_CHECK :
  2581.     {
  2582.       int tbg_xmul=atoi(mess_win->read(ID_MESS_STR1));
  2583.       int tbg_xdiv=atoi(mess_win->read(ID_MESS_STR2));
  2584.       int tbg_ymul=atoi(mess_win->read(ID_MESS_STR3));
  2585.       int tbg_ydiv=atoi(mess_win->read(ID_MESS_STR4));
  2586.  
  2587.       if ( (((float)tbg_xmul/(float)tbg_xdiv) < ((float)bg_xmul/(float)bg_xdiv)) ||
  2588.           (((float)tbg_ymul/(float)tbg_ydiv) < ((float)bg_ymul/(float)bg_ydiv)))
  2589.       {
  2590.         int wl=WINDOW_FRAME_LEFT,wt=WINDOW_FRAME_TOP,h=eh->font()->height()+8;
  2591.  
  2592.         warn_win=eh->new_window(xres/2-40,yres/2-40,-1,-1,
  2593.                 new info_field(wl,wt,ID_NULL,
  2594.                     symbol_str("back_loss"),
  2595.                     new button(wl+10,wt+h*4,ID_SET_SCROLL_OK,symbol_str("ok_button"),
  2596.                         new button(wt+40,wt+h*4,ID_WARN_CANCEL,symbol_str("cancel_button"),NULL))),
  2597.                 symbol_str("WARNING"));
  2598.         eh->grab_focus(warn_win);
  2599.       } else eh->push_event(new event(ID_SET_SCROLL_OK,NULL));
  2600.     } break;
  2601.     case ID_WARN_CANCEL :
  2602.     {
  2603.       eh->close_window(warn_win); warn_win=NULL;
  2604.       eh->push_event(new event(ID_CANCEL,NULL));
  2605.     } break;
  2606.     case ID_SET_SCROLL_OK :
  2607.     {
  2608.       if (warn_win) { eh->close_window(warn_win); warn_win=NULL; }
  2609.       bg_xmul=atoi(mess_win->read(ID_MESS_STR1));
  2610.       bg_xdiv=atoi(mess_win->read(ID_MESS_STR2));
  2611.       bg_ymul=atoi(mess_win->read(ID_MESS_STR3));
  2612.       bg_ydiv=atoi(mess_win->read(ID_MESS_STR4));
  2613.       eh->push_event(new event(ID_CANCEL,NULL));        // close window
  2614.     } break;
  2615.  
  2616.     case ID_CENTER_PLAYER :
  2617.     {
  2618.           do_command("center",ev); break;
  2619.     } break;
  2620.  
  2621.     case ID_INTERPOLATE_DRAW :  
  2622.     {
  2623.       interpolate_draw=!interpolate_draw;
  2624.     } break;
  2625.  
  2626.     case ID_DISABLE_AUTOLIGHT : 
  2627.     {
  2628.       disable_autolight=!disable_autolight;
  2629.     } break;
  2630.  
  2631.     case ID_ADD_PALETTE :
  2632.     {
  2633.       if (!mess_win)
  2634.       {
  2635.         int wl=WINDOW_FRAME_LEFT,wt=WINDOW_FRAME_TOP,h=eh->font()->height()+8;
  2636.         mess_win=eh->new_window(xres/2,yres/2,-1,-1,
  2637.                 new text_field(wl,wt+h*0,ID_MESS_STR1,symbol_str("ap_width"),"****",2,
  2638.             new text_field(wl,wt+h*1,ID_MESS_STR2,symbol_str("ap_height"),"****",2,
  2639.                         new text_field(wl,wt+h*2,ID_MESS_STR3,symbol_str("ap_name"),"***********","pal",
  2640.                             new button(wl+10,wt+h*3,ID_ADD_PALETTE_OK,symbol_str("ok_button"),
  2641.                                 new button(wt+40,wt+h*3,ID_CANCEL,symbol_str("cancel_button"),NULL))))),symbol_str("ap_pal"));
  2642.       } 
  2643.     } break;
  2644.     case ID_ADD_PALETTE_OK :
  2645.     {
  2646.       char name[70];
  2647.       sprintf(name,"(add_palette \"%s\" %d %d)",mess_win->read(ID_MESS_STR3),
  2648.               atoi(mess_win->read(ID_MESS_STR1)),
  2649.               atoi(mess_win->read(ID_MESS_STR2)));
  2650.       char *s=name;
  2651.       eval(compile(s));
  2652.       eh->push_event(new event(ID_CANCEL,NULL));        // close window
  2653.     } break;
  2654.     case ID_TOGGLE_DELAY :
  2655.     {
  2656.       the_game->toggle_delay(); break;
  2657.     } break;
  2658.  
  2659.     case ID_SMALL_MODE :
  2660.     {
  2661.       make_screen_size(311,160); break;
  2662.     } break;
  2663.     case ID_CLEAR_WEAPONS :
  2664.     {
  2665.       event ev;
  2666.       do_command("clear_weapons",ev); 
  2667.     } break;
  2668.     case ID_GOD_MODE :
  2669.     {
  2670.       for (view *v=player_list;v;v=v->next)
  2671.         v->god=!v->god;
  2672.     } break;
  2673.     case ID_MOUSE_SCROLL :
  2674.     {
  2675.       mouse_scrolling=!mouse_scrolling;
  2676.       prop->setd("mouse_scrolling",mouse_scrolling);
  2677.       if (mouse_scrolling)
  2678.         the_game->show_help(symbol_str("ms_on"));
  2679.       else
  2680.         the_game->show_help(symbol_str("ms_off"));
  2681.     } break;
  2682.  
  2683.     case ID_LOCK_PALETTES :
  2684.     {
  2685.       palettes_locked=!palettes_locked;
  2686.       prop->setd("palettes_locked",palettes_locked);
  2687.       if (palettes_locked)
  2688.         the_game->show_help(symbol_str("pal_lock"));
  2689.       else the_game->show_help(symbol_str("pal_unlock"));      
  2690.     } break;
  2691.  
  2692.     case ID_DISABLE_VIEW_SHIFT :
  2693.     {
  2694.       view_shift_disabled=!view_shift_disabled;
  2695.       prop->setd("view_shift_disabled",view_shift_disabled);
  2696.       if (view_shift_disabled)
  2697.         the_game->show_help(symbol_str("vs_dis"));
  2698.       else the_game->show_help(symbol_str("vs_en"));      
  2699.     } break; 
  2700.  
  2701.     case ID_WIN_FORE :
  2702.     { 
  2703.       toggle_fgw();
  2704.     } break;
  2705.     case ID_WIN_BACK :
  2706.     { 
  2707.       toggle_bgw();
  2708.     } break;
  2709.     case ID_WIN_OBJECTS :
  2710.     { 
  2711.       toggle_omenu();
  2712.     } break;
  2713.     case ID_WIN_PALETTES :
  2714.     { 
  2715.       toggle_pmenu();
  2716.     } break;
  2717.     case ID_WIN_LIGHTING :
  2718.     { 
  2719.       toggle_light_window();
  2720.     } break;
  2721.     case ID_WIN_LAYERS :
  2722.     {
  2723.       toggle_show_menu(); 
  2724.     } break;
  2725.     case ID_WIN_CONSOLE :
  2726.     {
  2727.       if (dev_console) dev_console->toggle();
  2728.     } break;
  2729.     case ID_WIN_TOOLBAR :
  2730.     {
  2731.       toggle_toolbar();
  2732.     } break;
  2733.  
  2734.     case DEV_AMBIENT :
  2735.     { if (!ambw) make_ambient(); } break;
  2736.     case DEV_AREA_OK :
  2737.     { close_area_win(1); } break;
  2738.     case DEV_AREA_DELETE :
  2739.     { close_area_win(0);
  2740.         if (current_area && current_level)
  2741.         {
  2742.           if (current_level->area_list==current_area)
  2743.             current_level->area_list=current_level->area_list->next;
  2744.           else
  2745.           {
  2746.             area_controller *a=current_level->area_list,*l=NULL;
  2747.             for (;a!=current_area && a;a=a->next) { l=a; }
  2748.             l->next=a->next;
  2749.             delete a;
  2750.           }
  2751.           current_area=NULL;
  2752.           the_game->need_refresh();
  2753.         }
  2754.     } break;
  2755.     case DEV_AI_OK :
  2756.       close_ai_window(); break;
  2757.     case DEV_OEDIT_AI :
  2758.       make_ai_window(edit_object); break;
  2759.     case DEV_OBJECTS_DELETE :
  2760.     {
  2761.       if (edit_object)
  2762.       {
  2763.         for (int i=0;i<edit_object->total_objects();i++)
  2764.           edit_object->remove_object(edit_object->get_object(0));
  2765.         the_game->need_refresh();        
  2766.       }
  2767.     } break;
  2768.  
  2769.     case DEV_LIGHTS_DELETE :
  2770.     {
  2771.       if (edit_object)
  2772.       {
  2773.         for (int i=0;i<edit_object->total_lights();i++)
  2774.           edit_object->remove_light(edit_object->get_light(0));
  2775.         the_game->need_refresh();        
  2776.       }
  2777.     } break;
  2778.  
  2779.     case DEV_LEDIT_DEL :
  2780.     {
  2781.           event_ledit_del(ev);
  2782.     } break;
  2783.     case DEV_LEDIT_OK :
  2784.     {
  2785.           event_ledit_ok(ev);
  2786.     } break;
  2787.     case DEV_LEDIT_MOVE :
  2788.     {
  2789.       prop->setd("ledit x",ledit->x);
  2790.       prop->setd("ledit y",ledit->y);
  2791.       eh->close_window(ledit); ledit=NULL;
  2792.       state=DEV_MOVE_LIGHT;
  2793.     } break;
  2794.     case DEV_LEDIT_COPY :
  2795.     {
  2796.       edit_light=edit_light->copy();
  2797.       prop->setd("ledit x",ledit->x);
  2798.       prop->setd("ledit y",ledit->y);
  2799.       eh->close_window(ledit); ledit=NULL;      
  2800.       state=DEV_MOVE_LIGHT;
  2801.     } break;
  2802.  
  2803.  
  2804.     case DEV_LIGHT0 :
  2805.     case DEV_LIGHT1 :
  2806.     case DEV_LIGHT2 :
  2807.     case DEV_LIGHT3 :
  2808.     case DEV_LIGHT4 :
  2809.     case DEV_LIGHT5 :
  2810.     case DEV_LIGHT6 :
  2811.     case DEV_LIGHT7 :
  2812.     case DEV_LIGHT8 :
  2813.     case DEV_LIGHT9 :
  2814.     {
  2815.       long lx,ly;
  2816.       the_game->mouse_to_game(last_demo_mx,last_demo_my,lx,ly);
  2817.       lx=snap_x(lx);
  2818.       ly=snap_y(ly);
  2819.       edit_light=add_light_source(ev.message.id-DEV_LIGHT0,lx,ly,
  2820.               atoi(lightw->read(DEV_LIGHTR1)),
  2821.               atoi(lightw->read(DEV_LIGHTR2)),
  2822.               atoi(lightw->read(DEV_LIGHTW)),
  2823.               atoi(lightw->read(DEV_LIGHTH)));
  2824.       state=DEV_MOVE_LIGHT;                       
  2825.     } break;
  2826.     case ID_RAISE_ALL :
  2827.     {
  2828.       raise_all=!raise_all;
  2829.       prop->setd("raise_all",raise_all);
  2830.       if (raise_all)
  2831.         the_game->show_help(symbol_str("fg_r"));
  2832.       else
  2833.         the_game->show_help(symbol_str("fg_l"));
  2834.     } break;
  2835.     case DEV_OEDIT_COPY :
  2836.     {
  2837.           event_oedit_copy(ev);
  2838.     } break;
  2839.     case DEV_OEDIT_LEFT :
  2840.     {
  2841.       if (edit_object)
  2842.       {
  2843.         the_game->need_refresh();
  2844.         edit_object->direction=-1;
  2845.       }
  2846.     } break;
  2847.     case DEV_OEDIT_RIGHT :
  2848.     {
  2849.       if (edit_object)
  2850.       {
  2851.         the_game->need_refresh();
  2852.         edit_object->direction=1;
  2853.       }
  2854.     } break;
  2855.  
  2856.  
  2857.     case DEV_COMMAND_OK :
  2858.     {
  2859.       char cmd[100];
  2860.       strcpy(cmd,commandw->inm->get(DEV_COMMAND)->read());        
  2861.       prop->setd("commandw x",commandw->x);
  2862.       prop->setd("commandw y",commandw->y);
  2863.       eh->close_window(commandw); 
  2864.       commandw=NULL;
  2865.       do_command(cmd,ev);
  2866.     } break;
  2867.  
  2868.     case ID_SHOW_FPS :
  2869.     { fps_on=!fps_on; } break;
  2870.     case ID_PROFILE :
  2871.     { profile_toggle(); 
  2872.         profile_on=!profile_on; 
  2873.     } break;
  2874.       
  2875.     case ID_TOGGLE_NAMES : { show_names=!show_names; } break;
  2876.     case DEV_QUIT : the_game->end_session(); break;
  2877.     case DEV_EDIT_FG : dev=1; break; //the_game->draw(); break;
  2878.     case DEV_EDIT_BG : dev=2; break; //the_game->draw(); break;
  2879.     case DEV_EDIT_FGBG : dev=3; break; //the_game->draw(); break;
  2880.     case DEV_PLAY : dev=0; break; //the_game->draw(); break;
  2881.     case SHOW_FOREGROUND :
  2882.     { dev=dev^DRAW_FG_LAYER; the_game->need_refresh(); } break;
  2883.     case SHOW_FOREGROUND_BOUND :
  2884.     { dev=dev^DRAW_FG_BOUND_LAYER; the_game->need_refresh(); } break;
  2885.     case SHOW_BACKGROUND :
  2886.     { dev=dev^DRAW_BG_LAYER; the_game->need_refresh(); } break;
  2887.     case SHOW_CHARACTERS :
  2888.     { dev=dev^DRAW_PEOPLE_LAYER; the_game->need_refresh(); } break;
  2889.     case SHOW_LIGHT :
  2890.     { dev=dev^DRAW_LIGHTS; the_game->need_refresh(); } break;        
  2891.     case SHOW_LINKS :
  2892.     { dev=dev^DRAW_LINKS;  the_game->need_refresh(); } break;
  2893.       
  2894.  
  2895.     case DEV_CREATE : 
  2896.     {      
  2897.       int val=get_omenu_item(((pick_list *)ev.message.data)->get_selection());
  2898.       char cmd[100];
  2899.       sprintf(cmd,"create %s",object_names[val]);
  2900.       do_command(cmd,ev);
  2901.       state=DEV_CREATE_OBJECT;
  2902.       dev|=(EDIT_MODE | DRAW_PEOPLE_LAYER);        
  2903.     }             
  2904.     break;    
  2905.  
  2906.     case DEV_PALETTE :
  2907.     {
  2908.       int val=((pick_list *)ev.message.data)->get_selection();        
  2909.       pal_wins[val]->open_window();
  2910.     } break;
  2911.  
  2912.     case DEV_MUSIC_PICKLIST : 
  2913.     {      
  2914.           /*        int *val=((int *)((pick_list *)ev.message.data)->read());
  2915.                     if (current_song) delete current_song;
  2916.                     current_song=new song(song_list[*val]);
  2917.                     current_song->play();        */
  2918.     }             
  2919.     break;         
  2920.  
  2921.     case DEV_OEDIT_OK : 
  2922.     { close_oedit_window(); } break;
  2923.       
  2924.     case DEV_OEDIT_DELETE : 
  2925.     {
  2926.       selected_object=edit_object;
  2927.       do_command("delete",ev);
  2928.       close_oedit_window();
  2929.     }
  2930.     break;
  2931.       
  2932.     case DEV_OEDIT_FRONT : 
  2933.     {
  2934.       do_command("to_front",ev);
  2935.       close_oedit_window();                  
  2936.     }
  2937.     break;
  2938.  
  2939.     case DEV_OEDIT_BACK : 
  2940.     {
  2941.       do_command("to_back",ev);
  2942.       close_oedit_window();                  
  2943.     }
  2944.     break;
  2945.  
  2946.     case DEV_OEDIT_MOVE :        
  2947.     {
  2948.       game_object *o=edit_object;
  2949.       close_oedit_window();
  2950.       edit_object=o;
  2951.       do_command("move",ev);
  2952.     }
  2953.     break;     
  2954.       }
  2955.     } break;
  2956.  
  2957.  
  2958.     case EV_CLOSE_WINDOW :
  2959.     {
  2960.       event_close_window(ev);
  2961.     }
  2962.     break;
  2963.     case EV_KEYRELEASE :
  2964.     {
  2965.       if (ev.key==JK_CTRL_L)
  2966.       {
  2967.         if (!edit_object && link_object && selected_object && link_object!=selected_object)
  2968.         {
  2969.           link_object->add_object(selected_object);
  2970.           if (S_LINK_SND>0) cash.sfx(S_LINK_SND)->play(sfx_volume/2);
  2971.           the_game->need_refresh();
  2972.         }
  2973.             
  2974.         link_object=NULL;
  2975.       }
  2976.     } break;
  2977.     case EV_KEY :
  2978.     {    
  2979.       event_key(ev);
  2980.     }
  2981.   }
  2982.   
  2983.  
  2984. }
  2985.  
  2986.  
  2987. void dev_controll::add_palette(void *args)
  2988. {
  2989.   total_pals++;
  2990.   pal_wins=(pal_win **)jrealloc(pal_wins,sizeof(pal_win *)*total_pals,"edit pal array");
  2991.   pal_wins[total_pals-1]=new pal_win(args);
  2992. }
  2993.  
  2994.  
  2995. pal_win::pal_win(void *args) 
  2996. {
  2997.   int i=0;
  2998.   Cell *ao=(Cell *)args;
  2999.  
  3000.   name=strcpy((char *)jmalloc(strlen(lstring_value(CAR(args)))+1,
  3001.       "pal name"),lstring_value(CAR(args)));
  3002.   ao=CDR(ao);
  3003.   scale=w=h=1;
  3004.   x=y=0;
  3005.   
  3006.   if (!NILP(ao))
  3007.   {
  3008.     w=lnumber_value(CAR(ao)); ao=CDR(ao);
  3009.     if (!NILP(ao))
  3010.     {
  3011.       h=lnumber_value(CAR(ao)); ao=CDR(ao);
  3012.       if (!NILP(ao))
  3013.       {
  3014.     x=lnumber_value(CAR(ao)); ao=CDR(ao);
  3015.     if (!NILP(ao))
  3016.     {
  3017.       y=lnumber_value(CAR(ao)); ao=CDR(ao);
  3018.       if (!NILP(ao))
  3019.         scale=lnumber_value(CAR(ao)); ao=CDR(ao);
  3020.     }
  3021.       }
  3022.     }
  3023.   }
  3024.  
  3025.   if (w<=0) w=0;
  3026.   if (h<=0) h=0;
  3027.  
  3028.   pat=(unsigned short *)jmalloc(w*h*sizeof(unsigned short),"palwin::pat");
  3029.   memset(pat,0,sizeof(unsigned short)*w*h);   // set the palette to black if no parameters are given
  3030.   while (!NILP(ao))   // loop until we run out of parameters
  3031.   {
  3032.     if (i>w*h)
  3033.     { 
  3034.       lbreak("to many parameters to add_palette ");
  3035.       exit(0);
  3036.     }
  3037.     pat[i]=lnumber_value(CAR(ao));
  3038.     // make sure the tile that they suggested exists
  3039.     if (pat[i]<=0 || pat[i]>nforetiles || foretiles[pat[i]]<0)
  3040.       pat[i]=0;    
  3041.     ao=CDR(ao);
  3042.     i++;
  3043.   }
  3044.   last_selected=-1;
  3045.   me=NULL;
  3046.   open_window();
  3047. }
  3048.  
  3049. void pal_win::open_window()
  3050.   if (me) close_window();
  3051.   me=eh->new_window(x,y,w*f_wid/scale,h*f_hi/scale,NULL,name);
  3052.   draw();
  3053. }
  3054.  
  3055. void pal_win::close_window()
  3056. {
  3057.   if (me)       // dont' close the window if the window is already closed
  3058.   {
  3059.     x=me->x;    //  save the old poisition of the window so that when we  open it
  3060.     //  it will be in the same spot
  3061.     y=me->y;
  3062.     eh->close_window(me);
  3063.     me=NULL;
  3064.     
  3065.   }
  3066. }
  3067.  
  3068. #ifdef __MAC__
  3069. #pragma global_optimizer on
  3070. #endif
  3071.  
  3072. void pal_win::draw()
  3073. {
  3074.   int i,find=-1,d=cur_fg;
  3075.   if (me)
  3076.   {
  3077.     me->clear();
  3078.     image *im=new image(the_game->ftile_width(),the_game->ftile_height());
  3079.     int th=the_game->ftile_height()/scale,tw=the_game->ftile_width()/scale;
  3080.  
  3081.     for (i=0;i<w*h;i++)
  3082.     {
  3083.       im->clear();      
  3084.       the_game->get_fg(pat[i])->im->put_image(im,0,0);
  3085.       scale_put(im,me->screen,me->x1()+(i%w)*tw,
  3086.           me->y1()+(i/w)*th,tw,th);
  3087.       if (d==pat[i])
  3088.       {
  3089.     find=i;
  3090.     me->screen->rectangle(me->x1()+(i%w)*tw,
  3091.             me->y1()+(i/w)*th,
  3092.             me->x1()+(i%w)*tw+tw-1,
  3093.             me->y1()+(i/w)*th+th-1,eh->bright_color());
  3094.       }
  3095.     }
  3096.     delete im;
  3097.     last_selected=d;
  3098.   }
  3099. }
  3100.  
  3101. #ifdef __MAC__
  3102. #pragma global_optimizer reset
  3103. #endif
  3104.  
  3105. void pal_win::handle_event(event &ev) 
  3106. {
  3107.   int d=cur_fg;
  3108.  
  3109.   if (d!=last_selected)  // if so see if we need to hilight any of our tiles.
  3110.   {
  3111.     int i,dr=0;
  3112.     for (i=0;i<w*h;i++) 
  3113.     {
  3114.       if (pat[i]==d || pat[i]==last_selected) 
  3115.         dr=1;
  3116.     }
  3117.     if (dr) draw();
  3118.     last_selected=d;
  3119.   }
  3120.  
  3121.   if (ev.window && ev.window==me)
  3122.   {
  3123.     switch (ev.type)
  3124.     {
  3125.       case EV_MOUSE_BUTTON :
  3126.       {
  3127.         if (ev.mouse_button==1)
  3128.     {      
  3129.       int selx=(last_demo_mx-me->x-me->x1())/(the_game->ftile_width()/scale),
  3130.             sely=(last_demo_my-me->y-me->y1())/(the_game->ftile_height()/scale);
  3131.       if (selx>=0 && sely>=0 && selx<w && sely<h)
  3132.       {
  3133.         cur_fg=pat[selx+sely*w];
  3134.         if (dev_cont->forew)      
  3135.           ((tile_picker *)dev_cont->forew->
  3136.                   read(DEV_FG_PICKER))->recenter(dev_cont->forew->screen,eh);      
  3137.       }
  3138.     } else if (ev.mouse_button==2)
  3139.     {
  3140.       if (palettes_locked)
  3141.         the_game->show_help(symbol_str("pal_lock"));
  3142.       else
  3143.       {
  3144.         int selx=(last_demo_mx-me->x-me->x1())/(the_game->ftile_width()/scale),
  3145.               sely=(last_demo_my-me->y-me->y1())/(the_game->ftile_height()/scale);
  3146.         if (selx>=0 && sely>=0 && selx<w && sely<h)
  3147.         {
  3148.           pat[selx+sely*w]=cur_fg;
  3149.           draw();
  3150.         }
  3151.       }
  3152.     }
  3153.       } break;
  3154.  
  3155.       case EV_KEY :
  3156.       {
  3157.         switch (ev.key)
  3158.     {
  3159.       case '+' :
  3160.       { if (scale>1)  
  3161.           {
  3162.             close_window();
  3163.             scale--;
  3164.             open_window();
  3165.           }
  3166.       } break;
  3167.       case '-' :
  3168.       { if (scale<the_game->ftile_height()/2) 
  3169.           {
  3170.             close_window();
  3171.             scale++;
  3172.             open_window();
  3173.           }
  3174.       } break;      
  3175.       case JK_LEFT : 
  3176.       {
  3177.         if (palettes_locked) the_game->show_help(symbol_str("pal_lock"));
  3178.         else if (w>1) resize(-1,0);
  3179.       } break;
  3180.       case JK_RIGHT : 
  3181.       {
  3182.         if (palettes_locked) the_game->show_help(symbol_str("pal_lock"));
  3183.         else
  3184.           resize(1,0); 
  3185.       } break;
  3186.       case JK_UP : 
  3187.       {
  3188.         if (palettes_locked) the_game->show_help(symbol_str("pal_lock"));
  3189.         else if (h>1) resize(0,-1); 
  3190.       } break;
  3191.       case JK_DOWN : 
  3192.       {
  3193.         if (palettes_locked)         
  3194.           the_game->show_help(symbol_str("pal_lock"));
  3195.         else
  3196.           resize(0,1); 
  3197.       } break;     
  3198.       case JK_ESC : close_window();     break;
  3199.       case ' ' : 
  3200.       {
  3201.         long xs,ys,xx,yy;
  3202.         the_game->ftile_on(me->x,me->y,xs,ys);
  3203.  
  3204.         for (xx=xs;xx<xs+w;xx++)
  3205.         {
  3206.           for (yy=ys;yy<ys+h;yy++)
  3207.           {          
  3208.         if (xx>=0 && yy>=0 && xx<current_level->foreground_width() &&
  3209.             yy<current_level->foreground_height())
  3210.           the_game->put_fg(xx,yy,raise_all ? make_above_tile(pat[xx-xs+(yy-ys)*w]) : pat[xx-xs+(yy-ys)*w] );
  3211.           }
  3212.         }
  3213.       } break;
  3214.       case 't' :
  3215.       {
  3216.         long xs,ys,xx,yy;
  3217.         the_game->ftile_on(me->x,me->y,xs,ys);
  3218.         dev_cont->fg_fill(-1,xs,ys,this);
  3219.       } break;
  3220.  
  3221.     }
  3222.       } break;
  3223.  
  3224.       case EV_CLOSE_WINDOW : close_window(); break;
  3225.     }
  3226.   }
  3227.  
  3228.  
  3229. }
  3230.  
  3231.  
  3232. void pal_win::resize(int xa, int ya)
  3233. {
  3234.   int i,j;
  3235.   unsigned short *npat;
  3236.   if (w+xa<1 || y+ya<1) return ;
  3237.  
  3238.   npat=(unsigned short *)jmalloc(sizeof(unsigned short)*(w+xa)*(h+ya),"resized pal_win");
  3239.   memset(npat,0,sizeof(unsigned short)*(w+xa)*(h+ya));
  3240.   for (i=0;i<(w+xa);i++)
  3241.     for (j=0;j<(h+ya);j++)
  3242.       if (i+j*w<w*h)
  3243.         npat[i+j*(w+xa)]=pat[i+j*w];
  3244.   jfree(pat);
  3245.   w+=xa;
  3246.   h+=ya;
  3247.   pat=npat;
  3248.   last_selected=-1;
  3249.   close_window();
  3250.   open_window();
  3251. }
  3252.  
  3253.  
  3254. void pal_win::save(FILE *fp)
  3255. {
  3256.   if (me)
  3257.   {
  3258.     x=me->x;
  3259.     y=me->y;
  3260.   }
  3261.  
  3262.   fprintf(fp,"(add_palette \"%s\" %d %d %d %d %d ",name,w,h,x,y,scale);
  3263.   int i;
  3264.   for (i=0;i<w*h;i++)
  3265.     fprintf(fp,"%d ",pat[i]&0x7fff);
  3266.   fprintf(fp,")\n");
  3267.  
  3268. }
  3269.  
  3270. FILE *open_FILE(char *filename, char *mode);
  3271.  
  3272. void dev_controll::save()
  3273. {
  3274.   FILE *fp=open_FILE("edit.lsp","w");
  3275.   if (!fp) 
  3276.     the_game->show_help(symbol_str("no_edit.lsp"));
  3277.   else
  3278.   {
  3279.     fprintf(fp,"(set_zoom %d)\n",the_game->zoom);
  3280.    
  3281.     int i;
  3282.     for (i=0;i<total_pals;i++)
  3283.     {
  3284.       pal_wins[i]->save(fp);
  3285.     }
  3286.     fprintf(fp,"\n");
  3287.     fclose(fp);
  3288.   }
  3289.  
  3290. }
  3291.  
  3292. int dev_controll::is_pal_win(jwindow *win)
  3293. {
  3294.   int i;
  3295.   for (i=0;i<total_pals;i++)
  3296.     if (win==pal_wins[i]->me) return 1;
  3297.   return 0;
  3298. }
  3299.  
  3300.  
  3301. class fill_rec
  3302. {
  3303.   public :
  3304.   short x,y;
  3305.   fill_rec *last;
  3306.   fill_rec(short X, short Y, fill_rec *Last)
  3307.   { x=X; y=Y; last=Last; }
  3308. } ;
  3309.  
  3310. static int get_color(int color, int x, int y, pal_win *p)
  3311. {
  3312.   if (p)  
  3313.   {
  3314.     while (x<0) x+=p->width();
  3315.     while (y<0) y+=p->height();
  3316.     return p->get_pat(x%p->width(),y%p->height());
  3317.   }
  3318.   else return color;
  3319. }
  3320.  
  3321. void dev_controll::fg_fill(int color, int x, int y, pal_win *p)
  3322. {
  3323.   unsigned short *sl,*above,*below;
  3324.   fill_rec *recs=NULL,*r;
  3325.   unsigned short fcolor;
  3326.   sl=current_level->get_fgline(y);
  3327.   fcolor=fgvalue(sl[x]);
  3328.   int startx=x,starty=y;
  3329.   if (fcolor==color) return ;
  3330.   do
  3331.   {
  3332.     if (recs)
  3333.     { r=recs;
  3334.     recs=recs->last;
  3335.     x=r->x; y=r->y;
  3336.     delete r;
  3337.     }
  3338.     sl=current_level->get_fgline(y);
  3339.     if (fgvalue(sl[x])==fcolor)
  3340.     {
  3341.       while (x>0 && fgvalue(sl[x])==fcolor) x--;
  3342.       if (fgvalue(sl[x])!=fgvalue(fcolor) && x<current_level->foreground_width()-1) x++;
  3343.       if (y>0)
  3344.       {
  3345.         above=current_level->get_fgline(y-1);
  3346.         if (fgvalue(above[x])==fcolor)
  3347.         { r=new fill_rec(x,y-1,recs);
  3348.         recs=r;  
  3349.         }
  3350.       }
  3351.       if (y<current_level->foreground_height()-1)
  3352.       {
  3353.         above=current_level->get_fgline(y+1);
  3354.         if (above[x]==fcolor)
  3355.         { r=new fill_rec(x,y+1,recs);
  3356.         recs=r;
  3357.         }
  3358.       }
  3359.  
  3360.  
  3361.  
  3362.       do
  3363.       {
  3364.         sl[x]=get_color(color,x-startx,y-starty,p);
  3365.         if (y>0)
  3366.         { above=current_level->get_fgline(y-1);
  3367.         if (x>0 && fgvalue(above[x-1])!=fgvalue(fcolor) && fgvalue(above[x])==fgvalue(fcolor))
  3368.         { r=new fill_rec(x,y-1,recs);
  3369.         recs=r;  
  3370.         }
  3371.         }
  3372.         if (y<current_level->foreground_height()-1)
  3373.         { below=current_level->get_fgline(y+1);
  3374.         if (x>0 && fgvalue(below[x-1])!=fgvalue(fcolor) && fgvalue(below[x])==fgvalue(fcolor))
  3375.         { r=new fill_rec(x,y+1,recs);
  3376.         recs=r;  
  3377.         }
  3378.         }
  3379.         x++;
  3380.       } while (fgvalue(sl[x])==fgvalue(fcolor) && x<current_level->foreground_width());
  3381.       x--;
  3382.       if (y>0)
  3383.       {
  3384.         above=current_level->get_fgline(y-1);
  3385.         if (fgvalue(above[x])==fgvalue(fcolor))
  3386.         { r=new fill_rec(x,y-1,recs);
  3387.         recs=r;
  3388.         }
  3389.       }
  3390.       if (y<current_level->foreground_height()-1)
  3391.       {
  3392.         above=current_level->get_fgline(y+1);
  3393.         if (fgvalue(above[x])==fgvalue(fcolor))
  3394.         { r=new fill_rec(x,y+1,recs);
  3395.         recs=r;
  3396.         }
  3397.       }
  3398.     }
  3399.   } while (recs);
  3400.   the_game->need_refresh();
  3401. }
  3402.  
  3403. int get_char_mem(int type, int print)
  3404. {
  3405.   int t=0;
  3406.   for (int j=0;j<MAX_STATE;j++)
  3407.   {
  3408.     if (figures[type]->has_sequence((character_state)j))
  3409.     {
  3410.       int s=figures[type]->get_sequence((character_state)j)->size();
  3411.       if (print)
  3412.         dprintf("(%s=%d)",state_names[j],s);
  3413.       t+=s;
  3414.     }
  3415.   }
  3416.   if (print)
  3417.     dprintf("\ntotal=%d\n",t);      
  3418.   return t;
  3419. }
  3420.  
  3421. void dev_controll::show_char_mem(char *name)
  3422. {
  3423.   int find=-1;
  3424.   for (int i=0;i<total_objects;i++)
  3425.   {
  3426.     if (!strcmp(name,object_names[i]))
  3427.       find=i;
  3428.   }
  3429.   if (find<0)
  3430.     dprintf("No character '%s' defined\n",name);
  3431.   else  
  3432.     get_char_mem(find,1);
  3433.   
  3434. }
  3435.  
  3436. void dev_controll::show_mem()
  3437. {
  3438.   int t=0,s=0;
  3439.   int i=0;
  3440.   for (;i<nforetiles;i++)
  3441.   {
  3442.     if (foretiles[i]>=0)
  3443.     {
  3444.       if (cash.loaded(foretiles[i]))
  3445.       {
  3446.     t++;      
  3447.     s+=cash.foret(foretiles[i])->size();
  3448.       }
  3449.     }
  3450.   }
  3451.   dprintf("%d loaded foretiles=%d bytes\n",t,s);
  3452.  
  3453.   t=0; s=0;
  3454.   for (i=0;i<nbacktiles;i++)
  3455.   {
  3456.     if (backtiles[i]>=0)
  3457.     {
  3458.       if (cash.loaded(foretiles[i]))
  3459.       {
  3460.     t++;
  3461.     s+=cash.backt(backtiles[i])->size();
  3462.       }
  3463.     }
  3464.   }
  3465.   dprintf("%d loaded backtiles=%d bytes\n",t,s);
  3466.   
  3467.   t=0; s=0;
  3468.   for (i=0;i<total_objects;i++)
  3469.   {
  3470.     t++;
  3471.     s+=get_char_mem(i,0);
  3472.   }
  3473.   dprintf("%d character=%d bytes\n",t,s);
  3474.  
  3475. }
  3476.  
  3477.  
  3478.  
  3479. void dev_cleanup()
  3480. {
  3481.   if (start_edit)  
  3482.     prop->save("defaults.prp");
  3483.   delete prop;
  3484.   if (listable_objs)
  3485.   {
  3486.     jfree(listable_objs);
  3487.     listable_objs=NULL;
  3488.   }
  3489.   crc_man.clean_up();
  3490.  
  3491. }
  3492.  
  3493.  
  3494.  
  3495. struct pmi
  3496. {
  3497.   char *name;
  3498.   int id;
  3499.   char *on_off;
  3500.   int key;
  3501. } ;
  3502.  
  3503.  
  3504. static pmi fm[]={
  3505.   {"menu1_load",         ID_LEVEL_LOAD,NULL,-1},
  3506.   {NULL,0,NULL,-1},
  3507.   {"menu1_save",     ID_LEVEL_SAVE,NULL,-1},
  3508.   {"menu1_saveas",      ID_LEVEL_SAVEAS,NULL,-1},
  3509.   {"menu1_savegame",          ID_GAME_SAVE,NULL,-1},
  3510.   {"menu1_new",          ID_LEVEL_NEW,NULL,-1},
  3511.   {"menu1_resize",         ID_LEVEL_RESIZE,NULL,-1},
  3512.   {NULL,0,NULL,-1},
  3513.   {"menu1_suspend",ID_SUSPEND,NULL,-1},
  3514.   {"menu1_toggle",ID_PLAY_MODE,NULL,-1},
  3515.   {NULL,0,NULL,-1},
  3516.   {"menu1_savepal",ID_EDIT_SAVE,NULL,-1},
  3517.   //      {"menu1_startc",ID_CACHE_PROFILE,NULL,-1},
  3518.   //      {"menu1_endc",ID_CACHE_PROFILE_END,NULL,-1},
  3519.   {NULL,0,NULL,-1},     
  3520.   {"menu1_quit",      ID_QUIT,NULL,-1},
  3521.   {NULL,-1,NULL,-1}
  3522. };
  3523.  
  3524.  
  3525. static pmi em[]={
  3526.   {"menu2_light",               ID_TOGGLE_LIGHT,NULL,-1},
  3527.   {"menu2_scroll",            ID_SET_SCROLL,NULL,-1},
  3528.   {"menu2_center",       ID_CENTER_PLAYER,NULL,-1},
  3529.   {"menu2_addpal",                ID_ADD_PALETTE,NULL,-1},
  3530.   {"menu2_delay",          ID_TOGGLE_DELAY,NULL,-1},
  3531.  
  3532.   {"menu2_god",                   ID_GOD_MODE,NULL,-1},
  3533.   {"menu2_clear",          ID_CLEAR_WEAPONS,NULL,-1},
  3534.   {"menu2_mscroll",               ID_MOUSE_SCROLL,&mouse_scrolling,-1},
  3535.   {"menu2_lock",       ID_LOCK_PALETTES,&palettes_locked,-1},
  3536.   {"menu2_raise",       ID_RAISE_ALL,&raise_all,-1},
  3537.   {"menu2_names",        ID_TOGGLE_NAMES,&show_names,-1},
  3538.  
  3539.   {NULL,0,NULL,-1},
  3540.   {"menu2_map",      ID_TOGGLE_MAP,NULL,-1},
  3541.   //  {"Shrink to 320x200 (F10)",    ID_SMALL_MODE,NULL,-1},
  3542.   {"menu2_view",        ID_DISABLE_VIEW_SHIFT,&view_shift_disabled,-1}, 
  3543.   //  {"Ultra Smooth draw (U)",      ID_INTERPOLATE_DRAW,  &interpolate_draw,'U'},
  3544.   {"menu2_alight",      ID_DISABLE_AUTOLIGHT, &disable_autolight,'A'},
  3545.   {"menu2_fps",         ID_SHOW_FPS,          &fps_on,-1},
  3546.   //  {NULL,0,NULL,-1},
  3547.   //  {"Record demo",                ID_RECORD_DEMO,NULL,-1},
  3548.   //  {"Play demo",                  ID_PLAY_DEMO,NULL,-1},
  3549.   {NULL,-1,NULL,-1}
  3550. };
  3551.  
  3552.  
  3553.  
  3554. // Window Menus
  3555. static pmi wm[]={
  3556.   {"menu3_fore",    ID_WIN_FORE,    &forew_on,-1},
  3557.   {"menu3_back",    ID_WIN_BACK,    &backw_on,-1},
  3558.   {"menu3_layers",    ID_WIN_LAYERS,  &show_menu_on,-1},
  3559.   {"menu3_light",    ID_WIN_LIGHTING,&ledit_on,-1},
  3560.   {"menu3_pal",    ID_WIN_PALETTES,&pmenu_on,-1},
  3561.   {"menu3_objs",    ID_WIN_OBJECTS, &omenu_on,-1},
  3562.   //      {"menu3_console",    ID_WIN_CONSOLE, &commandw_on,-1},
  3563.   {"menu3_toolbar",    ID_WIN_TOOLBAR, &tbw_on,-1},
  3564.   //      {"Search      (s)",    ID_SEARCH,      &searchw_on,-1},
  3565.   {"menu3_prof",    ID_PROFILE,     &profile_on,-1},
  3566.   {"menu3_save",     ID_SAVE_WINDOWS,NULL,-1},
  3567.   {NULL,-1,NULL,-1}
  3568. };
  3569.  
  3570.  
  3571.  
  3572. /*
  3573. static pmi fm[]={
  3574.           {"Load Level",         ID_LEVEL_LOAD,NULL,-1},
  3575.       {NULL,0,NULL,-1},
  3576.       {"Save Level (S)",     ID_LEVEL_SAVE,NULL,-1},
  3577.       {"Save level as",      ID_LEVEL_SAVEAS,NULL,-1},
  3578.       {"Save game",          ID_GAME_SAVE,NULL,-1},
  3579.       {"New level",          ID_LEVEL_NEW,NULL,-1},
  3580.       {"Resize map",         ID_LEVEL_RESIZE,NULL,-1},
  3581.       {NULL,0,NULL,-1},
  3582.       {"Suspend non-players",ID_SUSPEND,NULL,-1},
  3583.       {"Play mode toggle (TAB)",ID_PLAY_MODE,NULL,-1},
  3584.       {NULL,0,NULL,-1},
  3585.       {"Save Palettes         ",ID_EDIT_SAVE,NULL,-1},
  3586.       {"Start cache profile   ",ID_CACHE_PROFILE,NULL,-1},
  3587.       {"End cache profile     ",ID_CACHE_PROFILE_END,NULL,-1},
  3588.       {NULL,0,NULL,-1},     
  3589.       {"Quit      (Q)",      ID_QUIT,NULL,-1},
  3590.       {NULL,-1,NULL,-1}
  3591.     };
  3592.  
  3593.  
  3594. static pmi em[]={
  3595.   {"Toggle light",               ID_TOGGLE_LIGHT,NULL,-1},
  3596.   {"Set scroll rate",            ID_SET_SCROLL,NULL,-1},
  3597.   {"Center on player   (c)",       ID_CENTER_PLAYER,NULL,-1},
  3598.   {"Add palette",                ID_ADD_PALETTE,NULL,-1},
  3599.   {"Toggle Delays      (D)",          ID_TOGGLE_DELAY,NULL,-1},
  3600.  
  3601.   {"God mode",                   ID_GOD_MODE,NULL,-1},
  3602.   {"Clear weapons (z)",          ID_CLEAR_WEAPONS,NULL,-1},
  3603.   {"Mouse scroll",               ID_MOUSE_SCROLL,&mouse_scrolling,-1},
  3604.   {"Lock palette windows",       ID_LOCK_PALETTES,&palettes_locked,-1},
  3605.   {"Raise all foreground",       ID_RAISE_ALL,&raise_all,-1},
  3606.   {"Toggle object names",        ID_TOGGLE_NAMES,&show_names,-1},
  3607.  
  3608.   {NULL,0,NULL,-1},
  3609.   {"Toggle map        (m)",      ID_TOGGLE_MAP,NULL,-1},
  3610. //  {"Shrink to 320x200 (F10)",    ID_SMALL_MODE,NULL,-1},
  3611.   {"Disable view shifts",        ID_DISABLE_VIEW_SHIFT,&view_shift_disabled,-1}, 
  3612. //  {"Ultra Smooth draw (U)",      ID_INTERPOLATE_DRAW,  &interpolate_draw,'U'},
  3613.   {"Disable Autolight (A)",      ID_DISABLE_AUTOLIGHT, &disable_autolight,'A'},
  3614.   {"Show FPS/Obj count",         ID_SHOW_FPS,          &fps_on,-1},
  3615. //  {NULL,0,NULL,-1},
  3616. //  {"Record demo",                ID_RECORD_DEMO,NULL,-1},
  3617. //  {"Play demo",                  ID_PLAY_DEMO,NULL,-1},
  3618.   {NULL,-1,NULL,-1}
  3619. };
  3620.  
  3621.  
  3622.  
  3623. // Window Menus
  3624. static pmi wm[]={
  3625.           {"Foreground  (f)",    ID_WIN_FORE,    &forew_on,-1},
  3626.           {"Background  (b)",    ID_WIN_BACK,    &backw_on,-1},
  3627.           {"Draw layers (L)",    ID_WIN_LAYERS,  &show_menu_on,-1},
  3628.       {"Lighting    (l)",    ID_WIN_LIGHTING,&ledit_on,-1},
  3629.       {"Palettes    (p)",    ID_WIN_PALETTES,&pmenu_on,-1},
  3630.       {"Objects     (o)",    ID_WIN_OBJECTS, &omenu_on,-1},
  3631.       {"Console     (/)",    ID_WIN_CONSOLE, &commandw_on,-1},
  3632.       {"Tool Bar    (a)",    ID_WIN_TOOLBAR, &tbw_on,-1},
  3633. //      {"Search      (s)",    ID_SEARCH,      &searchw_on,-1},
  3634.       {"Profile     (P)",    ID_PROFILE,     &profile_on,-1},
  3635.       {"Save positions",     ID_SAVE_WINDOWS,NULL,-1},
  3636.       {NULL,-1,NULL,-1}
  3637.     };
  3638.  
  3639. */
  3640.     
  3641. static pmenu_item *i_recurse(pmi *first)
  3642. {
  3643.   if (first->id==-1)
  3644.     return NULL;
  3645.   else  
  3646.     return new pmenu_item(first->id,first->name ? symbol_str(first->name) : 0,first->on_off,first->key,i_recurse(first+1));
  3647. }
  3648.     
  3649. static pmenu *make_menu(int x, int y)
  3650. {
  3651.   return new pmenu(x,y,
  3652.       new pmenu_item(symbol_str("file_top"),new psub_menu(i_recurse(fm),NULL),
  3653.           new pmenu_item(symbol_str("edit_top"),new psub_menu(i_recurse(em),NULL),
  3654.               new pmenu_item(symbol_str("window_top"),new psub_menu(i_recurse(wm),NULL),NULL))),screen,eh);
  3655. }
  3656.  
  3657.  
  3658. void make_edit_mode_menu()
  3659. {
  3660.   if (!dev_menu && (dev&EDIT_MODE))
  3661.     dev_menu=make_menu(0,yres-eh->font()->height()-5);    
  3662. }
  3663.  
  3664. void kill_edit_mode_menu()
  3665. {
  3666.   if (dev_menu)
  3667.     delete dev_menu;
  3668.   dev_menu = 0; 
  3669. }
  3670.  
  3671. void toggle_edit_mode()
  3672. {
  3673.   dev=dev^EDIT_MODE;
  3674.   if (dev&EDIT_MODE)
  3675.   {
  3676.     eh->set_mouse_shape(cash.img(c_normal)->copy(),1,1);
  3677.     pal->load();
  3678.         make_edit_mode_menu();
  3679.   }
  3680.   else
  3681.   {
  3682.     if (dev&MAP_MODE) dev-=MAP_MODE;                        // no map mode while playing!
  3683.     eh->set_mouse_shape(cash.img(c_target)->copy(),8,8);
  3684.     kill_edit_mode_menu();
  3685.   }
  3686. }
  3687.  
  3688.  
  3689. int dev_controll::ok_to_scroll()
  3690. {
  3691.   if (state==DEV_MOVE_LIGHT || state==DEV_MOVE_OBJECT || mouse_scrolling) return 1;
  3692.   else return 0;
  3693. }
  3694.  
  3695. dev_controll::~dev_controll()
  3696. {
  3697.   for (int i=0;i<total_pals;i++)
  3698.     delete pal_wins[i];
  3699.   if (total_pals)
  3700.     jfree(pal_wins);
  3701. }
  3702.  
  3703.  
  3704.  
  3705. pal_win::~pal_win()
  3706. {
  3707.   jfree(pat);
  3708.   jfree(name);
  3709. }
  3710.