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

  1. #include "idle.hpp"
  2. #include "system.h"
  3. #include "game.hpp"
  4. #include "dev.hpp"
  5. #include "id.hpp"
  6. #include "joy.hpp"
  7. #include "timing.hpp"
  8. #include "help.hpp"
  9. #include "ability.hpp"
  10. #include "cache.hpp"
  11. #include "loader.hpp"
  12. #include "lisp.hpp"
  13. #include "monoprnt.hpp"
  14. #include "jrand.hpp"
  15. #include "config.hpp"
  16. #include "light.hpp"
  17. #include "scroller.hpp"
  18. #include "dprint.hpp"
  19. #include "nfserver.hpp"
  20. #include "video.hpp"
  21. #include "transp.hpp"
  22. #include "clisp.hpp"
  23. #include "guistat.hpp"
  24. #include "menu.hpp"
  25. #include "gamma.hpp"
  26. #include "lisp_gc.hpp"
  27. #include "demo.hpp"
  28. #include "sbar.hpp"
  29. #include "profile.hpp"
  30. #include "compiled.hpp"
  31. #include "lisp_gc.hpp"
  32. #include "pmenu.hpp"
  33. #include "timing.hpp"
  34. #include "chat.hpp"
  35. #include "demo.hpp"
  36. #include "netcfg.hpp"
  37. #include "specache.hpp"
  38. #include "ant.hpp"
  39. #include "netstat.hpp"
  40.  
  41.  
  42. #ifdef __MAC__
  43. //#include <profiler.h>  //prof
  44. #include "macgame.hpp"
  45. #include "macstat.hpp"
  46. #endif
  47.  
  48. #include <ctype.h>
  49. #include <setjmp.h>
  50.  
  51. #define SHIFT_RIGHT_DEFAULT 0
  52. #define SHIFT_DOWN_DEFAULT 30
  53.  
  54. class game;
  55. extern crc_manager *net_crcs;
  56. extern void show_verinfo(int argc, char **argv);
  57. game *the_game;
  58. window_manager *eh=NULL;
  59. int dev,shift_down=SHIFT_DOWN_DEFAULT,shift_right=SHIFT_RIGHT_DEFAULT;
  60. double sum_diffs=1,total_diffs=12;
  61. int total_active=0;
  62. long map_xoff=0,map_yoff=0;
  63. long current_vxadd,current_vyadd;
  64. int frame_panic=0,massive_frame_panic=0;
  65. int demo_start=0,idle_ticks=0;
  66. int req_end=0;
  67.  
  68. extern palette *old_pal;
  69. char **start_argv;
  70. int start_argc;
  71. int has_joystick=0;
  72. char req_name[100];
  73.  
  74. int registered=0;
  75.  
  76. extern int PixMult;
  77.  
  78. extern uchar chatting_enabled;
  79.  
  80. extern int confirm_quit();
  81.  
  82. #ifdef __MAC__
  83. extern char *macify_name(char *s);
  84.  
  85. #if 1
  86. #include "atalk.hpp"
  87. atalk_protocol atalk;
  88.  
  89. #else
  90. #include "tcpip.hpp"
  91.  
  92. tcpip_protocol tcpip;
  93. #endif
  94.  
  95. #endif
  96.  
  97.  
  98. #if !defined (MAC_PROFILE)
  99. #define StartTime(a)
  100. #define DiffTime(a,b)
  101. #else
  102.  
  103. // Timer code
  104. #include <Timer.h> // kill me (us)
  105.  
  106. #define KJCOUNTERS 20
  107. long kjcount[KJCOUNTERS];
  108. char kjfie[KJCOUNTERS][256] = { };  // kill me
  109.  
  110. extern long StartTime(int cnt);         //kill me
  111. extern long DiffTime(char *name, int cnt);   //kill me
  112. extern unsigned lighting_loop_time;
  113.  
  114. long StartTime(int cnt) //kill me too
  115. {
  116.   UnsignedWide t;
  117.   Microseconds(&t);
  118.     
  119.   return (kjcount[cnt] = t.lo);
  120. }
  121.  
  122. long DiffTime(char *name, int cnt) //kill me too
  123. {
  124.   UnsignedWide t;
  125.   Microseconds(&t);
  126.     
  127.   sprintf(kjfie[cnt],"%-16s %8d",name,t.lo-kjcount[cnt]);
  128.     
  129.   return (t.lo-kjcount[cnt]);
  130.  
  131. }
  132. #endif
  133.  
  134. void fade_in(image *im, int steps);
  135. void fade_out(int steps);
  136.  
  137. FILE *open_FILE(char *filename, char *mode)
  138. {
  139.   /*  char *prefix=get_filename_prefix() ? get_filename_prefix() : "",*c;
  140.   
  141.       if (get_save_filename_prefix)
  142.       {
  143.       for (c=mode;*c;c++) 
  144.       if (c=='w' || c=='W') 
  145.       {
  146.       }
  147.       } */
  148.       
  149.   
  150.   char tmp_name[200];
  151.   if (get_filename_prefix())
  152.     sprintf(tmp_name,"%s%s",get_filename_prefix(),filename);
  153.   else strcpy(tmp_name,filename);
  154. #ifdef __MAC__
  155.   macify_name(tmp_name);
  156. #endif
  157.   return fopen(tmp_name,mode);
  158. }
  159.  
  160.  
  161. void handle_no_space()
  162. {
  163.   char *no_space_msg= "\nYou are out of disk space or the game\n"
  164.     "was unable to write to disk for some reason\n"
  165.     "The game cannot continue, please check this out\n"
  166.     "and try again.\n";
  167.   if (eh)
  168.   {
  169.     jwindow *no_space=eh->new_window(0,0,-1,-1,
  170.         new button(WINDOW_FRAME_LEFT,WINDOW_FRAME_TOP,ID_QUIT_OK,"Quit",
  171.             new info_field(WINDOW_FRAME_LEFT,WINDOW_FRAME_TOP+eh->font()->height()*2,ID_NULL,
  172.                 no_space_msg,NULL)),"ERROR");
  173.     event ev;
  174.     do 
  175.     { 
  176.       eh->flush_screen();
  177.       eh->get_event(ev);
  178.     } while (ev.type!=EV_MESSAGE || ev.message.id!=ID_QUIT_OK);
  179.     eh->close_window(no_space);
  180.  
  181.     close_graphics();
  182.     exit(1);
  183.   } else
  184.   {
  185.     dprintf("%s\n",no_space_msg);
  186.     exit(0);
  187.   }
  188. }
  189.  
  190. void game::play_sound(int id, int vol, long x, long y)
  191. {
  192.   if (sound_avail&SFX_INITIALIZED)
  193.   {
  194.     if (vol<15) return ;
  195.     if (!player_list) return ;
  196.  
  197.     ulong mdist=0xffffffff;
  198.     view *cd=NULL;
  199.     for (view *f=player_list;f;f=f->next)
  200.     {
  201.       if (f->local_player())
  202.       {
  203.     long cx=abs(f->x_center()-x),cy=abs(f->y_center()-y),d;
  204.     if (cx<cy)
  205.           d=cx+cy-(cx>>1);
  206.     else d=cx+cy-(cy>>1);
  207.  
  208.     if (d<mdist)
  209.     {
  210.       cd=f;
  211.       mdist=d;
  212.     } 
  213.       }
  214.     }  
  215.     if (mdist>500 || !cd) return ;
  216.     if (mdist<100) mdist=0;
  217.     else mdist-=100;
  218.  
  219.     int v=(400-mdist)*sfx_volume/400-(127-vol);
  220.     if (v>0 && (sound_avail&SFX_INITIALIZED))
  221.       cash.sfx(id)->play(v);
  222.   }
  223. }
  224.  
  225. int get_option(char *name)
  226. {
  227.   int i;
  228.   for (i=1;i<start_argc;i++)
  229.     if (!strcmp(start_argv[i],name))
  230.       return i;
  231.   return 0;
  232. }
  233.  
  234.  
  235. void make_screen_size(int w, int h)
  236. {
  237.   return ;
  238.   /*
  239.   for (view *f=player_list;f;f=f->next)
  240.   {
  241.     if (f->local_player())
  242.     {
  243.       if (w>=xres-1) w=xres-2;
  244.       if (h>=yres-1) h=yres-2;
  245.       f->suggest.cx1=(xres+1)/2-w/2;
  246.       f->suggest.cx2=(xres+1)/2+w/2;
  247.       f->suggest.cy1=(yres-31)/2+5-h/2;
  248.       f->suggest.cy2=(yres-51)/2+5+h/2;
  249.       f->suggest.shift_down=f->shift_down;
  250.       f->suggest.shift_right=f->shift_right;
  251.       f->suggest.pan_x=f->pan_x;
  252.       f->suggest.pan_y=f->pan_y;
  253.  
  254.       f->suggest.send_view=1;
  255.     }
  256.   } */
  257. }
  258.  
  259. void game::grow_views(int amount)
  260. {
  261.   return ;
  262.   /*
  263.   int undo=0;
  264.   view *f=first_view;
  265.   for (;f;f=f->next)
  266.   {
  267.     if (f->local_player())
  268.     {
  269.       f->suggest.cx1=(f->cx1-amount);
  270.       f->suggest.cy1=f->cy1-amount/2;
  271.       f->suggest.cx2=(f->cx2+amount);
  272.       f->suggest.cy2=f->cy2+amount/2;
  273.       f->suggest.shift_down=f->shift_down;
  274.       f->suggest.shift_right=f->shift_right;
  275.       f->suggest.pan_x=f->pan_x;
  276.       f->suggest.pan_y=f->pan_y;
  277.  
  278.       f->suggest.send_view=1;
  279.     }
  280.   }
  281.  
  282.  
  283.   for (f=first_view;f;f=f->next)  
  284.   {
  285.     if (f->local_player())
  286.     {
  287.       if (f->suggest.cx2-f->suggest.cx1<20 || f->suggest.cy2-f->suggest.cy1<15 || 
  288.           f->suggest.cx1<0 || f->suggest.cy1<0) f->suggest.send_view=0;
  289.       if (f->next && f->next->local_player() && f->suggest.cy2>=f->next->cy1) f->suggest.send_view=0;
  290.     }
  291.   } */
  292. }
  293.  
  294. void game::pan(int xv, int yv) 
  295.   first_view->pan_x+=xv; 
  296.   first_view->pan_y+=yv; 
  297. }
  298.  
  299. view *game::view_in(int mousex, int mousey)
  300. {
  301.   for (view *f=first_view;f;f=f->next)
  302.     if (f->drawable() && mousex>=f->cx1 && mousey>=f->cy1 && mousex<=f->cx2 && mousey<=f->cy2)
  303.       return f;
  304.   return NULL;
  305. }
  306.  
  307. int playing_state(int state)
  308.   if (state==RUN_STATE || state==PAUSE_STATE) return 1;
  309.   else return 0;
  310. }
  311.  
  312. void game::ftile_on(int screenx, int screeny, long &x, long &y)
  313. {
  314.   mouse_to_game(screenx,screeny,x,y);
  315.   x/=ftile_width();
  316.   y/=ftile_height();
  317.   /*  view *f=view_in(screenx,screeny);
  318.       if (f)
  319.       {
  320.       x=((long)(screenx)-(long)f->cx1+f->xoff())/(long)f_wid;
  321.       y=((long)(screeny)-(long)f->cy1+f->yoff())/(long)f_hi;
  322.       }
  323.       else
  324.       {
  325.       x=-1; 
  326.       y=-1;
  327.       }*/
  328. }
  329.  
  330. void game::btile_on(int screenx, int screeny, long &x, long &y)
  331. {
  332.   view *f=view_in(screenx,screeny);
  333.   if (f)
  334.   {
  335.     x=((long)(screenx)-(long)f->cx1+f->xoff()*bg_xmul/bg_xdiv)/(long)b_wid; 
  336.     y=((long)(screeny)-(long)f->cy1+f->yoff()*bg_ymul/bg_ydiv)/(long)b_hi;
  337.   }
  338.   else
  339.   {
  340.     x=-1; 
  341.     y=-1;
  342.   }
  343. }
  344.  
  345.  
  346. void game::mouse_to_game(long x, long y, long &gamex, long &gamey, view *f)
  347. {
  348.   if (!f)
  349.   {
  350.     f=view_in(x,y);
  351.     if (!f) f=player_list;  // if not in a view use the first on
  352.   }
  353.  
  354.   if (f)
  355.   {
  356.     if (dev&MAP_MODE)
  357.     {
  358.       gamex=((x-(long)f->cx1)*ftile_width()/AUTOTILE_WIDTH+map_xoff*ftile_width());
  359.       gamey=((y-(long)f->cy1)*ftile_height()/AUTOTILE_HEIGHT+map_yoff*ftile_height());
  360.     } else
  361.     {
  362.       gamex=(x-(long)f->cx1+f->xoff());
  363.       gamey=(y-(long)f->cy1+f->yoff());
  364.     }
  365.   }
  366. }
  367.  
  368. void game::game_to_mouse(long gamex, long gamey, view *which, long &x, long &y)
  369. {
  370.   if (dev&MAP_MODE)
  371.   {
  372.     long x1,y1;
  373.     if (dev&EDIT_MODE)
  374.     {
  375.       x1=map_xoff;
  376.       y1=map_yoff;
  377.     } else
  378.     {
  379.       if (which->focus)
  380.       {
  381.     x1=which->focus->x/ftile_width()-(which->cx2-which->cx1)/AUTOTILE_WIDTH/2;
  382.     y1=which->focus->y/ftile_height()-(which->cy2-which->cy1)/AUTOTILE_HEIGHT/2;
  383.       } else x1=y1=0;
  384.     }
  385.     if (x1<0) x1=0;
  386.     if (y1<0) y1=0;
  387.  
  388.     x=gamex*AUTOTILE_WIDTH/ftile_width()-x1*AUTOTILE_WIDTH+which->cx1;
  389.     if (x1>0)
  390.       x-=((which->focus->x*AUTOTILE_WIDTH/ftile_width()) %AUTOTILE_WIDTH);
  391.  
  392.     y=gamey*AUTOTILE_HEIGHT/ftile_height()-y1*AUTOTILE_HEIGHT+which->cy1;
  393.     if (y1>0)
  394.       y-=((which->focus->y*AUTOTILE_HEIGHT/ftile_height()) %AUTOTILE_HEIGHT);
  395.   }
  396.   else
  397.   {
  398.     x=gamex-which->xoff()+which->cx1;
  399.     y=gamey-which->yoff()+which->cy1;
  400.   }
  401. }
  402.  
  403. int window_state(int state)
  404. {
  405.   switch (state)
  406.   {
  407.     case RUN_STATE : 
  408.     case PAUSE_STATE : 
  409.     case JOY_CALB_STATE :
  410.     { return 1; } break;
  411.  
  412.     case INTRO_START_STATE :
  413.     case HELP_STATE : 
  414.     case INTRO_MORPH_STATE :
  415.     case MENU_STATE :
  416.     case SCENE_STATE :
  417.     { return 0; } break;
  418.   }
  419.   return 1;
  420. }
  421.  
  422.  
  423. // not global for now
  424. extern void make_edit_mode_menu();
  425. extern void kill_edit_mode_menu();
  426.  
  427. void game::set_state(int new_state) 
  428. {
  429.   int d=0;
  430.   
  431.   reset_keymap();                             // we think all the keys are up right now
  432.  
  433.   if (!playing_state(new_state) && playing_state(state))
  434.   {
  435.     switch_mode(VMODE_640x480);
  436.   }
  437.  
  438.   if (playing_state(new_state) && !playing_state(state))
  439.   {
  440.     switch_mode(VMODE_320x200);
  441.     recalc_local_view_space();
  442.  
  443.     if (first_view && first_view!=player_list)
  444.     {
  445.       while (first_view)
  446.       {
  447.         view *tmp=first_view;
  448.         first_view=first_view->next;
  449.         delete tmp;
  450.       }
  451.       first_view=old_view;
  452.       old_view=NULL;
  453.     }
  454.     first_view=player_list;
  455.     d=1;
  456.   } else if (!playing_state(new_state) && (playing_state(state) || state==START_STATE))
  457.   {
  458.     if (player_list)    
  459.     {
  460.       first_view=new view(player_list->focus,NULL,-1);
  461.       first_view->pan_x=player_list->xoff();
  462.       first_view->pan_y=player_list->yoff();
  463.     }
  464.     else    
  465.       first_view=new view(NULL,NULL,0);
  466.  
  467.     /*
  468.     first_view->cx1=(xres+1)/2-155;
  469.     first_view->cy1=(yres+1)/2-95;
  470.     first_view->cx2=(xres+1)/2+155;
  471.     if (total_weapons)
  472.       first_view->cy2=(yres+1)/2+68;
  473.     else
  474.       first_view->cy2=(yres+1)/2+95;
  475.       */
  476.     
  477.     d=1;
  478.   }
  479.   
  480.  
  481.  
  482.   // switching to/from scene mode cause the screen size to change and the border to change
  483.   // so we need to redraw.
  484.   if (window_state(new_state) && !window_state(state))
  485.     eh->show_windows();
  486.   else if (!window_state(new_state) && window_state(state))
  487.     eh->hide_windows();
  488.  
  489.   int old_state=state;
  490.   state=new_state;
  491.  
  492.   pal->load();    // restore old palette
  493.  
  494.   if (playing_state(state) &&  !(dev&EDIT_MODE))
  495.     eh->set_mouse_shape(cash.img(c_target)->copy(),8,8);
  496.   else
  497.     eh->set_mouse_shape(cash.img(c_normal)->copy(),1,1);
  498.  
  499.     if (playing_state(new_state) && (dev&EDIT_MODE))
  500.         make_edit_mode_menu();
  501.     else
  502.         kill_edit_mode_menu();
  503.     
  504.   if (old_state==SCENE_STATE && new_state!=SCENE_STATE)
  505.   {
  506.     d=1;
  507.     scene_director.set_abort(0);   // don't skip any more scene stuff
  508.   }
  509.   else if (new_state==SCENE_STATE && old_state!=SCENE_STATE)
  510.     d=1;
  511.   
  512.   if (d)
  513.     draw(state==SCENE_STATE);
  514.  
  515.   dev_cont->set_state(new_state);
  516. }
  517.  
  518. void game::joy_calb(event &ev)
  519. {
  520.   if (joy_win)   // make sure the joy stick calibration window is open
  521.   {
  522.     
  523.     if (ev.type==EV_SPURIOUS)   // spurious means we should update your status
  524.     {
  525.       int b1,b2,b3=0,x,y;
  526.       joy_status(b1,b2,b2,x,y);
  527.       int but=b1|b2|b3;
  528.       if (x>0) x=1; else if (x<0) x=-1;
  529.       if (y>0) y=1; else if (y<0) y=-1;
  530.       if (but) but=1;
  531.       int dx=WINDOW_FRAME_LEFT+20,dy=WINDOW_FRAME_TOP+5;
  532.       image *jim=cash.img(joy_picts[but*9+(y+1)*3+x+1]);
  533.       joy_win->screen->bar(dx,dy,dx+jim->width()+6,dy+jim->height()+6,eh->black());
  534.       jim->put_image(joy_win->screen,dx+3,dy+3);
  535.  
  536.       if (but)
  537.         joy_calibrate();
  538.     } else if (ev.type==EV_MESSAGE && ev.message.id==JOY_OK)
  539.     {
  540.       eh->close_window(joy_win);
  541.       joy_win=NULL;
  542.       set_state(MENU_STATE);
  543.     }        
  544.   }
  545. }
  546.  
  547. void game::menu_select(event &ev)
  548. {
  549.   state=DEV_MOUSE_RELEASE;
  550.   if (top_menu)
  551.   {
  552.     /*    eh->push_event(new event(men_mess[((pick_list *)ev.message.data)->get_selection()],NULL));
  553.           eh->close_window(top_menu);
  554.           top_menu=NULL;*/
  555.   }
  556. }
  557.  
  558.  
  559. void game::show_help(char *st)
  560. {
  561.   strcpy(help_text,st);
  562.   help_text_frames=0;  
  563.   refresh=1;
  564. }
  565.  
  566. void game::draw_value(image *screen, int x, int y, int w, int h, int val, int max)
  567. {
  568.   screen->bar(x,y,x+w-1,y+h,eh->dark_color());
  569.   screen->bar(x,y+1,x+w*val/max,y+h-1,eh->bright_color());  
  570. }
  571.  
  572.  
  573. void game::set_level(level *nl)
  574. {
  575.   if (current_level) 
  576.     delete current_level;  
  577.   current_level=nl;
  578. }
  579.  
  580. void game::load_level(char *name)
  581. {
  582.   if (current_level) 
  583.     delete current_level;
  584.  
  585.   bFILE *fp=open_file(name,"rb");
  586.  
  587.   if (fp->open_failure())
  588.   {
  589.     delete fp;
  590.     current_level=new level(100,100,name);
  591.     char msg[100];
  592.     sprintf(msg,symbol_str("no_file"),name);
  593.     show_help(msg);
  594.   }
  595.   else
  596.   {                  
  597.     spec_directory sd(fp);  
  598.  
  599. #if 0
  600.     if (state != RUN_STATE)
  601.     {
  602.       // clear screen
  603.       image blank(2,2); blank.clear();
  604.       fade_out(16);
  605.       eh->set_mouse_shape(blank.copy(),0,0);      // don't show mouse
  606.       fade_in(cash.img(cdc_logo),16);
  607.     }
  608. #endif
  609.  
  610.     spec_entry *e=sd.find("Copyright 1995 Crack dot Com, All Rights reserved"); 
  611.     if (!e)
  612.     { 
  613.       the_game->show_help(symbol_str("missing_c"));
  614.       current_level=new level(100,100,"untitled");
  615.       the_game->need_refresh();
  616.     }
  617.     else 
  618.       current_level=new level(&sd,fp,name);
  619.     delete fp;
  620.   }
  621.   
  622.   base->current_tick=(current_level->tick_counter()&0xff); 
  623.  
  624.   current_level->level_loaded_notify();
  625.   the_game->help_text_frames=-1;  
  626.  
  627. }
  628.  
  629. int game::done() 
  630.   return finished || (main_net_cfg && main_net_cfg->restart_state());
  631.  
  632. }
  633.  
  634. void game::end_session()
  635. {
  636.   finished=1;
  637.   if (main_net_cfg)
  638.   {
  639.     delete main_net_cfg;
  640.     main_net_cfg=NULL;
  641.   }
  642. }
  643.  
  644. void game::put_block_fg(int x, int y, trans_image *im)
  645. {
  646.   for (view *f=first_view;f;f=f->next)
  647.   {
  648.     if (f->drawable())
  649.     {
  650.       int xoff=f->xoff(),yoff=f->yoff(),viewx1=f->cx1,viewy1=f->cy1,viewx2=f->cx2,viewy2=f->cy2;
  651.       if (xoff/ftile_width()>x || xoff/ftile_width()+(viewx2-viewx1)/ftile_width()+1<x ||
  652.       yoff/ftile_height()>y || yoff/ftile_height()+(viewy2-viewy1)/ftile_height()+1<y) return;
  653.       short cx1,cy1,cx2,cy2;
  654.       screen->get_clip(cx1,cy1,cx2,cy2);
  655.       screen->set_clip(viewx1,viewy1,viewx2,viewy2);
  656.       im->put_image(screen,(x-xoff/ftile_width())*ftile_width()+viewx1-xoff%ftile_width(),
  657.           (y-yoff/ftile_height())*ftile_height()+viewy1-yoff%ftile_height());
  658.       screen->set_clip(cx1,cy1,cx2,cy2);
  659.     }
  660.   }
  661. }
  662.  
  663. void game::put_block_bg(int x, int y, image *im)
  664. {
  665.   for (view *f=first_view;f;f=f->next)
  666.   {
  667.     if (f->drawable())
  668.     {
  669.       int xoff=f->xoff(),yoff=f->yoff(),viewx1=f->cx1,viewy1=f->cy1,viewx2=f->cx2,viewy2=f->cy2;
  670.       int xo=xoff*bg_xmul/bg_xdiv;
  671.       int yo=yoff*bg_ymul/bg_ydiv;
  672.       
  673.       if (xo/btile_width()>x || xo/btile_width()+(viewx2-viewx1)/btile_width()+1<x ||
  674.       yo/btile_height()>y || yo/btile_height()+(viewy2-viewy1)/btile_height()+1<y) return;
  675.       short cx1,cy1,cx2,cy2;
  676.       screen->get_clip(cx1,cy1,cx2,cy2);
  677.       screen->set_clip(viewx1,viewy1,viewx2,viewy2);
  678.       im->put_image(screen,(x-xo/btile_width())*btile_width()+viewx1-xo%btile_width(),
  679.           (y-yo/btile_height())*btile_height()+viewy1-yo%btile_height(),0);
  680.       screen->set_clip(cx1,cy1,cx2,cy2);
  681.     }
  682.   }
  683. }
  684.  
  685. int need_delay=1;
  686.  
  687. void game::dev_scroll()
  688. {
  689.   need_delay=0;
  690.   if (dev)
  691.   {
  692.     int xmargin,ymargin;
  693.     if (xres>400)
  694.     {
  695.       xmargin=20;
  696.       ymargin=10;
  697.     }
  698.     else 
  699.     {
  700.       xmargin=10;
  701.       ymargin=5;
  702.     }
  703.  
  704.     int xs,ys;
  705.     if (mousex<xmargin &&  dev_cont->ok_to_scroll()) xs=-18;
  706.     else if (mousex>(screen->width()-xmargin) &&  dev_cont->ok_to_scroll()) xs=18;
  707.     else if (eh->key_pressed(JK_LEFT) && !last_input && !dev_cont->need_arrows())
  708.       xs=-18;
  709.     else if (eh->key_pressed(JK_RIGHT) && !last_input && !dev_cont->need_arrows())
  710.       xs=18;
  711.     else xs=0;
  712.          
  713.  
  714.     if (mousey<ymargin && dev_cont->ok_to_scroll()) ys=-18;
  715.     else if (mousey>(screen->height()-ymargin) &&  dev_cont->ok_to_scroll()) ys=18;
  716.     else if (eh->key_pressed(JK_UP) && !last_input)
  717.       ys=-18;
  718.     else if (eh->key_pressed(JK_DOWN) && !last_input)
  719.       ys=18;
  720.     else ys=0;
  721.  
  722.     
  723.     if (xs || ys)
  724.     {
  725.       need_delay=1;
  726.       if (dev&MAP_MODE)
  727.       {
  728.         map_xoff+=xs/2;
  729.         map_yoff+=ys/2;
  730.         if (map_xoff<0) map_xoff=0;
  731.         if (map_yoff<0) map_yoff=0;
  732.       } 
  733.       else
  734.       { 
  735.         for (view *v=first_view;v;v=v->next)
  736.         {
  737.           if (xs>=0 || v->xoff()>0)
  738.             v->pan_x+=xs;
  739.           if (ys>=0 || v->yoff()>0)
  740.             v->pan_y+=ys;
  741.         }
  742.       }
  743.       refresh=1;
  744.     }
  745.   }
  746. }
  747.  
  748. void remap_area(image *screen, int x1, int y1, int x2, int y2, uchar *remap)
  749. {
  750.   uchar *sl=(uchar *)screen->scan_line(y1)+x1;
  751.   int x,y,a=screen->width()-(x2-x1+1);
  752.   uchar c;
  753.   for (y=y1;y<=y2;y++)
  754.   {
  755.     for (x=x1;x<=x2;x++)
  756.     {
  757.       c=*sl;
  758.       *(sl++)=remap[c];
  759.     }
  760.     sl+=a;
  761.   }
  762. }
  763.  
  764. void post_render()
  765. {
  766.   if (DEFINEDP(symbol_function(l_post_render)))
  767.   {
  768.     screen->dirt_off();
  769.     clear_tmp();
  770.     eval_function((lisp_symbol *)l_post_render,NULL);
  771.     clear_tmp();
  772.     screen->dirt_on();
  773.   }
  774. }
  775.   
  776. void game::draw_map(view *v, int interpolate)
  777. {
  778.   foretile *ft;
  779.   backtile *bt;
  780.   int x1,y1,x2,y2,x,y,xo,yo,nxoff,nyoff;
  781.   short cx1,cy1,cx2,cy2;
  782.   
  783.   StartTime(6); //kill me
  784.   
  785.   screen->get_clip(cx1,cy1,cx2,cy2);
  786.  
  787.   if (!current_level || state==MENU_STATE)
  788.   {
  789.     if (title_screen>=0)
  790.     {
  791.       if (state==SCENE_STATE)
  792.         screen->set_clip(v->cx1,v->cy1,v->cx2,v->cy2);        
  793.       image *tit=cash.img(title_screen);
  794.       tit->put_image(screen,screen->width()/2-tit->width()/2,
  795.           screen->height()/2-tit->height()/2);
  796.       if (state==SCENE_STATE)
  797.         screen->set_clip(cx1,cy1,cx2,cy2);
  798.       eh->flush_screen();
  799.     }   
  800.     return ;
  801.   }
  802.  
  803.   refresh=0;  
  804.  
  805.  
  806.   // save the dirty rect routines some work by markinging evrything in the 
  807.   // view area dirty alreadt
  808.  
  809.   if (small_render)
  810.     screen->add_dirty(v->cx1,v->cy1,(v->cx2-v->cx1+1)*2+v->cx1,v->cy1+(v->cy2-v->cy1+1)*2);    
  811.   else
  812.     screen->add_dirty(v->cx1,v->cy1,v->cx2,v->cy2);    
  813.  
  814.   if (v->draw_solid!=-1)      // fill the screen and exit..
  815.   {
  816.     int c=v->draw_solid;
  817.     for (int y=v->cy1;y<=v->cy2;y++)
  818.       memset(screen->scan_line(y)+v->cx1,c,v->cx2-v->cx1+1);
  819.     v->draw_solid=-1;
  820.     return ;
  821.   }
  822.  
  823.   long old_cx1,old_cy1,old_cx2,old_cy2;   // if we do a small render, we need to restore these
  824.   image *old_screen=NULL;
  825.   if (small_render && (dev&DRAW_LIGHTS))  // cannot do this if we skip lighting
  826.   {
  827.     old_cx1=v->cx1;
  828.     old_cy1=v->cy1;
  829.     old_cx2=v->cx2;
  830.     old_cy2=v->cy2;
  831.  
  832.     /*    v->cx1=0;
  833.     v->cy1=0;
  834.     v->cx2=small_render->width()-1;
  835.     v->cy2=small_render->height()-1; */
  836.  
  837.     old_screen=screen;
  838.     screen=small_render;
  839.   } else
  840.     screen->dirt_off();
  841.  
  842.  
  843.  
  844.   //  long max_xoff=(current_level->foreground_width()-1)*ftile_width()-(v->cx2-v->cx1+1);
  845.   //  long max_yoff=(current_level->foreground_height()-1)*ftile_height()-(v->cy2-v->cy1+1); 
  846.  
  847.   long xoff,yoff;
  848.   if (interpolate)
  849.   {
  850.     xoff=v->interpolated_xoff();
  851.     yoff=v->interpolated_yoff();
  852.   } else
  853.   {
  854.     xoff=v->xoff();
  855.     yoff=v->yoff();
  856.   }
  857.  
  858.   //  if (xoff>max_xoff) xoff=max_xoff;
  859.   //  if (yoff>max_yoff) yoff=max_yoff;  
  860.  
  861.   current_vxadd=xoff-v->cx1;
  862.   current_vyadd=yoff-v->cy1;
  863.  
  864.   screen->set_clip(v->cx1,v->cy1,v->cx2,v->cy2);
  865.  
  866.   nxoff=xoff*bg_xmul/bg_xdiv;
  867.   nyoff=yoff*bg_ymul/bg_ydiv;
  868.  
  869.   //  long max_bg_xoff=(current_level->background_width())*btile_width()-(v->cx2-v->cx1+1);
  870.   //  long max_bg_yoff=(current_level->background_height())*btile_height()-(v->cy2-v->cy1+1);
  871.   //  if (nxoff>max_bg_xoff) nxoff=max_xoff;
  872.   //  if (nyoff>max_bg_yoff) nyoff=max_yoff;  
  873.   
  874.   
  875.   x1=nxoff/btile_width(); y1=nyoff/btile_height();
  876.   x2=x1+(v->cx2-v->cx1+btile_width())/btile_width();
  877.   y2=y1+(v->cy2-v->cy1+btile_height())/btile_height();
  878.  
  879.  
  880.   xo=v->cx1-nxoff%btile_width();
  881.   yo=v->cy1-nyoff%btile_height();
  882.   
  883.   int xinc,yinc,draw_x,draw_y;
  884.  
  885.  
  886.   DiffTime("      PreDraw",6);//kill me
  887.   StartTime(7); //kill me
  888.   if (!(dev & MAP_MODE) && (dev & DRAW_BG_LAYER))
  889.   {
  890.     xinc=btile_width();  
  891.     yinc=btile_height();  
  892.     
  893.     int bh=current_level->background_height(),bw=current_level->background_width();
  894.     ushort *bl;
  895.     for (draw_y=yo,y=y1;y<=y2;y++,draw_y+=yinc)
  896.     {
  897.       if (y>=bh)
  898.         bl=NULL;
  899.       else
  900.         bl=current_level->get_bgline(y)+x1;
  901.  
  902.       for (x=x1,draw_x=xo;x<=x2;x++,draw_x+=xinc)
  903.       {
  904.         if (x<bw && y<bh)
  905.         {
  906.           bt=get_bg(*bl);
  907.           bl++;
  908.         }
  909.         else bt=get_bg(0);
  910.  
  911.         bt->im->put_image(screen,draw_x,draw_y); 
  912.         //        if (!(dev & EDIT_MODE) && bt->next)
  913.         //      current_level->put_bg(x,y,bt->next);
  914.       }
  915.     }
  916.   }
  917.   //  if (!(dev&EDIT_MODE))
  918.   //    server_check();
  919.  
  920.   uchar rescan=0;  
  921.  
  922.   int fw,fh;
  923.  
  924.   if (dev&MAP_MODE)
  925.   {
  926.     fw=AUTOTILE_WIDTH;
  927.     fh=AUTOTILE_HEIGHT;
  928.     if (dev&EDIT_MODE)
  929.     {
  930.       x1=map_xoff;
  931.       y1=map_yoff;
  932.     } else
  933.     {
  934.       if (v->focus)
  935.       {
  936.         x1=v->focus->x/ftile_width()-(v->cx2-v->cx1)/fw/2;
  937.         y1=v->focus->y/ftile_height()-(v->cy2-v->cy1)/fh/2;
  938.       } else x1=y1=0;
  939.     }
  940.     if (x1>0)
  941.       xo=v->cx1-((v->focus->x*fw/ftile_width()) %fw);
  942.     else xo=v->cx1;
  943.     if (y1>0)
  944.       yo=v->cy1-((v->focus->y*fh/ftile_height()) %fh);
  945.     else yo=v->cy1;
  946.   } else
  947.   {
  948.     fw=ftile_width();
  949.     fh=ftile_height();
  950.     x1=(xoff)/fw; y1=(yoff)/fh;
  951.     xo=v->cx1-xoff%fw;
  952.     yo=v->cy1-yoff%fh;
  953.  
  954.   }
  955.   if (x1<0) x1=0;
  956.   if (y1<0) y1=0;
  957.   
  958.   x2=x1+(v->cx2-v->cx1+fw)/fw;
  959.   y2=y1+(v->cy2-v->cy1+fh)/fh;
  960.   if (x2>=current_level->foreground_width())
  961.     x2=current_level->foreground_width()-1;
  962.   if (y2>=current_level->foreground_height())
  963.     y2=current_level->foreground_height()-1;
  964.  
  965.  
  966.   xinc=fw;
  967.   yinc=fh;
  968.  
  969.   DiffTime("      BG/MAP",7);//kill me
  970.   StartTime(8); //kill me
  971.  
  972.   if (dev & DRAW_FG_LAYER)
  973.   {
  974.     short ncx1,ncy1,ncx2,ncy2;
  975.     screen->get_clip(ncx1,ncy1,ncx2,ncy2);
  976.  
  977.     int scr_w=screen->width();
  978.     if (dev&MAP_MODE)
  979.     {
  980.       if (dev&EDIT_MODE)
  981.         screen->clear(eh->bright_color());
  982.       else
  983.         screen->clear(eh->black());
  984.       for (y=y1,draw_y=yo;y<=y2;y++,draw_y+=yinc)
  985.       {
  986.         if (!(draw_y<ncy1 ||draw_y+yinc>=ncy2))
  987.         {
  988.           ushort *cl=current_level->get_fgline(y)+x1;
  989.           uchar *sl1=screen->scan_line(draw_y)+xo;
  990.           for (x=x1,draw_x=xo;x<=x2;x++,cl++,sl1+=xinc,draw_x+=xinc)
  991.           {
  992.             if (!(draw_x<ncx1 || draw_x+xinc>=ncx2))
  993.             {
  994.               int fort_num;
  995.               //          if (*cl&0x8000 || (dev&EDIT_MODE))
  996.               fort_num=fgvalue(*cl);
  997.               //          else fort_num=0;
  998.             
  999.               uchar *sl2=get_fg(fort_num)->micro_image->scan_line(0);
  1000.               uchar *sl3=sl1;
  1001.               memcpy(sl3,sl2,AUTOTILE_WIDTH); sl2+=AUTOTILE_WIDTH; sl3+=scr_w;
  1002.               memcpy(sl3,sl2,AUTOTILE_WIDTH); sl2+=AUTOTILE_WIDTH; sl3+=scr_w;
  1003.               memcpy(sl3,sl2,AUTOTILE_WIDTH);
  1004.             }
  1005.           }
  1006.         }
  1007.       }
  1008.  
  1009.       if (dev&EDIT_MODE)
  1010.         current_level->draw_areas(v);
  1011.     } else
  1012.     {
  1013.  
  1014.       int fg_h=current_level->foreground_height(),fg_w=current_level->foreground_width();
  1015.       
  1016.       for (y=y1,draw_y=yo;y<=y2;y++,draw_y+=yinc)
  1017.       {
  1018.     
  1019.         ushort *cl;
  1020.         if (y<fg_h)
  1021.           cl=current_level->get_fgline(y)+x1;
  1022.         else cl=NULL;
  1023.         uchar *sl1=draw_y<ncy1 ? 0 : screen->scan_line(draw_y)+xo;
  1024.             
  1025.         for (x=x1,draw_x=xo;x<=x2;x++,draw_x+=xinc,cl++,sl1+=xinc)
  1026.         {
  1027.           if (x<fg_w && y<fg_h)
  1028.           {
  1029.             if (above_tile(*cl))
  1030.               rescan=1;
  1031.             else
  1032.             {
  1033.               int fort_num=fgvalue(*cl);      
  1034.               if (fort_num!=BLACK)
  1035.               {
  1036.                 if (draw_y<ncy1 || draw_y+yinc>=ncy2 || draw_x<ncx1 || draw_x+xinc>=ncx2)
  1037.                   get_fg(fort_num)->im->put_image(screen,draw_x,draw_y);
  1038.                 else
  1039.                   get_fg(fort_num)->im->put_image_offseted(screen,sl1);
  1040.             
  1041.                 if (!(dev & EDIT_MODE))
  1042.                   *cl|=0x8000;      // mark as has-been-seen
  1043.               }    
  1044.             }
  1045.           }
  1046.         }
  1047.       }  
  1048.     }
  1049.     /*        if (dev==0)
  1050.               current_level->put_fg(x,y,ft->next);  */       
  1051.   }
  1052.   
  1053.   DiffTime("      FG",8);//kill me
  1054.  
  1055.   //  if (!(dev&EDIT_MODE))
  1056.   //    server_check();
  1057.  
  1058.   long ro=rand_on;
  1059.   if (dev & DRAW_PEOPLE_LAYER)
  1060.   {
  1061.     if (interpolate)
  1062.       current_level->interpolate_draw_objects(v);
  1063.     else
  1064.       current_level->draw_objects(v);
  1065.   }
  1066.  
  1067.   //  if (!(dev&EDIT_MODE))
  1068.   //    server_check();
  1069.  
  1070.   StartTime(9); //kill me
  1071.   if (!(dev&MAP_MODE))
  1072.   {
  1073.  
  1074.     int fg_h=current_level->foreground_height(),fg_w=current_level->foreground_width();
  1075.  
  1076.     if (dev & DRAW_FG_LAYER && rescan)
  1077.     {
  1078.       for (y=y1,draw_y=yo;y<=y2;y++,draw_y+=yinc)
  1079.       {
  1080.         ushort *cl=current_level->get_fgline(y)+x1;
  1081.         for (x=x1,draw_x=xo;x<=x2;x++,draw_x+=xinc,cl++)
  1082.         {
  1083.           if (above_tile(*cl))
  1084.           {
  1085.             int fort_num=fgvalue(*cl);      
  1086.             if (fort_num!=BLACK)
  1087.             {
  1088.               if (dev & DRAW_BG_LAYER)
  1089.                 get_fg(fort_num)->im->put_image(screen,draw_x,draw_y);
  1090.               else
  1091.                 get_fg(fort_num)->im->put_image_filled(screen,draw_x,draw_y,0);
  1092.             
  1093.               if (!(dev & EDIT_MODE))
  1094.                 current_level->mark_seen(x,y);
  1095.               else
  1096.               {
  1097.                 screen->line(draw_x,draw_y,draw_x+xinc,draw_y+yinc,eh->bright_color());
  1098.                 screen->line(draw_x+xinc,draw_y,draw_x,draw_y+yinc,eh->bright_color());
  1099.               }
  1100.             }    
  1101.           }
  1102.         }
  1103.       }   
  1104.     }
  1105.  
  1106.     
  1107.     if (dev & DRAW_FG_BOUND_LAYER)
  1108.     {
  1109.       int b=eh->bright_color();
  1110.       int fg_h=current_level->foreground_height(),fg_w=current_level->foreground_width();
  1111.  
  1112.       for (y=y1,draw_y=yo;y<=y2;y++,draw_y+=yinc)
  1113.       {
  1114.         ushort *cl;
  1115.         if (y<fg_h)
  1116.           cl=current_level->get_fgline(y)+x1;
  1117.         else cl=NULL;
  1118.         for (x=x1,draw_x=xo;x<=x2;x++,draw_x+=xinc,cl++)
  1119.         {
  1120.           if (x<fg_w && y<fg_h)
  1121.           {
  1122.             int fort_num=fgvalue(*cl);      
  1123.             if (fort_num!=BLACK)
  1124.             {
  1125.               point_list *p=get_fg(fort_num)->points;
  1126.               uchar *d=p->data;    
  1127.               if (p->tot)
  1128.               {
  1129.                 for (int i=1;i<p->tot;i++)
  1130.                 {
  1131.                   d+=2;
  1132.                   screen->line(draw_x+*(d-2),draw_y+*(d-1),draw_x+*d,draw_y+*(d+1),b);
  1133.                 }
  1134.                 screen->line(draw_x+*d,draw_y+*(d-1),draw_x+p->data[0],draw_y+p->data[1],b);
  1135.               }
  1136.             }
  1137.           }
  1138.         }
  1139.       }
  1140.     }
  1141.  
  1142.     //    if (!(dev&EDIT_MODE))
  1143.     //      server_check();
  1144.  
  1145.     if (dev & DRAW_HELP_LAYER)
  1146.     {
  1147.       if (help_text_frames>=0)
  1148.       {
  1149.         int color;
  1150.                 
  1151.         if (help_text_frames<10)
  1152.           color=2;
  1153.         else
  1154.           color=2+(help_text_frames-10);
  1155.                 
  1156.         int x1=v->cx1,
  1157.           y1=v->cy2-(eh->font()->height()+5),
  1158.           x2=v->cx2,
  1159.           y2=v->cy2-1;
  1160.  
  1161.             
  1162.         remap_area(screen,x1,y1,x2,y2,white_light+40*256);
  1163.         screen->bar(x1,y1,x2,y1,color);
  1164.         screen->bar(x1,y2,x2,y2,color);
  1165.             
  1166.         eh->frame_font()->put_string(screen,x1+5,y1+5,
  1167.             help_text,color);
  1168.         if (color>30)
  1169.           help_text_frames=-1;      
  1170.         else help_text_frames++;
  1171.     
  1172.       }    
  1173.     }
  1174.     
  1175.     if (dev_cont)
  1176.       dev_cont->dev_draw(v);  
  1177.     if (cash.in_use())
  1178.       cash.img(vmm_image)->put_image(screen,v->cx1,v->cy2-cash.img(vmm_image)->height()+1);  
  1179.  
  1180.     if (dev&DRAW_LIGHTS)
  1181.     {  
  1182.       if (small_render)
  1183.       {
  1184.         double_light_screen(screen,xoff,yoff,white_light,v->ambient,old_screen,old_cx1,old_cy1);
  1185.             
  1186.         /*        v->cx1=old_cx1;
  1187.         v->cy1=old_cy1;
  1188.         v->cx2=old_cx2;
  1189.         v->cy2=old_cy2; */
  1190.         screen=old_screen;
  1191.       } else
  1192.       {      
  1193.         screen->dirt_on();
  1194.         if (xres*yres<=64000)
  1195.           light_screen(screen,xoff,yoff,white_light,v->ambient);
  1196.         else light_screen(screen,xoff,yoff,white_light,63);            // no lighting for hi-rez
  1197.       }
  1198.  
  1199.     } else 
  1200.       screen->dirt_on();
  1201.  
  1202.  
  1203.  
  1204.   }  else
  1205.     screen->dirt_on();
  1206.  
  1207.   DiffTime("      Other",9); //kill me
  1208.  
  1209.   StartTime(15); // kill me
  1210.   rand_on=ro;                // restore random start in case in draw funs moved it
  1211.   // ... not every machine will draw the same thing
  1212.  
  1213.   post_render();
  1214.  
  1215.   screen->set_clip(cx1,cy1,cx2,cy2);
  1216.     
  1217.  
  1218.  
  1219.  
  1220.   if (playing_state(state))        // draw stuff outside the clipping region
  1221.     v->draw_character_damage();
  1222.  
  1223.   if (profiling())
  1224.     profile_update();
  1225.  
  1226.   sbar.draw_update();
  1227.   DiffTime("      Post",15); //kill me
  1228. }
  1229.  
  1230. void game::put_fg(int x, int y, int type)
  1231.   if (current_level->get_fg(x,y)!=type)
  1232.   {
  1233.     current_level->put_fg(x,y,type);
  1234.     for (view *f=first_view;f;f=f->next)
  1235.       if (f->drawable())
  1236.         draw_map(f);    
  1237.     /*    put_block_bg(x,y,get_bg(current_level->get_bg(x/ASPECT,y/ASPECT))->im);
  1238.           if (type>BLACK)
  1239.           put_block_fg(x,y,get_fg(type)->im); */
  1240.   }
  1241. }
  1242.  
  1243. void game::put_bg(int x, int y, int type)
  1244. {
  1245.   if (current_level->get_bg(x,y)!=type)
  1246.   {
  1247.     current_level->put_bg(x,y,type);
  1248.     for (view *f=first_view;f;f=f->next)
  1249.       if (f->drawable())
  1250.         draw_map(f);    
  1251.     /*    put_block_bg(x,y,get_bg(type)->im);
  1252.           if (current_level->get_fg(x,y)>BLACK) 
  1253.           put_block_fg(x,y,get_fg(current_level->get_fg(x,y))->im);*/
  1254.   }
  1255. }
  1256.  
  1257. int game::in_area(event &ev, int x1, int y1, int x2, int y2)
  1258. {
  1259.   return (last_demo_mx>=x1 && last_demo_mx<=x2 &&
  1260.       last_demo_my>=y1 && last_demo_my<=y2);
  1261. }
  1262.  
  1263. void game::request_level_load(char *name)
  1264. {
  1265.   strcpy(req_name,name);
  1266. }
  1267.  
  1268. extern int start_doubled;
  1269.  
  1270. void fade_in(image *im, int steps)
  1271. {
  1272.   palette *old_pal=pal->copy();
  1273.   int i;
  1274.   if (im)
  1275.   {
  1276.     screen->clear();
  1277.     im->put_image(screen,(xres+1)/2-im->width()/2,(yres+1)/2-im->height()/2);
  1278.   }
  1279.  
  1280.   for (i=0;i<steps;i++)
  1281.   {
  1282.     uchar *sl1=(uchar *)pal->addr();    
  1283.     uchar *sl2=(uchar *)old_pal->addr();    
  1284.     int j;
  1285.     int r,g,b;
  1286.     int v=(i+1)*256/steps;
  1287.     for (j=0;j<256;j++)
  1288.     {
  1289.       *(sl1)=((int)*(sl2))*v/256;  sl1++; sl2++;
  1290.       *(sl1)=((int)*(sl2))*v/256;  sl1++; sl2++;
  1291.       *(sl1)=((int)*(sl2))*v/256;  sl1++; sl2++;
  1292.     }
  1293.     pal->load();
  1294.     eh->flush_screen();
  1295.     milli_wait(25);
  1296.   }
  1297.   delete pal;
  1298.   pal=old_pal;
  1299. }
  1300.  
  1301. void fade_out(int steps)
  1302. {
  1303.   palette *old_pal=pal->copy();
  1304.   int i;
  1305.   for (i=0;i<steps;i++)
  1306.   {
  1307.     uchar *sl1=(uchar *)pal->addr();    
  1308.     uchar *sl2=(uchar *)old_pal->addr();    
  1309.     int j;
  1310.     int r,g,b;
  1311.     int v=(steps-i)*256/steps;
  1312.     for (j=0;j<256;j++)
  1313.     {
  1314.       *(sl1)=((int)*(sl2))*v/256;  sl1++; sl2++;
  1315.       *(sl1)=((int)*(sl2))*v/256;  sl1++; sl2++;
  1316.       *(sl1)=((int)*(sl2))*v/256;  sl1++; sl2++;
  1317.     }
  1318.     pal->load();
  1319.     eh->flush_screen();
  1320.     milli_wait(25);
  1321.   }
  1322.   screen->clear();
  1323.   eh->flush_screen();
  1324.   delete pal;
  1325.   pal=old_pal;
  1326.   
  1327.   pal->load();
  1328. }
  1329.  
  1330. int text_draw(int y, int x1, int y1, int x2, int y2, char *buf, JCFont *font, uchar *cmap, char color);
  1331.  
  1332. void do_title()
  1333. {
  1334.   if (cdc_logo!=-1)
  1335.   {
  1336.     if (sound_avail&MUSIC_INITIALIZED)
  1337.     {
  1338.       if (current_song) { current_song->stop(); delete current_song; }
  1339.       current_song=new song("music/intro.hmi");
  1340.       current_song->play(music_volume);
  1341.     }
  1342.  
  1343.     void *logo_snd=symbol_value(make_find_symbol("LOGO_SND"));
  1344.  
  1345.     if (DEFINEDP(logo_snd) && (sound_avail&SFX_INITIALIZED))
  1346.       cash.sfx(lnumber_value(logo_snd))->play(sfx_volume);
  1347.  
  1348.     image blank(2,2); blank.clear();
  1349.     eh->set_mouse_shape(blank.copy(),0,0);      // don't show mouse
  1350.     fade_in(cash.img(cdc_logo),32);
  1351.     
  1352.     milli_wait(900);
  1353.  
  1354.     void *space_snd=symbol_value(make_find_symbol("SPACE_SND"));
  1355.  
  1356.     fade_out(32);
  1357.     milli_wait(300);
  1358.  
  1359.     int i,abort=0;
  1360.     char *str=lstring_value(eval(make_find_symbol("plot_start")));
  1361.     
  1362.     bFILE *fp=open_file("art/smoke.spe","rb");
  1363.     if (!fp->open_failure())
  1364.     {
  1365.       spec_directory sd(fp);
  1366.       palette *old_pal=pal;
  1367.       pal=new palette(sd.find(SPEC_PALETTE),fp);
  1368.       pal->shift(1);
  1369.  
  1370.       image *gray=new image(sd.find("gray_pict"),fp);
  1371.       image *smoke[5];
  1372.  
  1373.       char nm[20];
  1374.       for (i=0;i<5;i++)
  1375.       {
  1376.         sprintf(nm,"smoke%04d.pcx",i+1);
  1377.         smoke[i]=new image(sd.find(nm),fp);
  1378.       }
  1379.  
  1380.       screen->clear();
  1381.       pal->load();
  1382.  
  1383.       int dx=(xres+1)/2-gray->width()/2,dy=(yres+1)/2-gray->height()/2;
  1384.       gray->put_image(screen,dx,dy);
  1385.       smoke[0]->put_image(screen,dx+24,dy+5);
  1386.  
  1387.       fade_in(NULL,16);
  1388.       uchar cmap[32];
  1389.       for (i=0;i<32;i++)
  1390.         cmap[i]=pal->find_closest(i*256/32,i*256/32,i*256/32);
  1391.  
  1392.       event ev; ev.type=EV_SPURIOUS;
  1393.       time_marker start;
  1394.  
  1395.  
  1396.       for (i=0;i<600 && ev.type!=EV_KEY && ev.type!=EV_MOUSE_BUTTON;i++)
  1397.       {
  1398.         gray->put_part(screen,dx,dy,0,0,319,199);
  1399.         smoke[i%5]->put_image(screen,dx+65,dy+70);
  1400.         text_draw(205-i,dx+15,dy,dx+320-15,dy+199,str,eh->font(),cmap,eh->bright_color());
  1401.         eh->flush_screen();
  1402.         time_marker now;
  1403.         while (now.diff_time(&start)<0.15) 
  1404.           now.get_time();
  1405.         start.get_time();
  1406.             
  1407.         while (eh->event_waiting() && ev.type!=EV_KEY) eh->get_event(ev);
  1408.         if ((i%5)==0 && DEFINEDP(space_snd) && (sound_avail&SFX_INITIALIZED))
  1409.           cash.sfx(lnumber_value(space_snd))->play(sfx_volume*90/127);
  1410.       }
  1411.  
  1412.       the_game->reset_keymap();
  1413.  
  1414.       fade_out(16);
  1415.  
  1416.       for (i=0;i<5;i++) delete smoke[i];
  1417.       delete gray;
  1418.  
  1419.       delete pal;
  1420.       pal=old_pal;
  1421.     }
  1422.     delete fp;
  1423.  
  1424.     for (i=0;i<100 && !abort;i++)
  1425.     {
  1426.       
  1427.     }
  1428.  
  1429.  
  1430.  
  1431.     if (title_screen>=0)
  1432.       fade_in(cash.img(title_screen),32);
  1433.  
  1434.     eh->set_mouse_shape(cash.img(c_normal)->copy(),1,1);
  1435.   }
  1436. }
  1437.  
  1438. extern int start_edit;
  1439.  
  1440. void game::request_end()
  1441. {
  1442.   req_end=1;
  1443. }
  1444.  
  1445. extern void fast_load_start_recording(char *name);
  1446. extern void fast_load_stop_recording();
  1447. extern void fast_load_start_reloading(char *name);
  1448. extern void fast_load_stop_reloading();
  1449.  
  1450. game::game(int argc, char **argv)
  1451. {
  1452.   int i;
  1453.   req_name[0]=0;
  1454.   bg_xmul=bg_ymul=1;
  1455.   bg_xdiv=bg_ydiv=8;
  1456.   last_input=NULL;
  1457.   current_level=NULL;
  1458.   refresh=1;  
  1459.   the_game=this;  
  1460.   top_menu=joy_win=NULL;
  1461.   old_view=first_view=NULL;
  1462.   nplayers=1;
  1463.  
  1464.   help_text_frames=-1;  
  1465.   strcpy(help_text,"");
  1466.  
  1467.   for (i=1;i<argc;i++)
  1468.     if (!strcmp(argv[i],"-no_delay"))
  1469.     {
  1470.       no_delay=1;
  1471.       dprintf("Frame delay off (-nodelay)\n");
  1472.     }
  1473.   
  1474.   image_init();  
  1475.   zoom=15;  
  1476.   no_delay=0;
  1477.  
  1478.   if (get_option("-use_joy"))  
  1479.   {
  1480.     has_joystick=joy_init(argc,argv);
  1481.     dprintf("Joystick : ");
  1482.     if (has_joystick) dprintf("detected\n");
  1483.     else dprintf("not detected\n");
  1484.   }
  1485.   else has_joystick=0;
  1486.  
  1487.   //    fast_load_start_recording("fastload.dat");
  1488.   load_data(argc,argv);  
  1489.   //    fast_load_stop_recording();
  1490.  
  1491.   get_key_bindings();
  1492.  
  1493.  
  1494.   reset_keymap();                   // we think all the keys are up right now
  1495.   finished=0;
  1496.  
  1497.   calc_light_table(pal);
  1498.  
  1499.   if (current_level==NULL && net_start())  // if we joined a net game get level from server
  1500.   {
  1501.     if (!request_server_entry())
  1502.     {
  1503.       exit(0);
  1504.     }
  1505.     net_reload();
  1506.     //    load_level(NET_STARTFILE); 
  1507.   }
  1508.  
  1509.  
  1510.   if (get_option("-2") && (xres<639 || yres<399))
  1511.   {
  1512.     close_graphics();
  1513.     dprintf("Resolution must be > 640x400 to use -2 option\n");    
  1514.     exit(0);
  1515.   }
  1516.   pal->load();
  1517.   
  1518.   recalc_local_view_space();   // now that we know what size the screen is...
  1519.  
  1520.   dark_color=get_color(cash.img(window_colors)->pixel(2,0));
  1521.   bright_color=get_color(cash.img(window_colors)->pixel(0,0));
  1522.   med_color=get_color(cash.img(window_colors)->pixel(1,0));
  1523.  
  1524.   morph_dark_color=get_color(cash.img(window_colors)->pixel(2,1));
  1525.   morph_bright_color=get_color(cash.img(window_colors)->pixel(0,1));
  1526.   morph_med_color=get_color(cash.img(window_colors)->pixel(1,1));
  1527.   morph_sel_frame_color=pal->find_closest(255,255,0);
  1528.   light_connection_color=morph_sel_frame_color;
  1529.  
  1530.   if (NILP(symbol_value(l_default_font)))
  1531.   {
  1532.     dprintf("No font defined, set symbol default-font to an image name\n");
  1533.     exit(0);
  1534.   }
  1535.  
  1536.   int font_pict=big_font_pict;
  1537.   
  1538.   if (console_font_pict==-1) console_font_pict=font_pict;
  1539.   game_font=new JCFont(cash.img(big_font_pict));
  1540.   window_font=new JCFont(cash.img(small_font_pict));
  1541.  
  1542.   console_font=new JCFont(cash.img(console_font_pict));
  1543.  
  1544.   eh=new window_manager(screen,pal,bright_color,
  1545.       med_color,
  1546.       dark_color,
  1547.       game_font);  
  1548.   idle_man=new idle_manager;
  1549.  
  1550.  
  1551.   eh->set_frame_font(window_font);
  1552.  
  1553.   chat=new chat_console(eh,console_font,50,6);
  1554.  
  1555.   if (!eh->has_mouse())
  1556.   {
  1557.     close_graphics();
  1558.     image_uninit();
  1559.     dprintf("No mouse driver detected, please rectify.\n");
  1560.     exit(0);
  1561.   }
  1562.  
  1563.   gamma_correct(pal);
  1564.  
  1565.   if (main_net_cfg==NULL || (main_net_cfg->state!=net_configuration::SERVER &&
  1566.       main_net_cfg->state!=net_configuration::CLIENT))
  1567.   {
  1568.     if (!start_edit && !net_start())
  1569.       do_title();
  1570.   } else if (main_net_cfg && main_net_cfg->state==net_configuration::SERVER)
  1571.   {
  1572.     the_game->load_level(level_file);
  1573.     start_running=1;
  1574.   }
  1575.     
  1576.   dev|= DRAW_FG_LAYER | DRAW_BG_LAYER | DRAW_PEOPLE_LAYER | DRAW_HELP_LAYER | DRAW_LIGHTS | DRAW_LINKS;
  1577.  
  1578.   if (dev & EDIT_MODE)
  1579.     set_frame_size(0);
  1580.   //  do_intro();
  1581.   state=START_STATE;         // first set the state to one that has windows
  1582.  
  1583.   if (start_running)
  1584.     set_state(RUN_STATE);
  1585.   else
  1586.   {
  1587.     screen->clear();  
  1588.     if (title_screen>=0)
  1589.     {
  1590.       image *tit=cash.img(title_screen);
  1591.       tit->put_image(screen,screen->width()/2-tit->width()/2,
  1592.           screen->height()/2-tit->height()/2);
  1593.     }   
  1594.     set_state(MENU_STATE);   // then go to menu state so windows will turn off
  1595.   }
  1596. }
  1597.  
  1598.  
  1599.  
  1600. time_marker *led_last_time=NULL,*fps_mark_start=NULL;
  1601. double avg_fps=15.0,possible_fps=15.0;
  1602.  
  1603. void game::toggle_delay()
  1604. {
  1605.   no_delay=!no_delay;
  1606.   if (no_delay)
  1607.     show_help(symbol_str("delay_off"));
  1608.   else show_help(symbol_str("delay_on"));
  1609.   avg_fps=possible_fps=15.0;
  1610. }
  1611.  
  1612. void game::show_time()
  1613. {
  1614.   if (first_view && fps_on)
  1615.   {
  1616.     char str[10];
  1617.     sprintf(str,"%d",(long)(avg_fps*10.0));
  1618.     console_font->put_string(screen,first_view->cx1,first_view->cy1,str);
  1619.  
  1620.     sprintf(str,"%d",total_active);
  1621.     console_font->put_string(screen,first_view->cx1,first_view->cy1+10,str);
  1622.   }
  1623.  
  1624. #ifdef MAC_PROFILE
  1625.   for (int i=0; i<KJCOUNTERS; i++)
  1626.     console_font->put_string(screen,10,8*i+8,kjfie[i]); // kill me
  1627. #endif
  1628. }
  1629.  
  1630. void game::update_screen()
  1631. {
  1632.   if (state==HELP_STATE)
  1633.     draw_help();
  1634.   else if (current_level)
  1635.   {    
  1636.     if (!(dev & EDIT_MODE) || refresh)    
  1637.     {    
  1638.       view *f=first_view;
  1639.       current_level->clear_active_list();
  1640.       for (;f;f=f->next)
  1641.       {
  1642.         if (f->focus)           
  1643.         {
  1644.           int w,h;
  1645.             
  1646.           w=(f->cx2-f->cx1+1);
  1647.           h=(f->cy2-f->cy1+1);
  1648.             
  1649.           total_active+=current_level->add_drawables(f->xoff()-w/4,f->yoff()-h/4,
  1650.               f->xoff()+w+w/4,f->yoff()+h+h/4);
  1651.             
  1652.         }
  1653.       }
  1654.  
  1655.       for (f=first_view;f;f=f->next)
  1656.       {
  1657.         if (f->drawable())
  1658.         {
  1659.           StartTime(5); // kill me
  1660.           if (interpolate_draw)
  1661.           {
  1662.             draw_map(f,1);
  1663.             eh->flush_screen();
  1664.           }
  1665.           draw_map(f,0);
  1666.           DiffTime("    Drawmap",5); // kill me
  1667.         }
  1668.       }
  1669.  
  1670.     }  
  1671.     if (state==PAUSE_STATE)
  1672.     {
  1673.       for (view *f=first_view;f;f=f->next)
  1674.         cash.img(pause_image)->put_image(screen,(f->cx1+f->cx2)/2-cash.img(pause_image)->width()/2,
  1675.             f->cy1+5,1);
  1676.     }
  1677.     
  1678.     show_time();
  1679.   }
  1680.  
  1681.   if (state==RUN_STATE && cash.prof_is_on())
  1682.     cash.prof_poll_end();
  1683.  
  1684.   StartTime(16); //kill me
  1685.   eh->flush_screen();
  1686.   DiffTime("    Flush",16); //kill me
  1687. }
  1688.  
  1689. void game::do_intro()
  1690. {
  1691.  
  1692. }
  1693.  
  1694. #if 1
  1695. int game::calc_speed()
  1696. {
  1697.   int ret=0;
  1698.   if (fps_mark_start)
  1699.   {
  1700.  
  1701.     time_marker t;
  1702.  
  1703.     // find average fps for last 10 frames
  1704.     double td=t.diff_time(fps_mark_start);
  1705.     if (td<0.001)     // something is rotten in the state of demark
  1706.       td=0.001;
  1707.  
  1708.     avg_fps=avg_fps*9.0/10.0+1.0/(td*10.0);  
  1709.     possible_fps=possible_fps*9.0/10.0+1.0/(td*10.0);  
  1710.  
  1711.     if (avg_fps>14)
  1712.     {
  1713.       if (massive_frame_panic>20)
  1714.         massive_frame_panic=20;
  1715.       else if (massive_frame_panic)
  1716.         massive_frame_panic--;
  1717.     }
  1718.  
  1719.     if (avg_fps>15 && ((dev&EDIT_MODE)==0 || need_delay))
  1720.     {
  1721.       frame_panic=0;
  1722.       long stime=(long)((1/15.0-1.0/possible_fps)*1000.0); 
  1723.       if (stime>0 && !no_delay)
  1724.       {
  1725.         milli_wait(stime);
  1726.         avg_fps-=1.0/(td*10.0);        // subtract out old estimate
  1727.             
  1728.         time_marker t;
  1729.                 
  1730.         // find average fps for last 10 frames
  1731.         double td=t.diff_time(fps_mark_start);
  1732.         if (td<0.00001)     // something is rotten in the state of demark
  1733.           td=0.00001;
  1734.             
  1735.         avg_fps+=1.0/(td*10.0);       // add in new estimate
  1736.       }
  1737.     } else if (avg_fps<14)
  1738.     {
  1739.       if (avg_fps<10)
  1740.         massive_frame_panic++;
  1741.       frame_panic++;
  1742.       ret=1;
  1743.     }
  1744.     
  1745.     delete fps_mark_start;    
  1746.   }
  1747.   fps_mark_start=new time_marker;
  1748.   return ret;
  1749. }
  1750. #else
  1751. int game::calc_speed()
  1752. {
  1753.   static UnsignedWide last_t = {0,0};
  1754.   UnsignedWide t;
  1755.     
  1756.   if (dev & EDIT_MODE)
  1757.     return 0;
  1758.     
  1759.   do 
  1760.   {
  1761.     Microseconds(&t);
  1762.   } while( t.lo - last_t.lo < 60000);
  1763.     
  1764.   last_t = t;
  1765.     
  1766.   return 0;
  1767. }
  1768. #endif
  1769.  
  1770. extern int start_edit;
  1771.  
  1772. void single_render();
  1773. void double_render();
  1774.  
  1775. void game::get_input()
  1776. {
  1777.   event ev;  
  1778.   idle_ticks++;
  1779.   while (event_waiting(eh))
  1780.   {
  1781.     get_event(ev,eh);
  1782.  
  1783.     if (ev.type==EV_MOUSE_MOVE) last_input=ev.window;
  1784.     // don't process repeated keys in the main window, it will slow down the game handle such
  1785.     // useless events. However in other windows it might be useful, such as in input windows
  1786.     // where you want to repeatedly scroll down..
  1787.     if (ev.type!=EV_KEY || !key_down(ev.key) || ev.window || (dev&EDIT_MODE))
  1788.     {
  1789.       if (ev.type==EV_KEY)     
  1790.       {
  1791.           int input_key = ev.key;
  1792.           input_key = (input_key>='A' && input_key<='Z') ? input_key - 'A' + 'a' : input_key;
  1793.         set_key_down(input_key,1);
  1794.         if (playing_state(state))
  1795.         {     
  1796.           if (ev.key<256)
  1797.           {
  1798.             if (chat && chat->chat_event(ev))
  1799.               base->packet.write_byte(SCMD_CHAT_KEYPRESS);
  1800.             else
  1801.               base->packet.write_byte(SCMD_KEYPRESS);
  1802.           }
  1803.           else
  1804.             base->packet.write_byte(SCMD_EXT_KEYPRESS);
  1805.           base->packet.write_byte(client_number());
  1806.           if (ev.key>256)
  1807.             base->packet.write_byte(ev.key-256);
  1808.           else
  1809.             base->packet.write_byte(ev.key);      
  1810.         }
  1811.       }
  1812.       else if (ev.type==EV_KEYRELEASE)
  1813.       {
  1814.           int input_key=ev.key;
  1815.           input_key = (input_key>='A' && input_key<='Z') ? input_key - 'A' + 'a' : input_key;
  1816.         set_key_down(input_key,0);
  1817.         if (playing_state(state))
  1818.         {     
  1819.           if (ev.key<256)
  1820.             base->packet.write_byte(SCMD_KEYRELEASE);
  1821.           else
  1822.             base->packet.write_byte(SCMD_EXT_KEYRELEASE);
  1823.           base->packet.write_byte(client_number());
  1824.           if (ev.key>255)
  1825.             base->packet.write_byte(ev.key-256);
  1826.           else
  1827.             base->packet.write_byte(ev.key);      
  1828.         }    
  1829.       }
  1830.       
  1831.       if ((dev&EDIT_MODE) || start_edit || ev.type==EV_MESSAGE)
  1832.         dev_cont->handle_event(ev);
  1833.  
  1834.       view *v=first_view;
  1835.       for (;v;v=v->next)
  1836.         if (v->local_player() && v->handle_event(ev))
  1837.           ev.type=EV_SPURIOUS;       // if the event was used by the view, gobble it up
  1838.  
  1839.  
  1840.       
  1841.       help_handle_event(ev);    
  1842.       mousex=last_demo_mx;
  1843.       mousey=last_demo_my;
  1844.  
  1845.       if (ev.type==EV_MESSAGE)
  1846.       {
  1847.         switch (ev.message.id)
  1848.         {
  1849.           case CALB_JOY : 
  1850.           { 
  1851.             if (!joy_win)
  1852.             {
  1853.               int wx=WINDOW_FRAME_LEFT,wy=WINDOW_FRAME_TOP;
  1854.                       
  1855.               joy_win=eh->new_window(80,50,-1,-1,
  1856.                   new button(wx+70,wy+9,JOY_OK,"OK",
  1857.                       new info_field(wx,wy+30,DEV_NULL,
  1858.                           " Center joystick and\n"
  1859.                           "press the fire button",NULL)),
  1860.             
  1861.                   "Joystick");
  1862.               set_state(JOY_CALB_STATE); 
  1863.             }
  1864.           }
  1865.           case TOP_MENU :
  1866.           { menu_select(ev); } break;
  1867.           case DEV_QUIT :
  1868.           { finished=1; } break;
  1869.             
  1870.         }
  1871.       }        
  1872.       else if (ev.type==EV_CLOSE_WINDOW && ev.window==top_menu)
  1873.       {
  1874.         eh->close_window(top_menu);
  1875.         top_menu=NULL;
  1876.       }
  1877.     
  1878.       switch (state)
  1879.       {
  1880.         case JOY_CALB_STATE :
  1881.         { joy_calb(ev); } break;
  1882.         case INTRO_START_STATE : 
  1883.         { do_intro(); 
  1884.         if (dev & EDIT_MODE)
  1885.           set_state(RUN_STATE);
  1886.         else
  1887.           set_state(MENU_STATE); 
  1888.         } break;     
  1889.         case PAUSE_STATE : if (ev.type==EV_KEY && (ev.key==JK_SPACE || ev.key==JK_ENTER)) 
  1890.         { set_state(RUN_STATE); } break;
  1891.         case RUN_STATE : 
  1892.         {
  1893.           if (ev.window==NULL)
  1894.           {
  1895.                   
  1896.             switch (ev.type)
  1897.             {
  1898.               case EV_KEY : 
  1899.               { switch (ev.key)
  1900.               {
  1901.                 case 'm' : 
  1902.                 { 
  1903.                   if (dev&MAP_MODE) dev-=MAP_MODE;
  1904.                   else if ((player_list && player_list->next) || dev&EDIT_MODE) dev|=MAP_MODE;
  1905.                 
  1906.                   if (!(dev&MAP_MODE))
  1907.                   {
  1908.                     if (dev_cont->tbw) dev_cont->toggle_toolbar();
  1909.                     edit_mode=ID_DMODE_DRAW;
  1910.                   }
  1911.                   need_refresh();     
  1912.                 } break;
  1913.                 case 'v' : 
  1914.                 { eh->push_event(new event(DO_VOLUME,NULL)); } break;
  1915.                 case 'p' : 
  1916.                 { if (!(dev&EDIT_MODE) && (!main_net_cfg || 
  1917.                     (main_net_cfg->state!=net_configuration::SERVER &&
  1918.                         main_net_cfg->state!=net_configuration::CLIENT)))  
  1919.                   set_state(PAUSE_STATE); 
  1920.                 } break;
  1921.                 case 'S' : 
  1922.                   if (start_edit)
  1923.                   { eh->push_event(new event(ID_LEVEL_SAVE,NULL)); } break;
  1924.                 case JK_TAB : 
  1925.                 { if (start_edit) toggle_edit_mode(); need_refresh(); } break;
  1926.                 case 'c' :          
  1927.                 { if (chatting_enabled && (!(dev&EDIT_MODE) && chat))
  1928.                   chat->toggle();
  1929.                 } break;
  1930.                 case '9' : 
  1931.                 { dev=dev^PERFORMANCE_TEST_MODE; need_refresh(); } break;
  1932.                 
  1933.                 /*
  1934.                   case '=' :
  1935.                   case '+' : 
  1936.                   { if (!dev_cont->need_plus_minus())
  1937.                   { 
  1938.                   if (eh->key_pressed(JK_CTRL_L))
  1939.                   grow_views(20);
  1940.                   else
  1941.                   grow_views(5); 
  1942.                   draw(state==SCENE_STATE);
  1943.                   }
  1944.                   } break;
  1945.                   case JK_F10 : make_screen_size(311,160); break;
  1946.                   case '_' :
  1947.                   case '-' : 
  1948.                   {
  1949.                   if (!dev_cont->need_plus_minus())            
  1950.                   { 
  1951.                   if (eh->key_pressed(JK_CTRL_L))
  1952.                   grow_views(-20);
  1953.                   else
  1954.                   grow_views(-5); 
  1955.                   draw(state==SCENE_STATE); 
  1956.                   } 
  1957.                   } break; */
  1958.                 
  1959.               }
  1960.             } break;            
  1961.               case EV_RESIZE : 
  1962.               { 
  1963.                 view *v;
  1964.                 for (v=first_view;v;v=v->next)  // see if any views need to change size
  1965.                 {
  1966.                   if (v->local_player())
  1967.                   {
  1968.                     int w=(xres-10)/(small_render ? 2 : 1);
  1969.                     int h=(yres-10)/(small_render ? 2 : 1);
  1970.                 
  1971.                     /*                    v->suggest.send_view=1;
  1972.                     v->suggest.cx1=5;
  1973.                     v->suggest.cx2=5+w;
  1974.                     v->suggest.cy1=5;
  1975.                     v->suggest.cy2=5+h;
  1976.                     v->suggest.pan_x=v->pan_x;
  1977.                     v->suggest.pan_y=v->pan_y;
  1978.                     v->suggest.shift_down=v->shift_down;
  1979.                     v->suggest.shift_right=v->shift_right; */
  1980.                   }          
  1981.                 }
  1982.                 draw(); 
  1983.               } break;
  1984.               case EV_REDRAW : 
  1985.                 screen->add_dirty(ev.redraw.x1,ev.redraw.y1,
  1986.                     ev.redraw.x2,ev.redraw.y2); 
  1987.                 break;
  1988.               case EV_MESSAGE :        
  1989.                 switch (ev.message.id)
  1990.                 {
  1991.                   case RAISE_SFX :
  1992.                   case LOWER_SFX :
  1993.                   case RAISE_MUSIC :
  1994.                   case LOWER_MUSIC :
  1995.                     if (ev.message.id==RAISE_SFX && sfx_volume!=127) sfx_volume=min(127,sfx_volume+16);
  1996.                     if (ev.message.id==LOWER_SFX && sfx_volume!=0) sfx_volume=max(sfx_volume-16,0);
  1997.                     if (ev.message.id==RAISE_MUSIC && music_volume!=126) 
  1998.                     {            
  1999.                       music_volume=min(music_volume+16,127);
  2000.                       if (current_song && (sound_avail&MUSIC_INITIALIZED))
  2001.                         current_song->set_volume(music_volume);
  2002.                     }
  2003.               
  2004.                     if (ev.message.id==LOWER_MUSIC && music_volume!=0) 
  2005.                     {            
  2006.                       music_volume=max(music_volume-16,0);
  2007.                       if (current_song && (sound_avail&MUSIC_INITIALIZED))
  2008.                         current_song->set_volume(music_volume);
  2009.                     }            
  2010.               
  2011.                     ((button *)ev.message.data)->push();          
  2012.                     break;
  2013.                 }
  2014.                       
  2015.             }
  2016.           }
  2017.           } break;
  2018.       }
  2019.     }
  2020.   }
  2021. }
  2022.  
  2023.  
  2024. void net_send(int force=0)
  2025. {
  2026.   if ( (!(dev&EDIT_MODE)) || force)
  2027.   {
  2028.     if (demo_man.state==demo_manager::PLAYING)
  2029.     {
  2030.       base->input_state=INPUT_PROCESSING;
  2031.     } else
  2032.     {
  2033.       
  2034.  
  2035.  
  2036.       if (!player_list->focus)
  2037.       {
  2038.         dprintf("Players have not been created\ncall create_players");
  2039.         exit(0);
  2040.       }
  2041.  
  2042.  
  2043.       view *p=player_list;
  2044.       for (;p;p=p->next)
  2045.         if (p->local_player())
  2046.           p->get_input();
  2047.  
  2048.  
  2049.       base->packet.write_byte(SCMD_SYNC);
  2050.       base->packet.write_short(make_sync());
  2051.  
  2052.       if (base->join_list)
  2053.         base->packet.write_byte(SCMD_RELOAD);
  2054.  
  2055.       //      dprintf("save tick %d, pk size=%d, rand_on=%d, sync=%d\n",current_level->tick_counter(),
  2056.       //         base->packet.packet_size(),rand_on,make_sync());
  2057.       send_local_request();
  2058.     }
  2059.   }
  2060. }
  2061.  
  2062. void net_receive()
  2063. {
  2064.   if (!(dev&EDIT_MODE) && current_level)
  2065.   {
  2066.     uchar buf[PACKET_MAX_SIZE+1];
  2067.     int size;
  2068.  
  2069.     if (demo_man.state==demo_manager::PLAYING)
  2070.     { 
  2071.       if (!demo_man.get_packet(buf,size))
  2072.         size=0;
  2073.       base->packet.packet_reset();
  2074.       base->mem_lock=0;
  2075.     } else
  2076.     {
  2077.       size=get_inputs_from_server(buf);
  2078.       if (demo_man.state==demo_manager::RECORDING)
  2079.         demo_man.save_packet(buf,size);
  2080.     }
  2081.  
  2082.     process_packet_commands(buf,size);
  2083.   }
  2084. }
  2085.  
  2086. void game::step()
  2087. {
  2088.   clear_tmp();
  2089.   if (current_level)
  2090.   {
  2091.     current_level->unactivate_all();
  2092.     total_active=0;
  2093.     for (view *f=first_view;f;f=f->next)
  2094.     {
  2095.       if (f->focus)           
  2096.       {
  2097.         f->update_scroll();
  2098.         int w,h;
  2099.             
  2100.         w=(f->cx2-f->cx1+1);
  2101.         h=(f->cy2-f->cy1+1);
  2102.         total_active+=current_level->add_actives(f->xoff()-w/4,f->yoff()-h/4,
  2103.             f->xoff()+w+w/4,f->yoff()+h+h/4);
  2104.       }
  2105.     }
  2106.   }
  2107.  
  2108.   if (state==RUN_STATE)
  2109.   {    
  2110.     if ((dev&EDIT_MODE) || (main_net_cfg && (main_net_cfg->state==net_configuration::CLIENT ||
  2111.         main_net_cfg->state==net_configuration::SERVER)))
  2112.       idle_ticks=0;
  2113.  
  2114.     if (demo_man.current_state()==demo_manager::NORMAL && idle_ticks>420 && demo_start)
  2115.     {
  2116.       idle_ticks=0;
  2117.       set_state(MENU_STATE);    
  2118.     }
  2119.     else if (!(dev & EDIT_MODE))               // if edit mode, then don't step anything
  2120.     {
  2121. #ifdef __MAC__
  2122.       if (key_down(JK_ESC) || (key_down('q') && key_down(JK_COMMAND)))
  2123. #else
  2124.         if (key_down(JK_ESC))
  2125. #endif
  2126.         {
  2127.           int r=rand_on;
  2128.           set_state(MENU_STATE);
  2129.           main_menu();  
  2130.           rand_on=r;
  2131.           
  2132.           //          set_key_down(JK_ESC,0);
  2133.           //          return ;
  2134.         }
  2135.       ambient_ramp=0;
  2136.       view *v;
  2137.       for (v=first_view;v;v=v->next)
  2138.         v->update_scroll();
  2139.  
  2140.       cash.prof_poll_start();
  2141.       current_level->tick();
  2142.       sbar.step();
  2143.     } else    
  2144.       dev_scroll();  
  2145.   } else if (state==JOY_CALB_STATE)
  2146.   {
  2147.     event ev;
  2148.     joy_calb(ev);
  2149.   } else if (state==MENU_STATE)  
  2150.     main_menu();  
  2151.     
  2152.   if (key_down('x') && (key_down(JK_ALT_L) || key_down(JK_ALT_R)) && confirm_quit()) finished=1;
  2153. }
  2154.  
  2155. extern void *current_demo;
  2156.  
  2157. game::~game()
  2158. {  
  2159.   delete idle_man;
  2160.   idle_man=0;
  2161.  
  2162.   current_demo=NULL;
  2163.   if (first_view==player_list) first_view=NULL;
  2164.   while (player_list)
  2165.   {
  2166.     view *p=player_list;
  2167.     game_object *o=p->focus;
  2168.     player_list=player_list->next;
  2169.     delete p;
  2170.     o->set_controller(NULL);
  2171.     if (current_level && o)
  2172.       current_level->delete_object(o);
  2173.     else delete o;
  2174.   }
  2175.  
  2176.   if (current_level) { delete current_level; current_level=NULL; }
  2177.  
  2178.   if (first_view!=player_list)
  2179.   {
  2180.     while (player_list)
  2181.     {
  2182.       view *p=player_list;
  2183.       player_list=player_list->next;
  2184.       delete p;
  2185.     }
  2186.   }
  2187.  
  2188.   while (first_view)
  2189.   {
  2190.     view *p=first_view;
  2191.     first_view=first_view->next;
  2192.     delete p;
  2193.   }
  2194.  
  2195.   player_list=NULL;  
  2196.  
  2197.   if (old_view)
  2198.   {
  2199.     first_view=old_view;
  2200.     while (first_view)
  2201.     {
  2202.       view *p=first_view;
  2203.       first_view=first_view->next;
  2204.       delete p;
  2205.     }
  2206.   }
  2207.   old_view=NULL;
  2208.  
  2209.   int i=0;
  2210.   for (;i<total_objects;i++)
  2211.   {
  2212.     jfree(object_names[i]);
  2213.     delete figures[i];
  2214.   }
  2215.   if (fps_mark_start) delete fps_mark_start; fps_mark_start=NULL;
  2216.   delete pal;
  2217.   jfree(object_names);
  2218.   jfree(figures);
  2219.  
  2220.   jfree(backtiles);
  2221.   jfree(foretiles);
  2222.   if (total_weapons)
  2223.     jfree(weapon_types);
  2224.  
  2225.   config_cleanup();
  2226.   delete color_table;
  2227.   delete eh;
  2228.   eh = 0;
  2229.   
  2230.   delete game_font;
  2231.   delete window_font;
  2232.   delete big_font;
  2233.   delete console_font;
  2234.   if (total_help_screens)
  2235.     jfree(help_screens);
  2236.     
  2237.  
  2238.   //  image_uninit();
  2239. }
  2240.  
  2241.  
  2242.  
  2243. void game::draw(int scene_mode)
  2244. {
  2245.   screen->add_dirty(0,0,xres,yres);
  2246.   image *bt=cash.img(border_tile);
  2247.   int tw=bt->width(),th=bt->height(),dx,dy=0;
  2248.   int xt=screen->width()/tw+1,yt=screen->height()/th+1,x,y;
  2249.   screen->clear();
  2250.   //  for (y=0;y<yt;y++,dy+=th)
  2251.   //    for (x=0,dx=0;x<xt;x++,dx+=tw)
  2252.   //      bt->put_image(screen,dx,dy); 
  2253.   int lr=eh->bright_color(),
  2254.     mr=eh->medium_color();
  2255.  
  2256.   if (scene_mode)
  2257.   {
  2258.     char *helpstr="ARROW KEYS CHANGE TEXT SPEED";
  2259.     eh->font()->put_string(screen,screen->width()/2-(eh->font()->width()*strlen(helpstr))/2+1,
  2260.         screen->height()-eh->font()->height()-5+1,helpstr,eh->dark_color());    
  2261.     eh->font()->put_string(screen,screen->width()/2-(eh->font()->width()*strlen(helpstr))/2,
  2262.         screen->height()-eh->font()->height()-5,helpstr,eh->bright_color());    
  2263.   }
  2264.   /*  else
  2265.       {
  2266.       char *helpstr="PRESS h FOR HELP";
  2267.       eh->font()->put_string(screen,screen->width()-eh->font()->width()*strlen(helpstr)-5,
  2268.       screen->height()-eh->font()->height()-5,helpstr);
  2269.       }*/
  2270.   /*  int dc=cash.img(window_colors)->pixel(0,2);
  2271.       int mc=cash.img(window_colors)->pixel(1,2);
  2272.       int bc=cash.img(window_colors)->pixel(2,2);
  2273.       screen->line(0,0,screen->width()-1,0,dc);
  2274.       screen->line(0,0,0,screen->height()-1,dc);
  2275.       screen->line(0,screen->height()-1,screen->width()-1,screen->height()-1,bc);
  2276.       screen->line(screen->width()-1,0,screen->width()-1,screen->height()-1,bc);*/
  2277.   for (view *f=first_view;f;f=f->next)
  2278.     draw_map(f,0);
  2279.  
  2280.   sbar.redraw(screen);
  2281. }
  2282.  
  2283. int external_print=0;
  2284.  
  2285. void start_sound(int argc, char **argv)
  2286. {
  2287.   sfx_volume=music_volume=127;
  2288.  
  2289.   for (int i=1;i<argc;i++)
  2290.     if (!strcmp(argv[i],"-sfx_volume"))
  2291.     {
  2292.       i++;
  2293.       if (atoi(argv[i])>=0 && atoi(argv[i])<127)
  2294.         sfx_volume=atoi(argv[i]);
  2295.       else dprintf("Bad sound effects volume level, use 0..127\n");      
  2296.     }
  2297.     else if (!strcmp(argv[i],"-music_volume"))
  2298.     {
  2299.       i++;
  2300.       if (atoi(argv[i])>=0 && atoi(argv[i])<127)
  2301.         music_volume=atoi(argv[i]);
  2302.       else dprintf("Bad music volume level, use 0..127\n");      
  2303.     }
  2304.  
  2305.   sound_avail=sound_init(argc,argv);
  2306. }
  2307.  
  2308. void game_printer(char *st)
  2309. {
  2310.  
  2311. #if 0
  2312.     static FILE *f = 0;
  2313.     if (!f)
  2314.         f = fopen("abuse.out","wt");
  2315.     fprintf(f,st);
  2316.     fflush(f);
  2317. #endif
  2318.  
  2319.   if (dev_console && !external_print)
  2320.   {
  2321.     dev_console->put_string(st);
  2322.   }
  2323.  
  2324. #ifndef __MAC__
  2325.   else fprintf(stderr,"%s",st);
  2326. #endif
  2327. }
  2328.  
  2329. void game_echoer(char *st)
  2330. {
  2331.   #ifdef __MAC__
  2332.     static FILE *f = 0;
  2333.     if (!f)
  2334.         f = fopen("abuse.out","wt");
  2335.     fprintf(f,st);
  2336.     fflush(f);
  2337. #else
  2338.        
  2339.   if (dev_console && !external_print)
  2340.   {
  2341.     dev_console->put_string(st);
  2342.   } else if (external_print)
  2343.     fprintf(stderr,"%s",st);
  2344.  
  2345. #endif
  2346. }
  2347.  
  2348. void game_getter(char *st, int max)
  2349. {
  2350.   if (!max) return ;
  2351.   max--;
  2352.   *st=0;
  2353.   if (dev_console && !external_print)
  2354.   {    
  2355.     dev_console->show();
  2356.     int t=0;
  2357.     event ev;
  2358.     do
  2359.     {
  2360.       get_event(ev,eh);
  2361.       if (ev.type==EV_KEY)
  2362.       {
  2363.         if (ev.key==JK_BACKSPACE)
  2364.         {
  2365.           if (t) 
  2366.           {
  2367.             dev_console->printf("%c",ev.key);
  2368.             t--;
  2369.             st--;
  2370.             *st=0;
  2371.             max++;
  2372.           }
  2373.         } else if (ev.key>=' ' && ev.key<='~')
  2374.         {
  2375.           dev_console->printf("%c",ev.key);
  2376.           *st=ev.key;
  2377.           t++;
  2378.           max--;
  2379.           st++;
  2380.           *st=0;
  2381.         }              
  2382.       }
  2383.       eh->flush_screen();
  2384.     } while (ev.type!=EV_KEY || ev.key!=JK_ENTER);    
  2385.     dprintf("\n");
  2386.   }
  2387.   else 
  2388.   {
  2389.     if (fgets(st,max,stdin))
  2390.     {
  2391.       if (*st)
  2392.         st[strlen(st)-1]=0;
  2393.     }
  2394.   }
  2395. }
  2396.  
  2397.  
  2398. void show_startup()
  2399. {
  2400.   show_verinfo(start_argc,start_argv);
  2401. }
  2402.  
  2403. char *get_line(int open_braces)
  2404. {
  2405.   char *line=(char *)jmalloc(1000,"lstring");
  2406.   fgets(line,1000,stdin);
  2407.  
  2408.   char prev=' ';
  2409.   for (char *s=line;*s && (prev!=' ' || *s!=';');s++)
  2410.   {
  2411.     prev=*s;
  2412.     if (*s=='(') open_braces++;
  2413.     else if (*s==')') open_braces--;
  2414.   }
  2415.   if (open_braces<0)    
  2416.     dprintf("\nToo many )'s\n");
  2417.   else if (open_braces>0)
  2418.   {
  2419.     char *s2=get_line(open_braces);
  2420.     line=(char *)jrealloc(line,strlen(line)+strlen(s2)+1,"lstring");
  2421.     strcat(line,s2);
  2422.     jfree(s2);    
  2423.   }  
  2424.   return line;
  2425. }
  2426.  
  2427. void check_for_upgrade(int argc, char **argv)
  2428. {
  2429.   for (int i=1;i<argc;i++)
  2430.     if (!strcmp(argv[i],"-upgrade"))
  2431.     {
  2432.       lisp_init(0xf000,0x30000);
  2433.       char *prog="(load \"lisp/upgrade.lsp\")",*cs;
  2434.       cs=prog;
  2435.       if (!eval(compile(cs)))
  2436.     dprintf("file does not exists : lisp/upgrade.lsp, cannot upgrade\n");
  2437.  
  2438.       exit(0);
  2439.     }        
  2440. }
  2441.  
  2442. void check_for_lisp(int argc, char **argv)
  2443. {
  2444.   for (int i=1;i<argc;i++)
  2445.   {
  2446.     if (!strcmp(argv[i],"-lisp"))
  2447.     {
  2448.       lisp_init(0xf000,0x30000);
  2449.  
  2450. #ifdef __WATCOMC__
  2451.       char *eof_char="CTRL-Z";
  2452. #else
  2453.       char *eof_char="CTRL-D";
  2454. #endif
  2455.       dprintf(
  2456.               " CLIVE (C) 1995 Jonathan Clark, all rights reserved\n"
  2457.               "   (C LISP interpreter and various extentions)\n"
  2458.               "Type (%s) to exit\n",eof_char);
  2459.  
  2460.       while (!feof(stdin))
  2461.       {
  2462.     dprintf("Lisp> ");
  2463.     char *l=get_line(0);
  2464.     char *s=l;
  2465.     while (*s)
  2466.     {
  2467.       void *prog=compile(s);
  2468.       l_user_stack.push(prog);
  2469.       while (*s==' ' || *s=='\t' || *s=='\r' || *s=='\n') s++;
  2470.       lprint(eval(prog));
  2471.       l_user_stack.pop(1);
  2472.     }
  2473.     jfree(l);
  2474.       }      
  2475.  
  2476.       dprintf("End of input : bye\n");
  2477.       exit(0);
  2478.     }
  2479.   }
  2480. }
  2481.  
  2482.  
  2483. void music_check()
  2484. {
  2485.   if (sound_avail&MUSIC_INITIALIZED)
  2486.   {
  2487.     if (current_song && !current_song->playing())
  2488.     {
  2489.       current_song->play();
  2490.       dprintf("song finished\n");
  2491.     }
  2492.     if (!current_song)
  2493.     {
  2494.  
  2495.       current_song=new song("music/intro.hmi");
  2496.       current_song->play(music_volume);
  2497.  
  2498.       /*      if (DEFINEDP(symbol_function(l_next_song)))  // if user function installed, call it to load up next song
  2499.               {
  2500.               int sp=current_space;
  2501.               current_space=PERM_SPACE;
  2502.               eval_function((lisp_symbol *)l_next_song,NULL);
  2503.               current_space=sp;
  2504.               } */
  2505.     } 
  2506.   }
  2507. }
  2508.  
  2509. void setup(int argc, char **argv);
  2510.  
  2511. void share_end();
  2512. void show_end();
  2513.  
  2514. void show_sell(int abortable);
  2515.  
  2516. extern pmenu *dev_menu;
  2517.  
  2518.  
  2519. extern int jmalloc_max_size;
  2520. extern int jmalloc_min_low_size;
  2521.  
  2522. extern int (*verify_file_fun)(char *,char *);
  2523.  
  2524. int registered_ok(char *filename, char *mode)
  2525. {
  2526.   if (registered) return 1;
  2527.  
  2528.   char name[256],*c;
  2529.   c=name;
  2530.   while (*filename) { *c=*(filename++); *c=toupper(*c); c++; } *c=0;
  2531.   if (strstr(name,"REGISTER"))
  2532.     return 0;
  2533.   else return 1;
  2534. }
  2535.  
  2536. void game_net_init(int argc, char **argv)
  2537. {
  2538.   int nonet=!net_init(argc, argv);
  2539.   if (nonet)
  2540.     dprintf("No network driver, or network driver returned failure\n");
  2541.   else 
  2542.   {
  2543.     set_file_opener(open_nfs_file);
  2544.     if (main_net_cfg && main_net_cfg->state==net_configuration::CLIENT)
  2545.     {
  2546.       if (set_file_server(net_server))
  2547.         start_running=1;
  2548.       else
  2549.       {
  2550.         dprintf("Unable to attach to server, quiting\n");
  2551.         exit(0);
  2552.       }
  2553.     } else
  2554.     {
  2555.       int i;
  2556.       for (i=1;i<argc-1;i++)
  2557.         if (!strcmp(argv[i],"-fs"))
  2558.           if (!set_file_server(argv[i+1]))
  2559.             dprintf("could not set defualt file server to %s\n",argv[i+1]);
  2560.     }
  2561.   }    
  2562.  
  2563. }
  2564.  
  2565. #ifdef __MAC__
  2566. //extern int PixMult;
  2567. #if 1
  2568. char cmdline[256];
  2569. #elif 1
  2570. char cmdline[] = "";
  2571. #elif 1
  2572. char cmdline[] = "abuse -server -a deathmat";
  2573. #else
  2574. char cmdline[] = "abuse -net 193.246.40.9";
  2575. #endif
  2576. char delims[] = " ";
  2577. char *tmp_argv[255];
  2578.  
  2579. void GetArgs(int &argc, char **(&argv))
  2580. {
  2581.   char *s;
  2582.  
  2583.   dprintf(    "Usage:\n"
  2584.       "  abuse [-options]\n\n"
  2585.       "  Options:\n"
  2586.       "    -server -a deathmat        become a server for deathmatch game\n"
  2587.       "    -net <dotted ip address>   connect to a server\n\n"
  2588.       "Options for mac:\n"
  2589.       "  Hold down <control> for single pixel mode\n"
  2590.       "  Hold down <option> for edit mode\n"
  2591.       "  Hold down <left shift> for double size mode\n\n"
  2592.       "If started with no command line options, networking will attempt\n"
  2593.       "  to search the local network for servers\n\n"
  2594.                 );
  2595.   dprintf("Enter command line:\n");
  2596.   gets(cmdline);
  2597.     
  2598.   argc = 0;
  2599.   argv = tmp_argv;
  2600.   s = strtok(cmdline, delims);
  2601.   while (s)
  2602.   {
  2603.     argv[argc] = s;
  2604.     argc++;
  2605.     s = strtok(0, delims);
  2606.   }
  2607.   argv[argc] = 0;
  2608. }
  2609.  
  2610. extern void InitMacScreen();
  2611. extern void QuitMacScreen();
  2612.  
  2613. #endif
  2614.  
  2615. int main(int argc, char **argv)
  2616. {
  2617. #ifdef __MAC__
  2618.   InitMacScreen();
  2619. #if 1
  2620.   //    if (!MacMenu())
  2621.   //        return 0;
  2622.  
  2623.   unsigned char km[16];
  2624.  
  2625.   GetKeys((unsigned long*)&km);
  2626.   if ((km[ 0x37 >>3] >> (0x37 & 7)) &1 != 0)
  2627.       set_dprinter(game_echoer);
  2628.     else
  2629.       set_dprinter(game_printer);
  2630.  
  2631. #else
  2632.   unsigned char km[16];
  2633.  
  2634.   GetArgs(argc,argv);
  2635.     
  2636.   dprintf("Mac Options: ");
  2637.   GetKeys((unsigned long*)&km);
  2638.   if ((km[ 0x3a >>3] >> (0x3a & 7)) &1 != 0)
  2639.   {
  2640.     dev|=EDIT_MODE;    
  2641.     start_edit=1;
  2642.     start_running=1;
  2643.     disable_autolight=1;
  2644.     dprintf("Edit Mode...");
  2645.   }
  2646.   if ((km[ 0x3b >>3] >> (0x3b & 7)) &1 != 0)
  2647.   {
  2648.     PixMult = 1;
  2649.     dprintf("Single Pixel...");
  2650.   }
  2651.   else
  2652.   {
  2653.     PixMult = 2;
  2654.     dprintf("Double Pixel...");
  2655.   }
  2656.   if ((km[ 0x38 >>3] >> (0x38 & 7)) &1 != 0)
  2657.   {
  2658.     xres *= 2;  yres *= 2;
  2659.     dprintf("Double Size...");
  2660.   }
  2661.   dprintf("\n");
  2662.     
  2663.   if (tcpip.installed())
  2664.     dprintf( "Using %s\n", tcpip.name());
  2665. #endif
  2666.  
  2667. #else
  2668.  
  2669.   set_dprinter(game_printer);
  2670.  
  2671. #endif
  2672.  
  2673.   start_argc=argc;
  2674.   start_argv=argv;
  2675.   
  2676.   { for (int i=0;i<argc;i++)
  2677.   {
  2678.     if (!strcmp(argv[i],"-cprint"))
  2679.       external_print=1;
  2680.     if (!strcmp(argv[i],"-min_low"))
  2681.     {
  2682.       i++;
  2683.       jmalloc_min_low_size=atoi(argv[i]);
  2684.     }
  2685.   }
  2686.   }
  2687.  
  2688.   set_dgetter(game_getter);
  2689.   set_no_space_handler(handle_no_space);
  2690.  
  2691.   setup(argc,argv);
  2692.  
  2693.   show_startup();
  2694.  
  2695.   //  jmalloc_max_size=0x150000;
  2696.   jmalloc_init(0x150000); 
  2697.   //  jmalloc_init(100000); 
  2698.  
  2699.   start_sound(argc,argv);
  2700.  
  2701. //#ifdef __MAC__
  2702.   //stat_man=new mac_status_manager();
  2703. //#else
  2704.   stat_man=new text_status_manager();
  2705. //#endif
  2706.   if (!get_option("-no_timer"))
  2707.   {
  2708.     timer_init();
  2709.   }
  2710.  
  2711.  
  2712.   if (!get_option("-share"))
  2713.   {
  2714.     jFILE *fp=new jFILE("register/micron.vcd","rb");
  2715.     if (!fp->open_failure())
  2716.     {
  2717.       spec_directory sd(fp);
  2718.       if (sd.find("Copyright (C) 1995 Crack dot Com, All Rights reserved"))
  2719.         registered=1;
  2720.     }
  2721.     delete fp;
  2722.   }
  2723.  
  2724.   verify_file_fun=registered_ok;
  2725.  
  2726.  
  2727.  
  2728.   jrand_init();
  2729.   jrand();  // so compiler doesn't complain
  2730.  
  2731.  
  2732.   set_spec_main_file("abuse.spe");
  2733.  
  2734.   if (getenv("ABUSE_PATH"))       // look to see if we are supposed to fetch the data elsewhere
  2735.     set_filename_prefix(getenv("ABUSE_PATH"));   
  2736.  
  2737.   if (getenv("ABUSE_SAVE_PATH"))       // look to see if we are supposed to fetch the data elsewhere
  2738.     set_save_filename_prefix(getenv("ABUSE_SAVE_PATH"));   
  2739.  
  2740.   check_for_lisp(argc,argv);
  2741.   check_for_upgrade(argc,argv);
  2742.  
  2743.   set_mode(VMODE_640x480,argc,argv);
  2744.  
  2745.   if (stat_man)
  2746.     delete stat_man;
  2747.   stat_man=new net_status_manager("art/loading.spe",
  2748.       413,428,608,451,
  2749.       54,104);
  2750.  
  2751.  
  2752.  
  2753.   do
  2754.   {
  2755.     if (main_net_cfg) 
  2756.     {
  2757.  
  2758.  
  2759.       if (!main_net_cfg->notify_reset())
  2760.       {
  2761.         if (!get_option("-no_timer"))
  2762.           timer_uninit();
  2763.         sound_uninit();
  2764.         exit(0);
  2765.       }
  2766.     }
  2767.  
  2768.     game_net_init(argc,argv);
  2769.     lisp_init(0x16000,0x94000);
  2770.     //  lisp_init(0x100000,0x10000);
  2771.  
  2772.     dev_init(argc,argv);
  2773.  
  2774.  
  2775.     game *g=new game(argc,argv);
  2776.  
  2777.     delete stat_man;
  2778.     stat_man=new net_status_manager("art/status.spe",
  2779.         295,203,304,366,
  2780.         46,222);
  2781.  
  2782.  
  2783.  
  2784.     dev_cont=new dev_controll();
  2785.     dev_cont->load_stuff();
  2786.  
  2787.  
  2788.  
  2789.     g->get_input();      // prime the net
  2790.  
  2791.     int xx;
  2792.     for (xx=1;xx<argc;xx++)
  2793.       if (!strcmp(argv[xx],"-server"))
  2794.       {
  2795.         xx++;
  2796.         if (!become_server(argv[xx]))
  2797.         {      
  2798.           dprintf("unable to become a server\n");
  2799.           exit(0);
  2800.         }
  2801.         xx=argc+1;
  2802.       }
  2803.  
  2804.     if (main_net_cfg) 
  2805.       wait_min_players();
  2806.  
  2807.     net_send(1);
  2808.     if (net_start())
  2809.     {
  2810.       g->step();                        // process all the objects in the 
  2811.       g->calc_speed();
  2812.       g->update_screen();               // redraw the screen with any changes
  2813.     }
  2814.  
  2815.     while (!g->done())
  2816.     {
  2817.       StartTime(0);//kill me
  2818.         
  2819.       StartTime(1);//kill me
  2820.       //      music_check();
  2821.  
  2822.       if (req_end)
  2823.       {
  2824.         delete current_level;
  2825.         current_level=NULL;
  2826.                 
  2827.         if (!registered)
  2828.           share_end();
  2829.         else show_end();
  2830.             
  2831.         the_game->set_state(MENU_STATE);
  2832.         req_end=0;
  2833.       }
  2834.       
  2835.  
  2836.       if (demo_man.current_state()==demo_manager::NORMAL)
  2837.       {
  2838.         net_receive();
  2839.       }
  2840.  
  2841.       if (req_name[0])            // see if a request for a level load was made during the last tick
  2842.       {
  2843.         //                    ProfilerDump("\pabuse.prof");  //prof    
  2844.         //                    ProfilerTerm();
  2845.         int show;
  2846.         if (!current_level)
  2847.           show=0;
  2848.         else if (strcmp(req_name,current_level->name()) && memcmp(req_name,"save",4)!=0)
  2849.           show=1;
  2850.         else show=0;
  2851.  
  2852.         if (show)
  2853.           show_stats();
  2854.         g->load_level(req_name);
  2855.         switch_mode(VMODE_320x200);
  2856.                recalc_local_view_space();
  2857.         if (show)
  2858.           end_stats();
  2859.  
  2860.         //                    ProfilerInit(collectDetailed, bestTimeBase, 2000, 200); //prof
  2861.         req_name[0]=0;
  2862.         g->draw(g->state==SCENE_STATE);
  2863.       }
  2864.  
  2865.       //    if (demo_man.current_state()!=demo_manager::PLAYING)
  2866.       g->get_input();
  2867.       
  2868.       if (demo_man.current_state()==demo_manager::NORMAL)
  2869.           net_send();
  2870.       else
  2871.           demo_man.do_inputs();
  2872.  
  2873.       service_net_request();
  2874.  
  2875.       DiffTime("  PreStuff",1); //kill me
  2876.       StartTime(2);    //kill me
  2877.             
  2878.       g->step();                        // process all the objects in the 
  2879.  
  2880.       DiffTime("  Step",2);  // kill me
  2881.       StartTime(3);  // kill me
  2882.       server_check();
  2883.  
  2884.       g->calc_speed();
  2885.       DiffTime("  MidStuff",3);  // kill me
  2886.       StartTime(4);  // kill me
  2887.       if (!req_name[0])                // see if a request for a level load was made during the last tick
  2888.         g->update_screen();               // redraw the screen with any changes
  2889.       DiffTime("  Update",4);  // kill me
  2890.  
  2891.       DiffTime("GameLoop",0);
  2892.     }
  2893.     switch_mode(VMODE_640x480);
  2894.  
  2895.     if (main_net_cfg && main_net_cfg->restart_state())
  2896.     {
  2897.       fade_out(1);
  2898.       image blank(2,2); blank.clear();
  2899.       eh->set_mouse_shape(blank.copy(),0,0);      // don't show mouse
  2900.  
  2901.       char *msg="Wait while network data is collected...";
  2902.       screen->clear(255);
  2903.       eh->font()->put_string(screen,
  2904.           xres/2-strlen(msg)*eh->font()->width()/2,
  2905.           yres/2-eh->font()->height()/2,
  2906.           msg);
  2907.       eh->flush_screen();
  2908.       fade_in(0,8);
  2909.     }
  2910.  
  2911.     net_uninit();
  2912.  
  2913.     if (net_crcs)
  2914.     {
  2915.       net_crcs->clean_up();
  2916.       delete net_crcs;
  2917.       net_crcs=NULL;
  2918.     }
  2919.  
  2920.     delete chat;
  2921.  
  2922.     if (!registered)
  2923.       show_sell(0);
  2924.     else milli_wait(500);
  2925.  
  2926.  
  2927.     if (small_render) { delete small_render; small_render=NULL; }
  2928.  
  2929.     if (current_song) 
  2930.     { current_song->stop();
  2931.     delete current_song; 
  2932.     current_song=NULL; 
  2933.     }
  2934.  
  2935.  
  2936.     cash.empty();
  2937.  
  2938.  
  2939.     if (dev_console)
  2940.     {
  2941.       delete dev_console;
  2942.       dev_console=NULL;
  2943.     }
  2944.  
  2945.     if (dev_menu)
  2946.     {
  2947.       delete dev_menu;
  2948.       dev_menu=NULL;
  2949.     }
  2950.  
  2951.     delete g;
  2952.     if (old_pal) delete old_pal; old_pal=NULL;
  2953.     compiled_uninit();
  2954.     delete_all_lights();
  2955.     jfree(white_light_initial);
  2956.  
  2957.     for (int i=0;i<TTINTS;i++) jfree(tints[i]);
  2958.  
  2959.  
  2960.     dev_cleanup();
  2961.     delete dev_cont; dev_cont=NULL;
  2962.    
  2963.  
  2964.     if (!(main_net_cfg && main_net_cfg->restart_state()))
  2965.     {
  2966.       void *end_msg=make_find_symbol("end_msg");
  2967.       if (DEFINEDP(symbol_value(end_msg)))
  2968.         dprintf("%s\n",lstring_value(symbol_value(end_msg)));
  2969.     }
  2970.  
  2971.     lisp_uninit();
  2972.     sd_cache.clear();
  2973.  
  2974.     base->packet.packet_reset();
  2975.     mem_report("end.mem");
  2976.   } while (main_net_cfg && main_net_cfg->restart_state());
  2977.  
  2978.    close_graphics();
  2979.  
  2980.   if (main_net_cfg) { delete main_net_cfg; main_net_cfg=NULL; }
  2981.   set_filename_prefix(NULL);  // dealloc this mem if there was any
  2982.   set_save_filename_prefix(NULL);
  2983.  
  2984.   if (!get_option("-no_timer"))
  2985.     timer_uninit();
  2986.  
  2987.   if (stat_man)
  2988.   {
  2989.     delete stat_man;
  2990.     stat_man=0;
  2991.   }
  2992.  
  2993.  
  2994.   mem_report("end.mem");
  2995.   jmalloc_uninit();
  2996.   l_user_stack.clean_up();
  2997.   l_ptr_stack.clean_up();
  2998.  
  2999.   sound_uninit();
  3000.  
  3001. #ifdef __MAC__
  3002.   QuitMacScreen();
  3003. #endif
  3004.  
  3005.   exit(0);
  3006.  
  3007.   return 0;  
  3008. }
  3009.  
  3010.  
  3011.