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