2006-08-07 00:26:03 +00:00
/* $Id: automap.c,v 1.1.1.1 2006/03/17 19:56:52 zicodxx Exp $ */
2006-03-20 16:43:15 +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
2006-08-07 00:26:03 +00:00
AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE .
COPYRIGHT 1993 - 1999 PARALLAX SOFTWARE CORPORATION . ALL RIGHTS RESERVED .
2006-03-20 16:43:15 +00:00
*/
2006-08-07 00:26:03 +00:00
/*
*
* Routines for displaying the auto - map .
*
*/
2006-03-20 16:43:15 +00:00
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# ifdef OGL
# include "ogl_init.h"
# endif
# include "error.h"
# 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"
2009-12-02 13:49:54 +00:00
# include "newmenu.h"
# include "menu.h"
2006-03-20 16:43:15 +00:00
# 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"
# include "hostage.h"
# include "fuelcen.h"
# include "gameseq.h"
# include "gamefont.h"
2009-12-02 13:49:54 +00:00
# ifdef NETWORK
2006-03-20 16:43:15 +00:00
# include "multi.h"
2009-12-02 13:49:54 +00:00
# endif
# include "kconfig.h"
2006-03-20 16:43:15 +00:00
# include "endlevel.h"
# include "text.h"
# include "gauges.h"
# include "powerup.h"
2009-12-02 13:49:54 +00:00
# include "switch.h"
# include "automap.h"
2006-08-07 00:26:03 +00:00
# include "cntrlcen.h"
2007-03-25 21:00:14 +00:00
# include "timer.h"
2009-01-15 20:55:35 +00:00
# include "config.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:00 +00:00
# include "playsave.h"
2006-03-20 16:43:15 +00:00
2011-02-03 00:05:01 +00:00
# define LEAVE_TIME 0x4000
2006-08-07 00:26:03 +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
2006-03-20 16:43:15 +00:00
typedef struct Edge_info {
2006-08-07 00:26:03 +00:00
short verts [ 2 ] ; // 4 bytes
ubyte sides [ 4 ] ; // 4 bytes
short segnum [ 4 ] ; // 8 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 // 19 bytes...
2006-03-20 16:43:15 +00:00
} Edge_info ;
2009-12-02 13:49:54 +00:00
typedef struct automap
{
2010-12-10 23:18:03 +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:22 +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:22 +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:22 +00:00
Edge_info * edges ;
short * drawingListBright ;
2009-12-27 12:27:44 +00:00
// Screen canvas variables
2011-05-20 10:23:22 +00:00
grs_canvas automap_view ;
2009-12-27 12:27:44 +00:00
2011-05-20 10:23:22 +00:00
grs_bitmap automap_background ;
2009-12-27 12:27:44 +00:00
// Rendering variables
fix zoom ;
2011-05-20 10:23:22 +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:22 +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:31 +00:00
control_info controls ;
2009-12-02 13:49:54 +00:00
} automap ;
2006-08-07 00:26:03 +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_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 ;
2009-12-27 12:27:44 +00:00
void init_automap_colors ( automap * am )
2006-08-07 00:26:03 +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 ;
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-08-07 00:26:03 +00:00
}
2006-03-20 16:43:15 +00:00
// Segment visited list
ubyte Automap_visited [ MAX_SEGMENTS ] ;
// Map movement defines
2009-12-02 13:49:54 +00:00
# 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-03-20 16:43:15 +00:00
2009-12-02 13:49:54 +00:00
# define SLIDE_SPEED (350)
# define ZOOM_SPEED_FACTOR (500) //(1500)
# define ROT_SPEED_DIVISOR (115000)
2006-03-20 16:43:15 +00:00
2009-12-02 13:49:54 +00:00
// Function Prototypes
2009-12-27 12:27:44 +00:00
void adjust_segment_limit ( automap * am , int SegmentLimit ) ;
void draw_all_edges ( automap * am ) ;
void automap_build_edge_list ( automap * am ) ;
2006-08-07 00:26:03 +00:00
2006-08-13 15:52:49 +00:00
# define MAX_DROP_MULTI 2
2006-08-07 00:26:03 +00:00
# define MAX_DROP_SINGLE 9
2009-12-02 13:49:54 +00:00
extern vms_vector Matrix_scale ; //how the matrix is currently scaled
2006-08-07 00:26:03 +00:00
# define automap_draw_line g3_draw_line
2006-03-20 16:43:15 +00:00
void automap_clear_visited ( )
{
int i ;
for ( i = 0 ; i < MAX_SEGMENTS ; i + + )
Automap_visited [ i ] = 0 ;
}
void draw_player ( object * obj )
{
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 ) ;
2006-08-07 00:26:03 +00:00
automap_draw_line ( & sphere_point , & arrow_point ) ;
2006-03-20 16:43:15 +00:00
// 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 ) ;
2006-08-07 00:26:03 +00:00
automap_draw_line ( & arrow_point , & head_point ) ;
2006-03-20 16:43:15 +00:00
// 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 ) ;
2006-08-07 00:26:03 +00:00
automap_draw_line ( & arrow_point , & head_point ) ;
2006-03-20 16:43:15 +00:00
// 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 ) ;
2006-08-07 00:26:03 +00:00
automap_draw_line ( & sphere_point , & arrow_point ) ;
2006-03-20 16:43:15 +00:00
}
2009-12-27 12:27:44 +00:00
void name_frame ( automap * am )
2009-12-02 13:49:54 +00:00
{
2009-12-27 12:27:44 +00:00
char name_level [ 128 ] ;
2009-12-02 13:49:54 +00:00
if ( Current_level_num > 0 )
sprintf ( name_level , " %s %i: " , TXT_LEVEL , Current_level_num ) ;
else
name_level [ 0 ] = 0 ;
strcat ( name_level , Current_level_name ) ;
gr_set_curfont ( GAME_FONT ) ;
2009-12-27 12:27:44 +00:00
gr_set_fontcolor ( am - > green_31 , - 1 ) ;
2009-12-02 13:49:54 +00:00
gr_printf ( ( SWIDTH / 64 ) , ( SHEIGHT / 48 ) , " %s " , name_level ) ;
}
2009-12-27 12:27:44 +00:00
void draw_automap ( automap * am )
2006-03-20 16:43:15 +00:00
{
int i ;
int color ;
object * objp ;
g3s_point sphere_point ;
2011-02-03 00:05:01 +00:00
2011-02-06 13:25:31 +00:00
if ( am - > leave_mode = = 0 & & am - > controls . automap_state & & ( timer_query ( ) - am - > entry_time ) > LEAVE_TIME )
2011-02-03 00:05:01 +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 ) ;
2008-02-24 14:41:27 +00:00
gr_set_curfont ( HUGE_FONT ) ;
2007-04-01 05:06:35 +00:00
gr_set_fontcolor ( BM_XRGB ( 20 , 20 , 20 ) , - 1 ) ;
2008-04-02 12:13:21 +00:00
if ( ! MacHog )
gr_printf ( ( SWIDTH / 8 ) , ( SHEIGHT / 16 ) , TXT_AUTOMAP ) ;
else
gr_printf ( 80 * ( SWIDTH / 640.0 ) , 36 * ( SHEIGHT / 480.0 ) , TXT_AUTOMAP ) ;
2007-04-01 05:06:35 +00:00
gr_set_curfont ( GAME_FONT ) ;
gr_set_fontcolor ( BM_XRGB ( 20 , 20 , 20 ) , - 1 ) ;
2008-04-02 12:13:21 +00:00
if ( ! MacHog )
{
gr_printf ( ( SWIDTH / 4.923 ) , ( SHEIGHT / 1.126 ) , TXT_TURN_SHIP ) ;
gr_printf ( ( SWIDTH / 4.923 ) , ( SHEIGHT / 1.083 ) , TXT_SLIDE_UPDOWN ) ;
2008-11-18 14:43:30 +00:00
gr_printf ( ( SWIDTH / 4.923 ) , ( SHEIGHT / 1.043 ) , " F9/F10 Changes viewing distance " ) ;
2008-04-02 12:13:21 +00:00
}
else
{
// for the Mac automap they're shown up the top, hence the different layout
gr_printf ( 265 * ( SWIDTH / 640.0 ) , 27 * ( SHEIGHT / 480.0 ) , TXT_TURN_SHIP ) ;
gr_printf ( 265 * ( SWIDTH / 640.0 ) , 44 * ( SHEIGHT / 480.0 ) , TXT_SLIDE_UPDOWN ) ;
2008-11-18 14:43:30 +00:00
gr_printf ( 265 * ( SWIDTH / 640.0 ) , 61 * ( SHEIGHT / 480.0 ) , " F9/F10 Changes viewing distance " ) ;
2008-04-02 12:13:21 +00:00
}
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 16:43:15 +00:00
2006-08-07 00:26:03 +00:00
gr_clear_canvas ( BM_XRGB ( 0 , 0 , 0 ) ) ;
2006-03-20 16:43:15 +00:00
g3_start_frame ( ) ;
render_start_frame ( ) ;
2006-08-07 00:26:03 +00:00
2011-05-20 10:23:22 +00:00
if ( ! PlayerCfg . AutomapFreeFlight )
vm_vec_scale_add ( & am - > view_position , & am - > view_target , & am - > viewMatrix . fvec , - am - > viewDist ) ;
2011-04-10 11:53:51 +00:00
g3_set_view_matrix ( & am - > view_position , & am - > viewMatrix , am - > zoom ) ;
2006-03-20 16:43:15 +00:00
2009-12-27 12:27:44 +00:00
draw_all_edges ( am ) ;
2006-03-20 16:43:15 +00:00
// Draw player...
# ifdef NETWORK
if ( Game_mode & GM_TEAM )
color = get_team ( Player_num ) ;
else
# endif
2009-12-02 13:49:54 +00:00
color = Player_num ; // Note link to above if!
2006-08-07 00:26:03 +00:00
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 16:43:15 +00:00
draw_player ( & Objects [ Players [ Player_num ] . objnum ] ) ;
2006-08-07 00:26:03 +00:00
2006-03-20 16:43:15 +00:00
// Draw player(s)...
# ifdef NETWORK
if ( ( Game_mode & ( GM_TEAM | GM_MULTI_COOP ) ) | | ( Netgame . game_flags & NETGAME_FLAG_SHOW_MAP ) ) {
for ( i = 0 ; i < N_players ; i + + ) {
if ( ( i ! = Player_num ) & & ( ( Game_mode & GM_MULTI_COOP ) | | ( get_team ( Player_num ) = = get_team ( i ) ) | | ( Netgame . game_flags & NETGAME_FLAG_SHOW_MAP ) ) ) {
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 16:43:15 +00:00
draw_player ( & Objects [ Players [ i ] . objnum ] ) ;
}
}
}
}
# endif
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 16:43:15 +00:00
g3_rotate_point ( & sphere_point , & objp - > pos ) ;
g3_draw_sphere ( & sphere_point , objp - > size ) ;
break ;
case OBJ_POWERUP :
if ( Automap_visited [ objp - > segnum ] ) {
if ( ( objp - > id = = POW_KEY_RED ) | | ( objp - > id = = POW_KEY_BLUE ) | | ( objp - > id = = POW_KEY_GOLD ) ) {
switch ( objp - > id ) {
2008-02-24 14:41:27 +00:00
case POW_KEY_RED : gr_setcolor ( BM_XRGB ( 63 , 5 , 5 ) ) ; break ;
case POW_KEY_BLUE : gr_setcolor ( BM_XRGB ( 5 , 5 , 63 ) ) ; break ;
case POW_KEY_GOLD : gr_setcolor ( BM_XRGB ( 63 , 63 , 10 ) ) ; break ;
2006-08-07 00:26:03 +00:00
default :
Error ( " Illegal key type: %i " , objp - > id ) ;
2006-03-20 16:43:15 +00:00
}
g3_rotate_point ( & sphere_point , & objp - > pos ) ;
g3_draw_sphere ( & sphere_point , objp - > size * 4 ) ;
}
}
break ;
}
}
g3_end_frame ( ) ;
2009-12-27 12:27:44 +00:00
name_frame ( am ) ;
2011-01-06 13:56:12 +00:00
2011-01-10 15:12:00 +00:00
if ( PlayerCfg . MouseFlightSim & & PlayerCfg . MouseFSIndicator )
2011-02-10 13:09:05 +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 16:43:15 +00:00
2011-02-03 00:05:01 +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 :)
{
if ( GameArg . SysUseNiceFPS & & ! GameCfg . VSync )
timer_delay ( f1_0 / GameArg . SysMaxFPS - ( am - > t2 - am - > t1 ) ) ;
timer_update ( ) ;
am - > t2 = timer_query ( ) ;
}
if ( am - > pause_game )
{
FrameTime = am - > t2 - am - > t1 ;
FixedStepCalc ( ) ;
}
am - > t1 = am - > t2 ;
}
2006-08-07 00:26:03 +00:00
2006-03-20 16:43:15 +00:00
extern int set_segment_depths ( int start_seg , ubyte * segbuf ) ;
2006-08-07 00:26:03 +00:00
# define MAP_BACKGROUND_FILENAME "MAP.PCX"
2006-03-20 16:43:15 +00:00
2010-03-26 14:05:40 +00:00
int automap_key_command ( window * wind , d_event * event , automap * am )
{
2011-01-13 04:36:19 +00:00
int c = event_key_get ( event ) ;
2010-03-26 14:05:40 +00:00
switch ( c )
{
case KEY_PRINT_SCREEN : {
gr_set_current_canvas ( NULL ) ;
save_screen_shot ( 1 ) ;
return 1 ;
}
case KEY_ESC :
if ( am - > leave_mode = = 0 )
{
window_close ( wind ) ;
return 1 ;
}
return 1 ;
case KEY_ALTED + KEY_F : // Alt+F shows full map, if cheats enabled
2011-02-14 21:27:02 +00:00
if ( cheats . enabled )
2010-03-26 14:05:40 +00:00
{
2011-02-14 21:27:02 +00:00
cheats . fullautomap = ! cheats . fullautomap ;
2010-03-26 14:05:40 +00:00
automap_build_edge_list ( am ) ;
}
return 1 ;
# ifndef NDEBUG
case KEY_DEBUGGED + KEY_F : {
int i ;
for ( i = 0 ; i < = Highest_segment_index ; i + + )
Automap_visited [ i ] = 1 ;
automap_build_edge_list ( am ) ;
am - > max_segments_away = set_segment_depths ( Objects [ Players [ Player_num ] . objnum ] . segnum , Automap_visited ) ;
am - > segment_limit = am - > max_segments_away ;
adjust_segment_limit ( am , am - > segment_limit ) ;
}
return 1 ;
# endif
case KEY_F9 :
if ( am - > segment_limit > 1 ) {
am - > segment_limit - - ;
adjust_segment_limit ( am , am - > segment_limit ) ;
}
return 1 ;
case KEY_F10 :
if ( am - > segment_limit < am - > max_segments_away ) {
am - > segment_limit + + ;
adjust_segment_limit ( am , am - > segment_limit ) ;
}
return 1 ;
}
return 0 ;
}
2011-02-03 00:05:01 +00:00
int automap_process_input ( window * wind , d_event * event , automap * am )
2009-12-02 13:49:54 +00:00
{
2011-05-20 10:23:22 +00:00
vms_matrix tempm ;
2011-02-06 13:25:31 +00:00
Controls = am - > controls ;
kconfig_read_controls ( event , 1 ) ;
am - > controls = Controls ;
memset ( & Controls , 0 , sizeof ( control_info ) ) ;
if ( ! am - > controls . automap_state & & ( am - > leave_mode = = 1 ) )
2009-12-02 13:49:54 +00:00
{
window_close ( wind ) ;
return 1 ;
}
2011-02-06 13:25:31 +00:00
if ( am - > controls . automap_count > 0 )
2011-02-02 00:36:43 +00:00
{
2011-02-06 13:25:31 +00:00
am - > controls . automap_count = 0 ;
2009-12-02 13:49:54 +00:00
if ( am - > leave_mode = = 0 )
{
window_close ( wind ) ;
return 1 ;
}
}
2011-05-20 10:23:22 +00:00
if ( PlayerCfg . AutomapFreeFlight )
2011-04-10 11:53:51 +00:00
{
2011-05-20 10:23:22 +00:00
if ( am - > controls . fire_primary_count > 0 )
{
// 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 ) ;
am - > controls . fire_primary_count = 0 ;
}
if ( am - > controls . pitch_time | | am - > controls . heading_time | | am - > controls . bank_time )
{
vms_angvec tangles ;
vms_matrix new_m ;
2011-04-10 11:53:51 +00:00
2011-05-20 10:23:22 +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:53:51 +00:00
2011-05-20 10:23:22 +00:00
vm_angles_2_matrix ( & tempm , & tangles ) ;
vm_matrix_x_matrix ( & new_m , & am - > viewMatrix , & tempm ) ;
am - > viewMatrix = new_m ;
}
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
if ( am - > view_position . x > F1_0 * 32000 ) am - > view_position . x = F1_0 * 32000 ;
if ( am - > view_position . x < - F1_0 * 32000 ) am - > view_position . x = - F1_0 * 32000 ;
if ( am - > view_position . y > F1_0 * 32000 ) am - > view_position . y = F1_0 * 32000 ;
if ( am - > view_position . y < - F1_0 * 32000 ) am - > view_position . y = - F1_0 * 32000 ;
if ( am - > view_position . z > F1_0 * 32000 ) am - > view_position . z = F1_0 * 32000 ;
if ( am - > view_position . z < - F1_0 * 32000 ) am - > view_position . z = - F1_0 * 32000 ;
}
2011-04-10 11:53:51 +00:00
}
2011-05-20 10:23:22 +00:00
else
2011-04-10 11:53:51 +00:00
{
2011-05-20 10:23:22 +00:00
if ( am - > controls . fire_primary_count > 0 )
{
// 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 ;
am - > controls . fire_primary_count = 0 ;
}
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 ) ;
if ( am - > viewDist < ZOOM_MIN_VALUE ) am - > viewDist = ZOOM_MIN_VALUE ;
if ( am - > viewDist > ZOOM_MAX_VALUE ) am - > viewDist = ZOOM_MAX_VALUE ;
2011-04-10 11:53:51 +00:00
}
2010-01-20 11:04:09 +00:00
return 0 ;
}
int automap_handler ( window * wind , d_event * event , automap * am )
{
switch ( event - > type )
{
2010-02-25 08:00:15 +00:00
case EVENT_WINDOW_ACTIVATED :
game_flush_inputs ( ) ;
2010-12-28 18:11:06 +00:00
event_toggle_focus ( 1 ) ;
2011-02-02 00:36:43 +00:00
key_toggle_repeat ( 0 ) ;
2010-07-16 11:07:42 +00:00
break ;
case EVENT_WINDOW_DEACTIVATED :
2010-12-28 18:11:06 +00:00
event_toggle_focus ( 0 ) ;
2011-02-02 00:36:43 +00:00
key_toggle_repeat ( 1 ) ;
2010-02-25 08:00:15 +00:00
break ;
2011-02-03 00:05:01 +00:00
case EVENT_IDLE :
2011-02-02 00:36:43 +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 :
2011-02-03 00:05:01 +00:00
automap_process_input ( wind , event , am ) ;
2011-02-02 01:08:21 +00:00
break ;
2010-03-26 14:05:40 +00:00
case EVENT_KEY_COMMAND :
2011-02-02 00:36:43 +00:00
case EVENT_KEY_RELEASE :
2011-05-07 11:29:21 +00:00
{
int kret = automap_key_command ( wind , event , am ) ;
if ( ! kret )
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:31 +00:00
if ( ! am - > pause_game )
ConsoleObject - > mtype . phys_info . flags | = am - > old_wiggle ; // Restore wiggle
2010-12-28 18:11:06 +00:00
event_toggle_focus ( 0 ) ;
2011-02-02 00:36:43 +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 ) ;
d_free ( am ) ;
window_set_visible ( Game_wind , 1 ) ;
2010-01-29 03:36:44 +00:00
Automap_active = 0 ;
2010-01-28 03:27:49 +00:00
return 0 ; // continue closing
2010-01-20 11:04:09 +00:00
break ;
default :
return 0 ;
break ;
}
2009-12-02 13:49:54 +00:00
return 1 ;
}
2006-03-20 16:43:15 +00:00
2009-12-27 12:27:44 +00:00
void do_automap ( int key_code )
{
2009-12-02 13:49:54 +00:00
int pcx_error ;
ubyte pal [ 256 * 3 ] ;
2009-12-27 12:27:44 +00:00
window * automap_wind = NULL ;
automap * am ;
2009-12-02 13:49:54 +00:00
MALLOC ( am , automap , 1 ) ;
2010-01-31 21:51:59 +00:00
2009-12-02 13:49:54 +00:00
if ( am )
2010-01-31 21:51:59 +00:00
{
memset ( am , 0 , sizeof ( automap ) ) ;
2009-12-02 13:49:54 +00:00
automap_wind = window_create ( & grd_curscreen - > sc_canvas , 0 , 0 , SWIDTH , SHEIGHT , ( int ( * ) ( window * , d_event * , void * ) ) automap_handler , am ) ;
2010-01-31 21:51:59 +00:00
}
2006-03-20 16:43:15 +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 16:43:15 +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 ) ;
MALLOC ( am - > drawingListBright , short , am - > max_edges ) ;
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:22 +00:00
am - > viewDist = 0 ;
2006-03-20 16:43:15 +00:00
2009-12-27 12:27:44 +00:00
init_automap_colors ( am ) ;
2006-03-20 16:43:15 +00:00
2009-12-02 13:49:54 +00:00
key_code = key_code ; // disable warning...
2006-03-20 16:43:15 +00:00
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-08-07 00:26:03 +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 16:43:15 +00:00
}
2011-02-06 13:25:31 +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 16:43:15 +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 16:43:15 +00:00
2009-12-02 13:49:54 +00:00
gr_set_current_canvas ( NULL ) ;
2009-12-27 12:27:44 +00:00
automap_build_edge_list ( am ) ;
2006-08-07 00:26:03 +00:00
2011-05-20 10:23:22 +00:00
if ( am - > viewDist = = 0 )
am - > viewDist = ZOOM_DEFAULT ;
2009-12-02 13:49:54 +00:00
2011-05-20 10:23:22 +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:03 +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
am - > max_segments_away = set_segment_depths ( Objects [ Players [ Player_num ] . objnum ] . segnum , Automap_visited ) ;
am - > segment_limit = am - > max_segments_away ;
2009-12-27 12:27:44 +00:00
adjust_segment_limit ( am , am - > segment_limit ) ;
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 ) ;
2009-12-02 13:49:54 +00:00
if ( ! MacHog )
2009-12-27 12:27:44 +00:00
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
else
2009-12-27 12:27:44 +00:00
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 ) ) ;
2009-12-02 13:49:54 +00:00
gr_palette_load ( gr_palette ) ;
2010-01-29 03:36:44 +00:00
Automap_active = 1 ;
2006-03-20 16:43:15 +00:00
}
2009-12-27 12:27:44 +00:00
void adjust_segment_limit ( automap * am , int SegmentLimit )
2006-03-20 16:43:15 +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 16:43:15 +00:00
e - > flags | = EF_TOO_FAR ;
for ( e1 = 0 ; e1 < e - > num_faces ; e1 + + ) {
if ( Automap_visited [ e - > segnum [ e1 ] ] < = SegmentLimit ) {
e - > flags & = ( ~ EF_TOO_FAR ) ;
break ;
}
}
}
}
2009-12-27 12:27:44 +00:00
void draw_all_edges ( automap * am )
2006-03-20 16:43:15 +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 16:43:15 +00:00
if ( ! ( e - > flags & EF_USED ) ) continue ;
if ( e - > flags & EF_TOO_FAR ) continue ;
2009-12-02 13:49:54 +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 ) )
2009-12-02 13:49:54 +00:00
continue ; // If a line isn't secret and is normal color, then don't draw it
2006-03-20 16:43:15 +00:00
}
2006-08-07 00:26:03 +00:00
cc = rotate_list ( 2 , e - > verts ) ;
distance = Segment_points [ e - > verts [ 1 ] ] . p3_z ;
2006-03-20 16:43:15 +00:00
if ( min_distance > distance )
min_distance = distance ;
2009-12-02 13:49:54 +00:00
if ( ! cc . and ) { //all off screen?
2006-03-20 16:43:15 +00:00
nfacing = nnfacing = 0 ;
2006-08-07 00:26:03 +00:00
tv1 = & Vertices [ e - > verts [ 0 ] ] ;
2006-03-20 16:43:15 +00:00
j = 0 ;
while ( j < e - > num_faces & & ( nfacing = = 0 | | nnfacing = = 0 ) ) {
2006-08-07 00:26:03 +00:00
# ifdef COMPACT_SEGS
2006-03-20 16:43:15 +00:00
vms_vector temp_v ;
get_side_normal ( & Segments [ e - > segnum [ j ] ] , e - > sides [ j ] , 0 , & temp_v ) ;
if ( ! g3_check_normal_facing ( tv1 , & temp_v ) )
2006-08-07 00:26:03 +00:00
# else
2006-03-20 16:43:15 +00:00
if ( ! g3_check_normal_facing ( tv1 , & Segments [ e - > segnum [ j ] ] . sides [ e - > sides [ j ] ] . normals [ 0 ] ) )
2006-08-07 00:26:03 +00:00
# endif
2006-03-20 16:43:15 +00:00
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 16:43:15 +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 ] ) ;
2006-08-07 00:26:03 +00:00
g3_draw_line ( & Segment_points [ e - > verts [ 0 ] ] , & Segment_points [ e - > verts [ 1 ] ] ) ;
2006-03-20 16:43:15 +00:00
} else {
2009-12-27 12:27:44 +00:00
am - > drawingListBright [ nbright + + ] = e - am - > edges ;
2006-03-20 16:43:15 +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 16:43:15 +00:00
2006-08-07 00:26:03 +00:00
if ( Segment_points [ v1 ] . p3_z < Segment_points [ v2 ] . p3_z ) {
2006-03-20 16:43:15 +00:00
// 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 16:43:15 +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-08-07 00:26:03 +00:00
p1 = & Segment_points [ e - > verts [ 0 ] ] ;
p2 = & Segment_points [ e - > verts [ 1 ] ] ;
dist = p1 - > p3_z - min_distance ;
2006-03-20 16:43:15 +00:00
// 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 16:43:15 +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 16:43:15 +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 16:43:15 +00:00
{
2006-08-07 00:26:03 +00:00
long vv , evv ;
2006-03-20 16:43:15 +00:00
short hash , oldhash ;
2006-08-07 00:26:03 +00:00
int ret , ev0 , ev1 ;
2006-03-20 16:43:15 +00:00
vv = ( v1 < < 16 ) + v0 ;
2009-12-27 12:27:44 +00:00
oldhash = hash = ( ( v0 * 5 + v1 ) % am - > max_edges ) ;
2006-03-20 16:43:15 +00:00
ret = - 1 ;
while ( ret = = - 1 ) {
2009-12-27 12:27:44 +00:00
ev0 = ( int ) ( am - > edges [ hash ] . verts [ 0 ] ) ;
ev1 = ( int ) ( am - > edges [ hash ] . verts [ 1 ] ) ;
2006-08-07 00:26:03 +00:00
evv = ( ev1 < < 16 ) + ev0 ;
2009-12-27 12:27:44 +00:00
if ( am - > edges [ hash ] . num_faces = = 0 ) ret = 0 ;
2006-08-07 00:26:03 +00:00
else if ( evv = = vv ) ret = 1 ;
2006-03-20 16:43:15 +00:00
else {
2009-12-27 12:27:44 +00:00
if ( + + hash = = am - > max_edges ) hash = 0 ;
2006-03-20 16:43:15 +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 16:43:15 +00:00
if ( ret = = 0 )
return - 1 ;
else
return hash ;
}
2009-12-27 12:27:44 +00:00
void add_one_edge ( automap * am , short va , short vb , ubyte color , ubyte side , short segnum , int hidden , int grate , int no_fade ) {
2006-03-20 16:43:15 +00:00
int found ;
Edge_info * e ;
short tmp ;
2009-12-27 12:27:44 +00:00
if ( am - > num_edges > = am - > max_edges ) {
2006-08-07 00:26:03 +00:00
// GET JOHN! (And tell him that his
2006-03-20 16:43:15 +00:00
// MAX_EDGES_FROM_VERTS formula is hosed.)
2006-08-07 00:26:03 +00:00
// If he's not around, save the mine,
// and send him mail so he can look
2006-03-20 16:43:15 +00:00
// 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 16:43:15 +00:00
if ( found = = - 1 ) {
2006-08-07 00:26:03 +00:00
e - > verts [ 0 ] = va ;
e - > verts [ 1 ] = vb ;
2006-03-20 16:43:15 +00:00
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 16:43:15 +00:00
} else {
2009-12-27 12:27:44 +00:00
if ( color ! = am - > wall_normal_color )
2006-11-15 02:37:45 +00:00
e - > color = color ;
2006-03-20 16:43:15 +00:00
if ( e - > num_faces < 4 ) {
2006-11-15 02:37:45 +00:00
e - > sides [ e - > num_faces ] = side ;
2006-03-20 16:43:15 +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 ;
}
2009-12-27 12:27:44 +00:00
void add_one_unknown_edge ( automap * am , short va , short vb )
{
2006-03-20 16:43:15 +00:00
int found ;
Edge_info * e ;
short tmp ;
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 16:43:15 +00:00
if ( found ! = - 1 )
e - > flags | = EF_FRONTIER ; // Mark as a border edge
}
2006-08-07 00:26:03 +00:00
# ifndef _GAMESEQ_H
extern obj_position Player_init [ ] ;
# endif
2006-03-20 16:43:15 +00:00
2009-12-27 12:27:44 +00:00
void add_segment_edges ( automap * am , segment * seg )
2006-03-20 16:43:15 +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 + + ) {
short vertex_list [ 4 ] ;
hidden_flag = 0 ;
is_grate = 0 ;
no_fade = 0 ;
color = 255 ;
if ( seg - > children [ sn ] = = - 1 ) {
2009-12-27 12:27:44 +00:00
color = am - > wall_normal_color ;
2006-03-20 16:43:15 +00:00
}
switch ( seg - > special ) {
case SEGMENT_IS_FUELCEN :
color = BM_XRGB ( 29 , 27 , 13 ) ;
break ;
case SEGMENT_IS_CONTROLCEN :
2006-08-07 00:26:03 +00:00
if ( Control_center_present )
color = BM_XRGB ( 29 , 0 , 0 ) ;
2006-03-20 16:43:15 +00:00
break ;
case SEGMENT_IS_ROBOTMAKER :
color = BM_XRGB ( 29 , 0 , 31 ) ;
break ;
}
if ( seg - > sides [ sn ] . wall_num > - 1 ) {
2006-08-07 00:26:03 +00:00
2006-03-20 16:43:15 +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 16:43:15 +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 16:43:15 +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 16:43:15 +00:00
} else if ( ! ( WallAnims [ Walls [ seg - > sides [ sn ] . wall_num ] . clip_num ] . flags & WCF_HIDDEN ) ) {
int connected_seg = seg - > children [ sn ] ;
if ( connected_seg ! = - 1 ) {
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 16:43:15 +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 16:43:15 +00:00
default : Error ( " Inconsistent data. Supposed to be a colored wall, but not blue, gold or red. \n " ) ;
}
}
2006-08-07 00:26:03 +00:00
2006-03-20 16:43:15 +00:00
}
} else {
2009-12-27 12:27:44 +00:00
color = am - > wall_normal_color ;
2006-03-20 16:43:15 +00:00
hidden_flag = 1 ;
}
break ;
case WALL_CLOSED :
// Make grates draw properly
2006-08-07 00:26:03 +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 16:43:15 +00:00
break ;
case WALL_BLASTABLE :
// Hostage doors
2009-12-27 12:27:44 +00:00
color = am - > wall_door_color ;
2006-03-20 16:43:15 +00:00
break ;
}
}
if ( segnum = = Player_init [ Player_num ] . segnum )
color = BM_XRGB ( 31 , 0 , 31 ) ;
if ( color ! = 255 ) {
// If they have a map powerup, draw unvisited areas in dark blue.
if ( Players [ Player_num ] . flags & PLAYER_FLAGS_MAP_ALL & & ( ! Automap_visited [ segnum ] ) )
color = BM_XRGB ( 0 , 0 , 25 ) ;
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 16:43:15 +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 16:43:15 +00:00
}
}
}
}
// Adds all the edges from a segment we haven't visited yet.
2009-12-27 12:27:44 +00:00
void add_unknown_segment_edges ( automap * am , segment * seg )
2006-03-20 16:43:15 +00:00
{
int sn ;
int segnum = seg - Segments ;
for ( sn = 0 ; sn < MAX_SIDES_PER_SEGMENT ; sn + + ) {
short vertex_list [ 4 ] ;
// Only add edges that have no children
if ( seg - > children [ sn ] = = - 1 ) {
get_side_verts ( vertex_list , segnum , sn ) ;
2009-12-02 13:49:54 +00:00
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 16:43:15 +00:00
}
}
}
2009-12-27 12:27:44 +00:00
void automap_build_edge_list ( automap * am )
2006-03-20 16:43:15 +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 16:43:15 +00:00
}
2009-12-27 12:27:44 +00:00
am - > num_edges = 0 ;
am - > highest_edge_index = - 1 ;
2006-03-20 16:43:15 +00:00
2011-02-14 21:27:02 +00:00
if ( cheats . fullautomap | | ( Players [ Player_num ] . flags & PLAYER_FLAGS_MAP_ALL ) ) {
2006-03-20 16:43:15 +00:00
// Cheating, add all edges as visited
for ( s = 0 ; s < = Highest_segment_index ; s + + )
2006-08-07 00:26:03 +00:00
# ifdef EDITOR
2006-03-20 16:43:15 +00:00
if ( Segments [ s ] . segnum ! = - 1 )
2006-08-07 00:26:03 +00:00
# endif
2006-03-20 16:43:15 +00:00
{
2009-12-27 12:27:44 +00:00
add_segment_edges ( am , & Segments [ s ] ) ;
2006-03-20 16:43:15 +00:00
}
} else {
// Not cheating, add visited edges, and then unvisited edges
for ( s = 0 ; s < = Highest_segment_index ; s + + )
2006-08-07 00:26:03 +00:00
# ifdef EDITOR
2006-03-20 16:43:15 +00:00
if ( Segments [ s ] . segnum ! = - 1 )
2006-08-07 00:26:03 +00:00
# endif
2006-03-20 16:43:15 +00:00
if ( Automap_visited [ s ] ) {
2009-12-27 12:27:44 +00:00
add_segment_edges ( am , & Segments [ s ] ) ;
2006-03-20 16:43:15 +00:00
}
for ( s = 0 ; s < = Highest_segment_index ; s + + )
2006-08-07 00:26:03 +00:00
# ifdef EDITOR
2006-03-20 16:43:15 +00:00
if ( Segments [ s ] . segnum ! = - 1 )
2006-08-07 00:26:03 +00:00
# endif
2006-03-20 16:43:15 +00:00
if ( ! Automap_visited [ s ] ) {
2009-12-27 12:27:44 +00:00
add_unknown_segment_edges ( am , & Segments [ s ] ) ;
2006-03-20 16:43:15 +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 16:43:15 +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 ] ) ) {
2006-08-07 00:26:03 +00:00
# ifdef COMPACT_SEGS
2006-03-20 16:43:15 +00:00
vms_vector v1 , v2 ;
get_side_normal ( & Segments [ e - > segnum [ e1 ] ] , e - > sides [ e1 ] , 0 , & v1 ) ;
get_side_normal ( & Segments [ e - > segnum [ e2 ] ] , e - > sides [ e2 ] , 0 , & v2 ) ;
if ( vm_vec_dot ( & v1 , & v2 ) > ( F1_0 - ( F1_0 / 10 ) ) ) {
2006-08-07 00:26:03 +00:00
# else
2006-03-20 16:43:15 +00:00
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 ) ) ) {
2006-08-07 00:26:03 +00:00
# endif
2006-03-20 16:43:15 +00:00
e - > flags & = ( ~ EF_DEFINING ) ;
break ;
}
}
}
if ( ! ( e - > flags & EF_DEFINING ) )
break ;
}
2006-08-07 00:26:03 +00:00
}
2006-03-20 16:43:15 +00:00
}