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