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.
14 * $Source: /cvs/cvsroot/d2x/main/editor/med.c,v $
17 * $Date: 2001-10-25 02:27:17 $
19 * Editor loop for Inferno
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.
25 * Revision 2.3 1995/03/06 18:23:52 john
26 * Fixed bug with font screwing up.
28 * Revision 2.2 1995/03/06 16:34:55 john
29 * Fixed bug with previous.
31 * Revision 2.1 1995/03/06 15:20:57 john
32 * New screen mode method.
34 * Revision 2.0 1995/02/27 11:35:54 john
35 * Version 2.0! No anonymous unions, Watcom 10.0, with no need
38 * Revision 1.192 1994/11/30 12:33:55 mike
39 * set window clearing mode for editor.
41 * Revision 1.191 1994/11/27 23:17:02 matt
42 * Made changes for new mprintf calling convention
44 * Revision 1.190 1994/11/19 00:04:33 john
45 * Changed some shorts to ints.
47 * Revision 1.189 1994/11/17 14:47:57 mike
48 * validation functions moved from editor to game.
50 * Revision 1.188 1994/11/14 11:41:38 john
51 * Fixed bug with editor/game sequencing.
53 * Revision 1.187 1994/11/13 15:36:44 john
54 * Changed game sequencing with editor.
56 * Revision 1.186 1994/11/10 16:49:12 matt
57 * Don't sort seg list if no segs in list
59 * Revision 1.185 1994/11/08 09:28:39 mike
60 * reset ai paths on going to game.
62 * Revision 1.184 1994/10/30 14:13:05 mike
63 * rip out repair center stuff.
65 * Revision 1.183 1994/10/27 10:07:06 mike
66 * adapt to no inverse table.
68 * Revision 1.182 1994/10/20 12:48:03 matt
69 * Replaced old save files (MIN/SAV/HOT) with new LVL files
71 * Revision 1.181 1994/10/13 11:39:22 john
72 * Took out network stuff/.
74 * Revision 1.180 1994/10/07 22:21:38 mike
75 * Stop Delete-{whatever} from hanging you!
77 * Revision 1.179 1994/10/03 23:39:37 mike
78 * Adapt to newer, better, fuelcen_activate function.
80 * Revision 1.178 1994/09/30 00:38:05 mike
81 * Shorten diagnostic message erase -- was erasing outside canvas.
83 * Revision 1.177 1994/09/28 17:31:37 mike
84 * Add call to check_wall_validity();
86 * Revision 1.176 1994/08/19 10:57:42 mike
87 * Fix status message erase bug.
89 * Revision 1.175 1994/08/18 10:48:12 john
90 * Cleaned up game sequencing.
92 * Revision 1.174 1994/08/16 18:11:04 yuan
93 * Maded C place you in the center of a segment.
95 * Revision 1.173 1994/08/10 19:55:05 john
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.
102 * Revision 1.171 1994/08/04 09:14:11 matt
103 * Fixed problem I said I fixed last time
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
108 * Revision 1.169 1994/08/02 14:18:12 mike
109 * Clean up dialog boxes.
111 * Revision 1.168 1994/07/29 15:34:35 mike
112 * Kill some mprintfs.
114 * Revision 1.167 1994/07/29 14:56:46 yuan
115 * Close centers window, when you go into game.
117 * Revision 1.166 1994/07/28 17:16:20 john
118 * MAde editor use Network stuff.
120 * Revision 1.165 1994/07/28 16:59:10 mike
121 * objects containing objects.
123 * Revision 1.164 1994/07/22 12:37:07 matt
124 * Cleaned up editor/game interactions some more.
126 * Revision 1.163 1994/07/21 19:35:11 yuan
127 * Fixed #include problem
129 * Revision 1.162 1994/07/21 18:02:09 matt
130 * Don't re-init player stats when going from editor -> game
132 * Revision 1.161 1994/07/21 12:47:53 mike
133 * Add tilde key functionality for object movement.
135 * Revision 1.160 1994/07/18 10:44:55 mike
136 * One-click access to keypads.
138 * Revision 1.159 1994/07/01 18:05:54 john
139 * *** empty log message ***
141 * Revision 1.158 1994/07/01 17:57:06 john
142 * First version of not-working hostage system
145 * Revision 1.157 1994/07/01 11:32:29 john
146 * *** empty log message ***
148 * Revision 1.156 1994/06/24 17:04:36 john
149 * *** empty log message ***
151 * Revision 1.155 1994/06/23 15:53:47 matt
152 * Finished hacking in 3d rendering in big window
154 * Revision 1.154 1994/06/21 16:17:54 yuan
155 * Init stats when you go to game from editor
157 * Revision 1.153 1994/06/21 12:57:14 yuan
158 * Remove center from segment function added to menu.
168 #define DIAGNOSTIC_MESSAGE_MAX 90
169 #define EDITOR_STATUS_MESSAGE_DURATION 4 // Shows for 3+..4 seconds
182 //#define INCLUDE_XLISP
189 //#include "gamemine.h"
190 #include "gamesave.h"
208 #include "textures.h"
217 #include "texpage.h" // Textue selection paging stuff
218 #include "objpage.h" // Object selection paging stuff
223 #include "medrobot.h"
226 #include "ehostage.h"
234 //#include <wsample.h> //should come after inferno.h to get mark setting //Not included here.
236 #define COMPRESS_INTERVAL 5 // seconds
238 //char *undo_status[128];
242 //these are instances of canvases, pointed to by variables below
243 grs_canvas _canv_editor_game; //the game on the editor screen
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
249 grs_canvas *canv_offscreen; //for off-screen rendering
250 grs_canvas *Pad_text_canvas; // Keypad text
252 grs_font *editor_font=NULL;
254 //where the editor is looking
255 vms_vector Ed_view_target={0,0,0};
257 int gamestate_not_restored = 0;
259 UI_WINDOW * EditorWindow;
261 int Large_view_index = -1;
263 UI_GADGET_USERBOX * GameViewBox;
264 UI_GADGET_USERBOX * LargeViewBox;
265 UI_GADGET_USERBOX * GroupViewBox;
268 UI_GADGET_USERBOX * TopViewBox;
269 UI_GADGET_USERBOX * FrontViewBox;
270 UI_GADGET_USERBOX * RightViewBox;
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;
281 UI_EVENT * DemoBuffer = NULL;
283 //grs_canvas * BigCanvas[2];
284 //int CurrentBigCanvas = 0;
285 //int BigCanvasFirstTime = 1;
287 int Found_seg_index=0; // Index in Found_segs corresponding to Cursegp
290 void print_status_bar( char message[DIAGNOSTIC_MESSAGE_MAX] ) {
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 );
303 void print_diagnostic( char message[DIAGNOSTIC_MESSAGE_MAX] ) {
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 );
316 static char status_line[DIAGNOSTIC_MESSAGE_MAX];
318 struct tm Editor_status_last_time;
320 void editor_status( const char *format, ... )
324 va_start(ap, format);
325 vsprintf(status_line, format, ap);
328 print_status_bar(status_line);
330 Editor_status_last_time = Editor_time_of_day;
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 */
344 void clear_editor_status(void)
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;
349 if (cur_time > erase_time) {
351 char message[DIAGNOSTIC_MESSAGE_MAX];
353 for (i=0; i<DIAGNOSTIC_MESSAGE_MAX-1; i++)
357 print_status_bar(message);
358 Editor_status_last_time.tm_hour = 99;
363 void diagnostic_message( const char *format, ... )
365 char diag_line[DIAGNOSTIC_MESSAGE_MAX];
369 va_start(ap, format);
370 vsprintf(diag_line, format, ap);
373 editor_status(diag_line);
377 static char sub_status_line[DIAGNOSTIC_MESSAGE_MAX];
379 void editor_sub_status( const char *format, ... )
384 va_start(ap, format);
385 vsprintf(sub_status_line, format, ap);
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 );
398 int DropIntoDebugger()
422 int GotoGameCommon(int mode) {
425 //@@ init_player_stats();
427 //@@ Player_init.pos = Player->pos;
428 //@@ Player_init.orient = Player->orient;
429 //@@ Player_init.segnum = Player->segnum;
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.
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"));
441 ai_reset_all_paths();
451 return GotoGameCommon(3);
456 return GotoGameCommon(2);
460 void ReadLispMacro( FILE * file, char * buffer )
468 fscanf( file, " { %s } ", buffer );
476 if ( c == '(' ) pcount++;
477 if ( c == ')' ) break;
485 static int (*KeyFunction[2048])();
496 MALLOC( LispCommand, char, DIAGNOSTIC_MESSAGE_MAX );
498 for (i=0; i<2048; i++ )
499 KeyFunction[i] = NULL;
501 keyfile = fopen( "GLOBAL.KEY", "rt" );
504 while (fscanf( keyfile, " %s %s ", keypress, LispCommand ) != EOF )
506 //ReadLispMacro( keyfile, LispCommand );
508 if ( (key=DecodeKeyText( keypress ))!= -1 )
511 KeyFunction[key] = func_get( LispCommand, &np );
513 Error( "Bad key %s in GLOBAL.KEY!", keypress );
527 init_med_functions(); // Must be called before medlisp_init
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" );
541 editor_font = gr_init_font( "pc8x16.fnt" );
543 menubar_init( "MED.MNU" );
545 canv_offscreen = gr_create_canvas(LVIEW_W,LVIEW_H);
547 Draw_all_segments = 1; // Say draw all segments, not just connected ones
551 // atexit(close_editor);
553 Clear_window = 1; // do full window clear.
558 MessageBox( -2, -2, 1, "INFERNO Mine Editor\n\n" \
559 "Copyright (c) 1993 Parallax Software Corp.",
564 void move_player_2_segment(segment *seg,int side);
566 int SetPlayerFromCurseg()
568 move_player_2_segment(Cursegp,Curside);
569 Update_flags |= UF_ED_STATE_CHANGED | UF_GAME_VIEW_CHANGED;
573 int fuelcen_create_from_curseg()
575 Cursegp->special = SEGMENT_IS_FUELCEN;
576 fuelcen_activate( Cursegp, Cursegp->special);
580 int repaircen_create_from_curseg()
582 Int3(); // -- no longer supported!
583 // Cursegp->special = SEGMENT_IS_REPAIRCEN;
584 // fuelcen_activate( Cursegp, Cursegp->special);
588 int controlcen_create_from_curseg()
590 Cursegp->special = SEGMENT_IS_CONTROLCEN;
591 fuelcen_activate( Cursegp, Cursegp->special);
595 int robotmaker_create_from_curseg()
597 Cursegp->special = SEGMENT_IS_ROBOTMAKER;
598 fuelcen_activate( Cursegp, Cursegp->special);
602 int fuelcen_reset_all() {
607 int fuelcen_delete_from_curseg() {
608 fuelcen_delete( Cursegp );
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()
619 //@@// int newseg,newside;
620 //@@// get_previous_segment(SEG_PTR_2_NUM(Cursegp),Curside,&newseg,&newside);
621 //@@// move_player_2_segment(&Segments[newseg],newside);
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);
628 //@@ Player->seg = SEG_PTR_2_NUM(Cursegp);
630 //@@ Update_flags |= UF_GAME_VIEW_CHANGED;
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%
640 void move_player_2_segment_and_rotate(segment *seg,int side)
644 static int edgenum=0;
646 compute_segment_center(&ConsoleObject->pos,seg);
647 compute_center_point_on_side(&vp,seg,side);
648 vm_vec_sub2(&vp,&ConsoleObject->pos);
650 vm_vec_sub(&upvec, &Vertices[Cursegp->verts[Side_to_verts[Curside][edgenum%4]]], &Vertices[Cursegp->verts[Side_to_verts[Curside][(edgenum+3)%4]]]);
653 vm_vector_2_matrix(&ConsoleObject->orient,&vp,&upvec,NULL);
654 // vm_vector_2_matrix(&ConsoleObject->orient,&vp,NULL,NULL);
656 obj_relink( ConsoleObject-Objects, SEG_PTR_2_NUM(seg) );
660 int SetPlayerFromCursegAndRotate()
662 move_player_2_segment_and_rotate(Cursegp,Curside);
663 Update_flags |= UF_ED_STATE_CHANGED | UF_GAME_VIEW_CHANGED;
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()
672 vms_vector view_vec,view_vec2,side_center;
673 vms_vector corner_v[4];
675 g3s_point corner_p[4];
677 fix max,view_dist=f1_0*10;
678 static int edgenum=0;
681 view_vec = Cursegp->sides[Curside].normals[0];
682 vm_vec_negate(&view_vec);
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);
688 vm_vec_sub(&upvec, &Vertices[Cursegp->verts[Side_to_verts[Curside][edgenum%4]]], &Vertices[Cursegp->verts[Side_to_verts[Curside][(edgenum+3)%4]]]);
691 vm_vector_2_matrix(&ConsoleObject->orient,&view_vec,&upvec,NULL);
693 gr_set_current_canvas(Canv_editor_game);
695 g3_set_view_matrix(&ConsoleObject->pos,&ConsoleObject->orient,Render_zoom);
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);
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);
708 //obj_relink(ConsoleObject-Objects, SEG_PTR_2_NUM(Cursegp) );
709 //update_object_seg(ConsoleObject); //might have backed right out of curseg
711 newseg = find_point_seg(&ConsoleObject->pos,SEG_PTR_2_NUM(Cursegp) );
713 obj_relink(ConsoleObject-Objects,newseg);
715 Update_flags |= UF_ED_STATE_CHANGED | UF_GAME_VIEW_CHANGED;
719 int ToggleLighting(void)
721 char outstr[80] = "[shift-L] ";
725 if (Lighting_on >= 2)
728 Update_flags |= UF_GAME_VIEW_CHANGED;
730 if (last_keypress == KEY_L + KEY_SHIFTED)
735 switch (Lighting_on) {
737 strcpy(&outstr[chindex],"Lighting off.");
740 strcpy(&outstr[chindex],"Static lighting.");
743 strcpy(&outstr[chindex],"Ship lighting.");
746 strcpy(&outstr[chindex],"Ship and static lighting.");
750 diagnostic_message(outstr);
755 void find_concave_segs();
757 int FindConcaveSegs()
761 Update_flags |= UF_ED_STATE_CHANGED; //list may have changed
769 grs_bitmap * save_bitmap;
771 // Save the current graphics state.
773 w = grd_curscreen->sc_canvas.cv_bitmap.bm_w;
774 h = grd_curscreen->sc_canvas.cv_bitmap.bm_h;
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 );
779 gr_set_mode( SM_ORIGINAL );
781 printf( "\n\nType EXIT to return to Inferno" );
786 ok = spawnl(P_WAIT,getenv("COMSPEC"), NULL );
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();
802 int ToggleOutlineMode()
805 mode=toggle_outline_mode();
809 if (last_keypress != KEY_O)
810 diagnostic_message("[O] Outline Mode ON.");
812 diagnostic_message("Outline Mode ON.");
816 if (last_keypress != KEY_O)
817 diagnostic_message("[O] Outline Mode OFF.");
819 diagnostic_message("Outline Mode OFF.");
822 Update_flags |= UF_GAME_VIEW_CHANGED;
826 //@@int do_reset_orient()
828 //@@ slew_reset_orient(SlewObj);
830 //@@ Update_flags |= UF_GAME_VIEW_CHANGED;
832 //@@ * (ubyte *) 0x417 &= ~0x20;
839 Render_zoom = fixmul(Render_zoom,68985);
840 Update_flags |= UF_GAME_VIEW_CHANGED;
846 Render_zoom = fixmul(Render_zoom,62259);
847 Update_flags |= UF_GAME_VIEW_CHANGED;
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; }
863 #define PAD_WIDTH1 (PAD_WIDTH + 7)
865 int editor_screen_open = 0;
867 //setup the editors windows, canvases, gadgets, etc.
868 //called whenever the editor screen is selected
869 void init_editor_screen()
873 if (editor_screen_open) return;
875 grd_curscreen->sc_canvas.cv_font = editor_font;
877 //create canvas for game on the editor screen
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);
883 //Editor renders into full (320x200) game screen
887 //do other editor screen setup
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 );
896 gr_set_curfont(editor_font);
897 gr_set_fontcolor( CBLACK, CWHITE );
899 EditorWindow = ui_open_window( 0 , 0, ED_SCREEN_W, ED_SCREEN_H, WIN_FILLED );
901 LargeViewBox = ui_add_gadget_userbox( EditorWindow,LVIEW_X,LVIEW_Y,LVIEW_W,LVIEW_H);
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);
907 ui_gadget_calc_keys(EditorWindow); //make tab work for all windows
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);
912 // GameViewBox->when_tab = GameViewBox->when_btab = (UI_GADGET *) LargeViewBox;
913 // LargeViewBox->when_tab = LargeViewBox->when_btab = (UI_GADGET *) GameViewBox;
915 // ui_gadget_calc_keys(EditorWindow); //make tab work for all windows
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 );
925 meddraw_init_views(LargeViewBox->canvas);
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 );
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 );
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 );
952 gr_set_curfont(editor_font);
955 // INIT TEXTURE STUFF
956 texpage_init( EditorWindow );
957 objpage_init( EditorWindow );
959 EditorWindow->keyboard_focus_gadget = (UI_GADGET *)LargeViewBox;
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;
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 );
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);
978 Update_flags = UF_ALL;
980 editor_screen_open = 1;
983 //shutdown ui on the editor screen
984 void close_editor_screen()
986 if (!editor_screen_open) return;
988 editor_screen_open = 0;
990 gr_free_sub_canvas(Pad_text_canvas);
992 ui_close_window(EditorWindow);
996 // CLOSE TEXTURE STUFF
1004 void med_show_warning(char *s)
1006 grs_canvas *save_canv=grd_curcanv;
1008 //gr_pal_fade_in(grd_curscreen->pal); //in case palette is blacked
1010 MessageBox(-2,-2,1,s,"OK");
1012 gr_set_current_canvas(save_canv);
1016 // Returns 1 if OK to trash current mine.
1023 x = nm_messagebox( "Warning!", 2, "Cancel", "OK", "You are about to lose work." );
1033 //called at the end of the program
1034 void close_editor() {
1040 gr_close_font(editor_font);
1042 gr_free_canvas(canv_offscreen); canv_offscreen = NULL;
1048 //variables for find segments process
1050 // ---------------------------------------------------------------------------------------------------
1051 // Subtract all elements in Found_segs from selected list.
1052 void subtract_found_segments_from_selected_list(void)
1056 for (f=0; f<N_found_segs; f++) {
1057 int foundnum = Found_segs[f];
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];
1069 // ---------------------------------------------------------------------------------------------------
1070 // Add all elements in Found_segs to selected list.
1071 void add_found_segments_to_selected_list(void) {
1074 for (f=0; f<N_found_segs; f++) {
1075 int foundnum = Found_segs[f];
1077 for (s=0; s<N_selected_segs; s++)
1078 if (Selected_segs[s] == foundnum)
1081 if (s == N_selected_segs)
1082 Selected_segs[N_selected_segs++] = foundnum;
1086 void gamestate_restore_check() {
1087 char Message[DIAGNOSTIC_MESSAGE_MAX];
1088 obj_position Save_position;
1090 if (gamestate_not_restored) {
1091 sprintf( Message, "Do you wish to restore game state?\n");
1093 if (MessageBox( -2, -2, 2, Message, "Yes", "No" )==1) {
1095 // Save current position
1096 Save_position.pos = ConsoleObject->pos;
1097 Save_position.orient = ConsoleObject->orient;
1098 Save_position.segnum = ConsoleObject->segnum;
1100 load_level("GAMESAVE.LVL");
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);
1109 gamestate_not_restored = 0;
1110 Update_flags |= UF_WORLD_CHANGED;
1113 gamestate_not_restored = 1;
1117 int RestoreGameState() {
1118 load_level("GAMESAVE.LVL");
1119 gamestate_not_restored = 0;
1121 mprintf((0, "Gamestate restored.\n"));
1122 editor_status("Gamestate restored.\n");
1124 Update_flags |= UF_WORLD_CHANGED;
1128 extern void check_wall_validity(void);
1130 // ---------------------------------------------------------------------------------------------------
1131 //this function is the editor. called when editor mode selected. runs until
1132 //game mode or exit selected
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
1146 restore_effect_bitmap_icons();
1148 if (!set_screen_mode(SCREEN_EDITOR)) {
1149 set_screen_mode(SCREEN_GAME);
1150 Function_mode=FMODE_GAME; //force back into game
1154 gr_set_current_canvas( NULL );
1155 gr_set_curfont(editor_font);
1157 //Editor renders into full (320x200) game screen
1159 set_warn_func(med_show_warning);
1161 keyd_repeat = 1; // Allow repeat in editor
1163 // _MARK_("start of editor");//Nuked to compile -KRB
1167 ui_reset_idle_seconds();
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
1174 Viewer = ConsoleObject;
1175 slew_init(ConsoleObject);
1177 Update_flags = UF_ALL;
1179 medlisp_update_screen();
1181 //set the wire-frame window to be the current view
1182 current_view = &LargeView;
1187 //gr_pal_fade_in( grd_curscreen->pal );
1190 w = GameViewBox->canvas->cv_bitmap.bm_w;
1191 h = GameViewBox->canvas->cv_bitmap.bm_h;
1193 savedbitmap = gr_create_bitmap(w, h );
1195 gr_bm_ubitblt( w, h, 0, 0, 0, 0, &GameViewBox->canvas->cv_bitmap, savedbitmap );
1197 gr_set_current_canvas( GameViewBox->canvas );
1198 gr_set_curfont(editor_font);
1199 //gr_setcolor( CBLACK );
1200 //gr_deaccent_canvas();
1205 gr_set_curfont(editor_font);
1206 ui_pad_goto(padnum);
1208 gamestate_restore_check();
1210 while (Function_mode == FMODE_EDITOR) {
1212 gr_set_curfont(editor_font);
1213 info_display_all(EditorWindow);
1217 // Update the windows
1219 // Only update if there is no key waiting and we're not in
1221 if (!key_peekkey()) //-- && (MacroStatus != UI_STATUS_FASTPLAY))
1222 medlisp_update_screen();
1225 gr_set_curfont(editor_font);
1227 last_keypress &= ~KEY_DEBUGGED; // mask off delete key bit which has no function in editor.
1228 ui_window_do_gadgets(EditorWindow);
1232 do_trigger_window();
1233 do_hostage_window();
1234 do_centers_window();
1235 check_wall_validity();
1236 Assert(Num_walls>=0);
1238 if (Gameview_lockstep) {
1239 static segment *old_cursegp=NULL;
1240 static int old_curside=-1;
1242 if (old_cursegp!=Cursegp || old_curside!=Curside) {
1243 SetPlayerFromCursegMinusOne();
1244 old_cursegp = Cursegp;
1245 old_curside = Curside;
1249 // mprintf((0, "%d ", ui_get_idle_seconds() ));
1251 if ( ui_get_idle_seconds() > COMPRESS_INTERVAL )
1253 med_compress_mine();
1254 ui_reset_idle_seconds();
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 );
1265 // Remove keys used for slew
1266 switch(last_keypress)
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;
1289 gr_set_curfont(editor_font);
1290 menubar_do( last_keypress );
1292 //=================== DO FUNCTIONS ====================
1294 if ( KeyFunction[ last_keypress ] != NULL ) {
1295 KeyFunction[last_keypress]();
1298 switch (last_keypress)
1311 case KEY_SHIFTED + KEY_L:
1315 render_3d_in_big_window = !render_3d_in_big_window;
1316 Update_flags |= UF_ALL;
1321 GetKeyDescription( kdesc, last_keypress );
1322 editor_status("Error: %s isn't bound to anything.", kdesc );
1326 //================================================================
1330 close_editor_screen();
1331 Function_mode=FMODE_EXIT;
1332 gr_free_bitmap( savedbitmap );
1336 if (ModeFlag==2) //-- && MacroStatus==UI_STATUS_NORMAL )
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 );
1345 if (ModeFlag==3) //-- && MacroStatus==UI_STATUS_NORMAL )
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 );
1355 // if (CurWindow->keyboard_focus_gadget == (UI_GADGET *)GameViewBox) current_view=NULL;
1356 // if (CurWindow->keyboard_focus_gadget == (UI_GADGET *)GroupViewBox) current_view=NULL;
1358 new_cv = current_view ;
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;
1366 if (new_cv != current_view ) {
1367 current_view->ev_changed = 1;
1368 new_cv->ev_changed = 1;
1369 current_view = new_cv;
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;
1387 // Process selection of Cursegp using mouse.
1388 if (LargeViewBox->mouse_onme && LargeViewBox->b1_clicked && !render_3d_in_big_window)
1391 xcrd = LargeViewBox->b1_drag_x1;
1392 ycrd = LargeViewBox->b1_drag_y1;
1394 find_segments(xcrd,ycrd,LargeViewBox->canvas,&LargeView,Cursegp,Big_depth); // Sets globals N_found_segs, Found_segs
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();
1400 add_found_segments_to_selected_list();
1402 Found_seg_index = 0;
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);
1412 Update_flags |= UF_ED_STATE_CHANGED | UF_VIEWPOINT_MOVED;
1415 if (GameViewBox->mouse_onme && GameViewBox->b1_dragging) {
1417 x = GameViewBox->b1_drag_x2;
1418 y = GameViewBox->b1_drag_y2;
1421 gr_set_current_canvas( GameViewBox->canvas );
1423 gr_rect( x-1, y-1, x+1, y+1 );
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)) {
1435 int seg,side,face,poly,tmap;
1437 if (render_3d_in_big_window) {
1438 xcrd = LargeViewBox->b1_drag_x1;
1439 ycrd = LargeViewBox->b1_drag_y1;
1442 xcrd = GameViewBox->b1_drag_x1;
1443 ycrd = GameViewBox->b1_drag_y1;
1448 if (find_seg_side_face(xcrd,ycrd,&seg,&side,&face,&poly)) {
1451 if (seg<0) { //found an object
1453 Cur_object_index = -seg-1;
1454 editor_status("Object %d selected.",Cur_object_index);
1456 Update_flags |= UF_ED_STATE_CHANGED;
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];
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] ) {
1473 move_object_to_mouse_click();
1475 Cursegp = &Segments[seg];
1477 med_create_new_segment_from_cursegp();
1478 editor_status("Curseg and curside selected");
1482 Update_flags |= UF_ED_STATE_CHANGED;
1485 editor_status("Click on non-texture ingored");
1489 // Allow specification of LargeView using mouse
1490 if (keyd_pressed[ KEY_LCTRL ] || keyd_pressed[ KEY_RCTRL ]) {
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
1503 if ( keyd_pressed[ KEY_Z ] ) {
1505 if ( Mouse.dy!=0 ) {
1506 current_view->ev_dist += Mouse.dy*10000;
1507 current_view->ev_changed = 1;
1515 // _MARK_("end of editor");//Nuked to compile -KRB
1517 clear_warn_func(med_show_warning);
1519 //kill our camera object
1521 Viewer = ConsoleObject; //reset viewer
1522 //@@obj_delete(camera_objnum);
1524 padnum = ui_pad_get_current();
1532 void test_fade(void)
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];
1541 printf("[%3i %3i %3i] ",gr_palette[3*col],gr_palette[3*col+1],gr_palette[3*col+2]);
1549 void dump_stuff(void)
1553 printf("Palette:\n");
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]);
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]);
1568 printf("Colors indexed by intensity:\n");
1569 printf(". = change from previous, * = no change\n");
1570 for (j=0; j<256; j++) {
1573 for (i=0; i<16; i++) {
1574 int c = gr_fade_table[i*256 + j];
1575 if (c == prev_color)
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]);
1595 sprintf(mystr,"mark %i start",Mark_count);
1596 // _MARK_(mystr);//Nuked to compile -KRB
1604 sprintf(mystr,"mark %i end",Mark_count);
1606 // _MARK_(mystr);//Nuked to compile -KRB