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