2006-03-20 17:12:09 +00:00
/*
2014-06-01 17:55:23 +00:00
* Portions of this file are copyright Rebirth contributors and licensed as
* described in COPYING . txt .
* Portions of this file are copyright Parallax Software and licensed
* according to the Parallax license below .
* See COPYING . txt for license details .
2006-03-20 17:12:09 +00:00
THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
SOFTWARE CORPORATION ( " PARALLAX " ) . PARALLAX , IN DISTRIBUTING THE CODE TO
END - USERS , AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN , GRANTS A
ROYALTY - FREE , PERPETUAL LICENSE TO SUCH END - USERS FOR USE BY SUCH END - USERS
IN USING , DISPLAYING , AND CREATING DERIVATIVE WORKS THEREOF , SO LONG AS
SUCH USE , DISPLAY OR CREATION IS FOR NON - COMMERCIAL , ROYALTY OR REVENUE
FREE PURPOSES . IN NO EVENT SHALL THE END - USER USE THE COMPUTER CODE
CONTAINED HEREIN FOR REVENUE - BEARING PURPOSES . THE END - USER UNDERSTANDS
AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE .
COPYRIGHT 1993 - 1999 PARALLAX SOFTWARE CORPORATION . ALL RIGHTS RESERVED .
*/
/*
*
* Routines for displaying the auto - map .
*
*/
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# ifdef OGL
# include "ogl_init.h"
# endif
2012-07-07 18:35:06 +00:00
# include "dxxerror.h"
2006-03-20 17:12:09 +00:00
# include "3d.h"
# include "inferno.h"
# include "u_mem.h"
# include "render.h"
# include "object.h"
# include "vclip.h"
# include "game.h"
# include "polyobj.h"
# include "sounds.h"
# include "player.h"
# include "bm.h"
# include "key.h"
# include "newmenu.h"
# include "menu.h"
# include "screens.h"
# include "textures.h"
# include "mouse.h"
# include "timer.h"
# include "segpoint.h"
# include "joy.h"
# include "iff.h"
# include "pcx.h"
# include "palette.h"
# include "wall.h"
2009-12-02 13:49:54 +00:00
# include "hostage.h"
# include "fuelcen.h"
2014-07-20 01:09:55 +00:00
# include "physfsx.h"
2006-03-20 17:12:09 +00:00
# include "gameseq.h"
# include "gamefont.h"
2013-12-26 04:18:28 +00:00
# include "gameseg.h"
2013-09-24 01:59:09 +00:00
# include "common/3d/globvars.h"
2006-08-07 00:27:18 +00:00
# include "multi.h"
2006-03-20 17:12:09 +00:00
# include "kconfig.h"
# include "endlevel.h"
# include "text.h"
# include "gauges.h"
# include "powerup.h"
# include "switch.h"
# include "automap.h"
# include "cntrlcen.h"
2009-12-02 13:49:54 +00:00
# include "timer.h"
2009-01-15 20:55:35 +00:00
# include "config.h"
2009-12-02 13:49:54 +00:00
# include "playsave.h"
2009-03-03 12:55:27 +00:00
# include "rbaudio.h"
2009-12-02 13:49:54 +00:00
# include "window.h"
2011-01-10 15:12:04 +00:00
# include "playsave.h"
2013-03-03 19:41:09 +00:00
# include "args.h"
2012-11-11 00:14:30 +00:00
# include "physics.h"
2006-03-20 17:12:09 +00:00
2011-02-03 00:05:06 +00:00
# define LEAVE_TIME 0x4000
2006-03-20 17:12:09 +00:00
# define EF_USED 1 // This edge is used
# define EF_DEFINING 2 // A structure defining edge that should always draw.
# define EF_FRONTIER 4 // An edge between the known and the unknown.
# define EF_SECRET 8 // An edge that is part of a secret wall.
# define EF_GRATE 16 // A grate... draw it all the time.
# define EF_NO_FADE 32 // An edge that doesn't fade with distance
# define EF_TOO_FAR 64 // An edge that is too far away
2013-12-22 22:03:07 +00:00
struct Edge_info
{
2011-06-30 10:23:38 +00:00
int verts [ 2 ] ; // 8 bytes
ubyte sides [ 4 ] ; // 4 bytes
int segnum [ 4 ] ; // 16 bytes // This might not need to be stored... If you can access the normals of a side.
ubyte flags ; // 1 bytes // See the EF_??? defines above.
ubyte color ; // 1 bytes
ubyte num_faces ; // 1 bytes // 31 bytes...
2013-12-22 22:03:07 +00:00
} ;
2006-03-20 17:12:09 +00:00
2013-12-22 22:03:07 +00:00
struct automap
2009-12-02 13:49:54 +00:00
{
2010-12-10 23:18:17 +00:00
fix64 entry_time ;
fix64 t1 , t2 ;
2009-12-02 13:49:54 +00:00
int leave_mode ;
int pause_game ;
2011-05-20 10:23:28 +00:00
vms_angvec tangles ;
ushort old_wiggle ; // keep 4 byte aligned
2009-12-02 13:49:54 +00:00
int max_segments_away ;
int segment_limit ;
2009-12-27 12:27:44 +00:00
// Edge list variables
int num_edges ;
2011-05-20 10:23:28 +00:00
int max_edges ; //set each frame
2009-12-27 12:27:44 +00:00
int highest_edge_index ;
2011-05-20 10:23:28 +00:00
Edge_info * edges ;
2011-06-30 10:23:38 +00:00
int * drawingListBright ;
2009-12-27 12:27:44 +00:00
// Screen canvas variables
2011-05-20 10:23:28 +00:00
grs_canvas automap_view ;
2009-12-27 12:27:44 +00:00
2011-05-20 10:23:28 +00:00
grs_bitmap automap_background ;
2009-12-27 12:27:44 +00:00
// Rendering variables
fix zoom ;
2011-05-20 10:23:28 +00:00
vms_vector view_target ;
vms_vector view_position ;
2009-12-27 12:27:44 +00:00
fix farthest_dist ;
2011-05-20 10:23:28 +00:00
vms_matrix viewMatrix ;
fix viewDist ;
2009-12-27 12:27:44 +00:00
int wall_normal_color ;
int wall_door_color ;
int wall_door_blue ;
int wall_door_gold ;
int wall_door_red ;
int wall_revealed_color ;
int hostage_color ;
int font_color_20 ;
int green_31 ;
int white_63 ;
int blue_48 ;
int red_48 ;
2011-02-06 13:25:37 +00:00
control_info controls ;
2013-12-15 18:32:10 +00:00
segment_depth_array_t depth_array ;
2013-12-22 22:03:07 +00:00
} ;
2009-12-02 13:49:54 +00:00
2006-03-20 17:12:09 +00:00
# define MAX_EDGES_FROM_VERTS(v) ((v)*4)
# define MAX_EDGES 6000 // Determined by loading all the levels by John & Mike, Feb 9, 1995
# define K_WALL_NORMAL_COLOR BM_XRGB(29, 29, 29 )
# define K_WALL_DOOR_COLOR BM_XRGB(5, 27, 5 )
# define K_WALL_DOOR_BLUE BM_XRGB(0, 0, 31)
# define K_WALL_DOOR_GOLD BM_XRGB(31, 31, 0)
# define K_WALL_DOOR_RED BM_XRGB(31, 0, 0)
# define K_WALL_REVEALED_COLOR BM_XRGB(0, 0, 25 ) //what you see when you have the full map powerup
# define K_HOSTAGE_COLOR BM_XRGB(0, 31, 0 )
# define K_FONT_COLOR_20 BM_XRGB(20, 20, 20 )
# define K_GREEN_31 BM_XRGB(0, 31, 0)
2010-01-29 03:36:44 +00:00
int Automap_active = 0 ;
2013-12-15 18:32:10 +00:00
static int Automap_debug_show_all_segments ;
2010-01-29 03:36:44 +00:00
2013-10-27 22:00:14 +00:00
static void init_automap_colors ( automap * am )
2006-03-20 17:12:09 +00:00
{
2009-12-27 12:27:44 +00:00
am - > wall_normal_color = K_WALL_NORMAL_COLOR ;
am - > wall_door_color = K_WALL_DOOR_COLOR ;
am - > wall_door_blue = K_WALL_DOOR_BLUE ;
am - > wall_door_gold = K_WALL_DOOR_GOLD ;
am - > wall_door_red = K_WALL_DOOR_RED ;
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2009-12-27 12:27:44 +00:00
am - > wall_revealed_color = K_WALL_REVEALED_COLOR ;
2013-03-03 01:03:33 +00:00
# endif
2009-12-27 12:27:44 +00:00
am - > hostage_color = K_HOSTAGE_COLOR ;
am - > font_color_20 = K_FONT_COLOR_20 ;
am - > green_31 = K_GREEN_31 ;
am - > white_63 = gr_find_closest_color_current ( 63 , 63 , 63 ) ;
am - > blue_48 = gr_find_closest_color_current ( 0 , 0 , 48 ) ;
am - > red_48 = gr_find_closest_color_current ( 48 , 0 , 0 ) ;
2006-03-20 17:12:09 +00:00
}
2013-12-15 17:01:40 +00:00
array < ubyte , MAX_SEGMENTS > Automap_visited ; // Segment visited list
2006-03-20 17:12:09 +00:00
// Map movement defines
# define PITCH_DEFAULT 9000
# define ZOOM_DEFAULT i2f(20*10)
# define ZOOM_MIN_VALUE i2f(20*5)
# define ZOOM_MAX_VALUE i2f(20*100)
2006-08-07 00:27:18 +00:00
# define SLIDE_SPEED (350)
# define ZOOM_SPEED_FACTOR (500) //(1500)
2006-03-20 17:12:09 +00:00
# define ROT_SPEED_DIVISOR (115000)
2006-08-07 00:27:18 +00:00
// Function Prototypes
2013-09-22 22:26:27 +00:00
static void adjust_segment_limit ( automap * am , int SegmentLimit ) ;
static void draw_all_edges ( automap * am ) ;
2013-12-15 18:32:10 +00:00
static void automap_build_edge_list ( automap * am , int add_all_edges ) ;
2006-03-20 17:12:09 +00:00
2006-08-07 00:27:18 +00:00
# define MAX_DROP_MULTI 2
2006-03-20 17:12:09 +00:00
# define MAX_DROP_SINGLE 9
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2014-08-05 03:10:04 +00:00
# include "compiler-integer_sequence.h"
2006-03-20 17:12:09 +00:00
int HighlightMarker = - 1 ;
2013-12-28 18:56:34 +00:00
marker_message_text_t Marker_input ;
marker_messages_array_t MarkerMessage ;
2006-03-20 17:12:09 +00:00
float MarkerScale = 2.0 ;
2014-08-05 03:10:04 +00:00
template < std : : size_t . . . N >
static inline constexpr array < int16_t , sizeof . . . ( N ) > init_MarkerObject ( index_sequence < N . . . > )
{
return { ( ( void ) N , object_none ) . . . } ;
}
array < int16_t , NUM_MARKERS > MarkerObject = init_MarkerObject ( make_tree_index_sequence < NUM_MARKERS > ( ) ) ;
2013-03-03 01:03:33 +00:00
# endif
2006-03-20 17:12:09 +00:00
# define automap_draw_line g3_draw_line
// -------------------------------------------------------------
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_I)
static inline void DrawMarkers ( automap * am )
{
( void ) am ;
}
static inline void ClearMarkers ( )
{
}
# elif defined(DXX_BUILD_DESCENT_II)
2013-10-27 22:00:14 +00:00
static void DrawMarkerNumber ( automap * am , int num )
2006-08-07 00:27:18 +00:00
{
int i ;
g3s_point BasePoint , FromPoint , ToPoint ;
2013-11-29 03:55:51 +00:00
static const float sArrayX [ 10 ] [ 20 ] = { { - .25 , 0.0 , 0.0 , 0.0 , - 1.0 , 1.0 } ,
2006-08-07 00:27:18 +00:00
{ - 1.0 , 1.0 , 1.0 , 1.0 , - 1.0 , 1.0 , - 1.0 , - 1.0 , - 1.0 , 1.0 } ,
{ - 1.0 , 1.0 , 1.0 , 1.0 , - 1.0 , 1.0 , 0.0 , 1.0 } ,
{ - 1.0 , - 1.0 , - 1.0 , 1.0 , 1.0 , 1.0 } ,
{ - 1.0 , 1.0 , - 1.0 , - 1.0 , - 1.0 , 1.0 , 1.0 , 1.0 , - 1.0 , 1.0 } ,
{ - 1.0 , 1.0 , - 1.0 , - 1.0 , - 1.0 , 1.0 , 1.0 , 1.0 , - 1.0 , 1.0 } ,
{ - 1.0 , 1.0 , 1.0 , 1.0 } ,
{ - 1.0 , 1.0 , 1.0 , 1.0 , - 1.0 , 1.0 , - 1.0 , - 1.0 , - 1.0 , 1.0 } ,
{ - 1.0 , 1.0 , 1.0 , 1.0 , - 1.0 , 1.0 , - 1.0 , - 1.0 }
} ;
2013-11-29 03:55:51 +00:00
static const float sArrayY [ 10 ] [ 20 ] = { { .75 , 1.0 , 1.0 , - 1.0 , - 1.0 , - 1.0 } ,
2006-08-07 00:27:18 +00:00
{ 1.0 , 1.0 , 1.0 , 0.0 , 0.0 , 0.0 , 0.0 , - 1.0 , - 1.0 , - 1.0 } ,
{ 1.0 , 1.0 , 1.0 , - 1.0 , - 1.0 , - 1.0 , 0.0 , 0.0 } ,
{ 1.0 , 0.0 , 0.0 , 0.0 , 1.0 , - 1.0 } ,
{ 1.0 , 1.0 , 1.0 , 0.0 , 0.0 , 0.0 , 0.0 , - 1.0 , - 1.0 , - 1.0 } ,
{ 1.0 , 1.0 , 1.0 , - 1.0 , - 1.0 , - 1.0 , - 1.0 , 0.0 , 0.0 , 0.0 } ,
{ 1.0 , 1.0 , 1.0 , - 1.0 } ,
{ 1.0 , 1.0 , 1.0 , - 1.0 , - 1.0 , - 1.0 , - 1.0 , 1.0 , 0.0 , 0.0 } ,
{ 1.0 , 1.0 , 1.0 , - 1.0 , 0.0 , 0.0 , 0.0 , 1.0 }
} ;
2013-11-29 03:55:51 +00:00
static const int NumOfPoints [ ] = { 6 , 10 , 8 , 6 , 10 , 10 , 4 , 10 , 8 } ;
float ArrayX [ 10 ] , ArrayY [ 10 ] ;
2006-08-07 00:27:18 +00:00
for ( i = 0 ; i < NumOfPoints [ num ] ; i + + )
{
2013-11-29 03:55:51 +00:00
ArrayX [ i ] = sArrayX [ num ] [ i ] * MarkerScale ;
ArrayY [ i ] = sArrayY [ num ] [ i ] * MarkerScale ;
2006-08-07 00:27:18 +00:00
}
if ( num = = HighlightMarker )
2009-12-27 12:27:44 +00:00
gr_setcolor ( am - > white_63 ) ;
2006-08-07 00:27:18 +00:00
else
2009-12-27 12:27:44 +00:00
gr_setcolor ( am - > blue_48 ) ;
2006-08-07 00:27:18 +00:00
g3_rotate_point ( & BasePoint , & Objects [ MarkerObject [ ( Player_num * 2 ) + num ] ] . pos ) ;
for ( i = 0 ; i < NumOfPoints [ num ] ; i + = 2 )
{
FromPoint = BasePoint ;
ToPoint = BasePoint ;
2013-11-29 03:55:51 +00:00
FromPoint . p3_x + = fixmul ( ( fl2f ( ArrayX [ i ] ) ) , Matrix_scale . x ) ;
FromPoint . p3_y + = fixmul ( ( fl2f ( ArrayY [ i ] ) ) , Matrix_scale . y ) ;
2006-08-07 00:27:18 +00:00
g3_code_point ( & FromPoint ) ;
g3_project_point ( & FromPoint ) ;
2013-11-29 03:55:51 +00:00
ToPoint . p3_x + = fixmul ( ( fl2f ( ArrayX [ i + 1 ] ) ) , Matrix_scale . x ) ;
ToPoint . p3_y + = fixmul ( ( fl2f ( ArrayY [ i + 1 ] ) ) , Matrix_scale . y ) ;
2006-08-07 00:27:18 +00:00
g3_code_point ( & ToPoint ) ;
g3_project_point ( & ToPoint ) ;
automap_draw_line ( & FromPoint , & ToPoint ) ;
}
}
2006-03-20 17:12:09 +00:00
2013-10-27 22:00:14 +00:00
static void DropMarker ( int player_marker_num )
2006-03-20 17:12:09 +00:00
{
int marker_num = ( Player_num * 2 ) + player_marker_num ;
object * playerp = & Objects [ Players [ Player_num ] . objnum ] ;
2013-12-26 22:21:16 +00:00
if ( MarkerObject [ marker_num ] ! = object_none )
2006-03-20 17:12:09 +00:00
obj_delete ( MarkerObject [ marker_num ] ) ;
MarkerObject [ marker_num ] = drop_marker_object ( & playerp - > pos , playerp - > segnum , & playerp - > orient , marker_num ) ;
if ( Game_mode & GM_MULTI )
multi_send_drop_marker ( Player_num , playerp - > pos , player_marker_num , MarkerMessage [ marker_num ] ) ;
}
void DropBuddyMarker ( object * objp )
{
2006-08-07 00:27:18 +00:00
int marker_num ;
2006-03-20 17:12:09 +00:00
2006-08-07 00:27:18 +00:00
// Find spare marker slot. "if" code below should be an assert, but what if someone changes NUM_MARKERS or MAX_CROP_SINGLE and it never gets hit?
2006-03-20 17:12:09 +00:00
marker_num = MAX_DROP_SINGLE + 1 ;
if ( marker_num > NUM_MARKERS - 1 )
marker_num = NUM_MARKERS - 1 ;
2013-12-28 18:56:34 +00:00
snprintf ( & MarkerMessage [ marker_num ] [ 0 ] , MarkerMessage [ marker_num ] . size ( ) , " RIP: %s " , PlayerCfg . GuidebotName ) ;
2006-03-20 17:12:09 +00:00
2014-08-05 03:10:04 +00:00
if ( MarkerObject [ marker_num ] ! = object_none )
2006-03-20 17:12:09 +00:00
obj_delete ( MarkerObject [ marker_num ] ) ;
MarkerObject [ marker_num ] = drop_marker_object ( & objp - > pos , objp - > segnum , & objp - > orient , marker_num ) ;
}
# define MARKER_SPHERE_SIZE 0x58000
2013-10-27 22:00:14 +00:00
static void DrawMarkers ( automap * am )
2006-03-20 17:12:09 +00:00
{
int i , maxdrop ;
static int cyc = 10 , cycdir = 1 ;
g3s_point sphere_point ;
if ( Game_mode & GM_MULTI )
2006-08-07 00:27:18 +00:00
maxdrop = 2 ;
2006-03-20 17:12:09 +00:00
else
2006-08-07 00:27:18 +00:00
maxdrop = 9 ;
2006-03-20 17:12:09 +00:00
for ( i = 0 ; i < maxdrop ; i + + )
2013-12-26 22:21:16 +00:00
if ( MarkerObject [ ( Player_num * 2 ) + i ] ! = object_none ) {
2006-03-20 17:12:09 +00:00
g3_rotate_point ( & sphere_point , & Objects [ MarkerObject [ ( Player_num * 2 ) + i ] ] . pos ) ;
gr_setcolor ( gr_find_closest_color_current ( cyc , 0 , 0 ) ) ;
g3_draw_sphere ( & sphere_point , MARKER_SPHERE_SIZE ) ;
gr_setcolor ( gr_find_closest_color_current ( cyc + 10 , 0 , 0 ) ) ;
g3_draw_sphere ( & sphere_point , MARKER_SPHERE_SIZE / 2 ) ;
gr_setcolor ( gr_find_closest_color_current ( cyc + 20 , 0 , 0 ) ) ;
g3_draw_sphere ( & sphere_point , MARKER_SPHERE_SIZE / 4 ) ;
2009-12-27 12:27:44 +00:00
DrawMarkerNumber ( am , i ) ;
2006-03-20 17:12:09 +00:00
}
if ( cycdir )
cyc + = 2 ;
else
cyc - = 2 ;
if ( cyc > 43 )
2006-08-07 00:27:18 +00:00
{
2006-03-20 17:12:09 +00:00
cyc = 43 ;
cycdir = 0 ;
2006-08-07 00:27:18 +00:00
}
2006-03-20 17:12:09 +00:00
else if ( cyc < 10 )
2006-08-07 00:27:18 +00:00
{
2006-03-20 17:12:09 +00:00
cyc = 10 ;
cycdir = 1 ;
2006-08-07 00:27:18 +00:00
}
2006-03-20 17:12:09 +00:00
2006-08-07 00:27:18 +00:00
}
2006-03-20 17:12:09 +00:00
2013-10-27 22:00:14 +00:00
static void ClearMarkers ( )
2006-08-07 00:27:18 +00:00
{
2006-03-20 17:12:09 +00:00
int i ;
for ( i = 0 ; i < NUM_MARKERS ; i + + ) {
MarkerMessage [ i ] [ 0 ] = 0 ;
2013-12-26 22:21:16 +00:00
MarkerObject [ i ] = object_none ;
2006-03-20 17:12:09 +00:00
}
2006-08-07 00:27:18 +00:00
}
2013-03-03 01:03:33 +00:00
# endif
2006-03-20 17:12:09 +00:00
void automap_clear_visited ( )
{
2013-12-15 17:01:40 +00:00
Automap_visited . fill ( 0 ) ;
2013-12-15 18:32:10 +00:00
# ifndef NDEBUG
Automap_debug_show_all_segments = 0 ;
# endif
2006-08-07 00:27:18 +00:00
ClearMarkers ( ) ;
2006-03-20 17:12:09 +00:00
}
2013-10-27 22:00:14 +00:00
static void draw_player ( object * obj )
2006-03-20 17:12:09 +00:00
{
vms_vector arrow_pos , head_pos ;
g3s_point sphere_point , arrow_point , head_point ;
// Draw Console player -- shaped like a ellipse with an arrow.
g3_rotate_point ( & sphere_point , & obj - > pos ) ;
g3_draw_sphere ( & sphere_point , obj - > size ) ;
// Draw shaft of arrow
vm_vec_scale_add ( & arrow_pos , & obj - > pos , & obj - > orient . fvec , obj - > size * 3 ) ;
g3_rotate_point ( & arrow_point , & arrow_pos ) ;
automap_draw_line ( & sphere_point , & arrow_point ) ;
// Draw right head of arrow
vm_vec_scale_add ( & head_pos , & obj - > pos , & obj - > orient . fvec , obj - > size * 2 ) ;
vm_vec_scale_add2 ( & head_pos , & obj - > orient . rvec , obj - > size * 1 ) ;
g3_rotate_point ( & head_point , & head_pos ) ;
automap_draw_line ( & arrow_point , & head_point ) ;
// Draw left head of arrow
vm_vec_scale_add ( & head_pos , & obj - > pos , & obj - > orient . fvec , obj - > size * 2 ) ;
vm_vec_scale_add2 ( & head_pos , & obj - > orient . rvec , obj - > size * ( - 1 ) ) ;
g3_rotate_point ( & head_point , & head_pos ) ;
automap_draw_line ( & arrow_point , & head_point ) ;
// Draw player's up vector
vm_vec_scale_add ( & arrow_pos , & obj - > pos , & obj - > orient . uvec , obj - > size * 2 ) ;
g3_rotate_point ( & arrow_point , & arrow_pos ) ;
automap_draw_line ( & sphere_point , & arrow_point ) ;
}
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2008-02-24 14:41:27 +00:00
//name for each group. maybe move somewhere else
2013-11-28 00:21:46 +00:00
static const char system_name [ ] [ 17 ] = {
2008-02-24 14:41:27 +00:00
" Zeta Aquilae " ,
" Quartzon System " ,
" Brimspark System " ,
" Limefrost Spiral " ,
" Baloris Prime " ,
" Omega System " } ;
2013-03-03 01:03:33 +00:00
# endif
2008-02-24 14:41:27 +00:00
2013-10-27 22:00:14 +00:00
static void name_frame ( automap * am )
2008-02-24 14:41:27 +00:00
{
2013-10-27 17:07:54 +00:00
gr_set_curfont ( GAME_FONT ) ;
gr_set_fontcolor ( am - > green_31 , - 1 ) ;
char name_level_left [ 128 ] ;
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_I)
2013-10-27 17:07:54 +00:00
const char * name_level ;
2013-03-03 01:03:33 +00:00
if ( Current_level_num > 0 )
2013-10-27 17:07:54 +00:00
{
snprintf ( name_level_left , sizeof ( name_level_left ) , " %s %i: %s " , TXT_LEVEL , Current_level_num , Current_level_name ) ;
name_level = name_level_left ;
}
2013-03-03 01:03:33 +00:00
else
2013-10-27 17:07:54 +00:00
name_level = Current_level_name ;
2013-03-03 01:03:33 +00:00
2013-10-27 17:07:54 +00:00
gr_string ( ( SWIDTH / 64 ) , ( SHEIGHT / 48 ) , name_level ) ;
2013-03-03 01:03:33 +00:00
# elif defined(DXX_BUILD_DESCENT_II)
2013-10-27 17:07:54 +00:00
char name_level_right [ 128 ] ;
2008-02-24 14:41:27 +00:00
int wr , h , aw ;
if ( Current_level_num > 0 )
2013-10-27 17:07:54 +00:00
snprintf ( name_level_left , sizeof ( name_level_left ) , " %s %i " , TXT_LEVEL , Current_level_num ) ;
2008-02-24 14:41:27 +00:00
else
2013-10-27 17:07:54 +00:00
snprintf ( name_level_left , sizeof ( name_level_left ) , " Secret Level %i " , - Current_level_num ) ;
2008-02-24 14:41:27 +00:00
if ( PLAYING_BUILTIN_MISSION & & Current_level_num > 0 )
sprintf ( name_level_right , " %s %d: " , system_name [ ( Current_level_num - 1 ) / 4 ] , ( ( Current_level_num - 1 ) % 4 ) + 1 ) ;
else
strcpy ( name_level_right , " " ) ;
strcat ( name_level_right , Current_level_name ) ;
2012-06-24 20:52:25 +00:00
gr_string ( ( SWIDTH / 64 ) , ( SHEIGHT / 48 ) , name_level_left ) ;
2008-02-24 14:41:27 +00:00
gr_get_string_size ( name_level_right , & wr , & h , & aw ) ;
2012-06-24 20:52:25 +00:00
gr_string ( grd_curcanv - > cv_bitmap . bm_w - wr - ( SWIDTH / 64 ) , ( SHEIGHT / 48 ) , name_level_right ) ;
2013-03-03 01:03:33 +00:00
# endif
2008-02-24 14:41:27 +00:00
}
2006-12-24 09:15:37 +00:00
2013-10-27 22:00:14 +00:00
static void draw_automap ( automap * am )
2006-03-20 17:12:09 +00:00
{
int i ;
int color ;
object * objp ;
g3s_point sphere_point ;
2013-11-26 22:46:48 +00:00
if ( am - > leave_mode = = 0 & & am - > controls . state . automap & & ( timer_query ( ) - am - > entry_time ) > LEAVE_TIME )
2011-02-03 00:05:06 +00:00
am - > leave_mode = 1 ;
2007-04-01 05:06:35 +00:00
gr_set_current_canvas ( NULL ) ;
2009-12-27 12:27:44 +00:00
show_fullscr ( & am - > automap_background ) ;
2007-04-01 05:06:35 +00:00
gr_set_curfont ( HUGE_FONT ) ;
gr_set_fontcolor ( BM_XRGB ( 20 , 20 , 20 ) , - 1 ) ;
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_I)
if ( MacHog )
gr_string ( 80 * ( SWIDTH / 640.0 ) , 36 * ( SHEIGHT / 480.0 ) , TXT_AUTOMAP ) ;
else
# endif
gr_string ( ( SWIDTH / 8 ) , ( SHEIGHT / 16 ) , TXT_AUTOMAP ) ;
2008-02-24 14:41:27 +00:00
gr_set_curfont ( GAME_FONT ) ;
2007-04-01 05:06:35 +00:00
gr_set_fontcolor ( BM_XRGB ( 20 , 20 , 20 ) , - 1 ) ;
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_I)
if ( ! MacHog )
{
gr_string ( ( SWIDTH / 4.923 ) , ( SHEIGHT / 1.126 ) , TXT_TURN_SHIP ) ;
gr_string ( ( SWIDTH / 4.923 ) , ( SHEIGHT / 1.083 ) , TXT_SLIDE_UPDOWN ) ;
gr_string ( ( SWIDTH / 4.923 ) , ( SHEIGHT / 1.043 ) , " F9/F10 Changes viewing distance " ) ;
}
else
{
// for the Mac automap they're shown up the top, hence the different layout
gr_string ( 265 * ( SWIDTH / 640.0 ) , 27 * ( SHEIGHT / 480.0 ) , TXT_TURN_SHIP ) ;
gr_string ( 265 * ( SWIDTH / 640.0 ) , 44 * ( SHEIGHT / 480.0 ) , TXT_SLIDE_UPDOWN ) ;
gr_string ( 265 * ( SWIDTH / 640.0 ) , 61 * ( SHEIGHT / 480.0 ) , " F9/F10 Changes viewing distance " ) ;
}
# elif defined(DXX_BUILD_DESCENT_II)
2013-01-03 16:23:24 +00:00
gr_string ( ( SWIDTH / 10.666 ) , ( SHEIGHT / 1.126 ) , TXT_TURN_SHIP ) ;
2012-06-24 20:53:52 +00:00
gr_string ( ( SWIDTH / 10.666 ) , ( SHEIGHT / 1.083 ) , " F9/F10 Changes viewing distance " ) ;
2013-01-03 16:23:24 +00:00
gr_string ( ( SWIDTH / 10.666 ) , ( SHEIGHT / 1.043 ) , TXT_AUTOMAP_MARKER ) ;
2013-03-03 01:03:33 +00:00
# endif
2007-04-01 05:06:35 +00:00
2009-12-27 12:27:44 +00:00
gr_set_current_canvas ( & am - > automap_view ) ;
2006-03-20 17:12:09 +00:00
gr_clear_canvas ( BM_XRGB ( 0 , 0 , 0 ) ) ;
g3_start_frame ( ) ;
render_start_frame ( ) ;
2011-05-20 10:23:28 +00:00
if ( ! PlayerCfg . AutomapFreeFlight )
vm_vec_scale_add ( & am - > view_position , & am - > view_target , & am - > viewMatrix . fvec , - am - > viewDist ) ;
2011-04-10 11:57:06 +00:00
g3_set_view_matrix ( & am - > view_position , & am - > viewMatrix , am - > zoom ) ;
2006-03-20 17:12:09 +00:00
2009-12-27 12:27:44 +00:00
draw_all_edges ( am ) ;
2006-03-20 17:12:09 +00:00
// Draw player...
if ( Game_mode & GM_TEAM )
color = get_team ( Player_num ) ;
else
color = Player_num ; // Note link to above if!
2008-02-24 14:41:27 +00:00
gr_setcolor ( BM_XRGB ( player_rgb [ color ] . r , player_rgb [ color ] . g , player_rgb [ color ] . b ) ) ;
2006-03-20 17:12:09 +00:00
draw_player ( & Objects [ Players [ Player_num ] . objnum ] ) ;
2009-12-27 12:27:44 +00:00
DrawMarkers ( am ) ;
2006-03-20 17:12:09 +00:00
// Draw player(s)...
2013-08-24 16:33:51 +00:00
if ( ( Game_mode & ( GM_TEAM | GM_MULTI_COOP ) ) | | ( Netgame . game_flag . show_on_map ) ) {
2006-03-20 17:12:09 +00:00
for ( i = 0 ; i < N_players ; i + + ) {
2013-08-24 16:33:51 +00:00
if ( ( i ! = Player_num ) & & ( ( Game_mode & GM_MULTI_COOP ) | | ( get_team ( Player_num ) = = get_team ( i ) ) | | ( Netgame . game_flag . show_on_map ) ) ) {
2006-03-20 17:12:09 +00:00
if ( Objects [ Players [ i ] . objnum ] . type = = OBJ_PLAYER ) {
if ( Game_mode & GM_TEAM )
color = get_team ( i ) ;
else
color = i ;
2008-02-24 14:41:27 +00:00
gr_setcolor ( BM_XRGB ( player_rgb [ color ] . r , player_rgb [ color ] . g , player_rgb [ color ] . b ) ) ;
2006-03-20 17:12:09 +00:00
draw_player ( & Objects [ Players [ i ] . objnum ] ) ;
}
}
}
}
objp = & Objects [ 0 ] ;
for ( i = 0 ; i < = Highest_object_index ; i + + , objp + + ) {
switch ( objp - > type ) {
case OBJ_HOSTAGE :
2009-12-27 12:27:44 +00:00
gr_setcolor ( am - > hostage_color ) ;
2006-03-20 17:12:09 +00:00
g3_rotate_point ( & sphere_point , & objp - > pos ) ;
g3_draw_sphere ( & sphere_point , objp - > size ) ;
break ;
case OBJ_POWERUP :
2013-12-15 18:32:10 +00:00
if ( Automap_visited [ objp - > segnum ] | | Automap_debug_show_all_segments )
{
2013-12-15 18:08:12 +00:00
ubyte id = get_powerup_id ( objp ) ;
if ( id = = POW_KEY_RED )
gr_setcolor ( BM_XRGB ( 63 , 5 , 5 ) ) ;
else if ( id = = POW_KEY_BLUE )
gr_setcolor ( BM_XRGB ( 5 , 5 , 63 ) ) ;
else if ( id = = POW_KEY_GOLD )
gr_setcolor ( BM_XRGB ( 63 , 63 , 10 ) ) ;
else
break ;
g3_rotate_point ( & sphere_point , & objp - > pos ) ;
g3_draw_sphere ( & sphere_point , objp - > size * 4 ) ;
2006-03-20 17:12:09 +00:00
}
break ;
}
}
g3_end_frame ( ) ;
2009-12-27 12:27:44 +00:00
name_frame ( am ) ;
2008-02-24 14:41:27 +00:00
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2008-02-24 14:41:27 +00:00
if ( HighlightMarker > - 1 & & MarkerMessage [ HighlightMarker ] [ 0 ] ! = 0 )
{
2013-12-28 18:56:34 +00:00
gr_printf ( ( SWIDTH / 64 ) , ( SHEIGHT / 18 ) , " Marker %d: %s " , HighlightMarker + 1 , & MarkerMessage [ ( Player_num * 2 ) + HighlightMarker ] [ 0 ] ) ;
2008-02-24 14:41:27 +00:00
}
2013-03-03 01:03:33 +00:00
# endif
2011-01-06 13:56:26 +00:00
2011-01-10 15:12:04 +00:00
if ( PlayerCfg . MouseFlightSim & & PlayerCfg . MouseFSIndicator )
2011-02-10 13:09:10 +00:00
show_mousefs_indicator ( am - > controls . raw_mouse_axis [ 0 ] , am - > controls . raw_mouse_axis [ 1 ] , am - > controls . raw_mouse_axis [ 2 ] , GWIDTH - ( GHEIGHT / 8 ) , GHEIGHT - ( GHEIGHT / 8 ) , GHEIGHT / 5 ) ;
2006-03-20 17:12:09 +00:00
2011-02-03 00:05:06 +00:00
am - > t2 = timer_query ( ) ;
while ( am - > t2 - am - > t1 < F1_0 / ( GameCfg . VSync ? MAXIMUM_FPS : GameArg . SysMaxFPS ) ) // ogl is fast enough that the automap can read the input too fast and you start to turn really slow. So delay a bit (and free up some cpu :)
{
2013-12-09 15:28:34 +00:00
multi_do_frame ( ) ; // during long wait, keep packets flowing
2013-11-10 17:19:31 +00:00
if ( ! GameArg . SysNoNiceFPS & & ! GameCfg . VSync )
2013-12-09 15:28:34 +00:00
timer_delay ( F1_0 > > 8 ) ;
2011-02-03 00:05:06 +00:00
timer_update ( ) ;
am - > t2 = timer_query ( ) ;
}
if ( am - > pause_game )
{
FrameTime = am - > t2 - am - > t1 ;
2012-05-14 17:06:28 +00:00
calc_d_tick ( ) ;
2011-02-03 00:05:06 +00:00
}
am - > t1 = am - > t2 ;
}
2006-03-20 17:12:09 +00:00
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_I)
# define MAP_BACKGROUND_FILENAME (((SWIDTH>=640&&SHEIGHT>=480) && PHYSFSX_exists("maph.pcx",1))?"MAPH.PCX":"MAP.PCX")
# elif defined(DXX_BUILD_DESCENT_II)
2011-06-01 07:59:55 +00:00
# define MAP_BACKGROUND_FILENAME ((HIRESMODE && PHYSFSX_exists("mapb.pcx",1))?"MAPB.PCX":"MAP.PCX")
2013-03-03 01:03:33 +00:00
# endif
2006-03-20 17:12:09 +00:00
2013-12-15 18:32:10 +00:00
static void recompute_automap_segment_visibility ( automap * am )
{
int compute_depth_all_segments = ( cheats . fullautomap | | ( Players [ Player_num ] . flags & PLAYER_FLAGS_MAP_ALL ) ) ;
if ( Automap_debug_show_all_segments )
compute_depth_all_segments = 1 ;
automap_build_edge_list ( am , compute_depth_all_segments ) ;
am - > max_segments_away = set_segment_depths ( Objects [ Players [ Player_num ] . objnum ] . segnum , compute_depth_all_segments ? NULL : & Automap_visited , am - > depth_array ) ;
am - > segment_limit = am - > max_segments_away ;
adjust_segment_limit ( am , am - > segment_limit ) ;
}
2014-08-06 02:10:49 +00:00
static window_event_result automap_key_command ( window * wind , d_event * event , automap * am )
2010-03-26 14:05:40 +00:00
{
2011-01-14 09:51:13 +00:00
int c = event_key_get ( event ) ;
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2010-03-26 14:05:40 +00:00
int marker_num ;
char maxdrop ;
2013-03-03 01:03:33 +00:00
# endif
2010-03-26 14:05:40 +00:00
switch ( c )
{
case KEY_PRINT_SCREEN : {
gr_set_current_canvas ( NULL ) ;
save_screen_shot ( 1 ) ;
2014-08-06 02:10:49 +00:00
return window_event_result : : handled ;
2010-03-26 14:05:40 +00:00
}
case KEY_ESC :
if ( am - > leave_mode = = 0 )
{
window_close ( wind ) ;
2014-08-06 02:10:49 +00:00
return window_event_result : : close ;
2010-03-26 14:05:40 +00:00
}
2014-08-06 02:10:49 +00:00
return window_event_result : : handled ;
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_I)
case KEY_ALTED + KEY_F : // Alt+F shows full map, if cheats enabled
if ( cheats . enabled )
{
cheats . fullautomap = ! cheats . fullautomap ;
2013-12-15 12:11:14 +00:00
// if cheat of map powerup, work with full depth
2013-12-15 18:32:10 +00:00
recompute_automap_segment_visibility ( am ) ;
2013-03-03 01:03:33 +00:00
}
2014-08-06 02:10:49 +00:00
return window_event_result : : handled ;
2013-03-03 01:03:33 +00:00
# endif
2010-03-26 14:05:40 +00:00
# ifndef NDEBUG
case KEY_DEBUGGED + KEY_F : {
2013-12-15 18:32:10 +00:00
Automap_debug_show_all_segments = ! Automap_debug_show_all_segments ;
recompute_automap_segment_visibility ( am ) ;
2010-03-26 14:05:40 +00:00
}
2014-08-06 02:10:49 +00:00
return window_event_result : : handled ;
2010-03-26 14:05:40 +00:00
# endif
case KEY_F9 :
if ( am - > segment_limit > 1 ) {
am - > segment_limit - - ;
adjust_segment_limit ( am , am - > segment_limit ) ;
}
2014-08-06 02:10:49 +00:00
return window_event_result : : handled ;
2010-03-26 14:05:40 +00:00
case KEY_F10 :
if ( am - > segment_limit < am - > max_segments_away ) {
am - > segment_limit + + ;
adjust_segment_limit ( am , am - > segment_limit ) ;
}
2014-08-06 02:10:49 +00:00
return window_event_result : : handled ;
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2010-03-26 14:05:40 +00:00
case KEY_1 :
case KEY_2 :
case KEY_3 :
case KEY_4 :
case KEY_5 :
case KEY_6 :
case KEY_7 :
case KEY_8 :
case KEY_9 :
case KEY_0 :
if ( Game_mode & GM_MULTI )
maxdrop = 2 ;
else
maxdrop = 9 ;
marker_num = c - KEY_1 ;
if ( marker_num < = maxdrop )
{
2013-12-26 22:21:16 +00:00
if ( MarkerObject [ marker_num ] ! = object_none )
2010-03-26 14:05:40 +00:00
HighlightMarker = marker_num ;
}
2014-08-06 02:10:49 +00:00
return window_event_result : : handled ;
2010-03-26 14:05:40 +00:00
case KEY_D + KEY_CTRLED :
2013-12-26 22:21:16 +00:00
if ( HighlightMarker > - 1 & & MarkerObject [ HighlightMarker ] ! = object_none ) {
2010-03-26 14:05:40 +00:00
gr_set_current_canvas ( NULL ) ;
if ( nm_messagebox ( NULL , 2 , TXT_YES , TXT_NO , " Delete Marker? " ) = = 0 ) {
obj_delete ( MarkerObject [ HighlightMarker ] ) ;
2013-12-26 22:21:16 +00:00
MarkerObject [ HighlightMarker ] = object_none ;
2010-03-26 14:05:40 +00:00
MarkerMessage [ HighlightMarker ] [ 0 ] = 0 ;
HighlightMarker = - 1 ;
}
set_screen_mode ( SCREEN_GAME ) ;
}
2014-08-06 02:10:49 +00:00
return window_event_result : : handled ;
2010-03-26 14:05:40 +00:00
# ifndef RELEASE
2012-04-22 09:38:14 +00:00
case KEY_F11 : //KEY_COMMA:
2010-03-26 14:05:40 +00:00
if ( MarkerScale > .5 )
MarkerScale - = .5 ;
2014-08-06 02:10:49 +00:00
return window_event_result : : handled ;
2012-04-22 09:38:14 +00:00
case KEY_F12 : //KEY_PERIOD:
2010-03-26 14:05:40 +00:00
if ( MarkerScale < 30.0 )
MarkerScale + = .5 ;
2014-08-06 02:10:49 +00:00
return window_event_result : : handled ;
2013-03-03 01:03:33 +00:00
# endif
2010-03-26 14:05:40 +00:00
# endif
}
2014-08-06 02:10:49 +00:00
return window_event_result : : ignored ;
2010-03-26 14:05:40 +00:00
}
2014-08-06 02:10:49 +00:00
static window_event_result automap_process_input ( window * wind , d_event * event , automap * am )
2009-12-02 13:49:54 +00:00
{
2011-05-20 10:23:28 +00:00
vms_matrix tempm ;
2011-02-06 13:25:37 +00:00
Controls = am - > controls ;
kconfig_read_controls ( event , 1 ) ;
am - > controls = Controls ;
2014-07-04 03:50:50 +00:00
Controls = { } ;
2011-02-06 13:25:37 +00:00
2013-11-26 22:46:48 +00:00
if ( ! am - > controls . state . automap & & ( am - > leave_mode = = 1 ) )
2009-12-02 13:49:54 +00:00
{
window_close ( wind ) ;
2014-08-06 02:10:49 +00:00
return window_event_result : : close ;
2009-12-02 13:49:54 +00:00
}
2013-11-26 22:46:48 +00:00
if ( am - > controls . state . automap )
2011-02-02 00:36:49 +00:00
{
2013-11-26 22:46:48 +00:00
am - > controls . state . automap = 0 ;
2009-12-02 13:49:54 +00:00
if ( am - > leave_mode = = 0 )
{
window_close ( wind ) ;
2014-08-06 02:10:49 +00:00
return window_event_result : : close ;
2009-12-02 13:49:54 +00:00
}
}
2011-05-20 10:23:28 +00:00
if ( PlayerCfg . AutomapFreeFlight )
2011-04-10 11:57:06 +00:00
{
2013-11-26 22:46:48 +00:00
if ( am - > controls . state . fire_primary )
2011-05-20 10:23:28 +00:00
{
// Reset orientation
am - > viewMatrix = Objects [ Players [ Player_num ] . objnum ] . orient ;
vm_vec_scale_add ( & am - > view_position , & Objects [ Players [ Player_num ] . objnum ] . pos , & am - > viewMatrix . fvec , - ZOOM_DEFAULT ) ;
2013-11-26 22:46:48 +00:00
am - > controls . state . fire_primary = 0 ;
2011-05-20 10:23:28 +00:00
}
if ( am - > controls . pitch_time | | am - > controls . heading_time | | am - > controls . bank_time )
{
vms_angvec tangles ;
2011-04-10 11:57:06 +00:00
2011-05-20 10:23:28 +00:00
tangles . p = fixdiv ( am - > controls . pitch_time , ROT_SPEED_DIVISOR ) ;
tangles . h = fixdiv ( am - > controls . heading_time , ROT_SPEED_DIVISOR ) ;
tangles . b = fixdiv ( am - > controls . bank_time , ROT_SPEED_DIVISOR * 2 ) ;
2011-04-10 11:57:06 +00:00
2011-05-20 10:23:28 +00:00
vm_angles_2_matrix ( & tempm , & tangles ) ;
2014-07-13 04:40:28 +00:00
am - > viewMatrix = vm_matrix_x_matrix ( am - > viewMatrix , tempm ) ;
2011-07-15 14:01:40 +00:00
check_and_fix_matrix ( & am - > viewMatrix ) ;
2011-05-20 10:23:28 +00:00
}
if ( am - > controls . forward_thrust_time | | am - > controls . vertical_thrust_time | | am - > controls . sideways_thrust_time )
{
vm_vec_scale_add2 ( & am - > view_position , & am - > viewMatrix . fvec , am - > controls . forward_thrust_time * ZOOM_SPEED_FACTOR ) ;
vm_vec_scale_add2 ( & am - > view_position , & am - > viewMatrix . uvec , am - > controls . vertical_thrust_time * SLIDE_SPEED ) ;
vm_vec_scale_add2 ( & am - > view_position , & am - > viewMatrix . rvec , am - > controls . sideways_thrust_time * SLIDE_SPEED ) ;
// Crude wrapping check
2013-11-08 03:08:17 +00:00
clamp_fix_symmetric ( am - > view_position . x , F1_0 * 32000 ) ;
clamp_fix_symmetric ( am - > view_position . y , F1_0 * 32000 ) ;
clamp_fix_symmetric ( am - > view_position . z , F1_0 * 32000 ) ;
2011-05-20 10:23:28 +00:00
}
2011-04-10 11:57:06 +00:00
}
2011-05-20 10:23:28 +00:00
else
2011-04-10 11:57:06 +00:00
{
2013-11-26 22:46:48 +00:00
if ( am - > controls . state . fire_primary )
2011-05-20 10:23:28 +00:00
{
// Reset orientation
am - > viewDist = ZOOM_DEFAULT ;
am - > tangles . p = PITCH_DEFAULT ;
am - > tangles . h = 0 ;
am - > tangles . b = 0 ;
am - > view_target = Objects [ Players [ Player_num ] . objnum ] . pos ;
2013-11-26 22:46:48 +00:00
am - > controls . state . fire_primary = 0 ;
2011-05-20 10:23:28 +00:00
}
am - > viewDist - = am - > controls . forward_thrust_time * ZOOM_SPEED_FACTOR ;
am - > tangles . p + = fixdiv ( am - > controls . pitch_time , ROT_SPEED_DIVISOR ) ;
am - > tangles . h + = fixdiv ( am - > controls . heading_time , ROT_SPEED_DIVISOR ) ;
am - > tangles . b + = fixdiv ( am - > controls . bank_time , ROT_SPEED_DIVISOR * 2 ) ;
if ( am - > controls . vertical_thrust_time | | am - > controls . sideways_thrust_time )
{
vms_angvec tangles1 ;
vms_vector old_vt ;
old_vt = am - > view_target ;
tangles1 = am - > tangles ;
vm_angles_2_matrix ( & tempm , & tangles1 ) ;
vm_matrix_x_matrix ( & am - > viewMatrix , & Objects [ Players [ Player_num ] . objnum ] . orient , & tempm ) ;
vm_vec_scale_add2 ( & am - > view_target , & am - > viewMatrix . uvec , am - > controls . vertical_thrust_time * SLIDE_SPEED ) ;
vm_vec_scale_add2 ( & am - > view_target , & am - > viewMatrix . rvec , am - > controls . sideways_thrust_time * SLIDE_SPEED ) ;
if ( vm_vec_dist_quick ( & am - > view_target , & Objects [ Players [ Player_num ] . objnum ] . pos ) > i2f ( 1000 ) )
am - > view_target = old_vt ;
}
vm_angles_2_matrix ( & tempm , & am - > tangles ) ;
vm_matrix_x_matrix ( & am - > viewMatrix , & Objects [ Players [ Player_num ] . objnum ] . orient , & tempm ) ;
2013-11-08 03:19:05 +00:00
clamp_fix_lh ( am - > viewDist , ZOOM_MIN_VALUE , ZOOM_MAX_VALUE ) ;
2011-04-10 11:57:06 +00:00
}
2014-08-06 02:10:49 +00:00
return window_event_result : : ignored ;
2010-01-20 11:04:09 +00:00
}
2014-08-06 02:10:49 +00:00
static window_event_result automap_handler ( window * wind , d_event * event , automap * am )
2010-01-20 11:04:09 +00:00
{
switch ( event - > type )
{
2010-02-25 08:00:15 +00:00
case EVENT_WINDOW_ACTIVATED :
game_flush_inputs ( ) ;
2010-12-28 18:11:10 +00:00
event_toggle_focus ( 1 ) ;
2011-02-02 00:36:49 +00:00
key_toggle_repeat ( 0 ) ;
2010-07-16 11:07:42 +00:00
break ;
case EVENT_WINDOW_DEACTIVATED :
2010-12-28 18:11:10 +00:00
event_toggle_focus ( 0 ) ;
2011-02-02 00:36:49 +00:00
key_toggle_repeat ( 1 ) ;
2010-02-25 08:00:15 +00:00
break ;
2011-02-03 00:05:06 +00:00
case EVENT_IDLE :
2011-02-02 00:36:49 +00:00
case EVENT_JOYSTICK_BUTTON_UP :
case EVENT_JOYSTICK_BUTTON_DOWN :
case EVENT_JOYSTICK_MOVED :
case EVENT_MOUSE_BUTTON_UP :
case EVENT_MOUSE_BUTTON_DOWN :
case EVENT_MOUSE_MOVED :
2013-12-10 01:58:56 +00:00
case EVENT_KEY_RELEASE :
2014-08-06 02:10:49 +00:00
return automap_process_input ( wind , event , am ) ;
2010-03-26 14:05:40 +00:00
case EVENT_KEY_COMMAND :
2011-05-07 11:29:26 +00:00
{
2014-08-06 02:10:49 +00:00
window_event_result kret = automap_key_command ( wind , event , am ) ;
if ( kret = = window_event_result : : ignored )
2011-05-07 11:29:26 +00:00
automap_process_input ( wind , event , am ) ;
return kret ;
}
2010-01-20 11:04:09 +00:00
case EVENT_WINDOW_DRAW :
draw_automap ( am ) ;
break ;
case EVENT_WINDOW_CLOSE :
2011-02-06 13:25:37 +00:00
if ( ! am - > pause_game )
ConsoleObject - > mtype . phys_info . flags | = am - > old_wiggle ; // Restore wiggle
2010-12-28 18:11:10 +00:00
event_toggle_focus ( 0 ) ;
2011-02-02 00:36:49 +00:00
key_toggle_repeat ( 1 ) ;
2010-01-20 11:04:09 +00:00
# ifdef OGL
gr_free_bitmap_data ( & am - > automap_background ) ;
# endif
d_free ( am - > edges ) ;
d_free ( am - > drawingListBright ) ;
2014-08-01 03:11:28 +00:00
std : : default_delete < automap > ( ) ( am ) ;
2010-01-20 11:04:09 +00:00
window_set_visible ( Game_wind , 1 ) ;
2010-01-29 03:36:44 +00:00
Automap_active = 0 ;
2013-12-13 22:48:42 +00:00
multi_send_msgsend_state ( msgsend_none ) ;
2014-08-06 02:10:49 +00:00
return window_event_result : : ignored ; // continue closing
2010-01-20 11:04:09 +00:00
break ;
2013-02-21 00:20:26 +00:00
2010-01-20 11:04:09 +00:00
default :
2014-08-06 02:10:49 +00:00
return window_event_result : : ignored ;
2010-01-20 11:04:09 +00:00
break ;
}
2014-08-06 02:10:49 +00:00
return window_event_result : : handled ;
2009-12-02 13:49:54 +00:00
}
2006-03-20 17:12:09 +00:00
2014-07-16 02:35:14 +00:00
void do_automap ( )
2009-12-27 12:27:44 +00:00
{
2009-12-02 13:49:54 +00:00
int pcx_error ;
2013-01-06 21:03:57 +00:00
palette_array_t pal ;
2009-12-27 12:27:44 +00:00
window * automap_wind = NULL ;
2014-07-25 01:47:07 +00:00
automap * am = new automap { } ;
2010-01-31 21:51:59 +00:00
{
2013-12-01 05:21:47 +00:00
automap_wind = window_create ( & grd_curscreen - > sc_canvas , 0 , 0 , SWIDTH , SHEIGHT , automap_handler , am ) ;
2010-01-31 21:51:59 +00:00
}
2006-03-20 17:12:09 +00:00
2009-12-27 12:27:44 +00:00
if ( automap_wind = = NULL )
2009-12-02 13:49:54 +00:00
{
Warning ( " Out of memory " ) ;
return ;
}
2006-03-20 17:12:09 +00:00
2009-12-02 13:49:54 +00:00
am - > leave_mode = 0 ;
am - > pause_game = 1 ; // Set to 1 if everything is paused during automap...No pause during net.
am - > max_segments_away = 0 ;
am - > segment_limit = 1 ;
2009-12-27 12:27:44 +00:00
am - > num_edges = 0 ;
am - > highest_edge_index = - 1 ;
am - > max_edges = Num_segments * 12 ;
MALLOC ( am - > edges , Edge_info , am - > max_edges ) ;
2011-06-30 10:23:38 +00:00
MALLOC ( am - > drawingListBright , int , am - > max_edges ) ;
2009-12-27 12:27:44 +00:00
if ( ! am - > edges | | ! am - > drawingListBright )
{
if ( am - > edges )
d_free ( am - > edges ) ;
if ( am - > drawingListBright )
d_free ( am - > drawingListBright ) ;
Warning ( " Out of memory " ) ;
return ;
}
am - > zoom = 0x9000 ;
am - > farthest_dist = ( F1_0 * 20 * 50 ) ; // 50 segments away
2011-05-20 10:23:28 +00:00
am - > viewDist = 0 ;
2006-03-20 17:12:09 +00:00
2009-12-27 12:27:44 +00:00
init_automap_colors ( am ) ;
2010-04-04 01:31:48 +00:00
if ( ( Game_mode & GM_MULTI ) & & ( ! Endlevel_sequence ) )
2009-12-02 13:49:54 +00:00
am - > pause_game = 0 ;
2006-03-20 17:12:09 +00:00
2009-12-02 13:49:54 +00:00
if ( am - > pause_game ) {
2010-01-29 03:36:44 +00:00
window_set_visible ( Game_wind , 0 ) ;
2006-03-20 17:12:09 +00:00
}
2011-02-06 13:25:37 +00:00
if ( ! am - > pause_game ) {
am - > old_wiggle = ConsoleObject - > mtype . phys_info . flags & PF_WIGGLE ; // Save old wiggle
ConsoleObject - > mtype . phys_info . flags & = ~ PF_WIGGLE ; // Turn off wiggle
}
2006-03-20 17:12:09 +00:00
2009-12-27 12:27:44 +00:00
//Max_edges = min(MAX_EDGES_FROM_VERTS(Num_vertices),MAX_EDGES); //make maybe smaller than max
2006-03-20 17:12:09 +00:00
2009-12-02 13:49:54 +00:00
gr_set_current_canvas ( NULL ) ;
2011-05-20 10:23:28 +00:00
if ( am - > viewDist = = 0 )
am - > viewDist = ZOOM_DEFAULT ;
2009-12-02 13:49:54 +00:00
2011-05-20 10:23:28 +00:00
am - > viewMatrix = Objects [ Players [ Player_num ] . objnum ] . orient ;
am - > tangles . p = PITCH_DEFAULT ;
am - > tangles . h = 0 ;
am - > tangles . b = 0 ;
am - > view_target = Objects [ Players [ Player_num ] . objnum ] . pos ;
if ( PlayerCfg . AutomapFreeFlight )
vm_vec_scale_add ( & am - > view_position , & Objects [ Players [ Player_num ] . objnum ] . pos , & am - > viewMatrix . fvec , - ZOOM_DEFAULT ) ;
2009-12-02 13:49:54 +00:00
2010-12-10 23:18:17 +00:00
am - > t1 = am - > entry_time = timer_query ( ) ;
2009-12-02 13:49:54 +00:00
am - > t2 = am - > t1 ;
//Fill in Automap_visited from Objects[Players[Player_num].objnum].segnum
2013-12-15 18:32:10 +00:00
recompute_automap_segment_visibility ( am ) ;
2009-12-02 13:49:54 +00:00
// ZICO - code from above to show frame in OGL correctly. Redundant, but better readable.
// KREATOR - Now applies to all platforms so double buffering is supported
2009-12-27 12:27:44 +00:00
gr_init_bitmap_data ( & am - > automap_background ) ;
pcx_error = pcx_read_bitmap ( MAP_BACKGROUND_FILENAME , & am - > automap_background , BM_LINEAR , pal ) ;
2009-12-02 13:49:54 +00:00
if ( pcx_error ! = PCX_ERROR_NONE )
Error ( " File %s - PCX error: %s " , MAP_BACKGROUND_FILENAME , pcx_errormsg ( pcx_error ) ) ;
2009-12-27 12:27:44 +00:00
gr_remap_bitmap_good ( & am - > automap_background , pal , - 1 , - 1 ) ;
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_I)
if ( MacHog )
gr_init_sub_canvas ( & am - > automap_view , & grd_curscreen - > sc_canvas , 38 * ( SWIDTH / 640.0 ) , 77 * ( SHEIGHT / 480.0 ) , 564 * ( SWIDTH / 640.0 ) , 381 * ( SHEIGHT / 480.0 ) ) ;
else
# endif
gr_init_sub_canvas ( & am - > automap_view , & grd_curscreen - > sc_canvas , ( SWIDTH / 23 ) , ( SHEIGHT / 6 ) , ( SWIDTH / 1.1 ) , ( SHEIGHT / 1.45 ) ) ;
2009-12-02 13:49:54 +00:00
gr_palette_load ( gr_palette ) ;
2010-01-29 03:36:44 +00:00
Automap_active = 1 ;
2013-12-13 22:48:42 +00:00
multi_send_msgsend_state ( msgsend_automap ) ;
2006-03-20 17:12:09 +00:00
}
2009-12-27 12:27:44 +00:00
void adjust_segment_limit ( automap * am , int SegmentLimit )
2006-03-20 17:12:09 +00:00
{
int i , e1 ;
Edge_info * e ;
2009-12-27 12:27:44 +00:00
for ( i = 0 ; i < = am - > highest_edge_index ; i + + ) {
e = & am - > edges [ i ] ;
2006-03-20 17:12:09 +00:00
e - > flags | = EF_TOO_FAR ;
for ( e1 = 0 ; e1 < e - > num_faces ; e1 + + ) {
2013-12-15 18:32:10 +00:00
ubyte depthlimit = am - > depth_array [ e - > segnum [ e1 ] ] ;
2013-12-15 12:11:14 +00:00
if ( depthlimit < = SegmentLimit ) {
2006-03-20 17:12:09 +00:00
e - > flags & = ( ~ EF_TOO_FAR ) ;
break ;
}
}
}
}
2009-12-27 12:27:44 +00:00
void draw_all_edges ( automap * am )
2006-03-20 17:12:09 +00:00
{
g3s_codes cc ;
int i , j , nbright ;
ubyte nfacing , nnfacing ;
Edge_info * e ;
vms_vector * tv1 ;
fix distance ;
fix min_distance = 0x7fffffff ;
g3s_point * p1 , * p2 ;
nbright = 0 ;
2009-12-27 12:27:44 +00:00
for ( i = 0 ; i < = am - > highest_edge_index ; i + + ) {
//e = &am->edges[Edge_used_list[i]];
e = & am - > edges [ i ] ;
2006-03-20 17:12:09 +00:00
if ( ! ( e - > flags & EF_USED ) ) continue ;
if ( e - > flags & EF_TOO_FAR ) continue ;
2006-08-07 00:27:18 +00:00
if ( e - > flags & EF_FRONTIER ) { // A line that is between what we have seen and what we haven't
2009-12-27 12:27:44 +00:00
if ( ( ! ( e - > flags & EF_SECRET ) ) & & ( e - > color = = am - > wall_normal_color ) )
2006-08-07 00:27:18 +00:00
continue ; // If a line isn't secret and is normal color, then don't draw it
2006-03-20 17:12:09 +00:00
}
cc = rotate_list ( 2 , e - > verts ) ;
distance = Segment_points [ e - > verts [ 1 ] ] . p3_z ;
if ( min_distance > distance )
min_distance = distance ;
2012-11-02 17:08:58 +00:00
if ( ! cc . uand ) { //all off screen?
2006-03-20 17:12:09 +00:00
nfacing = nnfacing = 0 ;
tv1 = & Vertices [ e - > verts [ 0 ] ] ;
j = 0 ;
while ( j < e - > num_faces & & ( nfacing = = 0 | | nnfacing = = 0 ) ) {
if ( ! g3_check_normal_facing ( tv1 , & Segments [ e - > segnum [ j ] ] . sides [ e - > sides [ j ] ] . normals [ 0 ] ) )
nfacing + + ;
else
nnfacing + + ;
j + + ;
}
if ( nfacing & & nnfacing ) {
// a contour line
2009-12-27 12:27:44 +00:00
am - > drawingListBright [ nbright + + ] = e - am - > edges ;
2006-03-20 17:12:09 +00:00
} else if ( e - > flags & ( EF_DEFINING | EF_GRATE ) ) {
if ( nfacing = = 0 ) {
if ( e - > flags & EF_NO_FADE )
gr_setcolor ( e - > color ) ;
else
gr_setcolor ( gr_fade_table [ e - > color + 256 * 8 ] ) ;
g3_draw_line ( & Segment_points [ e - > verts [ 0 ] ] , & Segment_points [ e - > verts [ 1 ] ] ) ;
} else {
2009-12-27 12:27:44 +00:00
am - > drawingListBright [ nbright + + ] = e - am - > edges ;
2006-03-20 17:12:09 +00:00
}
}
}
}
if ( min_distance < 0 ) min_distance = 0 ;
// Sort the bright ones using a shell sort
{
int t ;
int i , j , incr , v1 , v2 ;
incr = nbright / 2 ;
while ( incr > 0 ) {
for ( i = incr ; i < nbright ; i + + ) {
j = i - incr ;
while ( j > = 0 ) {
// compare element j and j+incr
2009-12-27 12:27:44 +00:00
v1 = am - > edges [ am - > drawingListBright [ j ] ] . verts [ 0 ] ;
v2 = am - > edges [ am - > drawingListBright [ j + incr ] ] . verts [ 0 ] ;
2006-03-20 17:12:09 +00:00
if ( Segment_points [ v1 ] . p3_z < Segment_points [ v2 ] . p3_z ) {
// If not in correct order, them swap 'em
2009-12-27 12:27:44 +00:00
t = am - > drawingListBright [ j + incr ] ;
am - > drawingListBright [ j + incr ] = am - > drawingListBright [ j ] ;
am - > drawingListBright [ j ] = t ;
2006-03-20 17:12:09 +00:00
j - = incr ;
}
else
break ;
}
}
incr = incr / 2 ;
}
}
// Draw the bright ones
for ( i = 0 ; i < nbright ; i + + ) {
int color ;
fix dist ;
2009-12-27 12:27:44 +00:00
e = & am - > edges [ am - > drawingListBright [ i ] ] ;
2006-03-20 17:12:09 +00:00
p1 = & Segment_points [ e - > verts [ 0 ] ] ;
p2 = & Segment_points [ e - > verts [ 1 ] ] ;
dist = p1 - > p3_z - min_distance ;
// Make distance be 1.0 to 0.0, where 0.0 is 10 segments away;
if ( dist < 0 ) dist = 0 ;
2009-12-27 12:27:44 +00:00
if ( dist > = am - > farthest_dist ) continue ;
2006-03-20 17:12:09 +00:00
if ( e - > flags & EF_NO_FADE ) {
gr_setcolor ( e - > color ) ;
} else {
2009-12-27 12:27:44 +00:00
dist = F1_0 - fixdiv ( dist , am - > farthest_dist ) ;
2006-03-20 17:12:09 +00:00
color = f2i ( dist * 31 ) ;
gr_setcolor ( gr_fade_table [ e - > color + color * 256 ] ) ;
}
g3_draw_line ( p1 , p2 ) ;
}
}
//==================================================================
//
// All routines below here are used to build the Edge list
//
//==================================================================
//finds edge, filling in edge_ptr. if found old edge, returns index, else return -1
2009-12-27 12:27:44 +00:00
static int automap_find_edge ( automap * am , int v0 , int v1 , Edge_info * * edge_ptr )
2006-03-20 17:12:09 +00:00
{
long vv , evv ;
2011-06-30 10:23:38 +00:00
int hash , oldhash ;
2006-03-20 17:12:09 +00:00
int ret , ev0 , ev1 ;
vv = ( v1 < < 16 ) + v0 ;
2009-12-27 12:27:44 +00:00
oldhash = hash = ( ( v0 * 5 + v1 ) % am - > max_edges ) ;
2006-03-20 17:12:09 +00:00
ret = - 1 ;
while ( ret = = - 1 ) {
2011-06-30 10:23:38 +00:00
ev0 = am - > edges [ hash ] . verts [ 0 ] ;
ev1 = am - > edges [ hash ] . verts [ 1 ] ;
2006-03-20 17:12:09 +00:00
evv = ( ev1 < < 16 ) + ev0 ;
2009-12-27 12:27:44 +00:00
if ( am - > edges [ hash ] . num_faces = = 0 ) ret = 0 ;
2006-03-20 17:12:09 +00:00
else if ( evv = = vv ) ret = 1 ;
else {
2009-12-27 12:27:44 +00:00
if ( + + hash = = am - > max_edges ) hash = 0 ;
2006-03-20 17:12:09 +00:00
if ( hash = = oldhash ) Error ( " Edge list full! " ) ;
}
}
2009-12-27 12:27:44 +00:00
* edge_ptr = & am - > edges [ hash ] ;
2006-03-20 17:12:09 +00:00
if ( ret = = 0 )
return - 1 ;
else
return hash ;
}
2013-10-27 22:00:14 +00:00
static void add_one_edge ( automap * am , int va , int vb , ubyte color , ubyte side , int segnum , int hidden , int grate , int no_fade ) {
2006-03-20 17:12:09 +00:00
int found ;
Edge_info * e ;
2011-06-30 10:23:38 +00:00
int tmp ;
2006-03-20 17:12:09 +00:00
2009-12-27 12:27:44 +00:00
if ( am - > num_edges > = am - > max_edges ) {
2006-03-20 17:12:09 +00:00
// GET JOHN! (And tell him that his
// MAX_EDGES_FROM_VERTS formula is hosed.)
// If he's not around, save the mine,
// and send him mail so he can look
// at the mine later. Don't modify it.
// This is important if this happens.
Int3 ( ) ; // LOOK ABOVE!!!!!!
return ;
}
if ( va > vb ) {
tmp = va ;
va = vb ;
vb = tmp ;
}
2009-12-27 12:27:44 +00:00
found = automap_find_edge ( am , va , vb , & e ) ;
2006-03-20 17:12:09 +00:00
if ( found = = - 1 ) {
e - > verts [ 0 ] = va ;
e - > verts [ 1 ] = vb ;
e - > color = color ;
e - > num_faces = 1 ;
e - > flags = EF_USED | EF_DEFINING ; // Assume a normal line
e - > sides [ 0 ] = side ;
e - > segnum [ 0 ] = segnum ;
2009-12-27 12:27:44 +00:00
//Edge_used_list[am->num_edges] = e-am->edges;
if ( ( e - am - > edges ) > am - > highest_edge_index )
am - > highest_edge_index = e - am - > edges ;
am - > num_edges + + ;
2006-03-20 17:12:09 +00:00
} else {
2009-12-27 12:27:44 +00:00
if ( color ! = am - > wall_normal_color )
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2009-12-27 12:27:44 +00:00
if ( color ! = am - > wall_revealed_color )
2013-03-03 01:03:33 +00:00
# endif
2006-03-20 17:12:09 +00:00
e - > color = color ;
if ( e - > num_faces < 4 ) {
2009-12-02 13:49:54 +00:00
e - > sides [ e - > num_faces ] = side ;
2006-03-20 17:12:09 +00:00
e - > segnum [ e - > num_faces ] = segnum ;
e - > num_faces + + ;
}
}
if ( grate )
e - > flags | = EF_GRATE ;
if ( hidden )
e - > flags | = EF_SECRET ; // Mark this as a hidden edge
if ( no_fade )
e - > flags | = EF_NO_FADE ;
}
2013-10-27 22:00:14 +00:00
static void add_one_unknown_edge ( automap * am , int va , int vb )
2009-12-27 12:27:44 +00:00
{
2006-03-20 17:12:09 +00:00
int found ;
Edge_info * e ;
2011-06-30 10:23:38 +00:00
int tmp ;
2006-03-20 17:12:09 +00:00
if ( va > vb ) {
tmp = va ;
va = vb ;
vb = tmp ;
}
2009-12-27 12:27:44 +00:00
found = automap_find_edge ( am , va , vb , & e ) ;
2006-03-20 17:12:09 +00:00
if ( found ! = - 1 )
e - > flags | = EF_FRONTIER ; // Mark as a border edge
}
2013-10-27 22:00:14 +00:00
static void add_segment_edges ( automap * am , segment * seg )
2006-03-20 17:12:09 +00:00
{
int is_grate , no_fade ;
ubyte color ;
int sn ;
int segnum = seg - Segments ;
int hidden_flag ;
for ( sn = 0 ; sn < MAX_SIDES_PER_SEGMENT ; sn + + ) {
2011-06-30 10:23:38 +00:00
int vertex_list [ 4 ] ;
2006-03-20 17:12:09 +00:00
hidden_flag = 0 ;
is_grate = 0 ;
no_fade = 0 ;
color = 255 ;
2013-12-26 22:21:16 +00:00
if ( seg - > children [ sn ] = = segment_none ) {
2009-12-27 12:27:44 +00:00
color = am - > wall_normal_color ;
2006-03-20 17:12:09 +00:00
}
2013-03-03 01:03:33 +00:00
switch ( seg - > special ) {
2006-03-20 17:12:09 +00:00
case SEGMENT_IS_FUELCEN :
color = BM_XRGB ( 29 , 27 , 13 ) ;
break ;
case SEGMENT_IS_CONTROLCEN :
if ( Control_center_present )
color = BM_XRGB ( 29 , 0 , 0 ) ;
break ;
case SEGMENT_IS_ROBOTMAKER :
color = BM_XRGB ( 29 , 0 , 31 ) ;
break ;
}
if ( seg - > sides [ sn ] . wall_num > - 1 ) {
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
int trigger_num = Walls [ seg - > sides [ sn ] . wall_num ] . trigger ;
2013-11-10 18:07:19 +00:00
if ( trigger_num ! = - 1 & & Triggers [ trigger_num ] . type = = TT_SECRET_EXIT )
2006-03-20 17:12:09 +00:00
{
2006-08-07 00:27:18 +00:00
color = BM_XRGB ( 29 , 0 , 31 ) ;
2006-03-20 17:12:09 +00:00
no_fade = 1 ;
goto Here ;
}
2013-03-03 01:03:33 +00:00
# endif
2006-03-20 17:12:09 +00:00
switch ( Walls [ seg - > sides [ sn ] . wall_num ] . type ) {
case WALL_DOOR :
if ( Walls [ seg - > sides [ sn ] . wall_num ] . keys = = KEY_BLUE ) {
no_fade = 1 ;
2009-12-27 12:27:44 +00:00
color = am - > wall_door_blue ;
2006-03-20 17:12:09 +00:00
} else if ( Walls [ seg - > sides [ sn ] . wall_num ] . keys = = KEY_GOLD ) {
no_fade = 1 ;
2009-12-27 12:27:44 +00:00
color = am - > wall_door_gold ;
2006-03-20 17:12:09 +00:00
} else if ( Walls [ seg - > sides [ sn ] . wall_num ] . keys = = KEY_RED ) {
no_fade = 1 ;
2009-12-27 12:27:44 +00:00
color = am - > wall_door_red ;
2006-03-20 17:12:09 +00:00
} else if ( ! ( WallAnims [ Walls [ seg - > sides [ sn ] . wall_num ] . clip_num ] . flags & WCF_HIDDEN ) ) {
int connected_seg = seg - > children [ sn ] ;
2013-12-26 22:21:16 +00:00
if ( connected_seg ! = segment_none ) {
2006-03-20 17:12:09 +00:00
int connected_side = find_connect_side ( seg , & Segments [ connected_seg ] ) ;
int keytype = Walls [ Segments [ connected_seg ] . sides [ connected_side ] . wall_num ] . keys ;
if ( ( keytype ! = KEY_BLUE ) & & ( keytype ! = KEY_GOLD ) & & ( keytype ! = KEY_RED ) )
2009-12-27 12:27:44 +00:00
color = am - > wall_door_color ;
2006-03-20 17:12:09 +00:00
else {
switch ( Walls [ Segments [ connected_seg ] . sides [ connected_side ] . wall_num ] . keys ) {
2009-12-27 12:27:44 +00:00
case KEY_BLUE : color = am - > wall_door_blue ; no_fade = 1 ; break ;
case KEY_GOLD : color = am - > wall_door_gold ; no_fade = 1 ; break ;
case KEY_RED : color = am - > wall_door_red ; no_fade = 1 ; break ;
2006-03-20 17:12:09 +00:00
default : Error ( " Inconsistent data. Supposed to be a colored wall, but not blue, gold or red. \n " ) ;
}
}
}
} else {
2009-12-27 12:27:44 +00:00
color = am - > wall_normal_color ;
2006-03-20 17:12:09 +00:00
hidden_flag = 1 ;
}
break ;
case WALL_CLOSED :
// Make grates draw properly
2013-12-15 12:11:14 +00:00
// NOTE: In original D1, is_grate is 1, hidden_flag not used so grates never fade. I (zico) like this so I leave this alone for now.
2006-03-20 17:12:09 +00:00
if ( WALL_IS_DOORWAY ( seg , sn ) & WID_RENDPAST_FLAG )
is_grate = 1 ;
else
hidden_flag = 1 ;
2009-12-27 12:27:44 +00:00
color = am - > wall_normal_color ;
2006-03-20 17:12:09 +00:00
break ;
case WALL_BLASTABLE :
// Hostage doors
2009-12-27 12:27:44 +00:00
color = am - > wall_door_color ;
2006-03-20 17:12:09 +00:00
break ;
}
}
if ( segnum = = Player_init [ Player_num ] . segnum )
color = BM_XRGB ( 31 , 0 , 31 ) ;
if ( color ! = 255 ) {
2013-12-15 12:11:14 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
// If they have a map powerup, draw unvisited areas in dark blue.
2013-12-15 12:11:14 +00:00
// NOTE: D1 originally had this part of code but w/o cheat-check. It's only supposed to draw blue with powerup that does not exist in D1. So make this D2-only
2013-12-15 18:32:10 +00:00
if ( ! Automap_debug_show_all_segments )
2013-12-15 12:11:14 +00:00
if ( ( cheats . fullautomap | | Players [ Player_num ] . flags & PLAYER_FLAGS_MAP_ALL ) & & ( ! Automap_visited [ segnum ] ) )
2009-12-27 12:27:44 +00:00
color = am - > wall_revealed_color ;
2006-03-20 17:12:09 +00:00
Here :
2013-03-03 01:03:33 +00:00
# endif
2006-03-20 17:12:09 +00:00
get_side_verts ( vertex_list , segnum , sn ) ;
2009-12-27 12:27:44 +00:00
add_one_edge ( am , vertex_list [ 0 ] , vertex_list [ 1 ] , color , sn , segnum , hidden_flag , 0 , no_fade ) ;
add_one_edge ( am , vertex_list [ 1 ] , vertex_list [ 2 ] , color , sn , segnum , hidden_flag , 0 , no_fade ) ;
add_one_edge ( am , vertex_list [ 2 ] , vertex_list [ 3 ] , color , sn , segnum , hidden_flag , 0 , no_fade ) ;
add_one_edge ( am , vertex_list [ 3 ] , vertex_list [ 0 ] , color , sn , segnum , hidden_flag , 0 , no_fade ) ;
2006-03-20 17:12:09 +00:00
if ( is_grate ) {
2009-12-27 12:27:44 +00:00
add_one_edge ( am , vertex_list [ 0 ] , vertex_list [ 2 ] , color , sn , segnum , hidden_flag , 1 , no_fade ) ;
add_one_edge ( am , vertex_list [ 1 ] , vertex_list [ 3 ] , color , sn , segnum , hidden_flag , 1 , no_fade ) ;
2006-03-20 17:12:09 +00:00
}
}
}
}
// Adds all the edges from a segment we haven't visited yet.
2013-10-27 22:00:14 +00:00
static void add_unknown_segment_edges ( automap * am , segment * seg )
2006-03-20 17:12:09 +00:00
{
int sn ;
int segnum = seg - Segments ;
for ( sn = 0 ; sn < MAX_SIDES_PER_SEGMENT ; sn + + ) {
2011-06-30 10:23:38 +00:00
int vertex_list [ 4 ] ;
2006-03-20 17:12:09 +00:00
// Only add edges that have no children
2013-12-26 22:21:16 +00:00
if ( seg - > children [ sn ] = = segment_none ) {
2006-03-20 17:12:09 +00:00
get_side_verts ( vertex_list , segnum , sn ) ;
2009-12-27 12:27:44 +00:00
add_one_unknown_edge ( am , vertex_list [ 0 ] , vertex_list [ 1 ] ) ;
add_one_unknown_edge ( am , vertex_list [ 1 ] , vertex_list [ 2 ] ) ;
add_one_unknown_edge ( am , vertex_list [ 2 ] , vertex_list [ 3 ] ) ;
add_one_unknown_edge ( am , vertex_list [ 3 ] , vertex_list [ 0 ] ) ;
2006-03-20 17:12:09 +00:00
}
}
}
2013-12-15 18:32:10 +00:00
void automap_build_edge_list ( automap * am , int add_all_edges )
2006-03-20 17:12:09 +00:00
{
int i , e1 , e2 , s ;
Edge_info * e ;
// clear edge list
2009-12-27 12:27:44 +00:00
for ( i = 0 ; i < am - > max_edges ; i + + ) {
am - > edges [ i ] . num_faces = 0 ;
am - > edges [ i ] . flags = 0 ;
2006-03-20 17:12:09 +00:00
}
2009-12-27 12:27:44 +00:00
am - > num_edges = 0 ;
am - > highest_edge_index = - 1 ;
2006-03-20 17:12:09 +00:00
2013-12-15 18:32:10 +00:00
if ( add_all_edges ) {
2006-03-20 17:12:09 +00:00
// Cheating, add all edges as visited
for ( s = 0 ; s < = Highest_segment_index ; s + + )
2006-08-07 00:27:18 +00:00
# ifdef EDITOR
2013-12-26 22:21:16 +00:00
if ( Segments [ s ] . segnum ! = segment_none )
2006-08-07 00:27:18 +00:00
# endif
2006-03-20 17:12:09 +00:00
{
2009-12-27 12:27:44 +00:00
add_segment_edges ( am , & Segments [ s ] ) ;
2006-03-20 17:12:09 +00:00
}
} else {
// Not cheating, add visited edges, and then unvisited edges
for ( s = 0 ; s < = Highest_segment_index ; s + + )
2006-08-07 00:27:18 +00:00
# ifdef EDITOR
2013-12-26 22:21:16 +00:00
if ( Segments [ s ] . segnum ! = segment_none )
2006-08-07 00:27:18 +00:00
# endif
2006-03-20 17:12:09 +00:00
if ( Automap_visited [ s ] ) {
2009-12-27 12:27:44 +00:00
add_segment_edges ( am , & Segments [ s ] ) ;
2006-03-20 17:12:09 +00:00
}
for ( s = 0 ; s < = Highest_segment_index ; s + + )
2006-08-07 00:27:18 +00:00
# ifdef EDITOR
2013-12-26 22:21:16 +00:00
if ( Segments [ s ] . segnum ! = segment_none )
2006-08-07 00:27:18 +00:00
# endif
2006-03-20 17:12:09 +00:00
if ( ! Automap_visited [ s ] ) {
2009-12-27 12:27:44 +00:00
add_unknown_segment_edges ( am , & Segments [ s ] ) ;
2006-03-20 17:12:09 +00:00
}
}
// Find unnecessary lines (These are lines that don't have to be drawn because they have small curvature)
2009-12-27 12:27:44 +00:00
for ( i = 0 ; i < = am - > highest_edge_index ; i + + ) {
e = & am - > edges [ i ] ;
2006-03-20 17:12:09 +00:00
if ( ! ( e - > flags & EF_USED ) ) continue ;
for ( e1 = 0 ; e1 < e - > num_faces ; e1 + + ) {
for ( e2 = 1 ; e2 < e - > num_faces ; e2 + + ) {
if ( ( e1 ! = e2 ) & & ( e - > segnum [ e1 ] ! = e - > segnum [ e2 ] ) ) {
if ( vm_vec_dot ( & Segments [ e - > segnum [ e1 ] ] . sides [ e - > sides [ e1 ] ] . normals [ 0 ] , & Segments [ e - > segnum [ e2 ] ] . sides [ e - > sides [ e2 ] ] . normals [ 0 ] ) > ( F1_0 - ( F1_0 / 10 ) ) ) {
e - > flags & = ( ~ EF_DEFINING ) ;
break ;
}
}
}
if ( ! ( e - > flags & EF_DEFINING ) )
break ;
}
2009-12-02 13:49:54 +00:00
}
2006-03-20 17:12:09 +00:00
}
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
int Marker_index = 0 ;
ubyte DefiningMarkerMessage = 0 ;
ubyte MarkerBeingDefined ;
ubyte LastMarkerDropped ;
void InitMarkerInput ( )
2006-08-07 00:27:18 +00:00
{
2006-03-20 17:12:09 +00:00
int maxdrop , i ;
//find free marker slot
if ( Game_mode & GM_MULTI )
2006-08-07 00:27:18 +00:00
maxdrop = MAX_DROP_MULTI ;
2006-03-20 17:12:09 +00:00
else
2006-08-07 00:27:18 +00:00
maxdrop = MAX_DROP_SINGLE ;
2006-03-20 17:12:09 +00:00
for ( i = 0 ; i < maxdrop ; i + + )
2013-12-26 22:21:16 +00:00
if ( MarkerObject [ ( Player_num * 2 ) + i ] = = object_none ) //found free slot!
2006-03-20 17:12:09 +00:00
break ;
if ( i = = maxdrop ) //no free slot
{
if ( Game_mode & GM_MULTI )
i = ! LastMarkerDropped ; //in multi, replace older of two
else {
2013-06-23 16:27:34 +00:00
HUD_init_message_literal ( HM_DEFAULT , " No free marker slots " ) ;
2006-03-20 17:12:09 +00:00
return ;
}
}
//got a free slot. start inputting marker message
Marker_input [ 0 ] = 0 ;
Marker_index = 0 ;
DefiningMarkerMessage = 1 ;
MarkerBeingDefined = i ;
2011-02-02 00:36:49 +00:00
key_toggle_repeat ( 1 ) ;
2006-08-07 00:27:18 +00:00
}
2006-03-20 17:12:09 +00:00
2014-08-06 02:10:49 +00:00
window_event_result MarkerInputMessage ( int key )
2006-08-07 00:27:18 +00:00
{
2008-05-07 14:02:01 +00:00
switch ( key )
{
case KEY_F8 :
case KEY_ESC :
DefiningMarkerMessage = 0 ;
2011-02-02 00:36:49 +00:00
key_toggle_repeat ( 0 ) ;
2008-05-07 14:02:01 +00:00
game_flush_inputs ( ) ;
break ;
case KEY_LEFT :
case KEY_BACKSP :
case KEY_PAD4 :
if ( Marker_index > 0 )
Marker_index - - ;
Marker_input [ Marker_index ] = 0 ;
break ;
case KEY_ENTER :
2013-12-28 18:56:34 +00:00
MarkerMessage [ ( Player_num * 2 ) + MarkerBeingDefined ] = Marker_input ;
2008-05-07 14:02:01 +00:00
DropMarker ( MarkerBeingDefined ) ;
LastMarkerDropped = MarkerBeingDefined ;
2011-02-02 00:36:49 +00:00
key_toggle_repeat ( 0 ) ;
2008-05-07 14:02:01 +00:00
game_flush_inputs ( ) ;
DefiningMarkerMessage = 0 ;
break ;
default :
2008-11-17 23:38:43 +00:00
{
int ascii = key_ascii ( ) ;
2006-08-07 00:27:18 +00:00
if ( ( ascii < 255 ) )
if ( Marker_index < 38 )
{
Marker_input [ Marker_index + + ] = ascii ;
Marker_input [ Marker_index ] = 0 ;
}
2014-08-06 02:10:49 +00:00
return window_event_result : : ignored ;
2006-08-07 00:27:18 +00:00
}
2006-03-20 17:12:09 +00:00
}
2014-08-06 02:10:49 +00:00
return window_event_result : : handled ;
2006-08-07 00:27:18 +00:00
}
2013-03-03 01:03:33 +00:00
# endif