home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / main / medmisc.c < prev    next >
Text File  |  1998-06-08  |  17KB  |  671 lines

  1. /*
  2.  * $Source: f:/miner/source/main/editor/rcs/medmisc.c $
  3.  * $Revision: 2.1 $
  4.  * $Author: john $
  5.  * $Date: 1995/03/06 15:20:50 $
  6.  * 
  7.  * Miscellaneous functions stripped out of med.c
  8.  * 
  9.  * $Log: medmisc.c $
  10.  * Revision 2.1  1995/03/06  15:20:50  john
  11.  * New screen mode method.
  12.  * 
  13.  * Revision 2.0  1995/02/27  11:36:40  john
  14.  * Version 2.0. Ansi-fied.
  15.  * 
  16.  * Revision 1.31  1994/11/27  23:17:20  matt
  17.  * Made changes for new mprintf calling convention
  18.  * 
  19.  * Revision 1.30  1994/11/17  14:48:11  mike
  20.  * validation functions moved from editor to game.
  21.  * 
  22.  * Revision 1.29  1994/08/25  21:56:15  mike
  23.  * IS_CHILD stuff.
  24.  * 
  25.  * Revision 1.28  1994/08/09  16:06:00  john
  26.  * Added the ability to place players.  Made old
  27.  * Player variable be ConsoleObject.
  28.  * 
  29.  * Revision 1.27  1994/07/21  17:25:43  matt
  30.  * Took out unused func medlisp_create_new_mine() and its prototype
  31.  * 
  32.  * Revision 1.26  1994/07/21  13:27:01  matt
  33.  * Cleaned up render code and added error checking
  34.  * 
  35.  * Revision 1.25  1994/07/20  15:32:52  matt
  36.  * Added func to call g3_point_2_vec() for texture-mapped window
  37.  * 
  38.  * Revision 1.24  1994/07/15  15:26:53  yuan
  39.  * Fixed warning
  40.  * 
  41.  * Revision 1.23  1994/07/14  14:45:16  yuan
  42.  * Added function to set default segment and attach.
  43.  * 
  44.  * Revision 1.22  1994/07/14  09:46:34  yuan
  45.  * Make E attach segment as well as make default.
  46.  * 
  47.  * 
  48.  * Revision 1.21  1994/07/11  18:39:17  john
  49.  * Reversed y axis roll.
  50.  * 
  51.  * Revision 1.20  1994/07/06  16:36:32  mike
  52.  * Add hook for game to render wireframe view: draw_world_from_game.
  53.  * 
  54.  * Revision 1.19  1994/06/24  14:08:31  john
  55.  * Changed calling params for render_frame.
  56.  * 
  57.  * Revision 1.18  1994/06/23  15:54:02  matt
  58.  * Finished hacking in 3d rendering in big window
  59.  * 
  60.  * Revision 1.17  1994/06/22  00:32:56  matt
  61.  * New version, without all the errors of the last version. Sorry.
  62.  * 
  63.  * Revision 1.15  1994/05/23  14:48:54  mike
  64.  * make current segment be add segment.
  65.  * 
  66.  * Revision 1.14  1994/05/19  12:09:35  matt
  67.  * Use new vecmat macros and globals
  68.  * 
  69.  * Revision 1.13  1994/05/14  17:17:55  matt
  70.  * Got rid of externs in source (non-header) files
  71.  * 
  72.  * Revision 1.12  1994/05/09  23:35:06  mike
  73.  * Add ClearFoundList, which is probably no longer being called.
  74.  * 
  75.  * Revision 1.11  1994/05/04  14:11:40  mike
  76.  * Increase render depth from 4 to 6 by default.
  77.  * 
  78.  * Revision 1.10  1994/04/27  21:00:25  matt
  79.  * Made texture-mapped window redraw when editor state variables (such as
  80.  * current object) have changed.
  81.  * 
  82.  * Revision 1.9  1994/03/31  12:03:38  matt
  83.  * Cleaned up includes
  84.  * 
  85.  * Revision 1.8  1994/02/17  11:31:21  matt
  86.  * Changes in object system
  87.  * 
  88.  * Revision 1.7  1994/02/11  11:05:14  yuan
  89.  * Make chase mode unsettable... Gives a warning on the mono.
  90.  * 
  91.  * Revision 1.6  1994/01/21  17:37:24  matt
  92.  * Moved code from render_frame() to caller, making code cleaner
  93.  * 
  94.  * Revision 1.5  1994/01/11  18:12:43  yuan
  95.  * compress_mines removed.  Now it is called within
  96.  * the gamesave.min save whenever we go into the game.
  97.  * 
  98.  * Revision 1.4  1994/01/05  10:54:15  john
  99.  * New object code by John
  100.  * 
  101.  * Revision 1.3  1993/12/29  16:15:27  mike
  102.  * Kill scale field from segment struct.
  103.  * 
  104.  * Revision 1.2  1993/12/17  12:05:00  john
  105.  * Took stuff out of med.c; moved into medsel.c, meddraw.c, medmisc.c
  106.  * 
  107.  * Revision 1.1  1993/12/17  08:35:47  john
  108.  * Initial revision
  109.  * 
  110.  * 
  111.  */
  112.  
  113.  
  114. #pragma off (unreferenced)
  115. static char rcsid[] = "$Id: medmisc.c 2.1 1995/03/06 15:20:50 john Exp $";
  116. #pragma on (unreferenced)
  117.  
  118. #include <stdio.h>
  119. #include <stdlib.h>
  120. #include <stdarg.h>
  121. #include <string.h>
  122. #include <process.h>
  123.  
  124. #include "gr.h"
  125. #include "ui.h"
  126. #include "3d.h"
  127.  
  128. #include "mem.h"
  129. #include "error.h"
  130. #include "mono.h"
  131. #include "key.h"
  132. #include "func.h"
  133.  
  134. #include "inferno.h"
  135. #include "editor.h"
  136. #include "segment.h"
  137.  
  138. #include "render.h"
  139. #include "screens.h"
  140. #include "object.h"
  141.  
  142. #include "texpage.h"        // For texpage_goto_first
  143. #include "meddraw.h"        // For draw_World
  144. #include "game.h"
  145.  
  146. //return 2d distance, i.e, sqrt(x*x + y*y)
  147. long dist_2d(long x,long y);
  148.  
  149. #pragma aux dist_2d parm [eax] [ebx] value [eax] modify [ecx edx] = \
  150.     "imul    eax"            \
  151.     "xchg    ebx,eax"        \
  152.     "mov    ecx,edx"        \
  153.     "imul    eax"            \
  154.     "add    eax,ebx"        \
  155.     "adc    edx,ecx"        \
  156.     "call    quad_sqrt";
  157.  
  158. // Given mouse movement in dx, dy, returns a 3x3 rotation matrix in RotMat.
  159. // Taken from Graphics Gems III, page 51, "The Rolling Ball"
  160.  
  161. void GetMouseRotation( int idx, int idy, vms_matrix * RotMat )
  162. {
  163.     fix dr, cos_theta, sin_theta, denom, cos_theta1;
  164.     fix Radius = i2f(100);
  165.     fix dx,dy;
  166.     fix dxdr,dydr;
  167.  
  168.     idy *= -1;
  169.  
  170.     dx = i2f(idx); dy = i2f(idy);
  171.  
  172.     dr = dist_2d(dx,dy);
  173.  
  174.     denom = dist_2d(Radius,dr);
  175.  
  176.     cos_theta = fixdiv(Radius,denom);
  177.     sin_theta = fixdiv(dr,denom);
  178.  
  179.     cos_theta1 = f1_0 - cos_theta;
  180.  
  181.     dxdr = fixdiv(dx,dr);
  182.     dydr = fixdiv(dy,dr);
  183.  
  184.     RotMat->rvec.x = cos_theta + fixmul(fixmul(dydr,dydr),cos_theta1);
  185.     RotMat->uvec.x = - fixmul(fixmul(dxdr,dydr),cos_theta1);
  186.     RotMat->fvec.x = fixmul(dxdr,sin_theta);
  187.  
  188.     RotMat->rvec.y = RotMat->uvec.x;
  189.     RotMat->uvec.y = cos_theta + fixmul(fixmul(dxdr,dxdr),cos_theta1);
  190.     RotMat->fvec.y = fixmul(dydr,sin_theta);
  191.  
  192.     RotMat->rvec.z = -RotMat->fvec.x;
  193.     RotMat->uvec.z = -RotMat->fvec.y;
  194.     RotMat->fvec.z = cos_theta;
  195.  
  196. }
  197.  
  198. int Gameview_lockstep;        //if set, view is locked to Curseg
  199.  
  200. int ToggleLockstep()
  201. {
  202.     Gameview_lockstep = !Gameview_lockstep;
  203.     if (Gameview_lockstep == 0) {
  204.         if (last_keypress != KEY_L)
  205.             diagnostic_message("[L] - Lock mode OFF");
  206.         else
  207.             diagnostic_message("Lock mode OFF");
  208.     }
  209.     if (Gameview_lockstep) {
  210.         if (last_keypress != KEY_L)
  211.             diagnostic_message("[L] Lock mode ON");
  212.         else
  213.             diagnostic_message("Lock mode ON");
  214.  
  215.       Cursegp = &Segments[ConsoleObject->segnum];
  216.         med_create_new_segment_from_cursegp();
  217.         set_view_target_from_segment(Cursegp);
  218.         Update_flags = UF_ED_STATE_CHANGED;
  219.     }
  220.     return Gameview_lockstep;
  221. }
  222.  
  223. int medlisp_delete_segment(void)
  224. {
  225.     if (!med_delete_segment(Cursegp)) {
  226.         if (Lock_view_to_cursegp)
  227.             set_view_target_from_segment(Cursegp);
  228.           autosave_mine(mine_filename);
  229.           strcpy(undo_status[Autosave_count], "Delete Segment UNDONE.");
  230.         Update_flags |= UF_WORLD_CHANGED;
  231.         mine_changed = 1;
  232.         diagnostic_message("Segment deleted.");
  233.         warn_if_concave_segments();     // This could be faster -- just check if deleted segment was concave, warn accordingly
  234.     }
  235.  
  236.     return 1;
  237. }
  238.  
  239. int medlisp_scale_segment(void)
  240. {
  241.     vms_matrix    rotmat;
  242.     vms_vector    scale;
  243.  
  244.     scale.x = fl2f((float) func_get_param(0));
  245.     scale.y = fl2f((float) func_get_param(1));
  246.     scale.z = fl2f((float) func_get_param(2));
  247.     med_create_new_segment(&scale);
  248.     med_rotate_segment(Cursegp,vm_angles_2_matrix(&rotmat,&Seg_orientation));
  249.     Update_flags |= UF_WORLD_CHANGED;
  250.     mine_changed = 1;
  251.  
  252.     return 1;
  253. }
  254.  
  255. int medlisp_rotate_segment(void)
  256. {
  257.     vms_matrix    rotmat;
  258.  
  259.     Seg_orientation.p = func_get_param(0);
  260.     Seg_orientation.b = func_get_param(1);
  261.     Seg_orientation.h = func_get_param(2);
  262.     med_rotate_segment(Cursegp,vm_angles_2_matrix(&rotmat,&Seg_orientation));
  263.     Update_flags |= UF_WORLD_CHANGED | UF_VIEWPOINT_MOVED;
  264.     mine_changed = 1;
  265.     return 1;
  266. }
  267.  
  268. int ToggleLockViewToCursegp(void)
  269. {
  270.     Lock_view_to_cursegp = !Lock_view_to_cursegp;
  271.     Update_flags = UF_ED_STATE_CHANGED;
  272.     if (Lock_view_to_cursegp) {
  273.         if (last_keypress != KEY_V+KEY_CTRLED)
  274.             diagnostic_message("[ctrl-V] View locked to Cursegp.");
  275.         else
  276.             diagnostic_message("View locked to Cursegp.");
  277.         set_view_target_from_segment(Cursegp);
  278.     } else {
  279.         if (last_keypress != KEY_V+KEY_CTRLED)
  280.             diagnostic_message("[ctrl-V] View not locked to Cursegp.");
  281.         else
  282.             diagnostic_message("View not locked to Cursegp.");
  283.     }
  284.     return Lock_view_to_cursegp;
  285. }
  286.  
  287. int ToggleDrawAllSegments()
  288. {
  289.     Draw_all_segments = !Draw_all_segments;
  290.     Update_flags = UF_ED_STATE_CHANGED;
  291.     if (Draw_all_segments == 1) {
  292.         if (last_keypress != KEY_A+KEY_CTRLED)
  293.             diagnostic_message("[ctrl-A] Draw all segments ON.");
  294.         else
  295.             diagnostic_message("Draw all segments ON.");
  296.     }
  297.     if (Draw_all_segments == 0) {
  298.         if (last_keypress != KEY_A+KEY_CTRLED)
  299.             diagnostic_message("[ctrl-A] Draw all segments OFF.");
  300.         else
  301.             diagnostic_message("Draw all segments OFF.");
  302.     }
  303.     return Draw_all_segments;
  304. }
  305.  
  306. int    Big_depth=6;
  307.  
  308. int IncreaseDrawDepth(void)
  309. {
  310.     Big_depth++;
  311.     Update_flags = UF_ED_STATE_CHANGED;
  312.     return 1;
  313. }
  314.  
  315. int DecreaseDrawDepth(void)
  316. {
  317.     if (Big_depth > 1) {
  318.         Big_depth--;
  319.         Update_flags = UF_ED_STATE_CHANGED;
  320.     }
  321.     return 1;
  322. }
  323.  
  324.  
  325. int ToggleCoordAxes()
  326. {
  327.             //  Toggle display of coordinate axes.
  328.     Show_axes_flag = !Show_axes_flag;
  329.     LargeView.ev_changed = 1;
  330.     if (Show_axes_flag == 1) {
  331.         if (last_keypress != KEY_D+KEY_CTRLED)
  332.             diagnostic_message("[ctrl-D] Coordinate axes ON.");
  333.         else
  334.             diagnostic_message("Coordinate axes ON.");
  335.     }
  336.     if (Show_axes_flag == 0) {
  337.         if (last_keypress != KEY_D+KEY_CTRLED)
  338.             diagnostic_message("[ctrl-D] Coordinate axes OFF.");
  339.         else
  340.             diagnostic_message("Coordinate axes OFF.");
  341.     }
  342.     return Show_axes_flag;
  343. }
  344.  
  345. int med_keypad_goto_prev()
  346. {
  347.     ui_pad_goto_prev();
  348.     return 0;
  349. }
  350.  
  351. int med_keypad_goto_next()
  352. {
  353.     ui_pad_goto_next();
  354.     return 0;
  355. }
  356.  
  357. int med_keypad_goto()
  358. {
  359.     ui_pad_goto(func_get_param(0));
  360.     return 0;
  361. }
  362.  
  363. int render_3d_in_big_window=0;
  364.  
  365. int medlisp_update_screen()
  366. {
  367.     int vn;
  368.  
  369. if (!render_3d_in_big_window)
  370.     for (vn=0;vn<N_views;vn++)
  371.         if (Views[vn]->ev_changed || (Update_flags & (UF_WORLD_CHANGED|UF_VIEWPOINT_MOVED|UF_ED_STATE_CHANGED))) {
  372.             draw_world(Views[vn]->ev_canv,Views[vn],Cursegp,Big_depth);
  373.             Views[vn]->ev_changed = 0;
  374.         }
  375.  
  376.     if (Update_flags & (UF_WORLD_CHANGED|UF_GAME_VIEW_CHANGED|UF_ED_STATE_CHANGED)) {
  377.         grs_canvas temp_canvas;
  378.         grs_canvas *render_canv,*show_canv;
  379.         
  380.         if (render_3d_in_big_window) {
  381.             
  382.             gr_init_sub_canvas(&temp_canvas,canv_offscreen,0,0,
  383.                 LargeView.ev_canv->cv_bitmap.bm_w,LargeView.ev_canv->cv_bitmap.bm_h);
  384.  
  385.             render_canv = &temp_canvas;
  386.             show_canv = LargeView.ev_canv;
  387.  
  388.         }
  389.         else {
  390.             render_canv    = VR_offscreen_buffer;
  391.             show_canv    = Canv_editor_game;
  392.         }
  393.  
  394.         gr_set_current_canvas(render_canv);
  395.         render_frame(0);
  396.  
  397.         Assert(render_canv->cv_bitmap.bm_w == show_canv->cv_bitmap.bm_w &&
  398.                  render_canv->cv_bitmap.bm_h == show_canv->cv_bitmap.bm_h);
  399.  
  400.         ui_mouse_hide();
  401.         gr_bm_ubitblt(show_canv->cv_bitmap.bm_w,show_canv->cv_bitmap.bm_h,
  402.                           0,0,0,0,&render_canv->cv_bitmap,&show_canv->cv_bitmap);
  403.         ui_mouse_show();
  404.     }
  405.  
  406.     Update_flags=UF_NONE;       //clear flags
  407.  
  408.     return 1;
  409. }
  410.  
  411. med_point_2_vec(grs_canvas *canv,vms_vector *v,short sx,short sy)
  412. {
  413.     gr_set_current_canvas(canv);
  414.  
  415.     g3_start_frame();
  416.     g3_set_view_matrix(&Viewer->pos,&Viewer->orient,Render_zoom);
  417.  
  418.     g3_point_2_vec(v,sx,sy);
  419.  
  420.     g3_end_frame();
  421. }
  422.  
  423.  
  424.  
  425. void draw_world_from_game(void)
  426. {
  427.     if (ModeFlag == 2)
  428.         draw_world(Views[0]->ev_canv,Views[0],Cursegp,Big_depth);
  429. }
  430.  
  431. int UndoCommand()
  432. {   int u;
  433.  
  434.     u = undo();
  435.     if (Lock_view_to_cursegp)
  436.         set_view_target_from_segment(Cursegp);
  437.     if (u == 0) {
  438.         if (Autosave_count==9) diagnostic_message(undo_status[0]);
  439.             else
  440.                 diagnostic_message(undo_status[Autosave_count+1]);
  441.         }
  442.         else
  443.      if (u == 1) diagnostic_message("Can't Undo.");
  444.         else
  445.      if (u == 2) diagnostic_message("Can't Undo - Autosave OFF");
  446.     Update_flags |= UF_WORLD_CHANGED;
  447.      mine_changed = 1;
  448.     warn_if_concave_segments();
  449.     return 1;
  450. }
  451.  
  452.  
  453. int ToggleAutosave()
  454. {
  455.     Autosave_flag = !Autosave_flag;
  456.     if (Autosave_flag == 1) 
  457.       diagnostic_message("Autosave ON.");
  458.         else
  459.         diagnostic_message("Autosave OFF.");
  460.    return Autosave_flag;
  461. }
  462.  
  463.  
  464. int AttachSegment()
  465. {
  466.    if (med_attach_segment(Cursegp, &New_segment, Curside, AttachSide)==4) // Used to be WBACK instead of Curside
  467.         diagnostic_message("Cannot attach segment - already a connection on current side.");
  468.    else {
  469.         if (Lock_view_to_cursegp)
  470.             set_view_target_from_segment(Cursegp);
  471.         vm_angvec_make(&Seg_orientation,0,0,0);
  472.         Curside = WBACK;
  473.         Update_flags |= UF_WORLD_CHANGED;
  474.        autosave_mine(mine_filename);
  475.        strcpy(undo_status[Autosave_count], "Attach Segment UNDONE.\n");
  476.         mine_changed = 1;
  477.         warn_if_concave_segment(Cursegp);
  478.       }
  479.     return 1;
  480. }
  481.  
  482. int ForceTotalRedraw()
  483. {
  484.     Update_flags = UF_ALL;
  485.     return 1;
  486. }
  487.  
  488.  
  489. #if ORTHO_VIEWS
  490. int SyncLargeView()
  491. {
  492.     // Make large view be same as one of the orthogonal views.
  493.     Large_view_index = (Large_view_index + 1) % 3;  // keep in 0,1,2 for top, front, right
  494.     switch (Large_view_index) {
  495.         case 0: LargeView.ev_matrix = TopView.ev_matrix; break;
  496.         case 1: LargeView.ev_matrix = FrontView.ev_matrix; break;
  497.         case 2: LargeView.ev_matrix = RightView.ev_matrix; break;
  498.     }
  499.     Update_flags |= UF_VIEWPOINT_MOVED;
  500.     return 1;
  501. }
  502. #endif
  503.  
  504. int DeleteCurSegment()
  505. {
  506.     // Delete current segment.
  507.     med_delete_segment(Cursegp);
  508.     autosave_mine(mine_filename);
  509.     strcpy(undo_status[Autosave_count], "Delete segment UNDONE.");
  510.     if (Lock_view_to_cursegp)
  511.         set_view_target_from_segment(Cursegp);
  512.     Update_flags |= UF_WORLD_CHANGED;
  513.     mine_changed = 1;
  514.     diagnostic_message("Segment deleted.");
  515.     warn_if_concave_segments();     // This could be faster -- just check if deleted segment was concave, warn accordingly
  516.  
  517.     return 1;
  518. }
  519.  
  520. int CreateDefaultNewSegment()
  521. {
  522.     // Create a default segment for New_segment.
  523.     vms_vector  tempvec;
  524.     med_create_new_segment(vm_vec_make(&tempvec,DEFAULT_X_SIZE,DEFAULT_Y_SIZE,DEFAULT_Z_SIZE));
  525.     mine_changed = 1;
  526.  
  527.     return 1;
  528. }
  529.  
  530. int CreateDefaultNewSegmentandAttach()
  531. {
  532.     CreateDefaultNewSegment();
  533.     AttachSegment();
  534.  
  535.     return 1;
  536. }
  537.  
  538. int ExchangeMarkAndCurseg()
  539. {
  540.     // If Markedsegp != Cursegp, and Markedsegp->segnum != -1, exchange Markedsegp and Cursegp
  541.     if (Markedsegp)
  542.         if (Markedsegp->segnum != -1) {
  543.             segment *tempsegp;
  544.             int     tempside;
  545.             tempsegp = Markedsegp;  Markedsegp = Cursegp;   Cursegp = tempsegp;
  546.             tempside = Markedside;  Markedside = Curside;   Curside = tempside;
  547.             med_create_new_segment_from_cursegp();
  548.             Update_flags |= UF_ED_STATE_CHANGED;
  549.             mine_changed = 1;
  550.         }
  551.     return 1;
  552. }
  553.  
  554. int medlisp_add_segment()
  555. {
  556.     AttachSegment();
  557. //segment *ocursegp = Cursegp;
  558. //    med_attach_segment(Cursegp, &New_segment, Curside, WFRONT); // Used to be WBACK instead of Curside
  559. //med_propagate_tmaps_to_segments(ocursegp,Cursegp);
  560. //    set_view_target_from_segment(Cursegp);
  561. ////    while (!vm_angvec_make(&Seg_orientation,0,0,0));
  562. //    Curside = WBACK;
  563.  
  564.     return 1;
  565. }
  566.  
  567.  
  568. int ClearSelectedList(void)
  569. {
  570.     N_selected_segs = 0;
  571.     Update_flags |= UF_WORLD_CHANGED;
  572.  
  573.     diagnostic_message("Selected list cleared.");
  574.  
  575.     return 1;
  576. }
  577.  
  578.  
  579. int ClearFoundList(void)
  580. {
  581.     N_found_segs = 0;
  582.     Update_flags |= UF_WORLD_CHANGED;
  583.  
  584.     diagnostic_message("Found list cleared.");
  585.  
  586.     return 1;
  587. }
  588.  
  589.  
  590.  
  591.  
  592. // ---------------------------------------------------------------------------------------------------
  593. // Do chase mode.
  594. //    View current segment (Cursegp) from the previous segment.
  595. void set_chase_matrix(segment *sp)
  596. {
  597.     int            v;
  598.     vms_vector    forvec = ZERO_VECTOR, upvec;
  599.     vms_vector    tv = ZERO_VECTOR;
  600.     segment        *psp;
  601.  
  602.     // move back two segments, if possible, else move back one, if possible, else use current
  603.     if (IS_CHILD(sp->children[WFRONT])) {
  604.         psp = &Segments[sp->children[WFRONT]];
  605.         if (IS_CHILD(psp->children[WFRONT]))
  606.             psp = &Segments[psp->children[WFRONT]];
  607.     } else
  608.         psp = sp;
  609.  
  610.     for (v=0; v<MAX_VERTICES_PER_SEGMENT; v++)
  611.         vm_vec_add2(&forvec,&Vertices[sp->verts[v]]);
  612.     vm_vec_scale(&forvec,F1_0/MAX_VERTICES_PER_SEGMENT);
  613.  
  614.     for (v=0; v<MAX_VERTICES_PER_SEGMENT; v++)
  615.         vm_vec_add2(&tv,&Vertices[psp->verts[v]]);
  616.     vm_vec_scale(&tv,F1_0/MAX_VERTICES_PER_SEGMENT);
  617.  
  618.     Ed_view_target = forvec;
  619.  
  620.     vm_vec_sub2(&forvec,&tv);
  621.  
  622.     extract_up_vector_from_segment(psp,&upvec);
  623.  
  624.     if (!((forvec.x == 0) && (forvec.y == 0) && (forvec.z == 0)))
  625.         vm_vector_2_matrix(&LargeView.ev_matrix,&forvec,&upvec,NULL);
  626. }
  627.  
  628.  
  629.  
  630. // ---------------------------------------------------------------------------------------------------
  631. void set_view_target_from_segment(segment *sp)
  632. {
  633.     vms_vector    tv = ZERO_VECTOR;
  634.     int            v;
  635.  
  636.     if (Funky_chase_mode)
  637.         {
  638.         mprintf((0, "Trying to set chase mode\n"));
  639.         //set_chase_matrix(sp);
  640.         }
  641.     else {
  642.         for (v=0; v<MAX_VERTICES_PER_SEGMENT; v++)
  643.             vm_vec_add2(&tv,&Vertices[sp->verts[v]]);
  644.  
  645.         vm_vec_scale(&tv,F1_0/MAX_VERTICES_PER_SEGMENT);
  646.  
  647.         Ed_view_target = tv;
  648.  
  649.     }
  650.     Update_flags |= UF_VIEWPOINT_MOVED;
  651.  
  652. }
  653.  
  654.  
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662.  
  663.  
  664.  
  665.  
  666.  
  667.  
  668.  
  669.  
  670. 
  671.