home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / main / med.c < prev    next >
Text File  |  1998-06-08  |  42KB  |  1,586 lines

  1. /*
  2.  * $Source: f:/miner/source/main/editor/rcs/med.c $
  3.  * $Revision: 2.3 $
  4.  * $Author: john $
  5.  * $Date: 1995/03/06 18:23:52 $
  6.  *
  7.  * Editor loop for Inferno
  8.  *
  9.  * $Log: med.c $
  10.  * Revision 2.3  1995/03/06  18:23:52  john
  11.  * Fixed bug with font screwing up.
  12.  * 
  13.  * Revision 2.2  1995/03/06  16:34:55  john
  14.  * Fixed bug with previous.
  15.  * 
  16.  * Revision 2.1  1995/03/06  15:20:57  john
  17.  * New screen mode method.
  18.  * 
  19.  * Revision 2.0  1995/02/27  11:35:54  john
  20.  * Version 2.0! No anonymous unions, Watcom 10.0, with no need
  21.  * for bitmaps.tbl.
  22.  * 
  23.  * Revision 1.192  1994/11/30  12:33:55  mike
  24.  * set window clearing mode for editor.
  25.  * 
  26.  * Revision 1.191  1994/11/27  23:17:02  matt
  27.  * Made changes for new mprintf calling convention
  28.  * 
  29.  * Revision 1.190  1994/11/19  00:04:33  john
  30.  * Changed some shorts to ints.
  31.  * 
  32.  * Revision 1.189  1994/11/17  14:47:57  mike
  33.  * validation functions moved from editor to game.
  34.  * 
  35.  * Revision 1.188  1994/11/14  11:41:38  john
  36.  * Fixed bug with editor/game sequencing.
  37.  * 
  38.  * Revision 1.187  1994/11/13  15:36:44  john
  39.  * Changed game sequencing with editor.
  40.  * 
  41.  * Revision 1.186  1994/11/10  16:49:12  matt
  42.  * Don't sort seg list if no segs in list
  43.  * 
  44.  * Revision 1.185  1994/11/08  09:28:39  mike
  45.  * reset ai paths on going to game.
  46.  * 
  47.  * Revision 1.184  1994/10/30  14:13:05  mike
  48.  * rip out repair center stuff.
  49.  * 
  50.  * Revision 1.183  1994/10/27  10:07:06  mike
  51.  * adapt to no inverse table.
  52.  * 
  53.  * Revision 1.182  1994/10/20  12:48:03  matt
  54.  * Replaced old save files (MIN/SAV/HOT) with new LVL files
  55.  * 
  56.  * Revision 1.181  1994/10/13  11:39:22  john
  57.  * Took out network stuff/.
  58.  * 
  59.  * Revision 1.180  1994/10/07  22:21:38  mike
  60.  * Stop Delete-{whatever} from hanging you!
  61.  * 
  62.  * Revision 1.179  1994/10/03  23:39:37  mike
  63.  * Adapt to newer, better, fuelcen_activate function.
  64.  * 
  65.  * Revision 1.178  1994/09/30  00:38:05  mike
  66.  * Shorten diagnostic message erase -- was erasing outside canvas.
  67.  * 
  68.  * Revision 1.177  1994/09/28  17:31:37  mike
  69.  * Add call to check_wall_validity();
  70.  * 
  71.  * Revision 1.176  1994/08/19  10:57:42  mike
  72.  * Fix status message erase bug.
  73.  * 
  74.  * Revision 1.175  1994/08/18  10:48:12  john
  75.  * Cleaned up game sequencing.
  76.  * 
  77.  * Revision 1.174  1994/08/16  18:11:04  yuan
  78.  * Maded C place you in the center of a segment.
  79.  * 
  80.  * Revision 1.173  1994/08/10  19:55:05  john
  81.  * Changed font stuff.
  82.  * 
  83.  * Revision 1.172  1994/08/09  16:06:06  john
  84.  * Added the ability to place players.  Made old
  85.  * Player variable be ConsoleObject.
  86.  * 
  87.  * Revision 1.171  1994/08/04  09:14:11  matt
  88.  * Fixed problem I said I fixed last time
  89.  * 
  90.  * Revision 1.170  1994/08/04  00:27:57  matt
  91.  * When viewing a wall, update the objects segnum if moved out of the segment
  92.  * 
  93.  * Revision 1.169  1994/08/02  14:18:12  mike
  94.  * Clean up dialog boxes.
  95.  * 
  96.  * Revision 1.168  1994/07/29  15:34:35  mike
  97.  * Kill some mprintfs.
  98.  * 
  99.  * Revision 1.167  1994/07/29  14:56:46  yuan
  100.  * Close centers window, when you go into game.
  101.  * 
  102.  * Revision 1.166  1994/07/28  17:16:20  john
  103.  * MAde editor use Network stuff.
  104.  * 
  105.  * Revision 1.165  1994/07/28  16:59:10  mike
  106.  * objects containing objects.
  107.  * 
  108.  * Revision 1.164  1994/07/22  12:37:07  matt
  109.  * Cleaned up editor/game interactions some more.
  110.  * 
  111.  * Revision 1.163  1994/07/21  19:35:11  yuan
  112.  * Fixed #include problem
  113.  * 
  114.  * Revision 1.162  1994/07/21  18:02:09  matt
  115.  * Don't re-init player stats when going from editor -> game
  116.  * 
  117.  * Revision 1.161  1994/07/21  12:47:53  mike
  118.  * Add tilde key functionality for object movement.
  119.  * 
  120.  * Revision 1.160  1994/07/18  10:44:55  mike
  121.  * One-click access to keypads.
  122.  * 
  123.  * Revision 1.159  1994/07/01  18:05:54  john
  124.  * *** empty log message ***
  125.  * 
  126.  * Revision 1.158  1994/07/01  17:57:06  john
  127.  * First version of not-working hostage system
  128.  * 
  129.  * 
  130.  * Revision 1.157  1994/07/01  11:32:29  john
  131.  * *** empty log message ***
  132.  * 
  133.  * Revision 1.156  1994/06/24  17:04:36  john
  134.  * *** empty log message ***
  135.  * 
  136.  * Revision 1.155  1994/06/23  15:53:47  matt
  137.  * Finished hacking in 3d rendering in big window
  138.  * 
  139.  * Revision 1.154  1994/06/21  16:17:54  yuan
  140.  * Init stats when you go to game from editor
  141.  * 
  142.  * Revision 1.153  1994/06/21  12:57:14  yuan
  143.  * Remove center from segment function added to menu.
  144.  * 
  145.  */
  146.  
  147. //#define DEMO 1
  148.  
  149. #define    DIAGNOSTIC_MESSAGE_MAX                90
  150. #define    EDITOR_STATUS_MESSAGE_DURATION    4        //    Shows for 3+..4 seconds
  151.  
  152. #pragma off (unreferenced)
  153. static char rcsid[] = "$Id: med.c 2.3 1995/03/06 18:23:52 john Exp $";
  154. #pragma on (unreferenced)
  155.  
  156. #include <stdio.h>
  157. #include <stdlib.h>
  158. #include <stdarg.h>
  159. #include <string.h>
  160. #include <process.h>
  161. #include <time.h>
  162.  
  163. //#define INCLUDE_XLISP
  164.  
  165. #include "inferno.h"
  166. #include "segment.h"
  167. #include "gr.h"
  168. #include "ui.h"
  169. #include "editor.h"
  170. //#include "gamemine.h"
  171. #include "gamesave.h"
  172. #include "gameseg.h"
  173.  
  174. #include "key.h"
  175. #include "mono.h"
  176. #include "error.h"
  177. #include "kfuncs.h"
  178. #include "macro.h"
  179.  
  180. #ifdef INCLUDE_XLISP
  181. #include "medlisp.h"
  182. #endif
  183. #include "mem.h"
  184. #include "render.h"
  185. #include "game.h"
  186. #include "slew.h"
  187. #include "kdefs.h"
  188. #include "func.h"
  189. #include "textures.h"
  190. #include "screens.h"
  191. #include "texmap.h"
  192. #include "object.h"
  193. #include "cflib.h"
  194. #include "effects.h"
  195. #include "wall.h"
  196. #include "info.h"
  197. #include "ai.h"
  198.  
  199. #include "texpage.h"        // Textue selection paging stuff
  200. #include "objpage.h"        // Object selection paging stuff
  201.  
  202. #include "medmisc.h"
  203. #include "meddraw.h"
  204. #include "medsel.h"
  205. #include "medrobot.h"
  206. #include "medwall.h"
  207. #include "eswitch.h"
  208. #include "ehostage.h"
  209. #include "centers.h"
  210.  
  211. #include "fuelcen.h"
  212. #include "gameseq.h"
  213. #include "newmenu.h"
  214.  
  215. //#define _MARK_ON 1
  216. //#include <wsample.h>        //should come after inferno.h to get mark setting
  217.  
  218. #define COMPRESS_INTERVAL    5            // seconds
  219.  
  220. //char *undo_status[128];
  221.  
  222. int initializing;
  223.  
  224. //these are instances of canvases, pointed to by variables below
  225. grs_canvas _canv_editor_game;        //the game on the editor screen
  226.  
  227. //these are pointers to our canvases
  228. grs_canvas *Canv_editor;            //the editor screen
  229. grs_canvas *Canv_editor_game=&_canv_editor_game; //the game on the editor screen
  230.  
  231. grs_canvas *canv_offscreen;        //for off-screen rendering
  232. grs_canvas *Pad_text_canvas;        // Keypad text
  233.  
  234. grs_font *editor_font=NULL;
  235.  
  236. //where the editor is looking
  237. vms_vector Ed_view_target={0,0,0};
  238.  
  239. int gamestate_not_restored = 0;
  240.  
  241. UI_WINDOW * EditorWindow;
  242.  
  243. int    Large_view_index = -1;
  244.  
  245. UI_GADGET_USERBOX * GameViewBox;
  246. UI_GADGET_USERBOX * LargeViewBox;
  247. UI_GADGET_USERBOX * GroupViewBox;
  248.  
  249. #if ORTHO_VIEWS
  250. UI_GADGET_USERBOX * TopViewBox;
  251. UI_GADGET_USERBOX * FrontViewBox;
  252. UI_GADGET_USERBOX * RightViewBox;
  253. #endif
  254.  
  255. UI_GADGET_ICON * ViewIcon;
  256. UI_GADGET_ICON * AllIcon;
  257. UI_GADGET_ICON * AxesIcon;
  258. UI_GADGET_ICON * ChaseIcon;
  259. UI_GADGET_ICON * OutlineIcon;
  260. UI_GADGET_ICON * LockIcon;
  261. //-NOLIGHTICON- UI_GADGET_ICON * LightIcon;
  262.  
  263. UI_EVENT * DemoBuffer = NULL;
  264.  
  265. //grs_canvas * BigCanvas[2];
  266. //int CurrentBigCanvas = 0;
  267. //int BigCanvasFirstTime = 1;
  268.  
  269. int    Found_seg_index=0;                // Index in Found_segs corresponding to Cursegp
  270.  
  271.  
  272. void print_status_bar( char message[DIAGNOSTIC_MESSAGE_MAX] ) {
  273.     int w,h,aw;
  274.  
  275.     gr_set_current_canvas( NULL );
  276.     gr_set_curfont(editor_font);
  277.     gr_set_fontcolor( CBLACK, CGREY );
  278.     gr_get_string_size( message, &w, &h, &aw );
  279.     gr_string( 4, 583, message );
  280.     gr_set_fontcolor( CBLACK, CWHITE );
  281.     gr_setcolor( CGREY );
  282.     gr_rect( 4+w, 583, 799, 599 );
  283. }
  284.  
  285. void print_diagnostic( char message[DIAGNOSTIC_MESSAGE_MAX] ) {
  286.     int w,h,aw;
  287.  
  288.     gr_set_current_canvas( NULL );
  289.     gr_set_curfont(editor_font);
  290.     gr_set_fontcolor( CBLACK, CGREY );
  291.     gr_get_string_size( message, &w, &h, &aw );
  292.     gr_string( 4, 583, message );
  293.     gr_set_fontcolor( CBLACK, CWHITE );
  294.     gr_setcolor( CGREY );
  295.     gr_rect( 4+w, 583, 799, 599 );
  296. }
  297.  
  298. static char status_line[DIAGNOSTIC_MESSAGE_MAX];
  299.  
  300. struct tm    Editor_status_last_time;
  301.  
  302. void editor_status( const char *format, ... )
  303. {
  304.     va_list ap;
  305.  
  306.     va_start(ap, format);
  307.     vsprintf(status_line, format, ap);
  308.     va_end(ap);
  309.  
  310.     print_status_bar(status_line);
  311.  
  312.     Editor_status_last_time = Editor_time_of_day;
  313.  
  314. }
  315.  
  316. //     int  tm_sec;    /* seconds after the minute -- [0,61] */
  317. //     int  tm_min;    /* minutes after the hour    -- [0,59] */
  318. //     int  tm_hour;    /* hours after midnight    -- [0,23] */
  319. //     int  tm_mday;    /* day of the month        -- [1,31] */
  320. //     int  tm_mon;    /* months since January    -- [0,11] */
  321. //     int  tm_year;    /* years since 1900                */
  322. //     int  tm_wday;    /* days since Sunday        -- [0,6]  */
  323. //     int  tm_yday;    /* days since January 1    -- [0,365]*/
  324. //     int  tm_isdst;    /* Daylight Savings Time flag */
  325.  
  326. void clear_editor_status(void)
  327. {
  328.     int cur_time = Editor_time_of_day.tm_hour * 3600 + Editor_time_of_day.tm_min*60 + Editor_time_of_day.tm_sec;
  329.     int erase_time = Editor_status_last_time.tm_hour * 3600 + Editor_status_last_time.tm_min*60 + Editor_status_last_time.tm_sec + EDITOR_STATUS_MESSAGE_DURATION;
  330.  
  331.     if (cur_time > erase_time) {
  332.         int    i;
  333.         char    message[DIAGNOSTIC_MESSAGE_MAX];
  334.  
  335.         for (i=0; i<DIAGNOSTIC_MESSAGE_MAX-1; i++)
  336.             message[i] = ' ';
  337.  
  338.         message[i] = 0;
  339.         print_status_bar(message);
  340.         Editor_status_last_time.tm_hour = 99;
  341.     }
  342. }
  343.  
  344.  
  345. void diagnostic_message( char *format, ... )
  346. {
  347.     char diag_line[DIAGNOSTIC_MESSAGE_MAX];
  348.  
  349.     va_list ap;
  350.  
  351.     va_start(ap, format);
  352.     vsprintf(diag_line, format, ap);
  353.     va_end(ap);
  354.  
  355.     editor_status(diag_line);
  356. }
  357.  
  358.  
  359. static char sub_status_line[DIAGNOSTIC_MESSAGE_MAX];
  360.  
  361. void editor_sub_status( const char *format, ... )
  362. {
  363.     int w,h,aw;
  364.     va_list ap;
  365.  
  366.     va_start(ap, format);
  367.     vsprintf(sub_status_line, format, ap);
  368.     va_end(ap);
  369.  
  370.     gr_set_current_canvas( NULL );
  371.     gr_set_curfont(editor_font);
  372.     gr_set_fontcolor( BM_XRGB(0,0,31), CGREY );
  373.     gr_get_string_size( sub_status_line, &w, &h, &aw );
  374.     gr_string( 500, 583, sub_status_line );
  375.     gr_set_fontcolor( CBLACK, CWHITE );
  376.     gr_setcolor( CGREY );
  377.     gr_rect( 500+w, 583, 799, 599 );
  378. }
  379.  
  380. int DropIntoDebugger()
  381. {
  382.     Int3();
  383.     return 1;
  384. }
  385.  
  386.  
  387. #ifdef INCLUDE_XLISP
  388. int CallLisp()
  389. {
  390.     medlisp_go();
  391.     return 1;
  392. }
  393. #endif
  394.  
  395.  
  396. int ExitEditor()
  397. {
  398.     if (SafetyCheck())  {
  399.         ModeFlag = 1;
  400.     }
  401.     return 1;
  402. }
  403.  
  404. int    GotoGameCommon(int mode) {
  405.     stop_time();
  406.  
  407. //@@    init_player_stats();
  408. //@@
  409. //@@    Player_init.pos = Player->pos;
  410. //@@    Player_init.orient = Player->orient;
  411. //@@    Player_init.segnum = Player->segnum;    
  412.     
  413. // -- must always save gamesave.sav because the restore-objects code relies on it
  414. // -- that code could be made smarter and use the original file, if appropriate.
  415. //    if (mine_changed) 
  416.     if (gamestate_not_restored == 0) {
  417.         gamestate_not_restored = 1;
  418.         save_level("GAMESAVE.LVL");
  419.         editor_status("Gamestate saved.\n");
  420.         mprintf((0, "Gamestate saved.\n"));
  421.     }
  422.  
  423.     ai_reset_all_paths();
  424.  
  425.     start_time();
  426.  
  427.     ModeFlag = mode;
  428.     return 1;
  429. }
  430.  
  431. int GotoGameScreen()
  432. {
  433.     return GotoGameCommon(3);
  434. }
  435.  
  436. int GotoGame()
  437. {
  438.     return GotoGameCommon(2);
  439. }
  440.  
  441.  
  442. void ReadLispMacro( FILE * file, char * buffer )
  443. {
  444. //    char c;
  445. //    int size=0;
  446. //    int pcount = 0;
  447. //    char text[100];
  448. //    int i=0;
  449.     
  450.     fscanf( file, " { %s } ", buffer );
  451.  
  452. /*
  453.     while (1)
  454.     {
  455.         c = text[i++];
  456.         if (pcount > 0 )
  457.             buffer[size++] = c;
  458.         if ( c == '(' ) pcount++;
  459.         if ( c == ')' ) break;
  460.     }
  461.     buffer[size++] = 0;
  462. */
  463.  
  464.     return;
  465. }
  466.  
  467. static int (*KeyFunction[2048])();
  468.  
  469. void medkey_init()
  470. {
  471.     FILE * keyfile;
  472.     char keypress[100];
  473.     int key;
  474.     int i;    //, size;
  475.     int np;
  476.     char * LispCommand;
  477.  
  478.     //MALLOC( LispCommand, char, DIAGNOSTIC_MESSAGE_MAX );//KRB hack
  479.     LispCommand = (char *)malloc(DIAGNOSTIC_MESSAGE_MAX*sizeof(char));
  480.     for (i=0; i<2048; i++ )
  481.         KeyFunction[i] = NULL;
  482.  
  483.     keyfile = fopen( "GLOBAL.KEY", "rt" );
  484.     if (keyfile)
  485.     {
  486.         while (fscanf( keyfile, " %s %s ", keypress, LispCommand ) != EOF )
  487.         {
  488.             //ReadLispMacro( keyfile, LispCommand );
  489.  
  490.             if ( (key=DecodeKeyText( keypress ))!= -1 )
  491.             {
  492.                 Assert( key < 2048);
  493.                 KeyFunction[key] = func_get( LispCommand, &np );
  494.             } else {
  495.                 Error( "Bad key %s in GLOBAL.KEY!", keypress );
  496.             }
  497.         }
  498.         fclose(keyfile);
  499.     }
  500.     free( LispCommand );
  501. }
  502.  
  503. void init_editor()
  504. {
  505.     minit();
  506.  
  507.     ui_init();
  508.  
  509.     init_med_functions();    // Must be called before medlisp_init
  510.  
  511.     ui_pad_read( 0, "segmove.pad" );
  512.     ui_pad_read( 1, "segsize.pad" );
  513.     ui_pad_read( 2, "curve.pad" );
  514.     ui_pad_read( 3, "texture.pad" );
  515.     ui_pad_read( 4, "object.pad" );
  516.     ui_pad_read( 5, "objmov.pad" );
  517.     ui_pad_read( 6, "group.pad" );
  518.     ui_pad_read( 7, "lighting.pad" );
  519.     ui_pad_read( 8, "test.pad" );
  520.  
  521.     medkey_init();
  522.  
  523.     editor_font = gr_init_font( "pc8x16.fnt" );
  524.     
  525.     menubar_init( "MED.MNU" );
  526.  
  527.     canv_offscreen = gr_create_canvas(LVIEW_W,LVIEW_H);
  528.     
  529.     Draw_all_segments = 1;                        // Say draw all segments, not just connected ones
  530.  
  531.     init_autosave();
  532.   
  533. //    atexit(close_editor);
  534.  
  535.     Clear_window = 1;    //    do full window clear.
  536. }
  537.  
  538. int ShowAbout()
  539. {
  540.     MessageBox( -2, -2, 1,     "INFERNO Mine Editor\n\n"        \
  541.                                     "Copyright (c) 1993  Parallax Software Corp.",
  542.                                     "OK");
  543.     return 0;
  544. }
  545.  
  546. void move_player_2_segment(segment *seg,int side);
  547.  
  548. int SetPlayerFromCurseg()
  549. {
  550.     move_player_2_segment(Cursegp,Curside);
  551.     Update_flags |= UF_ED_STATE_CHANGED | UF_GAME_VIEW_CHANGED;
  552.     return 1;
  553. }
  554.  
  555. int fuelcen_create_from_curseg()
  556. {
  557.     Cursegp->special = SEGMENT_IS_FUELCEN;
  558.     fuelcen_activate( Cursegp, Cursegp->special);
  559.     return 1;
  560. }
  561.  
  562. int repaircen_create_from_curseg()
  563. {
  564.     Int3();    //    -- no longer supported!
  565. //    Cursegp->special = SEGMENT_IS_REPAIRCEN;
  566. //    fuelcen_activate( Cursegp, Cursegp->special);
  567.     return 1;
  568. }
  569.  
  570. int controlcen_create_from_curseg()
  571. {
  572.     Cursegp->special = SEGMENT_IS_CONTROLCEN;
  573.     fuelcen_activate( Cursegp, Cursegp->special);
  574.     return 1;
  575. }
  576.  
  577. int robotmaker_create_from_curseg()
  578. {
  579.     Cursegp->special = SEGMENT_IS_ROBOTMAKER;
  580.     fuelcen_activate( Cursegp, Cursegp->special);
  581.     return 1;
  582. }
  583.  
  584. int fuelcen_reset_all()    {
  585.     fuelcen_reset();
  586.     return 1;
  587. }
  588.  
  589. int fuelcen_delete_from_curseg() {
  590.     fuelcen_delete( Cursegp );
  591.     return 1;
  592. }
  593.  
  594.  
  595. //@@//this routine places the viewer in the center of the side opposite to curside,
  596. //@@//with the view toward the center of curside
  597. //@@int SetPlayerFromCursegMinusOne()
  598. //@@{
  599. //@@    vms_vector vp;
  600. //@@
  601. //@@//    int newseg,newside;
  602. //@@//    get_previous_segment(SEG_PTR_2_NUM(Cursegp),Curside,&newseg,&newside);
  603. //@@//    move_player_2_segment(&Segments[newseg],newside);
  604. //@@
  605. //@@    med_compute_center_point_on_side(&Player->obj_position,Cursegp,Side_opposite[Curside]);
  606. //@@    med_compute_center_point_on_side(&vp,Cursegp,Curside);
  607. //@@    vm_vec_sub2(&vp,&Player->position);
  608. //@@    vm_vector_2_matrix(&Player->orient,&vp,NULL,NULL);
  609. //@@
  610. //@@    Player->seg = SEG_PTR_2_NUM(Cursegp);
  611. //@@
  612. //@@    Update_flags |= UF_GAME_VIEW_CHANGED;
  613. //@@    return 1;
  614. //@@}
  615.  
  616. //this constant determines how much of the window will be occupied by the
  617. //viewed side when SetPlayerFromCursegMinusOne() is called.  It actually
  618. //determine how from from the center of the window the farthest point will be
  619. #define SIDE_VIEW_FRAC (f1_0*8/10)    //80%
  620.  
  621.  
  622. void move_player_2_segment_and_rotate(segment *seg,int side)
  623. {
  624.     vms_vector vp;
  625.     vms_vector    upvec;
  626.     static edgenum=0;
  627.  
  628.     compute_segment_center(&ConsoleObject->pos,seg);
  629.     compute_center_point_on_side(&vp,seg,side);
  630.     vm_vec_sub2(&vp,&ConsoleObject->pos);
  631.  
  632.     vm_vec_sub(&upvec, &Vertices[Cursegp->verts[Side_to_verts[Curside][edgenum%4]]], &Vertices[Cursegp->verts[Side_to_verts[Curside][(edgenum+3)%4]]]);
  633.     edgenum++;
  634.  
  635.     vm_vector_2_matrix(&ConsoleObject->orient,&vp,&upvec,NULL);
  636. //    vm_vector_2_matrix(&ConsoleObject->orient,&vp,NULL,NULL);
  637.  
  638.     obj_relink( ConsoleObject-Objects, SEG_PTR_2_NUM(seg) );
  639.     
  640. }
  641.  
  642. int SetPlayerFromCursegAndRotate()
  643. {
  644.     move_player_2_segment_and_rotate(Cursegp,Curside);
  645.     Update_flags |= UF_ED_STATE_CHANGED | UF_GAME_VIEW_CHANGED;
  646.     return 1;
  647. }
  648.  
  649.  
  650. //sets the player facing curseg/curside, normal to face0 of curside, and
  651. //far enough away to see all of curside
  652. int SetPlayerFromCursegMinusOne()
  653. {
  654.     vms_vector view_vec,view_vec2,side_center;
  655.     vms_vector corner_v[4];
  656.     vms_vector    upvec;
  657.     g3s_point corner_p[4];
  658.     int i;
  659.     fix max,view_dist=f1_0*10;
  660.     static edgenum=0;
  661.     int newseg;
  662.  
  663.     view_vec = Cursegp->sides[Curside].normals[0];
  664.     vm_vec_negate(&view_vec);
  665.  
  666.     compute_center_point_on_side(&side_center,Cursegp,Curside);
  667.     vm_vec_copy_scale(&view_vec2,&view_vec,view_dist);
  668.     vm_vec_sub(&ConsoleObject->pos,&side_center,&view_vec2);
  669.  
  670.     vm_vec_sub(&upvec, &Vertices[Cursegp->verts[Side_to_verts[Curside][edgenum%4]]], &Vertices[Cursegp->verts[Side_to_verts[Curside][(edgenum+3)%4]]]);
  671.     edgenum++;
  672.  
  673.     vm_vector_2_matrix(&ConsoleObject->orient,&view_vec,&upvec,NULL);
  674.  
  675.     gr_set_current_canvas(Canv_editor_game);
  676.     g3_start_frame();
  677.     g3_set_view_matrix(&ConsoleObject->pos,&ConsoleObject->orient,Render_zoom);
  678.  
  679.     for (i=max=0;i<4;i++) {
  680.         corner_v[i] = Vertices[Cursegp->verts[Side_to_verts[Curside][i]]];
  681.         g3_rotate_point(&corner_p[i],&corner_v[i]);
  682.         if (labs(corner_p[i].x) > max) max = labs(corner_p[i].x);
  683.         if (labs(corner_p[i].y) > max) max = labs(corner_p[i].y);
  684.     }
  685.  
  686.     view_dist = fixmul(view_dist,fixdiv(fixdiv(max,SIDE_VIEW_FRAC),corner_p[0].z));
  687.     vm_vec_copy_scale(&view_vec2,&view_vec,view_dist);
  688.     vm_vec_sub(&ConsoleObject->pos,&side_center,&view_vec2);
  689.  
  690.     //obj_relink(ConsoleObject-Objects, SEG_PTR_2_NUM(Cursegp) );
  691.     //update_object_seg(ConsoleObject);        //might have backed right out of curseg
  692.  
  693.     newseg = find_point_seg(&ConsoleObject->pos,SEG_PTR_2_NUM(Cursegp) );
  694.     if (newseg != -1)
  695.         obj_relink(ConsoleObject-Objects,newseg);
  696.  
  697.     Update_flags |= UF_ED_STATE_CHANGED | UF_GAME_VIEW_CHANGED;
  698.     return 1;
  699. }
  700.  
  701. int ToggleLighting(void)
  702. {
  703.     char    outstr[80] = "[shift-L] ";
  704.     int    chindex;
  705.  
  706.     Lighting_on++;
  707.     if (Lighting_on >= 2)
  708.         Lighting_on = 0;
  709.  
  710.     Update_flags |= UF_GAME_VIEW_CHANGED;
  711.  
  712.     if (last_keypress == KEY_L + KEY_SHIFTED)
  713.         chindex = 0;
  714.     else
  715.         chindex = 10;
  716.  
  717.     switch (Lighting_on) {
  718.         case 0:
  719.             strcpy(&outstr[chindex],"Lighting off.");
  720.             break;
  721.         case 1:
  722.             strcpy(&outstr[chindex],"Static lighting.");
  723.             break;
  724.         case 2:
  725.             strcpy(&outstr[chindex],"Ship lighting.");
  726.             break;
  727.         case 3:
  728.             strcpy(&outstr[chindex],"Ship and static lighting.");
  729.             break;
  730.     }
  731.  
  732.     diagnostic_message(outstr);
  733.  
  734.     return Lighting_on;
  735. }
  736.  
  737. void find_concave_segs();
  738.  
  739. int FindConcaveSegs()
  740. {
  741.     find_concave_segs();
  742.  
  743.     Update_flags |= UF_ED_STATE_CHANGED;        //list may have changed
  744.  
  745.     return 1;
  746. }
  747.  
  748. int DosShell()
  749. {
  750.     int ok, w, h;
  751.     grs_bitmap * save_bitmap;
  752.  
  753.     // Save the current graphics state.
  754.  
  755.     w = grd_curscreen->sc_canvas.cv_bitmap.bm_w;
  756.     h = grd_curscreen->sc_canvas.cv_bitmap.bm_h;
  757.  
  758.     save_bitmap = gr_create_bitmap( w, h );
  759.     gr_bm_ubitblt(w, h, 0, 0, 0, 0, &(grd_curscreen->sc_canvas.cv_bitmap), save_bitmap );
  760.  
  761.     gr_restore_mode();
  762.  
  763.     printf( "\n\nType EXIT to return to Inferno" );
  764.     fflush(stdout);
  765.  
  766.     key_close();
  767.     ok = spawnl(P_WAIT,getenv("COMSPEC"), NULL );
  768.     key_init();
  769.  
  770.     gr_set_mode(grd_curscreen->sc_mode);
  771.     gr_bm_ubitblt(w, h, 0, 0, 0, 0, save_bitmap, &(grd_curscreen->sc_canvas.cv_bitmap));
  772.     gr_free_bitmap( save_bitmap );
  773.     //gr_pal_setblock( 0, 256, grd_curscreen->pal );
  774.     //gr_use_palette_table();
  775.  
  776.     return 1;
  777.  
  778. }
  779.  
  780. int ToggleOutlineMode()
  781. {    int mode;
  782.  
  783.     mode=toggle_outline_mode();
  784.  
  785.     if (mode)
  786.         if (last_keypress != KEY_O)
  787.             diagnostic_message("[O] Outline Mode ON.");
  788.         else
  789.             diagnostic_message("Outline Mode ON.");
  790.     else
  791.         if (last_keypress != KEY_O)
  792.             diagnostic_message("[O] Outline Mode OFF.");
  793.         else
  794.             diagnostic_message("Outline Mode OFF.");
  795.  
  796.     Update_flags |= UF_GAME_VIEW_CHANGED;
  797.     return mode;
  798. }
  799.  
  800. //@@int do_reset_orient()
  801. //@@{
  802. //@@    slew_reset_orient(SlewObj);
  803. //@@
  804. //@@    Update_flags |= UF_GAME_VIEW_CHANGED;
  805. //@@
  806. //@@    * (ubyte *) 0x417 &= ~0x20;
  807. //@@
  808. //@@    return 1;
  809. //@@}
  810.  
  811. int GameZoomOut()
  812. {
  813.     Render_zoom = fixmul(Render_zoom,68985);
  814.     Update_flags |= UF_GAME_VIEW_CHANGED;
  815.     return 1;
  816. }
  817.  
  818. int GameZoomIn()
  819. {
  820.     Render_zoom = fixmul(Render_zoom,62259);
  821.     Update_flags |= UF_GAME_VIEW_CHANGED;
  822.     return 1;
  823. }
  824.  
  825.  
  826. int med_keypad_goto_0()    {    ui_pad_goto(0);    return 0;    }
  827. int med_keypad_goto_1()    {    ui_pad_goto(1);    return 0;    }
  828. int med_keypad_goto_2()    {    ui_pad_goto(2);    return 0;    }
  829. int med_keypad_goto_3()    {    ui_pad_goto(3);    return 0;    }
  830. int med_keypad_goto_4()    {    ui_pad_goto(4);    return 0;    }
  831. int med_keypad_goto_5()    {    ui_pad_goto(5);    return 0;    }
  832. int med_keypad_goto_6()    {    ui_pad_goto(6);    return 0;    }
  833. int med_keypad_goto_7()    {    ui_pad_goto(7);    return 0;    }
  834. int med_keypad_goto_8()    {    ui_pad_goto(8);    return 0;    }
  835.  
  836. #define    PAD_WIDTH    30
  837. #define    PAD_WIDTH1    (PAD_WIDTH + 7)
  838.  
  839. int editor_screen_open = 0;
  840.  
  841. //setup the editors windows, canvases, gadgets, etc.
  842. //called whenever the editor screen is selected
  843. void init_editor_screen()
  844. {    
  845. //    grs_bitmap * bmp;
  846.  
  847.     if (editor_screen_open) return;
  848.  
  849.     grd_curscreen->sc_canvas.cv_font = editor_font;
  850.     
  851.     //create canvas for game on the editor screen
  852.     initializing = 1;
  853.     gr_set_current_canvas(Canv_editor);
  854.     Canv_editor->cv_font = editor_font;
  855.     gr_init_sub_canvas(Canv_editor_game,Canv_editor,GAMEVIEW_X,GAMEVIEW_Y,GAMEVIEW_W,GAMEVIEW_H);
  856.     
  857.     //Editor renders into full (320x200) game screen 
  858.  
  859.     init_info = 1;
  860.  
  861.     //do other editor screen setup
  862.  
  863.     // Since the palette might have changed, find some good colors...
  864.     CBLACK = gr_find_closest_color( 1, 1, 1 );
  865.     CGREY = gr_find_closest_color( 28, 28, 28 );
  866.     CWHITE = gr_find_closest_color( 38, 38, 38 );
  867.     CBRIGHT = gr_find_closest_color( 60, 60, 60 );
  868.     CRED = gr_find_closest_color( 63, 0, 0 );
  869.  
  870.     gr_set_curfont(editor_font);
  871.     gr_set_fontcolor( CBLACK, CWHITE );
  872.  
  873.     EditorWindow = ui_open_window( 0 , 0, ED_SCREEN_W, ED_SCREEN_H, WIN_FILLED );
  874.  
  875.     LargeViewBox    = ui_add_gadget_userbox( EditorWindow,LVIEW_X,LVIEW_Y,LVIEW_W,LVIEW_H);
  876. #if ORTHO_VIEWS
  877.     TopViewBox        = ui_add_gadget_userbox( EditorWindow,TVIEW_X,TVIEW_Y,TVIEW_W,TVIEW_H);
  878.      FrontViewBox    = ui_add_gadget_userbox( EditorWindow,FVIEW_X,FVIEW_Y,FVIEW_W,FVIEW_H);
  879.     RightViewBox    = ui_add_gadget_userbox( EditorWindow,RVIEW_X,RVIEW_Y,RVIEW_W,RVIEW_H);
  880. #endif
  881.     ui_gadget_calc_keys(EditorWindow);    //make tab work for all windows
  882.  
  883.     GameViewBox    = ui_add_gadget_userbox( EditorWindow, GAMEVIEW_X, GAMEVIEW_Y, GAMEVIEW_W, GAMEVIEW_H );
  884. //    GroupViewBox    = ui_add_gadget_userbox( EditorWindow,GVIEW_X,GVIEW_Y,GVIEW_W,GVIEW_H);
  885.  
  886. //    GameViewBox->when_tab = GameViewBox->when_btab = (UI_GADGET *) LargeViewBox;
  887. //    LargeViewBox->when_tab = LargeViewBox->when_btab = (UI_GADGET *) GameViewBox;
  888.  
  889. //    ui_gadget_calc_keys(EditorWindow);    //make tab work for all windows
  890.  
  891.     ViewIcon    = ui_add_gadget_icon( EditorWindow, "Lock\nview",    455,25+530,     40, 22,    KEY_V+KEY_CTRLED, ToggleLockViewToCursegp );
  892.     AllIcon    = ui_add_gadget_icon( EditorWindow, "Draw\nall",    500,25+530,      40, 22,    KEY_A+KEY_CTRLED, ToggleDrawAllSegments );
  893.     AxesIcon    = ui_add_gadget_icon( EditorWindow, "Coord\naxes",545,25+530,        40, 22,    KEY_D+KEY_CTRLED, ToggleCoordAxes );
  894. //-NOLIGHTICON-    LightIcon    = ui_add_gadget_icon( EditorWindow, "Light\ning",    590,25+530,     40, 22,    KEY_L+KEY_SHIFTED,ToggleLighting );
  895.     ChaseIcon    = ui_add_gadget_icon( EditorWindow, "Chase\nmode",635,25+530,        40, 22,    -1,                ToggleChaseMode );
  896.     OutlineIcon = ui_add_gadget_icon( EditorWindow, "Out\nline",     680,25+530,      40, 22,    KEY_O,            ToggleOutlineMode );
  897.     LockIcon    = ui_add_gadget_icon( EditorWindow, "Lock\nstep", 725,25+530,     40, 22,    KEY_L,            ToggleLockstep );
  898.  
  899.     meddraw_init_views(LargeViewBox->canvas);
  900.  
  901.     //ui_add_gadget_button( EditorWindow, 460, 510, 50, 25, "Quit", ExitEditor );
  902.     //ui_add_gadget_button( EditorWindow, 520, 510, 50, 25, "Lisp", CallLisp );
  903.     //ui_add_gadget_button( EditorWindow, 580, 510, 50, 25, "Mine", MineMenu );
  904.     //ui_add_gadget_button( EditorWindow, 640, 510, 50, 25, "Help", DoHelp );
  905.     //ui_add_gadget_button( EditorWindow, 460, 540, 50, 25, "Macro", MacroMenu );
  906.     //ui_add_gadget_button( EditorWindow, 520, 540, 50, 25, "About", ShowAbout );
  907.     //ui_add_gadget_button( EditorWindow, 640, 540, 50, 25, "Shell", DosShell );
  908.  
  909.     ui_pad_activate( EditorWindow, PAD_X, PAD_Y );
  910.     Pad_text_canvas = gr_create_sub_canvas(Canv_editor, PAD_X + 250, PAD_Y + 8, 180, 160);
  911.     ui_add_gadget_button( EditorWindow, PAD_X+6, PAD_Y+(30*5)+22, PAD_WIDTH, 20, "<<",  med_keypad_goto_prev );
  912.     ui_add_gadget_button( EditorWindow, PAD_X+PAD_WIDTH1+6, PAD_Y+(30*5)+22, PAD_WIDTH, 20, ">>",  med_keypad_goto_next );
  913.  
  914.     {    int    i;
  915.         i = 0;    ui_add_gadget_button( EditorWindow, PAD_X+16+(i+2)*PAD_WIDTH1, PAD_Y+(30*5)+22, PAD_WIDTH, 20, "SR",  med_keypad_goto_0 );
  916.         i++;        ui_add_gadget_button( EditorWindow, PAD_X+16+(i+2)*PAD_WIDTH1, PAD_Y+(30*5)+22, PAD_WIDTH, 20, "SS",  med_keypad_goto_1 );
  917.         i++;        ui_add_gadget_button( EditorWindow, PAD_X+16+(i+2)*PAD_WIDTH1, PAD_Y+(30*5)+22, PAD_WIDTH, 20, "CF",  med_keypad_goto_2 );
  918.         i++;        ui_add_gadget_button( EditorWindow, PAD_X+16+(i+2)*PAD_WIDTH1, PAD_Y+(30*5)+22, PAD_WIDTH, 20, "TM",  med_keypad_goto_3 );
  919.         i++;        ui_add_gadget_button( EditorWindow, PAD_X+16+(i+2)*PAD_WIDTH1, PAD_Y+(30*5)+22, PAD_WIDTH, 20, "OP",  med_keypad_goto_4 );
  920.         i++;        ui_add_gadget_button( EditorWindow, PAD_X+16+(i+2)*PAD_WIDTH1, PAD_Y+(30*5)+22, PAD_WIDTH, 20, "OR",  med_keypad_goto_5 );
  921.         i++;        ui_add_gadget_button( EditorWindow, PAD_X+16+(i+2)*PAD_WIDTH1, PAD_Y+(30*5)+22, PAD_WIDTH, 20, "GE",  med_keypad_goto_6 );
  922.         i++;        ui_add_gadget_button( EditorWindow, PAD_X+16+(i+2)*PAD_WIDTH1, PAD_Y+(30*5)+22, PAD_WIDTH, 20, "LI",  med_keypad_goto_7 );
  923.         i++;        ui_add_gadget_button( EditorWindow, PAD_X+16+(i+2)*PAD_WIDTH1, PAD_Y+(30*5)+22, PAD_WIDTH, 20, "TT",  med_keypad_goto_8 );
  924.     }
  925.  
  926.     gr_set_curfont(editor_font);
  927.     menubar_show();
  928.  
  929.     // INIT TEXTURE STUFF
  930.     texpage_init( EditorWindow );
  931.     objpage_init( EditorWindow );
  932.  
  933.     EditorWindow->keyboard_focus_gadget = (UI_GADGET *)LargeViewBox;
  934.  
  935.     canv_offscreen->cv_font = grd_curscreen->sc_canvas.cv_font;
  936. //    BigCanvas[0]->cv_font = grd_curscreen->sc_canvas.cv_font; 
  937. //    BigCanvas[1]->cv_font = grd_curscreen->sc_canvas.cv_font; 
  938. //    BigCanvasFirstTime = 1;
  939.  
  940.     // Draw status box
  941.     gr_set_current_canvas( NULL );
  942.     gr_setcolor( CGREY );
  943.     gr_rect(STATUS_X,STATUS_Y,STATUS_X+STATUS_W-1,STATUS_Y+STATUS_H-1);            //0, 582, 799, 599 );
  944.  
  945.     // Draw icon box
  946.     // gr_set_current_canvas( NULL );
  947.     //  gr_setcolor( CBRIGHT );
  948.     //  gr_rect( 528, 2, 798, 22);
  949.     //  gr_setcolor( CGREY);
  950.     //  gr_rect( 530, 2, 799, 20);
  951.  
  952.     Update_flags = UF_ALL;
  953.     initializing = 0;
  954.     editor_screen_open = 1;
  955. }
  956.  
  957. //shutdown ui on the editor screen
  958. close_editor_screen()
  959. {
  960.     if (!editor_screen_open) return;
  961.  
  962.     editor_screen_open = 0;
  963.     ui_pad_deactivate();
  964.     gr_free_sub_canvas(Pad_text_canvas);
  965.  
  966.     ui_close_window(EditorWindow);
  967.  
  968.     close_all_windows();
  969.  
  970.     // CLOSE TEXTURE STUFF
  971.     texpage_close();
  972.     objpage_close();
  973.  
  974.     menubar_hide();
  975.  
  976. }
  977.  
  978. med_show_warning(char *s)
  979. {
  980.     grs_canvas *save_canv=grd_curcanv;
  981.  
  982.     //gr_pal_fade_in(grd_curscreen->pal);    //in case palette is blacked
  983.  
  984.     MessageBox(-2,-2,1,s,"OK");
  985.  
  986.     gr_set_current_canvas(save_canv);
  987.  
  988. }
  989.  
  990. // Returns 1 if OK to trash current mine.
  991. int SafetyCheck()
  992. {
  993.     int x;
  994.             
  995.     if (mine_changed) {
  996.         stop_time();                
  997.         x = nm_messagebox( "Warning!", 2, "Cancel", "OK", "You are about to lose work." );
  998.         if (x<1) {
  999.             start_time();
  1000.             return 0;
  1001.         }
  1002.         start_time();
  1003.     }
  1004.     return 1;
  1005. }
  1006.  
  1007. //called at the end of the program
  1008. void close_editor() {
  1009.  
  1010.     close_autosave();
  1011.  
  1012.     menubar_close();
  1013.     
  1014.     gr_close_font(editor_font);
  1015.  
  1016.     gr_free_canvas(canv_offscreen); canv_offscreen = NULL;
  1017.  
  1018.     return;
  1019.  
  1020. }
  1021.  
  1022. //variables for find segments process
  1023.  
  1024. // ---------------------------------------------------------------------------------------------------
  1025. //    Subtract all elements in Found_segs from selected list.
  1026. void subtract_found_segments_from_selected_list(void)
  1027. {
  1028.     int    s,f;
  1029.  
  1030.     for (f=0; f<N_found_segs; f++) {
  1031.         int    foundnum = Found_segs[f];
  1032.  
  1033.         for (s=0; s<N_selected_segs; s++) {
  1034.             if (Selected_segs[s] == foundnum) {
  1035.                 Selected_segs[s] = Selected_segs[N_selected_segs-1];
  1036.                 N_selected_segs--;
  1037.                 break;
  1038.             }
  1039.         }
  1040.     }
  1041. }
  1042.  
  1043. // ---------------------------------------------------------------------------------------------------
  1044. //    Add all elements in Found_segs to selected list.
  1045. void add_found_segments_to_selected_list(void) {
  1046.     int    s,f;
  1047.  
  1048.     for (f=0; f<N_found_segs; f++) {
  1049.         int    foundnum = Found_segs[f];
  1050.  
  1051.         for (s=0; s<N_selected_segs; s++)
  1052.             if (Selected_segs[s] == foundnum)
  1053.                 break;
  1054.  
  1055.         if (s == N_selected_segs)
  1056.             Selected_segs[N_selected_segs++] = foundnum;
  1057.     }
  1058. }
  1059.  
  1060. void gamestate_restore_check() {
  1061.     char Message[DIAGNOSTIC_MESSAGE_MAX];
  1062.     obj_position Save_position;
  1063.  
  1064.     if (gamestate_not_restored) {
  1065.         sprintf( Message, "Do you wish to restore game state?\n");
  1066.     
  1067.         if (MessageBox( -2, -2, 2, Message, "Yes", "No" )==1) {
  1068.  
  1069.             // Save current position
  1070.             Save_position.pos = ConsoleObject->pos;
  1071.             Save_position.orient = ConsoleObject->orient;
  1072.             Save_position.segnum = ConsoleObject->segnum;
  1073.  
  1074.             load_level("GAMESAVE.LVL");
  1075.  
  1076.             // Restore current position
  1077.             if (Save_position.segnum <= Highest_segment_index) {
  1078.                 ConsoleObject->pos = Save_position.pos;
  1079.                 ConsoleObject->orient = Save_position.orient;
  1080.                 obj_relink(ConsoleObject-Objects,Save_position.segnum);
  1081.             }
  1082.  
  1083.             gamestate_not_restored = 0;
  1084.             Update_flags |= UF_WORLD_CHANGED;    
  1085.             }
  1086.         else
  1087.             gamestate_not_restored = 1;
  1088.         }
  1089. }
  1090.  
  1091. void RestoreGameState() {
  1092.     load_level("GAMESAVE.LVL");
  1093.     gamestate_not_restored = 0;
  1094.  
  1095.     mprintf((0, "Gamestate restored.\n"));
  1096.     editor_status("Gamestate restored.\n");
  1097.  
  1098.     Update_flags |= UF_WORLD_CHANGED;
  1099. }
  1100.  
  1101. extern void check_wall_validity(void);
  1102.  
  1103. // ---------------------------------------------------------------------------------------------------
  1104. //this function is the editor. called when editor mode selected.  runs until
  1105. //game mode or exit selected
  1106. void editor(void)
  1107. {
  1108.     int w,h;
  1109.     grs_bitmap * savedbitmap;
  1110.     editor_view *new_cv;
  1111.     static padnum=0;
  1112.     vms_matrix    MouseRotMat,tempm;
  1113.     //@@short camera_objnum;            //a camera for viewing
  1114.  
  1115.     init_editor();
  1116.  
  1117.     InitCurve();
  1118.  
  1119.     restore_effect_bitmap_icons();
  1120.  
  1121.     if (!set_screen_mode(SCREEN_EDITOR))    {
  1122.         set_screen_mode(SCREEN_GAME);
  1123.         Function_mode=FMODE_GAME;            //force back into game
  1124.         return;
  1125.     }
  1126.  
  1127.     gr_set_current_canvas( NULL );
  1128.     gr_set_curfont(editor_font);
  1129.  
  1130.     //Editor renders into full (320x200) game screen 
  1131.  
  1132.     set_warn_func(med_show_warning);
  1133.  
  1134.     keyd_repeat = 1;        // Allow repeat in editor
  1135.  
  1136.     //_MARK_("start of editor");//Nuked to compile -KRB
  1137.  
  1138.     ui_mouse_hide();
  1139.  
  1140.     ui_reset_idle_seconds();
  1141.  
  1142. //@@    //create a camera for viewing in the editor. copy position from ConsoleObject
  1143. //@@    camera_objnum = obj_create(OBJ_CAMERA,0,ConsoleObject->segnum,&ConsoleObject->pos,&ConsoleObject->orient,0);
  1144. //@@    Viewer = &Objects[camera_objnum];
  1145. //@@    slew_init(Viewer);        //camera is slewing
  1146.  
  1147.     Viewer = ConsoleObject;
  1148.     slew_init(ConsoleObject);
  1149.  
  1150.     Update_flags = UF_ALL;
  1151.  
  1152.     medlisp_update_screen();
  1153.  
  1154.     //set the wire-frame window to be the current view
  1155.     current_view = &LargeView;
  1156.  
  1157.     if (faded_in==0)
  1158.     {
  1159.         faded_in = 1;
  1160.         //gr_pal_fade_in( grd_curscreen->pal );
  1161.     }
  1162.  
  1163.     w = GameViewBox->canvas->cv_bitmap.bm_w;
  1164.     h = GameViewBox->canvas->cv_bitmap.bm_h;
  1165.     
  1166.     savedbitmap = gr_create_bitmap(w, h );
  1167.  
  1168.     gr_bm_ubitblt( w, h, 0, 0, 0, 0, &GameViewBox->canvas->cv_bitmap, savedbitmap );
  1169.  
  1170.     gr_set_current_canvas( GameViewBox->canvas );
  1171.     gr_set_curfont(editor_font);
  1172.     //gr_setcolor( CBLACK );
  1173.     //gr_deaccent_canvas();
  1174.     //gr_grey_canvas();
  1175.     
  1176.     ui_mouse_show();
  1177.  
  1178.     gr_set_curfont(editor_font);
  1179.     ui_pad_goto(padnum);
  1180.  
  1181.     gamestate_restore_check();
  1182.  
  1183.     while (Function_mode == FMODE_EDITOR) {
  1184.  
  1185.         gr_set_curfont(editor_font);
  1186.         info_display_all(EditorWindow);
  1187.  
  1188.         ModeFlag = 0;
  1189.  
  1190.         // Update the windows
  1191.  
  1192.         // Only update if there is no key waiting and we're not in
  1193.         // fast play mode.
  1194.         if (!key_peekkey()) //-- && (MacroStatus != UI_STATUS_FASTPLAY))
  1195.             medlisp_update_screen();
  1196.  
  1197.         //do editor stuff
  1198.         gr_set_curfont(editor_font);
  1199.         ui_mega_process();
  1200.         last_keypress &= ~KEY_DEBUGGED;        //    mask off delete key bit which has no function in editor.
  1201.         ui_window_do_gadgets(EditorWindow);
  1202.         do_robot_window();
  1203.         do_object_window();
  1204.         do_wall_window();
  1205.         do_trigger_window();
  1206.         do_hostage_window();
  1207.         do_centers_window();
  1208.         check_wall_validity();
  1209.         Assert(Num_walls>=0);
  1210.  
  1211.         if (Gameview_lockstep) {
  1212.             static segment *old_cursegp=NULL;
  1213.             static int old_curside=-1;
  1214.  
  1215.             if (old_cursegp!=Cursegp || old_curside!=Curside) {
  1216.                 SetPlayerFromCursegMinusOne();
  1217.                 old_cursegp = Cursegp;
  1218.                 old_curside = Curside;
  1219.             }
  1220.         }
  1221.  
  1222. //        mprintf((0, "%d    ", ui_get_idle_seconds() ));
  1223.  
  1224.         if ( ui_get_idle_seconds() > COMPRESS_INTERVAL ) 
  1225.             {
  1226.             med_compress_mine();
  1227.             ui_reset_idle_seconds();
  1228.             }
  1229.   
  1230. //    Commented out because it occupies about 25% of time in twirling the mine.
  1231. // Removes some Asserts....
  1232. //        med_check_all_vertices();
  1233.         clear_editor_status();        // if enough time elapsed, clear editor status message
  1234.         TimedAutosave(mine_filename);
  1235.         set_editor_time_of_day();
  1236.         gr_set_current_canvas( GameViewBox->canvas );
  1237.         
  1238.         // Remove keys used for slew
  1239.         switch(last_keypress)
  1240.         {
  1241.         case KEY_PAD9:
  1242.         case KEY_PAD7:
  1243.         case KEY_PADPLUS:
  1244.         case KEY_PADMINUS:
  1245.         case KEY_PAD8:
  1246.         case KEY_PAD2:
  1247.         case KEY_LBRACKET:
  1248.         case KEY_RBRACKET:
  1249.         case KEY_PAD1:
  1250.         case KEY_PAD3:
  1251.         case KEY_PAD6:
  1252.         case KEY_PAD4:
  1253.             last_keypress = 0;
  1254.         }
  1255.         if ((last_keypress&0xff)==KEY_LSHIFT) last_keypress=0;
  1256.         if ((last_keypress&0xff)==KEY_RSHIFT) last_keypress=0;
  1257.         if ((last_keypress&0xff)==KEY_LCTRL) last_keypress=0;
  1258.         if ((last_keypress&0xff)==KEY_RCTRL) last_keypress=0;
  1259. //        if ((last_keypress&0xff)==KEY_LALT) last_keypress=0;
  1260. //        if ((last_keypress&0xff)==KEY_RALT) last_keypress=0;
  1261.  
  1262.         gr_set_curfont(editor_font);
  1263.         menubar_do( last_keypress );
  1264.  
  1265.         //=================== DO FUNCTIONS ====================
  1266.  
  1267.         if ( KeyFunction[ last_keypress ] != NULL )    {
  1268.             KeyFunction[last_keypress]();
  1269.             last_keypress = 0;
  1270.         }
  1271.         switch (last_keypress)
  1272.         {
  1273.         case 0:
  1274.         case KEY_Z:
  1275.         case KEY_G:
  1276.         case KEY_LALT:
  1277.         case KEY_RALT:
  1278.         case KEY_LCTRL:
  1279.         case KEY_RCTRL:
  1280.         case KEY_LSHIFT:
  1281.         case KEY_RSHIFT:
  1282.         case KEY_LAPOSTRO:
  1283.             break;
  1284.         case KEY_SHIFTED + KEY_L:
  1285.             ToggleLighting();
  1286.             break;
  1287.         case KEY_F1:
  1288.             render_3d_in_big_window = !render_3d_in_big_window;
  1289.             Update_flags |= UF_ALL;
  1290.             break;            
  1291.         default:
  1292.             {
  1293.             char kdesc[100];
  1294.             GetKeyDescription( kdesc, last_keypress );
  1295.             editor_status("Error: %s isn't bound to anything.", kdesc  );
  1296.             }
  1297.         }
  1298.  
  1299.         //================================================================
  1300.  
  1301.         if (ModeFlag==1)
  1302.         {
  1303.             close_editor_screen();
  1304.             Function_mode=FMODE_EXIT;
  1305.                 gr_free_bitmap( savedbitmap );
  1306.             break;
  1307.         }
  1308.  
  1309.         if (ModeFlag==2) //-- && MacroStatus==UI_STATUS_NORMAL )
  1310.         {
  1311.             ui_mouse_hide();
  1312.             Function_mode = FMODE_GAME;
  1313.             gr_bm_ubitblt( w, h, 0, 0, 0, 0, savedbitmap, &GameViewBox->canvas->cv_bitmap);
  1314.             gr_free_bitmap( savedbitmap );
  1315.             break;
  1316.         }
  1317.  
  1318.         if (ModeFlag==3) //-- && MacroStatus==UI_STATUS_NORMAL )
  1319.         {
  1320. //            med_compress_mine();                        //will be called anyways before game.
  1321.             close_editor_screen();
  1322.             Function_mode=FMODE_GAME;            //force back into game
  1323.             set_screen_mode(SCREEN_GAME);        //put up game screen
  1324.             gr_free_bitmap( savedbitmap );
  1325.             break;
  1326.         }
  1327.  
  1328. //        if (CurWindow->keyboard_focus_gadget == (UI_GADGET *)GameViewBox) current_view=NULL;
  1329. //        if (CurWindow->keyboard_focus_gadget == (UI_GADGET *)GroupViewBox) current_view=NULL;
  1330.  
  1331.         new_cv = current_view ;
  1332.  
  1333. #if ORTHO_VIEWS
  1334.         if (CurWindow->keyboard_focus_gadget == (UI_GADGET *)LargeViewBox) new_cv=&LargeView;
  1335.         if (CurWindow->keyboard_focus_gadget == (UI_GADGET *)TopViewBox)    new_cv=&TopView;
  1336.         if (CurWindow->keyboard_focus_gadget == (UI_GADGET *)FrontViewBox) new_cv=&FrontView;
  1337.         if (CurWindow->keyboard_focus_gadget == (UI_GADGET *)RightViewBox) new_cv=&RightView;
  1338. #endif
  1339.         if (new_cv != current_view ) {
  1340.             current_view->ev_changed = 1;
  1341.             new_cv->ev_changed = 1;
  1342.             current_view = new_cv;
  1343.         }
  1344.  
  1345.         calc_frame_time();
  1346.         if (slew_frame(0)) 
  1347.         {        //do movement and check keys
  1348.             Update_flags |= UF_GAME_VIEW_CHANGED;
  1349.             if (Gameview_lockstep) {
  1350.                 Cursegp = &Segments[ConsoleObject->segnum];
  1351.                 med_create_new_segment_from_cursegp();
  1352.                 Update_flags |= UF_ED_STATE_CHANGED;
  1353.             }
  1354.         }
  1355.  
  1356.         // DO TEXTURE STUFF
  1357.         texpage_do();
  1358.         objpage_do();
  1359.  
  1360.  
  1361.         // Process selection of Cursegp using mouse.
  1362.         if (LargeViewBox->mouse_onme && LargeViewBox->b1_clicked && !render_3d_in_big_window) 
  1363.         {
  1364.             int    xcrd,ycrd;
  1365.             xcrd = LargeViewBox->b1_drag_x1;
  1366.             ycrd = LargeViewBox->b1_drag_y1;
  1367.  
  1368.             find_segments(xcrd,ycrd,LargeViewBox->canvas,&LargeView,Cursegp,Big_depth);    // Sets globals N_found_segs, Found_segs
  1369.  
  1370.             // If shift is down, then add segment to found list
  1371.             if (keyd_pressed[ KEY_LSHIFT ] || keyd_pressed[ KEY_RSHIFT ])
  1372.                 subtract_found_segments_from_selected_list();
  1373.             else
  1374.                 add_found_segments_to_selected_list();
  1375.  
  1376.               Found_seg_index = 0;    
  1377.         
  1378.             if (N_found_segs > 0) {
  1379.                 sort_seg_list(N_found_segs,Found_segs,&ConsoleObject->pos);
  1380.                 Cursegp = &Segments[Found_segs[0]];
  1381.                 med_create_new_segment_from_cursegp();
  1382.                 if (Lock_view_to_cursegp)
  1383.                     set_view_target_from_segment(Cursegp);
  1384.             }
  1385.  
  1386.             Update_flags |= UF_ED_STATE_CHANGED | UF_VIEWPOINT_MOVED;
  1387.         }
  1388.  
  1389.         if (GameViewBox->mouse_onme && GameViewBox->b1_dragging) {
  1390.             int    x, y;
  1391.             x = GameViewBox->b1_drag_x2;
  1392.             y = GameViewBox->b1_drag_y2;
  1393.  
  1394.             ui_mouse_hide();
  1395.             gr_set_current_canvas( GameViewBox->canvas );
  1396.             gr_setcolor( 15 );
  1397.             gr_rect( x-1, y-1, x+1, y+1 );
  1398.             ui_mouse_show();
  1399.  
  1400.         }
  1401.         
  1402.         // Set current segment and side by clicking on a polygon in game window.
  1403.         //    If ctrl pressed, also assign current texture map to that side.
  1404.         //if (GameViewBox->mouse_onme && (GameViewBox->b1_done_dragging || GameViewBox->b1_clicked)) {
  1405.         if ((GameViewBox->mouse_onme && GameViewBox->b1_clicked && !render_3d_in_big_window) ||
  1406.             (LargeViewBox->mouse_onme && LargeViewBox->b1_clicked && render_3d_in_big_window)) {
  1407.  
  1408.             int    xcrd,ycrd;
  1409.             int seg,side,face,poly,tmap;
  1410.  
  1411.             if (render_3d_in_big_window) {
  1412.                 xcrd = LargeViewBox->b1_drag_x1;
  1413.                 ycrd = LargeViewBox->b1_drag_y1;
  1414.             }
  1415.             else {
  1416.                 xcrd = GameViewBox->b1_drag_x1;
  1417.                 ycrd = GameViewBox->b1_drag_y1;
  1418.             }
  1419.     
  1420.             //Int3();
  1421.  
  1422.             if (find_seg_side_face(xcrd,ycrd,&seg,&side,&face,&poly)) {
  1423.  
  1424.  
  1425.                 if (seg<0) {                            //found an object
  1426.  
  1427.                     Cur_object_index = -seg-1;
  1428.                     editor_status("Object %d selected.",Cur_object_index);
  1429.  
  1430.                     Update_flags |= UF_ED_STATE_CHANGED;
  1431.                 }
  1432.                 else {
  1433.  
  1434.                     //    See if either shift key is down and, if so, assign texture map
  1435.                     if (keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT]) {
  1436.                         Cursegp = &Segments[seg];
  1437.                         Curside = side;
  1438.                         AssignTexture();
  1439.                         med_create_new_segment_from_cursegp();
  1440.                         editor_status("Texture assigned");
  1441.                     } else if (keyd_pressed[KEY_G])    {
  1442.                         tmap = Segments[seg].sides[side].tmap_num;
  1443.                         texpage_grab_current(tmap);
  1444.                         editor_status( "Texture grabbed." );
  1445.                     } else if (keyd_pressed[ KEY_LAPOSTRO] ) {
  1446.                         ui_mouse_hide();
  1447.                         move_object_to_mouse_click();
  1448.                     } else {
  1449.                         Cursegp = &Segments[seg];
  1450.                         Curside = side;
  1451.                         med_create_new_segment_from_cursegp();
  1452.                         editor_status("Curseg and curside selected");
  1453.                     }
  1454.                 }
  1455.  
  1456.                 Update_flags |= UF_ED_STATE_CHANGED;
  1457.             }
  1458.             else 
  1459.                 editor_status("Click on non-texture ingored");
  1460.  
  1461.         }
  1462.  
  1463.         // Allow specification of LargeView using mouse
  1464.         if (keyd_pressed[ KEY_LCTRL ] || keyd_pressed[ KEY_RCTRL ]) {
  1465.             ui_mouse_hide();
  1466.             if ( (Mouse.dx!=0) && (Mouse.dy!=0) ) {
  1467.                 GetMouseRotation( Mouse.dx, Mouse.dy, &MouseRotMat );
  1468.                 vm_matrix_x_matrix(&tempm,&LargeView.ev_matrix,&MouseRotMat);
  1469.                 LargeView.ev_matrix = tempm;
  1470.                 LargeView.ev_changed = 1;
  1471.                 Large_view_index = -1;            // say not one of the orthogonal views
  1472.             }
  1473.         } else  {
  1474.             ui_mouse_show();
  1475.         }
  1476.  
  1477.         if ( keyd_pressed[ KEY_Z ] ) {
  1478.             ui_mouse_hide();
  1479.             if ( Mouse.dy!=0 ) {
  1480.                 current_view->ev_dist += Mouse.dy*10000;
  1481.                 current_view->ev_changed = 1;
  1482.             }
  1483.         } else {
  1484.             ui_mouse_show();
  1485.         }
  1486.  
  1487.     }
  1488.  
  1489. //    _MARK_("end of editor");//Nuked to compile -KRB
  1490.  
  1491.     clear_warn_func(med_show_warning);
  1492.  
  1493.     //kill our camera object
  1494.  
  1495.     Viewer = ConsoleObject;                    //reset viewer
  1496.     //@@obj_delete(camera_objnum);
  1497.  
  1498.     padnum = ui_pad_get_current();
  1499.  
  1500.     close_editor();
  1501.     ui_close();
  1502.  
  1503.  
  1504. }
  1505.  
  1506. void test_fade(void)
  1507. {
  1508.     int    i,c;
  1509.  
  1510.     for (c=0; c<256; c++) {
  1511.         printf("%4i: {%3i %3i %3i} ",c,gr_palette[3*c],gr_palette[3*c+1],gr_palette[3*c+2]);
  1512.         for (i=0; i<16; i++) {
  1513.             int col = gr_fade_table[256*i+c];
  1514.  
  1515.             printf("[%3i %3i %3i] ",gr_palette[3*col],gr_palette[3*col+1],gr_palette[3*col+2]);
  1516.         }
  1517.         if ( (c%16) == 15)
  1518.             printf("\n");
  1519.         printf("\n");
  1520.     }
  1521. }
  1522.  
  1523. void dump_stuff(void)
  1524. {
  1525.     int    i,j,prev_color;
  1526.  
  1527.     printf("Palette:\n");
  1528.  
  1529.     for (i=0; i<256; i++)
  1530.         printf("%3i: %2i %2i %2i\n",i,gr_palette[3*i],gr_palette[3*i+1],gr_palette[3*i+2]);
  1531.  
  1532.     for (i=0; i<16; i++) {
  1533.         printf("\nFade table #%i\n",i);
  1534.         for (j=0; j<256; j++) {
  1535.             int    c = gr_fade_table[i*256 + j];
  1536.             printf("[%3i %2i %2i %2i] ",c, gr_palette[3*c], gr_palette[3*c+1], gr_palette[3*c+2]);
  1537.             if ((j % 8) == 7)
  1538.                 printf("\n");
  1539.         }
  1540.     }
  1541.  
  1542.     printf("Colors indexed by intensity:\n");
  1543.     printf(". = change from previous, * = no change\n");
  1544.     for (j=0; j<256; j++) {
  1545.         printf("%3i: ",j);
  1546.         prev_color = -1;
  1547.         for (i=0; i<16; i++) {
  1548.             int    c = gr_fade_table[i*256 + j];
  1549.             if (c == prev_color)
  1550.                 printf("*");
  1551.             else
  1552.                 printf(".");
  1553.             prev_color = c;
  1554.         }
  1555.         printf("  ");
  1556.         for (i=0; i<16; i++) {
  1557.             int    c = gr_fade_table[i*256 + j];
  1558.             printf("[%3i %2i %2i %2i] ", c, gr_palette[3*c], gr_palette[3*c+1], gr_palette[3*c+2]);
  1559.         }
  1560.         printf("\n");
  1561.     }
  1562.  
  1563. }
  1564.  
  1565.  
  1566. int MarkStart(void)
  1567. {
  1568.     char mystr[30];
  1569.     sprintf(mystr,"mark %i start",Mark_count);
  1570. //    _MARK_(mystr);//Nuked to compile -KRB
  1571.  
  1572.     return 1;
  1573. }
  1574.  
  1575. int MarkEnd(void)
  1576. {
  1577.     char mystr[30];
  1578.     sprintf(mystr,"mark %i end",Mark_count);
  1579.     Mark_count++;
  1580. //    _MARK_(mystr);//Nuked to compile -KRB
  1581.  
  1582.     return 1;
  1583. }
  1584.  
  1585. 
  1586.