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