Subversion Repositories Games.Descent

Rev

Blame | Last modification | View Log | Download | RSS feed

  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.  * Miscellaneous functions stripped out of med.c
  23.  *
  24.  */
  25.  
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <stdarg.h>
  29. #include <string.h>
  30. #include "gr.h"
  31. #include "ui.h"
  32. #include "3d.h"
  33. #include "u_mem.h"
  34. #include "dxxerror.h"
  35. #include "key.h"
  36. #include "mouse.h"
  37. #include "func.h"
  38. #include "inferno.h"
  39. #include "editor/editor.h"
  40. #include "editor/esegment.h"
  41. #include "editor/medmisc.h"
  42. #include "gameseg.h"
  43. #include "segment.h"
  44. #include "render.h"
  45. #include "screens.h"
  46. #include "object.h"
  47. #include "texpage.h"            // For texpage_goto_first
  48. #include "meddraw.h"            // For draw_World
  49. #include "game.h"
  50. #include "kdefs.h"
  51.  
  52. #if DXX_USE_OGL
  53. #include "ogl_init.h"
  54. #endif
  55.  
  56. #include "compiler-range_for.h"
  57.  
  58. //return 2d distance, i.e, sqrt(x*x + y*y)
  59. #ifdef __WATCOMC__
  60. long dist_2d(long x,long y);
  61.  
  62. #pragma aux dist_2d parm [eax] [ebx] value [eax] modify [ecx edx] = \
  63.         "imul   eax"                    \
  64.         "xchg   ebx,eax"                \
  65.         "mov    ecx,edx"                \
  66.         "imul   eax"                    \
  67.         "add    eax,ebx"                \
  68.         "adc    edx,ecx"                \
  69.         "call   quad_sqrt";
  70. #else
  71. #include <math.h>
  72. static long dist_2d(long x,long y) {
  73.         return sqrt(static_cast<double>(x) * static_cast<double>(x) + static_cast<double>(y) * static_cast<double>(y));
  74. }
  75. #endif
  76.  
  77. // Given mouse movement in dx, dy, returns a 3x3 rotation matrix in RotMat.
  78. // Taken from Graphics Gems III, page 51, "The Rolling Ball"
  79.  
  80. void GetMouseRotation( int idx, int idy, vms_matrix * RotMat )
  81. {
  82.         fix dr, cos_theta, sin_theta, denom, cos_theta1;
  83.         fix Radius = i2f(100);
  84.         fix dx,dy;
  85.         fix dxdr,dydr;
  86.  
  87.         idy *= -1;
  88.  
  89.         dx = i2f(idx); dy = i2f(idy);
  90.  
  91.         dr = dist_2d(dx,dy);
  92.  
  93.         denom = dist_2d(Radius,dr);
  94.  
  95.         cos_theta = fixdiv(Radius,denom);
  96.         sin_theta = fixdiv(dr,denom);
  97.  
  98.         cos_theta1 = f1_0 - cos_theta;
  99.  
  100.         dxdr = fixdiv(dx,dr);
  101.         dydr = fixdiv(dy,dr);
  102.  
  103.         RotMat->rvec.x = cos_theta + fixmul(fixmul(dydr,dydr),cos_theta1);
  104.         RotMat->uvec.x = - fixmul(fixmul(dxdr,dydr),cos_theta1);
  105.         RotMat->fvec.x = fixmul(dxdr,sin_theta);
  106.  
  107.         RotMat->rvec.y = RotMat->uvec.x;
  108.         RotMat->uvec.y = cos_theta + fixmul(fixmul(dxdr,dxdr),cos_theta1);
  109.         RotMat->fvec.y = fixmul(dydr,sin_theta);
  110.  
  111.         RotMat->rvec.z = -RotMat->fvec.x;
  112.         RotMat->uvec.z = -RotMat->fvec.y;
  113.         RotMat->fvec.z = cos_theta;
  114.  
  115. }
  116.  
  117. int Gameview_lockstep;          //if set, view is locked to Curseg
  118.  
  119. int ToggleLockstep()
  120. {
  121.         auto &LevelSharedVertexState = LevelSharedSegmentState.get_vertex_state();
  122.         auto &Vertices = LevelSharedVertexState.get_vertices();
  123.         Gameview_lockstep = !Gameview_lockstep;
  124.     if (Gameview_lockstep == 0) {
  125.         //if (keypress != KEY_L)
  126.             diagnostic_message("[Ctrl-L] - Lock mode OFF");
  127.         //else
  128.         //    diagnostic_message("Lock mode OFF");
  129.     }
  130.     if (Gameview_lockstep) {
  131.         //if (keypress != KEY_L)
  132.             diagnostic_message("[Ctrl-L] Lock mode ON");
  133.         //else
  134.         //    diagnostic_message("Lock mode ON");
  135.  
  136.                 Cursegp = imsegptridx(ConsoleObject->segnum);
  137.                 med_create_new_segment_from_cursegp();
  138.                 auto &vcvertptr = Vertices.vcptr;
  139.                 set_view_target_from_segment(vcvertptr, Cursegp);
  140.                 Update_flags = UF_ED_STATE_CHANGED;
  141.         }
  142.     return Gameview_lockstep;
  143. }
  144.  
  145. int medlisp_delete_segment(void)
  146. {
  147.         auto &LevelSharedVertexState = LevelSharedSegmentState.get_vertex_state();
  148.         auto &Vertices = LevelSharedVertexState.get_vertices();
  149.     if (!med_delete_segment(Cursegp)) {
  150.         if (Lock_view_to_cursegp)
  151.                 {
  152.                         auto &vcvertptr = Vertices.vcptr;
  153.             set_view_target_from_segment(vcvertptr, Cursegp);
  154.                 }
  155.                   autosave_mine(mine_filename);
  156.                 undo_status[Autosave_count] = "Delete Segment UNDONE.";
  157.         Update_flags |= UF_WORLD_CHANGED;
  158.         mine_changed = 1;
  159.         diagnostic_message("Segment deleted.");
  160.         warn_if_concave_segments();     // This could be faster -- just check if deleted segment was concave, warn accordingly
  161.     }
  162.  
  163.         return 1;
  164. }
  165.  
  166. int medlisp_scale_segment(void)
  167. {
  168.         vms_vector      scale;
  169.  
  170.         scale.x = fl2f(static_cast<float>(func_get_param(0)));
  171.         scale.y = fl2f(static_cast<float>(func_get_param(1)));
  172.         scale.z = fl2f(static_cast<float>(func_get_param(2)));
  173.         med_create_new_segment(scale);
  174.         med_rotate_segment(Cursegp,vm_angles_2_matrix(Seg_orientation));
  175.         Update_flags |= UF_WORLD_CHANGED;
  176.         mine_changed = 1;
  177.  
  178.         return 1;
  179. }
  180.  
  181. int medlisp_rotate_segment(void)
  182. {
  183.         Seg_orientation.p = func_get_param(0);
  184.         Seg_orientation.b = func_get_param(1);
  185.         Seg_orientation.h = func_get_param(2);
  186.         med_rotate_segment(Cursegp,vm_angles_2_matrix(Seg_orientation));
  187.         Update_flags |= UF_WORLD_CHANGED | UF_VIEWPOINT_MOVED;
  188.         mine_changed = 1;
  189.         return 1;
  190. }
  191.  
  192. int ToggleLockViewToCursegp(void)
  193. {
  194.         auto &LevelSharedVertexState = LevelSharedSegmentState.get_vertex_state();
  195.         auto &Vertices = LevelSharedVertexState.get_vertices();
  196.         Lock_view_to_cursegp = !Lock_view_to_cursegp;
  197.         Update_flags = UF_ED_STATE_CHANGED;
  198.         if (Lock_view_to_cursegp) {
  199.         //if (keypress != KEY_V+KEY_CTRLED)
  200.             diagnostic_message("[ctrl-V] View locked to Cursegp.");
  201.         //else
  202.         //    diagnostic_message("View locked to Cursegp.");
  203.                 auto &vcvertptr = Vertices.vcptr;
  204.         set_view_target_from_segment(vcvertptr, Cursegp);
  205.     } else {
  206.         //if (keypress != KEY_V+KEY_CTRLED)
  207.             diagnostic_message("[ctrl-V] View not locked to Cursegp.");
  208.         //else
  209.         //    diagnostic_message("View not locked to Cursegp.");
  210.     }
  211.     return Lock_view_to_cursegp;
  212. }
  213.  
  214. int ToggleDrawAllSegments()
  215. {
  216.         Draw_all_segments = !Draw_all_segments;
  217.         Update_flags = UF_ED_STATE_CHANGED;
  218.     if (Draw_all_segments == 1) {
  219.         //if (keypress != KEY_A+KEY_CTRLED)
  220.             diagnostic_message("[ctrl-A] Draw all segments ON.");
  221.         //else
  222.         //    diagnostic_message("Draw all segments ON.");
  223.     }
  224.     if (Draw_all_segments == 0) {
  225.         //if (keypress != KEY_A+KEY_CTRLED)
  226.             diagnostic_message("[ctrl-A] Draw all segments OFF.");
  227.         //else
  228.         //    diagnostic_message("Draw all segments OFF.");
  229.     }
  230.     return Draw_all_segments;
  231. }
  232.  
  233. int     Big_depth=6;
  234.  
  235. int IncreaseDrawDepth(void)
  236. {
  237.         Big_depth++;
  238.         Update_flags = UF_ED_STATE_CHANGED;
  239.         return 1;
  240. }
  241.  
  242. int DecreaseDrawDepth(void)
  243. {
  244.         if (Big_depth > 1) {
  245.                 Big_depth--;
  246.                 Update_flags = UF_ED_STATE_CHANGED;
  247.         }
  248.         return 1;
  249. }
  250.  
  251.  
  252. int ToggleCoordAxes()
  253. {
  254.                         //  Toggle display of coordinate axes.
  255.         Show_axes_flag = !Show_axes_flag;
  256.         LargeView.ev_changed = 1;
  257.     if (Show_axes_flag == 1) {
  258.         //if (keypress != KEY_D+KEY_CTRLED)
  259.             diagnostic_message("[ctrl-D] Coordinate axes ON.");
  260.         //else
  261.         //    diagnostic_message("Coordinate axes ON.");
  262.     }
  263.     if (Show_axes_flag == 0) {
  264.         //if (keypress != KEY_D+KEY_CTRLED)
  265.             diagnostic_message("[ctrl-D] Coordinate axes OFF.");
  266.         //else
  267.         //    diagnostic_message("Coordinate axes OFF.");
  268.     }
  269.     return Show_axes_flag;
  270. }
  271.  
  272. int med_keypad_goto_prev()
  273. {
  274.         ui_pad_goto_prev();
  275.         return 0;
  276. }
  277.  
  278. int med_keypad_goto_next()
  279. {
  280.         ui_pad_goto_next();
  281.         return 0;
  282. }
  283.  
  284. int med_keypad_goto()
  285. {
  286.         ui_pad_goto(func_get_param(0));
  287.         return 0;
  288. }
  289.  
  290. int render_3d_in_big_window=0;
  291.  
  292. int medlisp_update_screen()
  293. {
  294. #if 1   //def OGL
  295.         Update_flags = UF_ALL;
  296. #endif
  297.  
  298.         if (!render_3d_in_big_window)
  299.                 range_for (const auto vn, Views)
  300.                         if (vn->ev_changed || (Update_flags & (UF_WORLD_CHANGED | UF_VIEWPOINT_MOVED | UF_ED_STATE_CHANGED)))
  301.                         {
  302.                                 draw_world(vn->ev_canv, vn, Cursegp, Big_depth);
  303.                                 vn->ev_changed = 0;
  304.                         }
  305.  
  306.         if (Update_flags & (UF_WORLD_CHANGED|UF_GAME_VIEW_CHANGED|UF_ED_STATE_CHANGED)) {
  307.                 grs_canvas *render_canv,*show_canv;
  308.                
  309.                 if (render_3d_in_big_window) {
  310.                         render_canv = LargeView.ev_canv;
  311.                         show_canv = LargeView.ev_canv;
  312.                 }
  313.                 else {
  314.                         render_canv     = Canv_editor_game;
  315.                         show_canv       = Canv_editor_game;
  316.                 }
  317.  
  318.                 gr_set_current_canvas(render_canv);
  319.                 render_frame(*grd_curcanv, 0);
  320.  
  321.                 Assert(render_canv->cv_bitmap.bm_w == show_canv->cv_bitmap.bm_w &&
  322.                                  render_canv->cv_bitmap.bm_h == show_canv->cv_bitmap.bm_h);
  323.                 (void)show_canv;
  324.         }
  325.  
  326.         Update_flags=UF_NONE;       //clear flags
  327.  
  328.         return 1;
  329. }
  330.  
  331. void med_point_2_vec(grs_canvas *canv,vms_vector &v,short sx,short sy)
  332. {
  333.         gr_set_current_canvas(canv);
  334.  
  335.         g3_start_frame(*grd_curcanv);
  336.         g3_set_view_matrix(Viewer->pos,Viewer->orient,Render_zoom);
  337.         g3_point_2_vec(v,sx,sy);
  338.         g3_end_frame();
  339. }
  340.  
  341. void draw_world_from_game(void)
  342. {
  343.         if (ModeFlag == 2)
  344.                 draw_world(Views[0]->ev_canv,Views[0],Cursegp,Big_depth);
  345. }
  346.  
  347. int UndoCommand()
  348. {  
  349.         auto &LevelSharedVertexState = LevelSharedSegmentState.get_vertex_state();
  350.         auto &Vertices = LevelSharedVertexState.get_vertices();
  351.         int u;
  352.  
  353.     u = undo();
  354.     if (Lock_view_to_cursegp)
  355.         {
  356.                 auto &vcvertptr = Vertices.vcptr;
  357.                 set_view_target_from_segment(vcvertptr, Cursegp);
  358.         }
  359.     if (u == 0) {
  360.         if (Autosave_count==9) diagnostic_message(undo_status[0]);
  361.             else
  362.                 diagnostic_message(undo_status[Autosave_count+1]);
  363.         }
  364.         else
  365.          if (u == 1) diagnostic_message("Can't Undo.");
  366.         else
  367.          if (u == 2) diagnostic_message("Can't Undo - Autosave OFF");
  368.     Update_flags |= UF_WORLD_CHANGED;
  369.          mine_changed = 1;
  370.     warn_if_concave_segments();
  371.     return 1;
  372. }
  373.  
  374.  
  375. int ToggleAutosave()
  376. {
  377.         Autosave_flag = !Autosave_flag;
  378.         if (Autosave_flag == 1)
  379.       diagnostic_message("Autosave ON.");
  380.         else
  381.                 diagnostic_message("Autosave OFF.");
  382.    return Autosave_flag;
  383. }
  384.  
  385.  
  386. int AttachSegment()
  387. {
  388.         auto &LevelSharedVertexState = LevelSharedSegmentState.get_vertex_state();
  389.         auto &Vertices = LevelSharedVertexState.get_vertices();
  390.    if (med_attach_segment(Cursegp, vmsegptr(&New_segment), Curside, AttachSide)==4) // Used to be WBACK instead of Curside
  391.         diagnostic_message("Cannot attach segment - already a connection on current side.");
  392.    else {
  393.                 if (Lock_view_to_cursegp)
  394.                 {
  395.                         auto &vcvertptr = Vertices.vcptr;
  396.                         set_view_target_from_segment(vcvertptr, Cursegp);
  397.                 }
  398.                 vm_angvec_make(&Seg_orientation,0,0,0);
  399.                 Curside = WBACK;
  400.                 Update_flags |= UF_WORLD_CHANGED;
  401.            autosave_mine(mine_filename);
  402.                 undo_status[Autosave_count] = "Attach Segment UNDONE.";
  403.                 mine_changed = 1;
  404.                 warn_if_concave_segment(Cursegp);
  405.       }
  406.         return 1;
  407. }
  408.  
  409.  
  410. #if ORTHO_VIEWS
  411. int SyncLargeView()
  412. {
  413.         // Make large view be same as one of the orthogonal views.
  414.         Large_view_index = (Large_view_index + 1) % 3;  // keep in 0,1,2 for top, front, right
  415.         switch (Large_view_index) {
  416.                 case 0: LargeView.ev_matrix = TopView.ev_matrix; break;
  417.                 case 1: LargeView.ev_matrix = FrontView.ev_matrix; break;
  418.                 case 2: LargeView.ev_matrix = RightView.ev_matrix; break;
  419.         }
  420.         Update_flags |= UF_VIEWPOINT_MOVED;
  421.         return 1;
  422. }
  423. #endif
  424.  
  425. int CreateDefaultNewSegment()
  426. {
  427.         // Create a default segment for New_segment.
  428.         med_create_new_segment({DEFAULT_X_SIZE, DEFAULT_Y_SIZE, DEFAULT_Z_SIZE});
  429.         mine_changed = 1;
  430.  
  431.         return 1;
  432. }
  433.  
  434. int CreateDefaultNewSegmentandAttach()
  435. {
  436.         CreateDefaultNewSegment();
  437.         AttachSegment();
  438.  
  439.         return 1;
  440. }
  441.  
  442. int ExchangeMarkandCurseg()
  443. {
  444.         // If Markedsegp != Cursegp, and Markedsegp->segnum != -1, exchange Markedsegp and Cursegp
  445.         if (Markedsegp)
  446.                 if (Markedsegp->segnum != segment_none) {
  447.                         using std::swap;
  448.                         swap(Markedsegp, Cursegp);
  449.                         swap(Markedside, Curside);
  450.                         med_create_new_segment_from_cursegp();
  451.                         Update_flags |= UF_ED_STATE_CHANGED;
  452.                         mine_changed = 1;
  453.                 }
  454.         return 1;
  455. }
  456.  
  457. int ClearSelectedList(void)
  458. {
  459.         Selected_segs.clear();
  460.         Update_flags |= UF_WORLD_CHANGED;
  461.  
  462.         diagnostic_message("Selected list cleared.");
  463.  
  464.         return 1;
  465. }
  466.  
  467.  
  468. int ClearFoundList(void)
  469. {
  470.         Found_segs.clear();
  471.         Update_flags |= UF_WORLD_CHANGED;
  472.  
  473.         diagnostic_message("Found list cleared.");
  474.  
  475.         return 1;
  476. }
  477.  
  478. // ---------------------------------------------------------------------------------------------------
  479. void set_view_target_from_segment(fvcvertptr &vcvertptr, const shared_segment &sp)
  480. {
  481.         if (Funky_chase_mode)
  482.                 {
  483.                 //set_chase_matrix(sp);
  484.                 }
  485.         else {
  486.                 vms_vector tv{};
  487.                 range_for (const auto &v, sp.verts)
  488.                         vm_vec_add2(tv, vcvertptr(v));
  489.  
  490.                 vm_vec_scale(tv,F1_0/MAX_VERTICES_PER_SEGMENT);
  491.                 Ed_view_target = tv;
  492.         }
  493.         Update_flags |= UF_VIEWPOINT_MOVED;
  494.  
  495. }
  496.