diff options
| author | Felix Morgner <felix.morgner@gmail.com> | 2026-08-24 11:16:07 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@gmail.com> | 2026-08-24 11:16:07 +0200 |
| commit | c068f22329d5cc722622a2183bbb22eef2093df7 (patch) | |
| tree | 12d56c1aede67988a55e241364606bfbb4dba933 /src/parsec/h_drwhud.cpp | |
| download | openparsec-c068f22329d5cc722622a2183bbb22eef2093df7.tar.xz openparsec-c068f22329d5cc722622a2183bbb22eef2093df7.zip | |
Diffstat (limited to 'src/parsec/h_drwhud.cpp')
| -rw-r--r-- | src/parsec/h_drwhud.cpp | 953 |
1 files changed, 953 insertions, 0 deletions
diff --git a/src/parsec/h_drwhud.cpp b/src/parsec/h_drwhud.cpp new file mode 100644 index 0000000..75b98e5 --- /dev/null +++ b/src/parsec/h_drwhud.cpp @@ -0,0 +1,953 @@ +/* + * PARSEC - Draw Heads Up Display + * + * $Author: uberlinuxguy $ - $Date: 2004/09/26 03:43:37 $ + * + * Orginally written by: + * Copyright (c) Markus Hadwiger <msh@parsec.org> 1996-2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +// C library +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +// compilation flags/debug support +#include "config.h" +#include "debug.h" + +// general definitions +#include "general.h" +#include "objstruc.h" +#include "od_class.h" + +// global externals +#include "globals.h" + +// subsystem headers +#include "aud_defs.h" +#include "inp_defs.h" +#include "net_defs.h" +#include "sys_defs.h" +#include "vid_defs.h" + +// drawing subsystem +#include "d_bmap.h" +#include "d_font.h" +#include "d_misc.h" + +// rendering subsystem +#include "r_perf.h" + +// mathematics header +#include "utl_math.h" + +// local module header +#include "h_drwhud.h" + +// proprietary module headers +#include "con_aux.h" +#include "e_color.h" +#include "e_demo.h" +#include "e_draw.h" +#include "h_cockpt.h" +#include "h_frmplt.h" +#include "h_radar.h" +#include "h_supp.h" +#include "obj_ctrl.h" +#include "obj_game.h" + + +// flags +#define SHOW_ARMOR_INFO +#define NEW_ONLINE_HELP + + +// height of remoteplayer name +#define REMPLAYERNAME_HEIGHT 10 + +// crosshair bitmap to use +int bm_crosshair = BM_CROSSHAIR; + +// online help geometry constants +#define HELP_FRAME_LEFT 8 +#define HELP_FRAME_TOP 5 +#define NUM_HELP_LINES 27 +#define HELP_LINE_WIDTH 27 +#define NUM_HELP_LINES_LORES (27-6) +#define HELP_LORES_FILT_LO 19 +#define HELP_LORES_FILT_HI 24 + +// geometry of online help +int Help_Text_X; +int Help_Text_Y; +int Help_Text_LineDist; +int Num_Help_Lines; + +// generic string paste area +#define PASTE_STR_LEN 255 +static char paste_str[ PASTE_STR_LEN + 1 ]; + + +// hud coordinates ------------------------------------------------------------ +// +int hud_line_dist; +int hud_displ; +int hud_left_x; + +int obj_cam_x; +int obj_cam_y; + +int Tracking_Width; +int Tracking_Height; + +char hud_lockd_str[] = "locked"; +char hud_track_str[] = "tracking"; + +int hud_lockd_x; +int hud_lockd_y; +int hud_track_x; +int hud_track_y; + +int TrackingLeftBoundX; +int TrackingRightBoundX; +int TrackingLeftBoundY; +int TrackingRightBoundY; + +int hud_crosshair_x; +int hud_crosshair_y; + + +// init hud geometry for local ship ------------------------------------------- +// +PRIVATE +void InitHudGeometryMyShip() +{ + if ( MyShip->ObjectType == SHIP1TYPE ) { + + bm_crosshair = BM_CROSSHAIR2; + + hud_track_x = Screen_XOfs - 15 - ( 1-hud_displ ); + hud_track_y = Screen_YOfs - 44 - hud_displ*8; + hud_lockd_x = Screen_XOfs - 11 - ( 1-hud_displ ); + hud_lockd_y = Screen_YOfs + 37 + hud_displ*10; + + } else if ( MyShip->ObjectType == SHIP2TYPE ) { + + bm_crosshair = BM_CROSSHAIR; + + hud_track_x = Screen_XOfs - 15 - ( 1-hud_displ ); + hud_track_y = Screen_YOfs - 7/*52*/ - hud_displ*8; + hud_lockd_x = Screen_XOfs - 11 - ( 1-hud_displ ); + hud_lockd_y = Screen_YOfs + 45 + hud_displ*10; + + } else { + + bm_crosshair = BM_CROSSHAIR3; + + hud_track_x = Screen_XOfs - 15 - ( 1-hud_displ ); + hud_track_y = Screen_YOfs - 44 - hud_displ*8; + hud_lockd_x = Screen_XOfs - 11 - ( 1-hud_displ ); + hud_lockd_y = Screen_YOfs + 37 + hud_displ*10; + } +} + + +// init hud geometry for radar ------------------------------------------------ +// +PRIVATE +void InitHudGeometryRadar() +{ + // must be offset by -<radar_bitmap_width>/2 + hud_radar_bitm_x = Screen_XOfs + hud_displ + 1; + + // must be offset by -<radar_bitmap_height> + hud_radar_bitm_y = Screen_Height; + + // must be subtracted from <radar_bitmap_width>/2 + hud_radar_w = 3*hud_displ + 3; + + // must be subtracted from <radar_bitmap_height>/2 + hud_radar_h = 3*hud_displ + 3; + + // is valid as is + hud_radar_x = Screen_XOfs; + + // must be offset by -<radar_bitmap_height> + hud_radar_y = Screen_Height - 2 + 1; +} + + +// init hud geometry for object camera ---------------------------------------- +// +PRIVATE +void InitHudGeometryObjCamera() +{ + obj_cam_x = 6 + (hud_displ+0)*hud_line_dist; + obj_cam_y = 6 + (hud_displ+0)*hud_line_dist; +} + + +// init hud geometry for online help window ----------------------------------- +// +PRIVATE +void InitHudGeometryOnlineHelp() +{ + Help_Text_X = CharsetInfo[ HUD_CHARSETNO ].width * 3; + Help_Text_Y = hud_line_dist * ( 6 + 4 * hud_displ ) + 7 * hud_displ; + Help_Text_LineDist = hud_line_dist; +} + + +// init hud geometry for message area ----------------------------------------- +// +PRIVATE +void InitHudGeometryMessageArea() +{ + Msg_ScreenTop = 4 + hud_displ * CharsetInfo[ MSG_CHARSETNO ].height; +} + + +// init hud geometry for target tracking -------------------------------------- +// +PRIVATE +void InitHudGeometryTracking() +{ + Tracking_Width = BitmapInfo[ bm_crosshair ].width / 2; + Tracking_Height = BitmapInfo[ bm_crosshair ].height / 2; + + Tracking_Width = (int)( Tracking_Width * (float)Screen_Width / 640.0 ); + Tracking_Height = (int)( Tracking_Height * (float)Screen_Height / 480.0 ); + + TrackingLeftBoundX = Screen_XOfs - Tracking_Width; + TrackingRightBoundX = Screen_XOfs + Tracking_Width; + TrackingLeftBoundY = Screen_YOfs + 5 - Tracking_Height; + TrackingRightBoundY = Screen_YOfs + 5 + Tracking_Height; +} + + +// init hud geometry for crosshair -------------------------------------------- +// +PRIVATE +void InitHudGeometryCrosshair() +{ + hud_crosshair_x = ((Screen_XOfs - BitmapInfo[ bm_crosshair ].width/2)&~3) + 4; + hud_crosshair_y = Screen_YOfs - BitmapInfo[ bm_crosshair ].height/2 + 3; +} + + +// init coordinates of hud display -------------------------------------------- +// +void InitHudDisplay() +{ + Hud_Char_ColOfs[ 0 ] = CalcHudCharAddress( 0 ); + Hud_Char_ColOfs[ 1 ] = CalcHudCharAddress( 1 ); + Hud_Char_ColOfs[ 2 ] = CalcHudCharAddress( 2 ); + Hud_Char_ColOfs[ 3 ] = CalcHudCharAddress( 3 ); + Hud_Char_ColOfs[ 4 ] = CalcHudCharAddress( 4 ); + Hud_Char_ColOfs[ 5 ] = CalcHudCharAddress( 5 ); + + hud_displ = 1; + hud_line_dist = CharsetInfo[ HUD_CHARSETNO ].height + 2; + hud_left_x = 12; + Num_Help_Lines = NUM_HELP_LINES; + + InitHudGeometryMyShip(); + + InitHudGeometryOnlineHelp(); + InitHudGeometryMessageArea(); + InitHudGeometryObjCamera(); + InitHudGeometryTracking(); + InitHudGeometryCrosshair(); + InitHudGeometryRadar(); +} + + +// set string context to MIN_CHARSETNO ---------------------------------------- +// +INLINE +void SET_MIN_CHAR_CONTEXT() +{ + D_SetWStrContext( CharsetInfo[ MIN_CHARSETNO ].charsetpointer, + CharsetInfo[ MIN_CHARSETNO ].geompointer, + NULL, + CharsetInfo[ MIN_CHARSETNO ].width, + CharsetInfo[ MIN_CHARSETNO ].height ); +} + + +// set string context to HUD_CHARSETNO ---------------------------------------- +// +INLINE +void SET_HUD_CHAR_CONTEXT() +{ + D_SetWStrContext( CharsetInfo[ HUD_CHARSETNO ].charsetpointer, + CharsetInfo[ HUD_CHARSETNO ].geompointer, + NULL, + CharsetInfo[ HUD_CHARSETNO ].width, + CharsetInfo[ HUD_CHARSETNO ].height ); +} + + +// type for writestring function pointer -------------------------------------- +// +typedef void (*WSFP)( ... ); + +//NOTE: +// this declaration is in global scope because of the extern "C". +// only gcc needs the otherwise redundant curly braces. + + +#include "inp_keyn.h" + +#define NUM_KEYS 28 + + +// text descriptions for gamefunc keys ---------------------------------------- +// +static char help_gamefunc_names[ NUM_KEYS ][ HELP_LINE_WIDTH + 1 ] = { + + "escape", + "turn left", + "turn right", + "dive down", + "pull up", + "roll left", + "roll right", + "shoot weapon", + "launch missile", + "next weapon", + "next missile", + "accelerate", + "decelerate", + "slide left", + "slide right", + "slide up", + "slide down", + "next target", + "toggle frame rate info", + "toggle object camera", + "toggle help", + "toggle console", + "save screenshot", + "show kill stats", + "speed zero", + "target speed", + "activate after burner", + "select target in front" +}; + +static int *keyb_config; + + +// draw online help for the new millenium ------------------------------------- +// +void DrawOnlineHelp() +{ + int helpwidth = 0; + int keynameoffs = 0; + + keyb_config = (int *) KeyAssignments; + int kid =0; + for ( kid = 0; kid < NUM_KEYS; kid++ ) { + + int key_code = keyb_config[ kid ]; + + if (key_names[ key_code ] == NULL) + key_code = 0; + + int linewidth = strlen( help_gamefunc_names[ kid ] ); + + if ( linewidth > keynameoffs ) + keynameoffs = linewidth; + + linewidth = keynameoffs + strlen( key_names[ key_code ] ); + + if ( linewidth > helpwidth ) + helpwidth = linewidth; + } + + helpwidth += 4; + keynameoffs += 1; + + int chr_width = CharsetInfo[ HUD_CHARSETNO ].width; + int yko = Help_Text_Y; + + // determine whether translucency should be used + int translucent = VID_TRANSLUCENCY_SUPPORTED; + + int wx = Help_Text_X - HELP_FRAME_LEFT; + int wy = Help_Text_Y - HELP_FRAME_TOP; + int ww = chr_width * helpwidth + HELP_FRAME_LEFT * 2; + int wh = Help_Text_LineDist * NUM_KEYS + HELP_FRAME_TOP * 2; + + if ( translucent ) { + D_DrawTrRect( wx, wy, ww, wh, TRTAB_PANELBACK ); + + DRAW_PanelDecorations( wx, wy, ww, wh ); + } + + SET_HUD_CHAR_CONTEXT(); + + // write text transparent only for color depths below 32 bit per pixel + WSFP wsfp = ( translucent ) ? + (WSFP) &D_WriteTrString : + (WSFP) &D_WriteString; + + for ( kid = 0; kid < NUM_KEYS; kid++ ) { + + int key_code = keyb_config[ kid ]; + + if (key_names[ key_code ] == NULL) + key_code = 0; + + wsfp( help_gamefunc_names[ kid ] , Help_Text_X, yko, TRTAB_PANELTEXT ); + wsfp( key_names[ key_code ], Help_Text_X + keynameoffs * chr_width, yko, TRTAB_PANELTEXT ); + + yko += Help_Text_LineDist; + } +} + + +// x position of debug info in hud -------------------------------------------- +// +#define DI_XPOS 12 + + +// show network packet info in hud -------------------------------------------- +// +INLINE +void HUD_DrawDebugInfoPackets() +{ + #define DI_PACKETS_LINE1 130 + + sprintf( paste_str, "last packet ids: %d %d %d %d", + Player_LastMsgId[ 0 ], + Player_LastMsgId[ 1 ], + Player_LastMsgId[ 2 ], + Player_LastMsgId[ 3 ] ); + D_WriteString( paste_str, DI_XPOS, DI_PACKETS_LINE1 ); +} + + +// show memory allocation statistics in hud ----------------------------------- +// +INLINE +void HUD_DrawDebugInfoMemory() +{ + #define DI_MEMORY_LINE1 140 + #define DI_MEMORY_LINE2 (DI_MEMORY_LINE1+10) + #define DI_MEMORY_LINE3 (DI_MEMORY_LINE2+10) + #define DI_MEMORY_LINE4 (DI_MEMORY_LINE3+10) + + extern unsigned int Num_Allocs; + extern unsigned int Num_Frees; + extern unsigned int Dyn_Mem_Size; + + sprintf( paste_str, "mallocs : %d", Num_Allocs ); + D_WriteString( paste_str, DI_XPOS, DI_MEMORY_LINE1 ); + + sprintf( paste_str, "frees : %d", Num_Frees ); + D_WriteString( paste_str, DI_XPOS, DI_MEMORY_LINE2 ); + + sprintf( paste_str, "memobjs : %d", Num_Allocs - Num_Frees ); + D_WriteString( paste_str, DI_XPOS, DI_MEMORY_LINE3 ); + + sprintf( paste_str, "heapsize: %d", Dyn_Mem_Size ); + D_WriteString( paste_str, DI_XPOS, DI_MEMORY_LINE4 ); +} + + +// show hud debug info about object lists ------------------------------------- +// +INLINE +void HUD_DrawDebugInfoObjects() +{ + #define DI_OBJECTS_LINE1 190 + #define DI_OBJECTS_LINE2 (DI_OBJECTS_LINE1+10) + #define DI_OBJECTS_LINE3 (DI_OBJECTS_LINE2+10) + #define DI_OBJECTS_LINE4 (DI_OBJECTS_LINE3+10) + #define DI_OBJECTS_LINE5 (DI_OBJECTS_LINE4+10) + + ASSERT( PShipObjects != NULL ); + ASSERT( LaserObjects != NULL ); + ASSERT( MisslObjects != NULL ); + ASSERT( ExtraObjects != NULL ); + ASSERT( CustmObjects != NULL ); + + GenObject *walklist; + int listlength; + + listlength = 0; + for ( walklist = FetchFirstShip(); walklist; walklist = walklist->NextObj ) + listlength++; + sprintf( paste_str, "ships : %d", listlength ); + D_WriteString( paste_str, DI_XPOS, DI_OBJECTS_LINE1 ); + + listlength = 0; + for ( walklist = FetchFirstLaser(); walklist; walklist = walklist->NextObj ) + listlength++; + sprintf( paste_str, "lasers : %d", listlength ); + D_WriteString( paste_str, DI_XPOS, DI_OBJECTS_LINE2 ); + + listlength = 0; + for ( walklist = FetchFirstMissile(); walklist; walklist = walklist->NextObj ) + listlength++; + sprintf( paste_str, "missiles: %d", listlength ); + D_WriteString( paste_str, DI_XPOS, DI_OBJECTS_LINE3 ); + + listlength = 0; + for ( walklist = FetchFirstExtra(); walklist; walklist = walklist->NextObj ) + listlength++; + sprintf( paste_str, "extras : %d (%d)", listlength, CurrentNumExtras ); + D_WriteString( paste_str, DI_XPOS, DI_OBJECTS_LINE4 ); + + sprintf( paste_str, "partobjs: %d", CurrentNumPrtExtras ); + D_WriteString( paste_str, DI_XPOS, DI_OBJECTS_LINE5 ); + + //TODO: + // display custom objects. +/* + listlength = 0; + for ( walklist = FetchFirstCustom(); walklist; walklist = walklist->NextObj ) + listlength++; + sprintf( paste_str, "customs : %d", listlength ); + D_WriteString( paste_str, DI_XPOS, DI_OBJECTS_LINE6 ); +*/ +} + + +// show geometry stage statistics --------------------------------------------- +// +INLINE +void HUD_DrawDebugInfoGeometry() +{ + #define DI_GEOMETRY_LINE1 280 + + geomperfstats_s perf; + R_QueryGeometryPerfStats( &perf ); + + int triangles_in = ( perf.fieldstate & GEOMPERF_TRIANGLES_IN ) ? (int)perf.triangles_in : -1; + int triangles_out = ( perf.fieldstate & GEOMPERF_TRIANGLES_OUT) ? (int)perf.triangles_out : -1; + + sprintf( paste_str, "triangles: in:%d out:%d", triangles_in, triangles_out); + D_WriteString( paste_str, DI_XPOS, DI_GEOMETRY_LINE1 ); + + // reset counters before next frame + R_ResetGeometryPerfStats(); +} + + +// show rasterization stage statistics ---------------------------------------- +// +INLINE +void HUD_DrawDebugInfoRasterization() +{ + #define DI_RASTERIZATION_LINE1 250 + #define DI_RASTERIZATION_LINE2 (DI_RASTERIZATION_LINE1+10) + #define DI_RASTERIZATION_LINE3 (DI_RASTERIZATION_LINE2+10) + + rastperfstats_s perf; + R_QueryRasterizationPerfStats( &perf ); + + int fragments = ( perf.fieldstate & RASTPERF_FRAGMENTS ) ? (int)perf.fragments : -1; + int pixels = ( perf.fieldstate & RASTPERF_PIXELS ) ? (int)perf.pixels : -1; + int faildepth = ( perf.fieldstate & RASTPERF_FAILDEPTH ) ? (int)perf.faildepth : -1; + int failalpha = ( perf.fieldstate & RASTPERF_FAILALPHA ) ? (int)perf.failalpha : -1; + int failchroma = ( perf.fieldstate & RASTPERF_FAILCHROMA ) ? (int)perf.failchroma : -1; + + sprintf( paste_str, "polygons: genobj:%d", NumRenderedPolygons ); + D_WriteString( paste_str, DI_XPOS, DI_RASTERIZATION_LINE1 ); + + sprintf( paste_str, "fragment: in:%d out:%d", fragments, pixels ); + D_WriteString( paste_str, DI_XPOS, DI_RASTERIZATION_LINE2 ); + + sprintf( paste_str, "failed : z:%d a:%d c:%d", faildepth, failalpha, failchroma ); + D_WriteString( paste_str, DI_XPOS, DI_RASTERIZATION_LINE3 ); + + // reset counters before next frame + R_ResetRasterizationPerfStats(); +} + + +// show current camera position in hud ---------------------------------------- +// +INLINE +void HUD_DrawDebugInfoPosition() +{ + #define DI_POSITION_LINE1 300 + #define DI_POSITION_LINE2 (DI_POSITION_LINE1+10) + #define DI_POSITION_LINE3 (DI_POSITION_LINE2+10) + #define DI_POSITION_LINE4 (DI_POSITION_LINE3+20) + #define DI_POSITION_LINE5 (DI_POSITION_LINE4+10) + #define DI_POSITION_LINE6 (DI_POSITION_LINE5+10) + #define DI_POSITION_LINE7 (DI_POSITION_LINE6+10) + #define DI_POSITION_LINE8 (DI_POSITION_LINE7+10) + #define DI_POSITION_LINE9 (DI_POSITION_LINE8+10) + + sprintf( paste_str, "pitch: %d", (short)AbsPitch / 256 ); + D_WriteString( paste_str, DI_XPOS, DI_POSITION_LINE1 ); + + sprintf( paste_str, "yaw : %d", (short)AbsYaw / 256 ); + D_WriteString( paste_str, DI_XPOS, DI_POSITION_LINE2 ); + + sprintf( paste_str, "roll : %d", (short)AbsRoll / 256 ); + D_WriteString( paste_str, DI_XPOS, DI_POSITION_LINE3 ); + + sprintf( paste_str, "x-pos: %f", GEOMV_TO_FLOAT( MyShip->ObjPosition[ 0 ][ 3 ] ) ); + D_WriteString( paste_str, DI_XPOS, DI_POSITION_LINE4 ); + + sprintf( paste_str, "y-pos: %f", GEOMV_TO_FLOAT( MyShip->ObjPosition[ 1 ][ 3 ] ) ); + D_WriteString( paste_str, DI_XPOS, DI_POSITION_LINE5 ); + + sprintf( paste_str, "z-pos: %f", GEOMV_TO_FLOAT( MyShip->ObjPosition[ 2 ][ 3 ] ) ); + D_WriteString( paste_str, DI_XPOS, DI_POSITION_LINE6 ); + + sprintf( paste_str, "txpos: %f", GEOMV_TO_FLOAT( ViewCamera[ 0 ][ 3 ] ) ); + D_WriteString( paste_str, DI_XPOS, DI_POSITION_LINE7 ); + + sprintf( paste_str, "typos: %f", GEOMV_TO_FLOAT( ViewCamera[ 1 ][ 3 ] ) ); + D_WriteString( paste_str, DI_XPOS, DI_POSITION_LINE8 ); + + sprintf( paste_str, "tzpos: %f", GEOMV_TO_FLOAT( ViewCamera[ 2 ][ 3 ] ) ); + D_WriteString( paste_str, DI_XPOS, DI_POSITION_LINE9 ); +} + + +// draw permanent debugging info in hud --------------------------------------- +// +INLINE +void HUD_DrawDebugInfo() +{ + SetHudCharColor( 0 ); + + if ( AUX_HUD_DEBUGINFO_PACKETS ) + HUD_DrawDebugInfoPackets(); + + if ( AUX_HUD_DEBUGINFO_MEMORY ) + HUD_DrawDebugInfoMemory(); + + if ( AUX_HUD_DEBUGINFO_OBJECTS ) + HUD_DrawDebugInfoObjects(); + + if ( AUX_HUD_DEBUGINFO_GEOMETRY ) + HUD_DrawDebugInfoGeometry(); + + if ( AUX_HUD_DEBUGINFO_RASTERIZATION ) + HUD_DrawDebugInfoRasterization(); + + if ( AUX_HUD_DEBUGINFO_POSITION ) + HUD_DrawDebugInfoPosition(); +} + + +// draw demo replay info in hud ----------------------------------------------- +// +INLINE +void HUD_DrawDemoInfo() +{ + if ( DEMO_ReplayActive() ) { + + SetHudCharColor( 4 ); + + int seconds = ( demoinfo_curtime / FRAME_MEASURE_TIMEBASE ) % 60; + int minutes = demoinfo_curtime / ( FRAME_MEASURE_TIMEBASE * 60 ); + + char secstr[ 3 ]; + DIG2_TO_STR( secstr, seconds ); + + sprintf( paste_str, "time: %d:%s (%u) frame: %d line: %d ofs: %u", + minutes, secstr, + (unsigned int)demoinfo_curtime, demoinfo_curframe, + demoinfo_curline, (unsigned int)demoinfo_curofs ); + D_WriteString( paste_str, 0, 0 ); + } +} + + +// draw hud bitmaps (crosshair, radar) ---------------------------------------- +// +PUBLIC +void HUD_DrawBitmaps() +{ + //NOTE: + // also used by H_COCKPT::COCKPIT_DrawDisplay(). + + // draw crosshair + D_PutTrBitmap( BitmapInfo[ bm_crosshair ].bitmappointer, + BitmapInfo[ bm_crosshair ].width, + BitmapInfo[ bm_crosshair ].height, + hud_crosshair_x, hud_crosshair_y ); + + // draw radar frame (no contents) + HUD_DrawHUDRadarFrame(); +} + + +// draw miscellaneous hud texts (tracking text) ------------------------------- +// +PUBLIC +void HUD_DrawTrackingText( int targetvisible ) +{ + //NOTE: + // also used by H_COCKPT::COCKPIT_DrawDisplay(). + + static int trackcount = 0; + static int newlylocked = 1; + static int newlytracked = 1; + static int beepdone = 0; + + int tracking_y = 0; + int locked_y = 0; + + if ( AUX_DRAW_COCKPIT && AUX_DRAW_COCKPIT_CROSSHAIR ) { + tracking_y = (int)(Screen_YOfs - ( cockpitinfo[ CROSS ].height * Scaled_Screen_Height * 0.4f )) ; + tracking_y -= CharsetInfo[ HUD_CHARSETNO ].height; + locked_y = (int)(Screen_YOfs + ( cockpitinfo[ CROSS ].height * Scaled_Screen_Height * 0.4f )); + } else { + tracking_y = hud_track_y; + locked_y = hud_lockd_y; + } + + int homingactive = ( SelectedMissile == 1 ) && ( MyShip->NumHomMissls > 0 ); + int swarmactive = ( SelectedMissile == 3 ) && ( MyShip->NumPartMissls > 0 ); + + if ( targetvisible && ( homingactive || swarmactive ) ) { + +#define TRACK_COUNT_MAX 500 + + SET_HUD_CHAR_CONTEXT(); + + if ( TargetLocked ) { + D_WriteString( hud_lockd_str, hud_lockd_x, locked_y ); + if ( newlylocked ) { + newlylocked = 0; + AUD_Locked(); + } + } else { + trackcount += CurScreenRefFrames; + if ( trackcount > TRACK_COUNT_MAX ) trackcount = 0; + if ( trackcount < TRACK_COUNT_MAX/2 ) { + D_WriteString( hud_track_str, hud_track_x, tracking_y ); + if ( !beepdone ) { + AUD_TrackingBeep(); + beepdone = 1; + } + } else { + beepdone = 0; + } + if ( newlytracked ) { + newlytracked = 0; + AUD_Tracking(); + } + newlylocked = 1; + } + + SET_HUD_CHAR_CONTEXT(); + + } else { + + newlytracked = 1; + trackcount = 0; + } +} + + +// write string for ammo of missiles ------------------------------------------ +// +PUBLIC +void HUD_WriteAmmoString( int ammo, int x, int y ) +{ + //NOTE: + // also used by H_COCKPT::COCKPIT_DrawWeapons(). + + char ammo_str[4]; + DIG2_TO_STR( ammo_str, ammo ); + + SET_HUD_CHAR_CONTEXT(); + SetHudCharColor( 4 ); + + D_WriteString( ammo_str, x, y ); +} + + +// draw packet loss graph ----------------------------------------------------- +// +PRIVATE +void HUD_DrawPacketLossMeter() +{ + #define PACKET_GRAPH_COLOR1 102 + #define PACKET_GRAPH_COLOR2 85 + + if ( !NetConnected || !NetJoined ) + return; + + visual_t xlatcol1 = COLINDX_TO_VISUAL( PACKET_GRAPH_COLOR1 ); + visual_t xlatcol2 = COLINDX_TO_VISUAL( PACKET_GRAPH_COLOR2 ); + + char *packetgraph; + int graphsize; + if ( NETs_DeterminePacketLoss( &packetgraph, &graphsize, TRUE ) ) { + + int ratio = 0; + for ( int i = 0; i < graphsize; i++ ) { + + if ( packetgraph[ i ] == 0 ) { + D_DrawVertBar( DI_XPOS + (i << 1), 110 + 15, xlatcol1, 1 ); + } else { + D_DrawVertBar( DI_XPOS + (i << 1), 110, xlatcol2, 16 ); + ratio++; + } + } + + //FIXME: + // only works if ( graphsize == 100 ) + + ASSERT( graphsize == 100 ); + + SetHudCharColor( 0 ); + D_WriteString( "recv packet loss:", DI_XPOS, 100 ); + + char ratio_str[ 5 ]; + DIG3_TO_STR( ratio_str, ratio ); + ratio_str[ 3 ] = '%'; + ratio_str[ 4 ] = 0; + int dofs = 0; + if ( ( ratio_str[ 0 ] == '0' ) && ( ratio_str[ 1 ] == '0' ) ) + dofs = 2; + else if ( ratio_str[ 0 ] == '0' ) + dofs = 1; + D_WriteString( ratio_str + dofs, DI_XPOS+17*8+4, 100 ); + } + + if ( NETs_DeterminePacketLoss( &packetgraph, &graphsize, FALSE ) ) { + + int ratio = 0; + for ( int i = 0; i < graphsize; i++ ) { + + if ( packetgraph[ i ] == 0 ) { + D_DrawVertBar( DI_XPOS+220 + (i << 1), 110 + 15, xlatcol1, 1 ); + } else { + D_DrawVertBar( DI_XPOS+220 + (i << 1), 110, xlatcol2, 16 ); + ratio++; + } + } + + //FIXME: + // only works if ( graphsize == 100 ) + + ASSERT( graphsize == 100 ); + + SetHudCharColor( 0 ); + D_WriteString( "send packet loss:", DI_XPOS+220, 100 ); + + char ratio_str[ 5 ]; + DIG3_TO_STR( ratio_str, ratio ); + ratio_str[ 3 ] = '%'; + ratio_str[ 4 ] = 0; + int dofs = 0; + if ( ( ratio_str[ 0 ] == '0' ) && ( ratio_str[ 1 ] == '0' ) ) + dofs = 2; + else if ( ratio_str[ 0 ] == '0' ) + dofs = 1; + D_WriteString( ratio_str + dofs, DI_XPOS+220+17*8+4, 100 ); + } +} + + +// counter for blinking speed of objcam text ---------------------------------- +// +PUBLIC +int objcam_textcount = 0; // reset by G_SUPP::ObjCamOn() + + +// display hud text in object camera view ------------------------------------- +// +PRIVATE +void HUD_DrawObjCamDisplay() +{ + #define OBJCAM_TEXT_COUNT_MAX 900 + + if ( AUX_FLAGWORD_SCREENSHOT_HELPERS & 0x10 ) { + // allow text disabling for screenshots + return; + } + + if ( ( objcam_textcount += CurScreenRefFrames ) > OBJCAM_TEXT_COUNT_MAX ) { + objcam_textcount = 0; + } + + if ( objcam_textcount < OBJCAM_TEXT_COUNT_MAX/2 ) { + D_WriteString( "object camera", obj_cam_x, obj_cam_y ); + } +} + + +// draw heads up display ------------------------------------------------------ +// +void HUD_DrawHUD() +{ + SET_HUD_CHAR_CONTEXT(); + + // never overlay any displays in floating menu + if ( !InFloatingMenu ) { + + // check whether user displays should be drawn + if ( !EntryMode && !AUX_HUD_DISABLE_USER_DISPLAYS ) { + + if ( ObjCameraActive ) { + + // object camera view + HUD_DrawObjCamDisplay(); + + } else { + + if ( AUX_DRAW_COCKPIT ) { + + // draw 'advanced' cockpit + COCKPIT_DrawDisplay(); + + } + } + } + + // normally debuginfo is disabled while console is visible + if ( ( ConsoleSliding == 0 ) || AUX_HUD_DEBUGINFO_OVER_CONSOLE ) { + + // draw debug info + if ( AUX_HUD_ENABLE_DEBUGINFO ) + HUD_DrawDebugInfo(); + + // draw packet loss info + if ( AUX_HUD_ENABLE_PACKET_LOSS_METER ) + HUD_DrawPacketLossMeter(); + } + } + + // draw quick say (console line) + COCKPIT_DrawQuickSayBuffer(); + + // draw demo info if enabled + if ( AUX_ENABLE_DEMO_REPLAY_INFO_DISPLAY ) { + HUD_DrawDemoInfo(); + } +} + + + |
