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