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