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 $
16 * $Author: schaffner $
17 * $Date: 2004-08-29 14:03:51 $
19 * Editor loop for Inferno
21 * $Log: not supported by cvs2svn $
22 * Revision 1.1 2001/10/25 02:27:17 bradleyb
23 * attempt at support for editor, makefile changes, etc
25 * Revision 1.1.1.1 1999/06/14 22:03:43 donut
26 * Import of d1x 1.37 source.
36 #define DIAGNOSTIC_MESSAGE_MAX 90
37 #define EDITOR_STATUS_MESSAGE_DURATION 4 // Shows for 3+..4 seconds
50 //#define INCLUDE_XLISP
57 //#include "gamemine.h"
85 #include "texpage.h" // Textue selection paging stuff
86 #include "objpage.h" // Object selection paging stuff
102 //#include <wsample.h> //should come after inferno.h to get mark setting //Not included here.
104 #define COMPRESS_INTERVAL 5 // seconds
106 //char *undo_status[128];
110 //these are instances of canvases, pointed to by variables below
111 grs_canvas _canv_editor_game; //the game on the editor screen
113 //these are pointers to our canvases
114 grs_canvas *Canv_editor; //the editor screen
115 grs_canvas *Canv_editor_game=&_canv_editor_game; //the game on the editor screen
117 grs_canvas *canv_offscreen; //for off-screen rendering
118 grs_canvas *Pad_text_canvas; // Keypad text
120 grs_font *editor_font=NULL;
122 //where the editor is looking
123 vms_vector Ed_view_target={0,0,0};
125 int gamestate_not_restored = 0;
127 UI_WINDOW * EditorWindow;
129 int Large_view_index = -1;
131 UI_GADGET_USERBOX * GameViewBox;
132 UI_GADGET_USERBOX * LargeViewBox;
133 UI_GADGET_USERBOX * GroupViewBox;
136 UI_GADGET_USERBOX * TopViewBox;
137 UI_GADGET_USERBOX * FrontViewBox;
138 UI_GADGET_USERBOX * RightViewBox;
141 UI_GADGET_ICON * ViewIcon;
142 UI_GADGET_ICON * AllIcon;
143 UI_GADGET_ICON * AxesIcon;
144 UI_GADGET_ICON * ChaseIcon;
145 UI_GADGET_ICON * OutlineIcon;
146 UI_GADGET_ICON * LockIcon;
147 //-NOLIGHTICON- UI_GADGET_ICON * LightIcon;
149 UI_EVENT * DemoBuffer = NULL;
151 //grs_canvas * BigCanvas[2];
152 //int CurrentBigCanvas = 0;
153 //int BigCanvasFirstTime = 1;
155 int Found_seg_index=0; // Index in Found_segs corresponding to Cursegp
158 void print_status_bar( char message[DIAGNOSTIC_MESSAGE_MAX] ) {
161 gr_set_current_canvas( NULL );
162 gr_set_curfont(editor_font);
163 gr_set_fontcolor( CBLACK, CGREY );
164 gr_get_string_size( message, &w, &h, &aw );
165 gr_string( 4, 583, message );
166 gr_set_fontcolor( CBLACK, CWHITE );
167 gr_setcolor( CGREY );
168 gr_rect( 4+w, 583, 799, 599 );
171 void print_diagnostic( char message[DIAGNOSTIC_MESSAGE_MAX] ) {
174 gr_set_current_canvas( NULL );
175 gr_set_curfont(editor_font);
176 gr_set_fontcolor( CBLACK, CGREY );
177 gr_get_string_size( message, &w, &h, &aw );
178 gr_string( 4, 583, message );
179 gr_set_fontcolor( CBLACK, CWHITE );
180 gr_setcolor( CGREY );
181 gr_rect( 4+w, 583, 799, 599 );
184 static char status_line[DIAGNOSTIC_MESSAGE_MAX];
186 struct tm Editor_status_last_time;
188 void editor_status( const char *format, ... )
192 va_start(ap, format);
193 vsprintf(status_line, format, ap);
196 print_status_bar(status_line);
198 Editor_status_last_time = Editor_time_of_day;
202 // int tm_sec; /* seconds after the minute -- [0,61] */
203 // int tm_min; /* minutes after the hour -- [0,59] */
204 // int tm_hour; /* hours after midnight -- [0,23] */
205 // int tm_mday; /* day of the month -- [1,31] */
206 // int tm_mon; /* months since January -- [0,11] */
207 // int tm_year; /* years since 1900 */
208 // int tm_wday; /* days since Sunday -- [0,6] */
209 // int tm_yday; /* days since January 1 -- [0,365]*/
210 // int tm_isdst; /* Daylight Savings Time flag */
212 void clear_editor_status(void)
214 int cur_time = Editor_time_of_day.tm_hour * 3600 + Editor_time_of_day.tm_min*60 + Editor_time_of_day.tm_sec;
215 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;
217 if (cur_time > erase_time) {
219 char message[DIAGNOSTIC_MESSAGE_MAX];
221 for (i=0; i<DIAGNOSTIC_MESSAGE_MAX-1; i++)
225 print_status_bar(message);
226 Editor_status_last_time.tm_hour = 99;
231 void diagnostic_message( const char *format, ... )
233 char diag_line[DIAGNOSTIC_MESSAGE_MAX];
237 va_start(ap, format);
238 vsprintf(diag_line, format, ap);
241 editor_status(diag_line);
245 static char sub_status_line[DIAGNOSTIC_MESSAGE_MAX];
247 void editor_sub_status( const char *format, ... )
252 va_start(ap, format);
253 vsprintf(sub_status_line, format, ap);
256 gr_set_current_canvas( NULL );
257 gr_set_curfont(editor_font);
258 gr_set_fontcolor( BM_XRGB(0,0,31), CGREY );
259 gr_get_string_size( sub_status_line, &w, &h, &aw );
260 gr_string( 500, 583, sub_status_line );
261 gr_set_fontcolor( CBLACK, CWHITE );
262 gr_setcolor( CGREY );
263 gr_rect( 500+w, 583, 799, 599 );
266 int DropIntoDebugger()
290 int GotoGameCommon(int mode) {
293 //@@ init_player_stats();
295 //@@ Player_init.pos = Player->pos;
296 //@@ Player_init.orient = Player->orient;
297 //@@ Player_init.segnum = Player->segnum;
299 // -- must always save gamesave.sav because the restore-objects code relies on it
300 // -- that code could be made smarter and use the original file, if appropriate.
302 if (gamestate_not_restored == 0) {
303 gamestate_not_restored = 1;
304 save_level("GAMESAVE.LVL");
305 editor_status("Gamestate saved.\n");
306 mprintf((0, "Gamestate saved.\n"));
309 ai_reset_all_paths();
319 return GotoGameCommon(3);
324 return GotoGameCommon(2);
328 void ReadLispMacro( FILE * file, char * buffer )
336 fscanf( file, " { %s } ", buffer );
344 if ( c == '(' ) pcount++;
345 if ( c == ')' ) break;
353 static int (*KeyFunction[2048])();
364 MALLOC( LispCommand, char, DIAGNOSTIC_MESSAGE_MAX );
366 for (i=0; i<2048; i++ )
367 KeyFunction[i] = NULL;
369 keyfile = fopen( "GLOBAL.KEY", "rt" );
372 while (fscanf( keyfile, " %s %s ", keypress, LispCommand ) != EOF )
374 //ReadLispMacro( keyfile, LispCommand );
376 if ( (key=DecodeKeyText( keypress ))!= -1 )
379 KeyFunction[key] = func_get( LispCommand, &np );
381 Error( "Bad key %s in GLOBAL.KEY!", keypress );
395 init_med_functions(); // Must be called before medlisp_init
397 ui_pad_read( 0, "segmove.pad" );
398 ui_pad_read( 1, "segsize.pad" );
399 ui_pad_read( 2, "curve.pad" );
400 ui_pad_read( 3, "texture.pad" );
401 ui_pad_read( 4, "object.pad" );
402 ui_pad_read( 5, "objmov.pad" );
403 ui_pad_read( 6, "group.pad" );
404 ui_pad_read( 7, "lighting.pad" );
405 ui_pad_read( 8, "test.pad" );
409 editor_font = gr_init_font( "pc8x16.fnt" );
411 menubar_init( "MED.MNU" );
413 canv_offscreen = gr_create_canvas(LVIEW_W,LVIEW_H);
415 Draw_all_segments = 1; // Say draw all segments, not just connected ones
419 // atexit(close_editor);
421 Clear_window = 1; // do full window clear.
426 MessageBox( -2, -2, 1, "INFERNO Mine Editor\n\n" \
427 "Copyright (c) 1993 Parallax Software Corp.",
432 void move_player_2_segment(segment *seg,int side);
434 int SetPlayerFromCurseg()
436 move_player_2_segment(Cursegp,Curside);
437 Update_flags |= UF_ED_STATE_CHANGED | UF_GAME_VIEW_CHANGED;
441 int fuelcen_create_from_curseg()
443 Cursegp->special = SEGMENT_IS_FUELCEN;
444 fuelcen_activate( Cursegp, Cursegp->special);
448 int repaircen_create_from_curseg()
450 Int3(); // -- no longer supported!
451 // Cursegp->special = SEGMENT_IS_REPAIRCEN;
452 // fuelcen_activate( Cursegp, Cursegp->special);
456 int controlcen_create_from_curseg()
458 Cursegp->special = SEGMENT_IS_CONTROLCEN;
459 fuelcen_activate( Cursegp, Cursegp->special);
463 int robotmaker_create_from_curseg()
465 Cursegp->special = SEGMENT_IS_ROBOTMAKER;
466 fuelcen_activate( Cursegp, Cursegp->special);
470 int fuelcen_reset_all() {
475 int fuelcen_delete_from_curseg() {
476 fuelcen_delete( Cursegp );
481 //@@//this routine places the viewer in the center of the side opposite to curside,
482 //@@//with the view toward the center of curside
483 //@@int SetPlayerFromCursegMinusOne()
487 //@@// int newseg,newside;
488 //@@// get_previous_segment(SEG_PTR_2_NUM(Cursegp),Curside,&newseg,&newside);
489 //@@// move_player_2_segment(&Segments[newseg],newside);
491 //@@ med_compute_center_point_on_side(&Player->obj_position,Cursegp,Side_opposite[Curside]);
492 //@@ med_compute_center_point_on_side(&vp,Cursegp,Curside);
493 //@@ vm_vec_sub2(&vp,&Player->position);
494 //@@ vm_vector_2_matrix(&Player->orient,&vp,NULL,NULL);
496 //@@ Player->seg = SEG_PTR_2_NUM(Cursegp);
498 //@@ Update_flags |= UF_GAME_VIEW_CHANGED;
502 //this constant determines how much of the window will be occupied by the
503 //viewed side when SetPlayerFromCursegMinusOne() is called. It actually
504 //determine how from from the center of the window the farthest point will be
505 #define SIDE_VIEW_FRAC (f1_0*8/10) //80%
508 void move_player_2_segment_and_rotate(segment *seg,int side)
512 static int edgenum=0;
514 compute_segment_center(&ConsoleObject->pos,seg);
515 compute_center_point_on_side(&vp,seg,side);
516 vm_vec_sub2(&vp,&ConsoleObject->pos);
518 vm_vec_sub(&upvec, &Vertices[Cursegp->verts[Side_to_verts[Curside][edgenum%4]]], &Vertices[Cursegp->verts[Side_to_verts[Curside][(edgenum+3)%4]]]);
521 vm_vector_2_matrix(&ConsoleObject->orient,&vp,&upvec,NULL);
522 // vm_vector_2_matrix(&ConsoleObject->orient,&vp,NULL,NULL);
524 obj_relink( ConsoleObject-Objects, SEG_PTR_2_NUM(seg) );
528 int SetPlayerFromCursegAndRotate()
530 move_player_2_segment_and_rotate(Cursegp,Curside);
531 Update_flags |= UF_ED_STATE_CHANGED | UF_GAME_VIEW_CHANGED;
536 //sets the player facing curseg/curside, normal to face0 of curside, and
537 //far enough away to see all of curside
538 int SetPlayerFromCursegMinusOne()
540 vms_vector view_vec,view_vec2,side_center;
541 vms_vector corner_v[4];
543 g3s_point corner_p[4];
545 fix max,view_dist=f1_0*10;
546 static int edgenum=0;
549 view_vec = Cursegp->sides[Curside].normals[0];
550 vm_vec_negate(&view_vec);
552 compute_center_point_on_side(&side_center,Cursegp,Curside);
553 vm_vec_copy_scale(&view_vec2,&view_vec,view_dist);
554 vm_vec_sub(&ConsoleObject->pos,&side_center,&view_vec2);
556 vm_vec_sub(&upvec, &Vertices[Cursegp->verts[Side_to_verts[Curside][edgenum%4]]], &Vertices[Cursegp->verts[Side_to_verts[Curside][(edgenum+3)%4]]]);
559 vm_vector_2_matrix(&ConsoleObject->orient,&view_vec,&upvec,NULL);
561 gr_set_current_canvas(Canv_editor_game);
563 g3_set_view_matrix(&ConsoleObject->pos,&ConsoleObject->orient,Render_zoom);
565 for (i=max=0;i<4;i++) {
566 corner_v[i] = Vertices[Cursegp->verts[Side_to_verts[Curside][i]]];
567 g3_rotate_point(&corner_p[i],&corner_v[i]);
568 if (labs(corner_p[i].p3_x) > max) max = labs(corner_p[i].p3_x);
569 if (labs(corner_p[i].p3_y) > max) max = labs(corner_p[i].p3_y);
572 view_dist = fixmul(view_dist,fixdiv(fixdiv(max,SIDE_VIEW_FRAC),corner_p[0].p3_z));
573 vm_vec_copy_scale(&view_vec2,&view_vec,view_dist);
574 vm_vec_sub(&ConsoleObject->pos,&side_center,&view_vec2);
576 //obj_relink(ConsoleObject-Objects, SEG_PTR_2_NUM(Cursegp) );
577 //update_object_seg(ConsoleObject); //might have backed right out of curseg
579 newseg = find_point_seg(&ConsoleObject->pos,SEG_PTR_2_NUM(Cursegp) );
581 obj_relink(ConsoleObject-Objects,newseg);
583 Update_flags |= UF_ED_STATE_CHANGED | UF_GAME_VIEW_CHANGED;
587 int ToggleLighting(void)
589 char outstr[80] = "[shift-L] ";
593 if (Lighting_on >= 2)
596 Update_flags |= UF_GAME_VIEW_CHANGED;
598 if (last_keypress == KEY_L + KEY_SHIFTED)
603 switch (Lighting_on) {
605 strcpy(&outstr[chindex],"Lighting off.");
608 strcpy(&outstr[chindex],"Static lighting.");
611 strcpy(&outstr[chindex],"Ship lighting.");
614 strcpy(&outstr[chindex],"Ship and static lighting.");
618 diagnostic_message(outstr);
623 void find_concave_segs();
625 int FindConcaveSegs()
629 Update_flags |= UF_ED_STATE_CHANGED; //list may have changed
637 grs_bitmap * save_bitmap;
639 // Save the current graphics state.
641 w = grd_curscreen->sc_canvas.cv_bitmap.bm_w;
642 h = grd_curscreen->sc_canvas.cv_bitmap.bm_h;
644 save_bitmap = gr_create_bitmap( w, h );
645 gr_bm_ubitblt(w, h, 0, 0, 0, 0, &(grd_curscreen->sc_canvas.cv_bitmap), save_bitmap );
647 gr_set_mode( SM_ORIGINAL );
649 printf( "\n\nType EXIT to return to Inferno" );
654 ok = spawnl(P_WAIT,getenv("COMSPEC"), NULL );
660 gr_set_mode(grd_curscreen->sc_mode);
661 gr_bm_ubitblt(w, h, 0, 0, 0, 0, save_bitmap, &(grd_curscreen->sc_canvas.cv_bitmap));
662 gr_free_bitmap( save_bitmap );
663 //gr_pal_setblock( 0, 256, grd_curscreen->pal );
664 //gr_use_palette_table();
670 int ToggleOutlineMode()
673 mode=toggle_outline_mode();
677 if (last_keypress != KEY_O)
678 diagnostic_message("[O] Outline Mode ON.");
680 diagnostic_message("Outline Mode ON.");
684 if (last_keypress != KEY_O)
685 diagnostic_message("[O] Outline Mode OFF.");
687 diagnostic_message("Outline Mode OFF.");
690 Update_flags |= UF_GAME_VIEW_CHANGED;
694 //@@int do_reset_orient()
696 //@@ slew_reset_orient(SlewObj);
698 //@@ Update_flags |= UF_GAME_VIEW_CHANGED;
700 //@@ * (ubyte *) 0x417 &= ~0x20;
707 Render_zoom = fixmul(Render_zoom,68985);
708 Update_flags |= UF_GAME_VIEW_CHANGED;
714 Render_zoom = fixmul(Render_zoom,62259);
715 Update_flags |= UF_GAME_VIEW_CHANGED;
720 int med_keypad_goto_0() { ui_pad_goto(0); return 0; }
721 int med_keypad_goto_1() { ui_pad_goto(1); return 0; }
722 int med_keypad_goto_2() { ui_pad_goto(2); return 0; }
723 int med_keypad_goto_3() { ui_pad_goto(3); return 0; }
724 int med_keypad_goto_4() { ui_pad_goto(4); return 0; }
725 int med_keypad_goto_5() { ui_pad_goto(5); return 0; }
726 int med_keypad_goto_6() { ui_pad_goto(6); return 0; }
727 int med_keypad_goto_7() { ui_pad_goto(7); return 0; }
728 int med_keypad_goto_8() { ui_pad_goto(8); return 0; }
731 #define PAD_WIDTH1 (PAD_WIDTH + 7)
733 int editor_screen_open = 0;
735 //setup the editors windows, canvases, gadgets, etc.
736 //called whenever the editor screen is selected
737 void init_editor_screen()
741 if (editor_screen_open) return;
743 grd_curscreen->sc_canvas.cv_font = editor_font;
745 //create canvas for game on the editor screen
747 gr_set_current_canvas(Canv_editor);
748 Canv_editor->cv_font = editor_font;
749 gr_init_sub_canvas(Canv_editor_game,Canv_editor,GAMEVIEW_X,GAMEVIEW_Y,GAMEVIEW_W,GAMEVIEW_H);
751 //Editor renders into full (320x200) game screen
755 //do other editor screen setup
757 // Since the palette might have changed, find some good colors...
758 CBLACK = gr_find_closest_color( 1, 1, 1 );
759 CGREY = gr_find_closest_color( 28, 28, 28 );
760 CWHITE = gr_find_closest_color( 38, 38, 38 );
761 CBRIGHT = gr_find_closest_color( 60, 60, 60 );
762 CRED = gr_find_closest_color( 63, 0, 0 );
764 gr_set_curfont(editor_font);
765 gr_set_fontcolor( CBLACK, CWHITE );
767 EditorWindow = ui_open_window( 0 , 0, ED_SCREEN_W, ED_SCREEN_H, WIN_FILLED );
769 LargeViewBox = ui_add_gadget_userbox( EditorWindow,LVIEW_X,LVIEW_Y,LVIEW_W,LVIEW_H);
771 TopViewBox = ui_add_gadget_userbox( EditorWindow,TVIEW_X,TVIEW_Y,TVIEW_W,TVIEW_H);
772 FrontViewBox = ui_add_gadget_userbox( EditorWindow,FVIEW_X,FVIEW_Y,FVIEW_W,FVIEW_H);
773 RightViewBox = ui_add_gadget_userbox( EditorWindow,RVIEW_X,RVIEW_Y,RVIEW_W,RVIEW_H);
775 ui_gadget_calc_keys(EditorWindow); //make tab work for all windows
777 GameViewBox = ui_add_gadget_userbox( EditorWindow, GAMEVIEW_X, GAMEVIEW_Y, GAMEVIEW_W, GAMEVIEW_H );
778 // GroupViewBox = ui_add_gadget_userbox( EditorWindow,GVIEW_X,GVIEW_Y,GVIEW_W,GVIEW_H);
780 // GameViewBox->when_tab = GameViewBox->when_btab = (UI_GADGET *) LargeViewBox;
781 // LargeViewBox->when_tab = LargeViewBox->when_btab = (UI_GADGET *) GameViewBox;
783 // ui_gadget_calc_keys(EditorWindow); //make tab work for all windows
785 ViewIcon = ui_add_gadget_icon( EditorWindow, "Lock\nview", 455,25+530, 40, 22, KEY_V+KEY_CTRLED, ToggleLockViewToCursegp );
786 AllIcon = ui_add_gadget_icon( EditorWindow, "Draw\nall", 500,25+530, 40, 22, KEY_A+KEY_CTRLED, ToggleDrawAllSegments );
787 AxesIcon = ui_add_gadget_icon( EditorWindow, "Coord\naxes",545,25+530, 40, 22, KEY_D+KEY_CTRLED, ToggleCoordAxes );
788 //-NOLIGHTICON- LightIcon = ui_add_gadget_icon( EditorWindow, "Light\ning", 590,25+530, 40, 22, KEY_L+KEY_SHIFTED,ToggleLighting );
789 ChaseIcon = ui_add_gadget_icon( EditorWindow, "Chase\nmode",635,25+530, 40, 22, -1, ToggleChaseMode );
790 OutlineIcon = ui_add_gadget_icon( EditorWindow, "Out\nline", 680,25+530, 40, 22, KEY_O, ToggleOutlineMode );
791 LockIcon = ui_add_gadget_icon( EditorWindow, "Lock\nstep", 725,25+530, 40, 22, KEY_L, ToggleLockstep );
793 meddraw_init_views(LargeViewBox->canvas);
795 //ui_add_gadget_button( EditorWindow, 460, 510, 50, 25, "Quit", ExitEditor );
796 //ui_add_gadget_button( EditorWindow, 520, 510, 50, 25, "Lisp", CallLisp );
797 //ui_add_gadget_button( EditorWindow, 580, 510, 50, 25, "Mine", MineMenu );
798 //ui_add_gadget_button( EditorWindow, 640, 510, 50, 25, "Help", DoHelp );
799 //ui_add_gadget_button( EditorWindow, 460, 540, 50, 25, "Macro", MacroMenu );
800 //ui_add_gadget_button( EditorWindow, 520, 540, 50, 25, "About", ShowAbout );
801 //ui_add_gadget_button( EditorWindow, 640, 540, 50, 25, "Shell", DosShell );
803 ui_pad_activate( EditorWindow, PAD_X, PAD_Y );
804 Pad_text_canvas = gr_create_sub_canvas(Canv_editor, PAD_X + 250, PAD_Y + 8, 180, 160);
805 ui_add_gadget_button( EditorWindow, PAD_X+6, PAD_Y+(30*5)+22, PAD_WIDTH, 20, "<<", med_keypad_goto_prev );
806 ui_add_gadget_button( EditorWindow, PAD_X+PAD_WIDTH1+6, PAD_Y+(30*5)+22, PAD_WIDTH, 20, ">>", med_keypad_goto_next );
809 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 );
810 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 );
811 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 );
812 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 );
813 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 );
814 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 );
815 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 );
816 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 );
817 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 );
820 gr_set_curfont(editor_font);
823 // INIT TEXTURE STUFF
824 texpage_init( EditorWindow );
825 objpage_init( EditorWindow );
827 EditorWindow->keyboard_focus_gadget = (UI_GADGET *)LargeViewBox;
829 canv_offscreen->cv_font = grd_curscreen->sc_canvas.cv_font;
830 // BigCanvas[0]->cv_font = grd_curscreen->sc_canvas.cv_font;
831 // BigCanvas[1]->cv_font = grd_curscreen->sc_canvas.cv_font;
832 // BigCanvasFirstTime = 1;
835 gr_set_current_canvas( NULL );
836 gr_setcolor( CGREY );
837 gr_rect(STATUS_X,STATUS_Y,STATUS_X+STATUS_W-1,STATUS_Y+STATUS_H-1); //0, 582, 799, 599 );
840 // gr_set_current_canvas( NULL );
841 // gr_setcolor( CBRIGHT );
842 // gr_rect( 528, 2, 798, 22);
843 // gr_setcolor( CGREY);
844 // gr_rect( 530, 2, 799, 20);
846 Update_flags = UF_ALL;
848 editor_screen_open = 1;
851 //shutdown ui on the editor screen
852 void close_editor_screen()
854 if (!editor_screen_open) return;
856 editor_screen_open = 0;
858 gr_free_sub_canvas(Pad_text_canvas);
860 ui_close_window(EditorWindow);
864 // CLOSE TEXTURE STUFF
872 void med_show_warning(char *s)
874 grs_canvas *save_canv=grd_curcanv;
876 //gr_pal_fade_in(grd_curscreen->pal); //in case palette is blacked
878 MessageBox(-2,-2,1,s,"OK");
880 gr_set_current_canvas(save_canv);
884 // Returns 1 if OK to trash current mine.
891 x = nm_messagebox( "Warning!", 2, "Cancel", "OK", "You are about to lose work." );
901 //called at the end of the program
902 void close_editor() {
908 gr_close_font(editor_font);
910 gr_free_canvas(canv_offscreen); canv_offscreen = NULL;
916 //variables for find segments process
918 // ---------------------------------------------------------------------------------------------------
919 // Subtract all elements in Found_segs from selected list.
920 void subtract_found_segments_from_selected_list(void)
924 for (f=0; f<N_found_segs; f++) {
925 int foundnum = Found_segs[f];
927 for (s=0; s<N_selected_segs; s++) {
928 if (Selected_segs[s] == foundnum) {
929 Selected_segs[s] = Selected_segs[N_selected_segs-1];
937 // ---------------------------------------------------------------------------------------------------
938 // Add all elements in Found_segs to selected list.
939 void add_found_segments_to_selected_list(void) {
942 for (f=0; f<N_found_segs; f++) {
943 int foundnum = Found_segs[f];
945 for (s=0; s<N_selected_segs; s++)
946 if (Selected_segs[s] == foundnum)
949 if (s == N_selected_segs)
950 Selected_segs[N_selected_segs++] = foundnum;
954 void gamestate_restore_check() {
955 char Message[DIAGNOSTIC_MESSAGE_MAX];
956 obj_position Save_position;
958 if (gamestate_not_restored) {
959 sprintf( Message, "Do you wish to restore game state?\n");
961 if (MessageBox( -2, -2, 2, Message, "Yes", "No" )==1) {
963 // Save current position
964 Save_position.pos = ConsoleObject->pos;
965 Save_position.orient = ConsoleObject->orient;
966 Save_position.segnum = ConsoleObject->segnum;
968 load_level("GAMESAVE.LVL");
970 // Restore current position
971 if (Save_position.segnum <= Highest_segment_index) {
972 ConsoleObject->pos = Save_position.pos;
973 ConsoleObject->orient = Save_position.orient;
974 obj_relink(ConsoleObject-Objects,Save_position.segnum);
977 gamestate_not_restored = 0;
978 Update_flags |= UF_WORLD_CHANGED;
981 gamestate_not_restored = 1;
985 int RestoreGameState() {
986 load_level("GAMESAVE.LVL");
987 gamestate_not_restored = 0;
989 mprintf((0, "Gamestate restored.\n"));
990 editor_status("Gamestate restored.\n");
992 Update_flags |= UF_WORLD_CHANGED;
996 extern void check_wall_validity(void);
998 // ---------------------------------------------------------------------------------------------------
999 //this function is the editor. called when editor mode selected. runs until
1000 //game mode or exit selected
1004 grs_bitmap * savedbitmap;
1005 editor_view *new_cv;
1006 static int padnum=0;
1007 vms_matrix MouseRotMat,tempm;
1008 //@@short camera_objnum; //a camera for viewing
1014 restore_effect_bitmap_icons();
1016 if (!set_screen_mode(SCREEN_EDITOR)) {
1017 set_screen_mode(SCREEN_GAME);
1018 Function_mode=FMODE_GAME; //force back into game
1022 gr_set_current_canvas( NULL );
1023 gr_set_curfont(editor_font);
1025 //Editor renders into full (320x200) game screen
1027 set_warn_func(med_show_warning);
1029 keyd_repeat = 1; // Allow repeat in editor
1031 // _MARK_("start of editor");//Nuked to compile -KRB
1035 ui_reset_idle_seconds();
1037 //@@ //create a camera for viewing in the editor. copy position from ConsoleObject
1038 //@@ camera_objnum = obj_create(OBJ_CAMERA,0,ConsoleObject->segnum,&ConsoleObject->pos,&ConsoleObject->orient,0);
1039 //@@ Viewer = &Objects[camera_objnum];
1040 //@@ slew_init(Viewer); //camera is slewing
1042 Viewer = ConsoleObject;
1043 slew_init(ConsoleObject);
1045 Update_flags = UF_ALL;
1047 medlisp_update_screen();
1049 //set the wire-frame window to be the current view
1050 current_view = &LargeView;
1055 //gr_pal_fade_in( grd_curscreen->pal );
1058 w = GameViewBox->canvas->cv_bitmap.bm_w;
1059 h = GameViewBox->canvas->cv_bitmap.bm_h;
1061 savedbitmap = gr_create_bitmap(w, h );
1063 gr_bm_ubitblt( w, h, 0, 0, 0, 0, &GameViewBox->canvas->cv_bitmap, savedbitmap );
1065 gr_set_current_canvas( GameViewBox->canvas );
1066 gr_set_curfont(editor_font);
1067 //gr_setcolor( CBLACK );
1068 //gr_deaccent_canvas();
1073 gr_set_curfont(editor_font);
1074 ui_pad_goto(padnum);
1076 gamestate_restore_check();
1078 while (Function_mode == FMODE_EDITOR) {
1080 gr_set_curfont(editor_font);
1081 info_display_all(EditorWindow);
1085 // Update the windows
1087 // Only update if there is no key waiting and we're not in
1089 if (!key_peekkey()) //-- && (MacroStatus != UI_STATUS_FASTPLAY))
1090 medlisp_update_screen();
1093 gr_set_curfont(editor_font);
1095 last_keypress &= ~KEY_DEBUGGED; // mask off delete key bit which has no function in editor.
1096 ui_window_do_gadgets(EditorWindow);
1100 do_trigger_window();
1101 do_hostage_window();
1102 do_centers_window();
1103 check_wall_validity();
1104 Assert(Num_walls>=0);
1106 if (Gameview_lockstep) {
1107 static segment *old_cursegp=NULL;
1108 static int old_curside=-1;
1110 if (old_cursegp!=Cursegp || old_curside!=Curside) {
1111 SetPlayerFromCursegMinusOne();
1112 old_cursegp = Cursegp;
1113 old_curside = Curside;
1117 // mprintf((0, "%d ", ui_get_idle_seconds() ));
1119 if ( ui_get_idle_seconds() > COMPRESS_INTERVAL )
1121 med_compress_mine();
1122 ui_reset_idle_seconds();
1125 // Commented out because it occupies about 25% of time in twirling the mine.
1126 // Removes some Asserts....
1127 // med_check_all_vertices();
1128 clear_editor_status(); // if enough time elapsed, clear editor status message
1129 TimedAutosave(mine_filename);
1130 set_editor_time_of_day();
1131 gr_set_current_canvas( GameViewBox->canvas );
1133 // Remove keys used for slew
1134 switch(last_keypress)
1150 if ((last_keypress&0xff)==KEY_LSHIFT) last_keypress=0;
1151 if ((last_keypress&0xff)==KEY_RSHIFT) last_keypress=0;
1152 if ((last_keypress&0xff)==KEY_LCTRL) last_keypress=0;
1153 if ((last_keypress&0xff)==KEY_RCTRL) last_keypress=0;
1154 // if ((last_keypress&0xff)==KEY_LALT) last_keypress=0;
1155 // if ((last_keypress&0xff)==KEY_RALT) last_keypress=0;
1157 gr_set_curfont(editor_font);
1158 menubar_do( last_keypress );
1160 //=================== DO FUNCTIONS ====================
1162 if ( KeyFunction[ last_keypress ] != NULL ) {
1163 KeyFunction[last_keypress]();
1166 switch (last_keypress)
1179 case KEY_SHIFTED + KEY_L:
1183 render_3d_in_big_window = !render_3d_in_big_window;
1184 Update_flags |= UF_ALL;
1189 GetKeyDescription( kdesc, last_keypress );
1190 editor_status("Error: %s isn't bound to anything.", kdesc );
1194 //================================================================
1198 close_editor_screen();
1199 Function_mode=FMODE_EXIT;
1200 gr_free_bitmap( savedbitmap );
1204 if (ModeFlag==2) //-- && MacroStatus==UI_STATUS_NORMAL )
1207 Function_mode = FMODE_GAME;
1208 gr_bm_ubitblt( w, h, 0, 0, 0, 0, savedbitmap, &GameViewBox->canvas->cv_bitmap);
1209 gr_free_bitmap( savedbitmap );
1213 if (ModeFlag==3) //-- && MacroStatus==UI_STATUS_NORMAL )
1215 // med_compress_mine(); //will be called anyways before game.
1216 close_editor_screen();
1217 Function_mode=FMODE_GAME; //force back into game
1218 set_screen_mode(SCREEN_GAME); //put up game screen
1219 gr_free_bitmap( savedbitmap );
1223 // if (CurWindow->keyboard_focus_gadget == (UI_GADGET *)GameViewBox) current_view=NULL;
1224 // if (CurWindow->keyboard_focus_gadget == (UI_GADGET *)GroupViewBox) current_view=NULL;
1226 new_cv = current_view ;
1229 if (CurWindow->keyboard_focus_gadget == (UI_GADGET *)LargeViewBox) new_cv=&LargeView;
1230 if (CurWindow->keyboard_focus_gadget == (UI_GADGET *)TopViewBox) new_cv=&TopView;
1231 if (CurWindow->keyboard_focus_gadget == (UI_GADGET *)FrontViewBox) new_cv=&FrontView;
1232 if (CurWindow->keyboard_focus_gadget == (UI_GADGET *)RightViewBox) new_cv=&RightView;
1234 if (new_cv != current_view ) {
1235 current_view->ev_changed = 1;
1236 new_cv->ev_changed = 1;
1237 current_view = new_cv;
1241 if (slew_frame(0)) { //do movement and check keys
1242 Update_flags |= UF_GAME_VIEW_CHANGED;
1243 if (Gameview_lockstep) {
1244 Cursegp = &Segments[ConsoleObject->segnum];
1245 med_create_new_segment_from_cursegp();
1246 Update_flags |= UF_ED_STATE_CHANGED;
1255 // Process selection of Cursegp using mouse.
1256 if (LargeViewBox->mouse_onme && LargeViewBox->b1_clicked && !render_3d_in_big_window)
1259 xcrd = LargeViewBox->b1_drag_x1;
1260 ycrd = LargeViewBox->b1_drag_y1;
1262 find_segments(xcrd,ycrd,LargeViewBox->canvas,&LargeView,Cursegp,Big_depth); // Sets globals N_found_segs, Found_segs
1264 // If shift is down, then add segment to found list
1265 if (keyd_pressed[ KEY_LSHIFT ] || keyd_pressed[ KEY_RSHIFT ])
1266 subtract_found_segments_from_selected_list();
1268 add_found_segments_to_selected_list();
1270 Found_seg_index = 0;
1272 if (N_found_segs > 0) {
1273 sort_seg_list(N_found_segs,Found_segs,&ConsoleObject->pos);
1274 Cursegp = &Segments[Found_segs[0]];
1275 med_create_new_segment_from_cursegp();
1276 if (Lock_view_to_cursegp)
1277 set_view_target_from_segment(Cursegp);
1280 Update_flags |= UF_ED_STATE_CHANGED | UF_VIEWPOINT_MOVED;
1283 if (GameViewBox->mouse_onme && GameViewBox->b1_dragging) {
1285 x = GameViewBox->b1_drag_x2;
1286 y = GameViewBox->b1_drag_y2;
1289 gr_set_current_canvas( GameViewBox->canvas );
1291 gr_rect( x-1, y-1, x+1, y+1 );
1296 // Set current segment and side by clicking on a polygon in game window.
1297 // If ctrl pressed, also assign current texture map to that side.
1298 //if (GameViewBox->mouse_onme && (GameViewBox->b1_done_dragging || GameViewBox->b1_clicked)) {
1299 if ((GameViewBox->mouse_onme && GameViewBox->b1_clicked && !render_3d_in_big_window) ||
1300 (LargeViewBox->mouse_onme && LargeViewBox->b1_clicked && render_3d_in_big_window)) {
1303 int seg,side,face,poly,tmap;
1305 if (render_3d_in_big_window) {
1306 xcrd = LargeViewBox->b1_drag_x1;
1307 ycrd = LargeViewBox->b1_drag_y1;
1310 xcrd = GameViewBox->b1_drag_x1;
1311 ycrd = GameViewBox->b1_drag_y1;
1316 if (find_seg_side_face(xcrd,ycrd,&seg,&side,&face,&poly)) {
1319 if (seg<0) { //found an object
1321 Cur_object_index = -seg-1;
1322 editor_status("Object %d selected.",Cur_object_index);
1324 Update_flags |= UF_ED_STATE_CHANGED;
1328 // See if either shift key is down and, if so, assign texture map
1329 if (keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT]) {
1330 Cursegp = &Segments[seg];
1333 med_create_new_segment_from_cursegp();
1334 editor_status("Texture assigned");
1335 } else if (keyd_pressed[KEY_G]) {
1336 tmap = Segments[seg].sides[side].tmap_num;
1337 texpage_grab_current(tmap);
1338 editor_status( "Texture grabbed." );
1339 } else if (keyd_pressed[ KEY_LAPOSTRO] ) {
1341 move_object_to_mouse_click();
1343 Cursegp = &Segments[seg];
1345 med_create_new_segment_from_cursegp();
1346 editor_status("Curseg and curside selected");
1350 Update_flags |= UF_ED_STATE_CHANGED;
1353 editor_status("Click on non-texture ingored");
1357 // Allow specification of LargeView using mouse
1358 if (keyd_pressed[ KEY_LCTRL ] || keyd_pressed[ KEY_RCTRL ]) {
1360 if ( (Mouse.dx!=0) && (Mouse.dy!=0) ) {
1361 GetMouseRotation( Mouse.dx, Mouse.dy, &MouseRotMat );
1362 vm_matrix_x_matrix(&tempm,&LargeView.ev_matrix,&MouseRotMat);
1363 LargeView.ev_matrix = tempm;
1364 LargeView.ev_changed = 1;
1365 Large_view_index = -1; // say not one of the orthogonal views
1371 if ( keyd_pressed[ KEY_Z ] ) {
1373 if ( Mouse.dy!=0 ) {
1374 current_view->ev_dist += Mouse.dy*10000;
1375 current_view->ev_changed = 1;
1383 // _MARK_("end of editor");//Nuked to compile -KRB
1385 clear_warn_func(med_show_warning);
1387 //kill our camera object
1389 Viewer = ConsoleObject; //reset viewer
1390 //@@obj_delete(camera_objnum);
1392 padnum = ui_pad_get_current();
1400 void test_fade(void)
1404 for (c=0; c<256; c++) {
1405 printf("%4i: {%3i %3i %3i} ",c,gr_palette[3*c],gr_palette[3*c+1],gr_palette[3*c+2]);
1406 for (i=0; i<16; i++) {
1407 int col = gr_fade_table[256*i+c];
1409 printf("[%3i %3i %3i] ",gr_palette[3*col],gr_palette[3*col+1],gr_palette[3*col+2]);
1417 void dump_stuff(void)
1421 printf("Palette:\n");
1423 for (i=0; i<256; i++)
1424 printf("%3i: %2i %2i %2i\n",i,gr_palette[3*i],gr_palette[3*i+1],gr_palette[3*i+2]);
1426 for (i=0; i<16; i++) {
1427 printf("\nFade table #%i\n",i);
1428 for (j=0; j<256; j++) {
1429 int c = gr_fade_table[i*256 + j];
1430 printf("[%3i %2i %2i %2i] ",c, gr_palette[3*c], gr_palette[3*c+1], gr_palette[3*c+2]);
1436 printf("Colors indexed by intensity:\n");
1437 printf(". = change from previous, * = no change\n");
1438 for (j=0; j<256; j++) {
1441 for (i=0; i<16; i++) {
1442 int c = gr_fade_table[i*256 + j];
1443 if (c == prev_color)
1450 for (i=0; i<16; i++) {
1451 int c = gr_fade_table[i*256 + j];
1452 printf("[%3i %2i %2i %2i] ", c, gr_palette[3*c], gr_palette[3*c+1], gr_palette[3*c+2]);
1463 sprintf(mystr,"mark %i start",Mark_count);
1464 // _MARK_(mystr);//Nuked to compile -KRB
1472 sprintf(mystr,"mark %i end",Mark_count);
1474 // _MARK_(mystr);//Nuked to compile -KRB