From 8d55b07ab76ec9eeb4f80890576a72b2aa333716 Mon Sep 17 00:00:00 2001 From: P3rlE <97919909+P3rlE@users.noreply.github.com> Date: Sun, 6 Mar 2022 08:25:18 +0100 Subject: [PATCH] =?UTF-8?q?added=20zturtleman=C2=B4s=20flexible=20HUD=20co?= =?UTF-8?q?de?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- engine/code/cgame/cg_draw.c | 164 +++++++++++++++++++++++++++--- engine/code/cgame/cg_drawtools.c | 87 +++++++++++++++- engine/code/cgame/cg_info.c | 2 +- engine/code/cgame/cg_local.h | 29 ++++++ engine/code/cgame/cg_main.c | 42 +++++++- engine/code/cgame/cg_scoreboard.c | 10 +- engine/code/cgame/cg_view.c | 13 +++ engine/code/cgame/cg_weapons.c | 56 +++++++--- engine/code/qcommon/q_shared.h | 2 +- q3rallycode.ppr | 102 +++++++++++++------ 10 files changed, 435 insertions(+), 72 deletions(-) diff --git a/engine/code/cgame/cg_draw.c b/engine/code/cgame/cg_draw.c index d0269119..81a84f06 100644 --- a/engine/code/cgame/cg_draw.c +++ b/engine/code/cgame/cg_draw.c @@ -240,6 +240,10 @@ static void CG_DrawField (int x, int y, int width, int value) { l = width; x += 2 + CHAR_WIDTH*(width - l); + // center x, move y to bottom. + x += (1.0f-cg_statusScale.value)*l*CHAR_WIDTH*0.5f; + y += (1.0f-cg_statusScale.value)*CHAR_HEIGHT; + ptr = num; while (*ptr && l) { @@ -248,8 +252,8 @@ static void CG_DrawField (int x, int y, int width, int value) { else frame = *ptr -'0'; - CG_DrawPic( x,y, CHAR_WIDTH, CHAR_HEIGHT, cgs.media.numberShaders[frame] ); - x += CHAR_WIDTH; + CG_DrawPic( x,y, CHAR_WIDTH*cg_statusScale.value, CHAR_HEIGHT*cg_statusScale.value, cgs.media.numberShaders[frame] ); + x += CHAR_WIDTH*cg_statusScale.value; ptr++; l--; } @@ -299,6 +303,57 @@ void CG_Draw3DModel( float x, float y, float w, float h, qhandle_t model, qhandl trap_R_RenderScene( &refdef ); } +/* +================== +CG_DrawHealthModel +================== +*/ +void CG_DrawHealthModel( float x, float y, float w, float h, qhandle_t model, qhandle_t skin, qhandle_t model2, vec3_t origin, vec3_t angles, float yaw2 ) { + refdef_t refdef; + refEntity_t ent; + + if ( !cg_draw3dIcons.integer || !cg_drawIcons.integer ) { + return; + } + + CG_AdjustFrom640( &x, &y, &w, &h ); + + memset( &refdef, 0, sizeof( refdef ) ); + + memset( &ent, 0, sizeof( ent ) ); + AnglesToAxis( angles, ent.axis ); + VectorCopy( origin, ent.origin ); + ent.hModel = model; + ent.customSkin = skin; + ent.renderfx = RF_NOSHADOW; // no stencil shadows + + refdef.rdflags = RDF_NOWORLDMODEL; + + AxisClear( refdef.viewaxis ); + + refdef.fov_x = 30; + refdef.fov_y = 30; + + refdef.x = x; + refdef.y = y; + refdef.width = w; + refdef.height = h; + + refdef.time = cg.time; + + trap_R_ClearScene(); + trap_R_AddRefEntityToScene( &ent ); + + if ( model2 ) { + ent.hModel = model2; + angles[YAW] = yaw2; + AnglesToAxis( angles, ent.axis ); + trap_R_AddRefEntityToScene( &ent ); + } + + trap_R_RenderScene( &refdef ); +} + /* ================================================================== CG_DrawFlagModel - Used for both the status bar and the scoreboard @@ -423,7 +478,8 @@ CG_DrawStatusBarFlag */ #ifndef MISSIONPACK static void CG_DrawStatusBarFlag( float x, int team ) { - CG_DrawFlagModel( x, 480 - ICON_SIZE, ICON_SIZE, ICON_SIZE, team, qfalse ); + int iconSize = ICON_SIZE*cg_statusScale.value; + CG_DrawFlagModel( x+(1.0f-cg_statusScale.value)*ICON_SIZE*0.5f, 480 - iconSize, iconSize, iconSize, team, qfalse ); } #endif // MISSIONPACK @@ -462,7 +518,9 @@ void CG_DrawTeamBackground( int x, int y, int w, int h, float alpha, int team ) return; } trap_R_SetColor( hcolor ); + CG_SetScreenPlacement(PLACE_STRETCH, CG_GetScreenVerticalPlacement()); CG_DrawPic( x, y, w, h, cgs.media.teamStatusBar ); + CG_PopScreenPlacement(); trap_R_SetColor( NULL ); } @@ -523,6 +581,7 @@ static void CG_DrawStatusBar( void ) { vec4_t hcolor; vec3_t angles; vec3_t origin; + float scale, iconSize; static float colors[4][4] = { // { 0.2, 1.0, 0.2, 1.0 } , { 1.0, 0.2, 0.2, 1.0 }, {0.5, 0.5, 0.5, 1} }; @@ -535,8 +594,14 @@ static void CG_DrawStatusBar( void ) { return; } + CG_SetScreenPlacement(PLACE_CENTER, PLACE_BOTTOM); + + scale = Com_Clamp( 0.1f, 2, cg_statusScale.value); + + iconSize = scale * ICON_SIZE; + // draw the team background - CG_DrawTeamBackground( 0, 420, 640, 60, 0.33f, cg.snap->ps.persistant[PERS_TEAM] ); + CG_DrawTeamBackground( 0, 480 - 60*scale, 640, 60*scale, 0.33f, cg.snap->ps.persistant[PERS_TEAM] ); cent = &cg_entities[cg.snap->ps.clientNum]; ps = &cg.snap->ps; @@ -549,11 +614,25 @@ static void CG_DrawStatusBar( void ) { origin[1] = 0; origin[2] = 0; angles[YAW] = 90 + 20 * sin( cg.time / 1000.0 ); - CG_Draw3DModel( CHAR_WIDTH*3 + TEXT_ICON_SPACE, 432, ICON_SIZE, ICON_SIZE, + CG_Draw3DModel( CHAR_WIDTH*3 + TEXT_ICON_SPACE, 480-iconSize, iconSize, iconSize, cg_weapons[ cent->currentState.weapon ].ammoModel, 0, origin, angles ); } - CG_DrawStatusBarHead( 185 + CHAR_WIDTH*3 + TEXT_ICON_SPACE ); + if ( cg_drawStatusHead.integer == 2 ) { + origin[0] = 60; + origin[1] = 0; + origin[2] = -5; + angles[YAW] = ( cg.time & 2047 ) * 360 / 4096.0; + CG_DrawHealthModel( 185 + CHAR_WIDTH*3 + TEXT_ICON_SPACE, 480-iconSize, iconSize, iconSize, + cg_items[ 6 /*item_health_large*/].models[0], 0, cg_items[ 6 /*item_health_large*/].models[1], origin, angles, 0 ); + + // if we didn't draw a 3D icon, draw a 2D icon for health + if ( !cg_draw3dIcons.integer && cg_drawIcons.integer ) { + CG_DrawPic( 185 + CHAR_WIDTH*3 + TEXT_ICON_SPACE, 480 - iconSize, iconSize, iconSize, cg_items[6/*item_health_large*/].icon ); + } + } + else if ( cg_drawStatusHead.integer == 1 ) + CG_DrawStatusBarHead( 185 + CHAR_WIDTH*3 + TEXT_ICON_SPACE ); if( cg.predictedPlayerState.powerups[PW_REDFLAG] ) { CG_DrawStatusBarFlag( 185 + CHAR_WIDTH*3 + TEXT_ICON_SPACE + ICON_SIZE, TEAM_RED ); @@ -568,7 +647,7 @@ static void CG_DrawStatusBar( void ) { origin[1] = 0; origin[2] = -10; angles[YAW] = ( cg.time & 2047 ) * 360 / 2048.0; - CG_Draw3DModel( 370 + CHAR_WIDTH*3 + TEXT_ICON_SPACE, 432, ICON_SIZE, ICON_SIZE, + CG_Draw3DModel( 370 + CHAR_WIDTH*3 + TEXT_ICON_SPACE, 480 - iconSize, iconSize, iconSize, cgs.media.armorModel, 0, origin, angles ); } // @@ -601,7 +680,7 @@ static void CG_DrawStatusBar( void ) { icon = cg_weapons[ cg.predictedPlayerState.weapon ].ammoIcon; if ( icon ) { - CG_DrawPic( CHAR_WIDTH*3 + TEXT_ICON_SPACE, 432, ICON_SIZE, ICON_SIZE, icon ); + CG_DrawPic( CHAR_WIDTH*3 + TEXT_ICON_SPACE, 480 - iconSize, iconSize, iconSize, icon ); } } } @@ -638,7 +717,7 @@ static void CG_DrawStatusBar( void ) { trap_R_SetColor( NULL ); // if we didn't draw a 3D icon, draw a 2D icon for armor if ( !cg_draw3dIcons.integer && cg_drawIcons.integer ) { - CG_DrawPic( 370 + CHAR_WIDTH*3 + TEXT_ICON_SPACE, 432, ICON_SIZE, ICON_SIZE, cgs.media.armorIcon ); + CG_DrawPic( 370 + CHAR_WIDTH*3 + TEXT_ICON_SPACE, 480 - iconSize, iconSize, iconSize, cgs.media.armorIcon ); } } @@ -1241,6 +1320,8 @@ static void CG_DrawUpperRight(stereoFrame_t stereoFrame) float y; y = 0; + + CG_SetScreenPlacement(PLACE_RIGHT, PLACE_TOP); y = CG_DrawUpperRightHUD( y ); @@ -1287,6 +1368,10 @@ float CG_DrawScores( float x, float y ) { float y1; gitem_t *item; + if ( !cg_drawScores.integer ) { + return y; + } + s1 = cgs.scores1; s2 = cgs.scores2; s3 = cgs.scores3; @@ -1762,6 +1847,8 @@ static void CG_DrawLowerRight( void ) { y = 470; + CG_SetScreenPlacement(PLACE_RIGHT, PLACE_BOTTOM); + if ( isRaceObserver( cg.snap->ps.clientNum ) ) return; @@ -1785,12 +1872,21 @@ CG_DrawPickupItem static int CG_DrawPickupItem( int y ) { int value; float *fadeColor; + float iconSize, charWidth, charHeight; + + if ( cg_drawPickups.value <= 0 ) { + return y; + } if ( cg.snap->ps.stats[STAT_HEALTH] <= 0 ) { return y; } - y -= ICON_SIZE; + iconSize = ICON_SIZE*cg_drawPickups.value; + charWidth = BIGCHAR_WIDTH*cg_drawPickups.value; + charHeight = BIGCHAR_HEIGHT*cg_drawPickups.value; + + y -= iconSize; value = cg.itemPickup; if ( value ) { @@ -1798,8 +1894,8 @@ static int CG_DrawPickupItem( int y ) { if ( fadeColor ) { CG_RegisterItemVisuals( value ); trap_R_SetColor( fadeColor ); - CG_DrawPic( 8, y, ICON_SIZE, ICON_SIZE, cg_items[ value ].icon ); - CG_DrawBigString( ICON_SIZE + 16, y + (ICON_SIZE/2 - BIGCHAR_HEIGHT/2), bg_itemlist[ value ].pickup_name, fadeColor[0] ); + CG_DrawPic( 8, y, iconSize, iconSize, cg_items[ value ].icon ); + CG_DrawStringExt( iconSize + 16, y + (iconSize/2 - charHeight/2), bg_itemlist[ value ].pickup_name, fadeColor, qfalse, qtrue, charWidth, charHeight, 0 ); trap_R_SetColor( NULL ); } } @@ -1818,6 +1914,8 @@ static void CG_DrawLowerLeft( void ) { float y; y = 480; + + CG_SetScreenPlacement(PLACE_LEFT, PLACE_BOTTOM); if (y > 404) y = 404; @@ -1858,6 +1956,8 @@ static void CG_DrawTeamInfo( void ) { if (chatHeight <= 0) return; // disabled + CG_SetScreenPlacement( PLACE_LEFT, PLACE_BOTTOM ); + if (cgs.teamLastChatPos != cgs.teamChatPos) { if (cg.time - cgs.teamChatMsgTimes[cgs.teamLastChatPos % chatHeight] > cg_teamChatTime.integer) { cgs.teamLastChatPos++; @@ -1908,6 +2008,8 @@ CG_DrawHoldableItem static void CG_DrawHoldableItem( void ) { int value; + CG_SetScreenPlacement(PLACE_RIGHT, PLACE_CENTER); + value = cg.snap->ps.stats[STAT_HOLDABLE_ITEM]; if ( value ) { CG_RegisterItemVisuals( value ); @@ -1927,6 +2029,8 @@ CG_DrawPersistantPowerup static void CG_DrawPersistantPowerup( void ) { int value; + CG_SetScreenPlacement(PLACE_RIGHT, PLACE_CENTER); + value = cg.snap->ps.stats[STAT_PERSISTANT_POWERUP]; if ( value ) { CG_RegisterItemVisuals( value ); @@ -1952,6 +2056,8 @@ static void CG_DrawReward( void ) { return; } + CG_SetScreenPlacement(PLACE_RIGHT, PLACE_CENTER); + color = CG_FadeColor( cg.rewardTime, REWARD_TIME ); if ( !color ) { if (cg.rewardStack > 0) { @@ -2086,6 +2192,8 @@ static void CG_DrawDisconnect( void ) { return; } + CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER); + // also add text in center of screen s = "Connection Interrupted"; w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH; @@ -2096,6 +2204,8 @@ static void CG_DrawDisconnect( void ) { return; } + CG_SetScreenPlacement(PLACE_RIGHT, PLACE_BOTTOM); + #ifdef MISSIONPACK x = 640 - 48; y = 480 - 144; @@ -2128,6 +2238,8 @@ static void CG_DrawLagometer( void ) { return; } + CG_SetScreenPlacement(PLACE_RIGHT, PLACE_BOTTOM); + // // draw the graph // @@ -2285,6 +2397,8 @@ static void CG_DrawCenterString( void ) { return; } + CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER); + trap_R_SetColor( color ); start = cg.centerPrint; @@ -2366,6 +2480,8 @@ static void CG_DrawCrosshair(void) return; } + CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER); + // set color based on health if ( cg_crosshairHealth.integer ) { vec4_t hcolor; @@ -2388,7 +2504,6 @@ static void CG_DrawCrosshair(void) x = cg_crosshairX.integer; y = cg_crosshairY.integer; - CG_AdjustFrom640( &x, &y, &w, &h ); ca = cg_drawCrosshair.integer; if (ca < 0) { @@ -2396,9 +2511,7 @@ static void CG_DrawCrosshair(void) } hShader = cgs.media.crosshairShader[ ca % NUM_CROSSHAIRS ]; - trap_R_DrawStretchPic( x + cg.refdef.x + 0.5 * (cg.refdef.width - w), - y + cg.refdef.y + 0.5 * (cg.refdef.height - h), - w, h, 0, 0, 1, 1, hShader ); + CG_DrawPic( ((SCREEN_WIDTH-w)*0.5f)+x, ((SCREEN_HEIGHT-h)*0.5f)+y, w, h, hShader ); trap_R_SetColor( NULL ); } @@ -2536,6 +2649,8 @@ static void CG_DrawCrosshairNames( void ) { return; } + CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER); + // scan the known entities to see if the crosshair is sighted on one CG_ScanForCrosshairEntity(); @@ -2567,6 +2682,7 @@ CG_DrawSpectator ================= */ static void CG_DrawSpectator(void) { + CG_SetScreenPlacement(PLACE_CENTER, PLACE_BOTTOM); CG_DrawBigString(320 - 9 * 8, 440, "SPECTATOR", 1.0F); // Q3Rally Code Start - removed gametype /* @@ -2594,6 +2710,8 @@ static void CG_DrawVote(void) { return; } + CG_SetScreenPlacement(PLACE_LEFT, PLACE_TOP); + // play a talk beep whenever it is modified if ( cgs.voteModified ) { cgs.voteModified = qfalse; @@ -2635,6 +2753,8 @@ static void CG_DrawTeamVote(void) { return; } + CG_SetScreenPlacement(PLACE_LEFT, PLACE_TOP); + // play a talk beep whenever it is modified if ( cgs.teamVoteModified[cs_offset] ) { cgs.teamVoteModified[cs_offset] = qfalse; @@ -2655,6 +2775,8 @@ static qboolean CG_DrawScoreboard( void ) { #ifdef MISSIONPACK static qboolean firstTime = qtrue; + CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER); + if (menuScoreboard) { menuScoreboard->window.flags &= ~WINDOW_FORCED; } @@ -2755,6 +2877,9 @@ static qboolean CG_DrawFollow( void ) { if ( !(cg.snap->ps.pm_flags & PMF_FOLLOW) ) { return qfalse; } + + CG_SetScreenPlacement(PLACE_CENTER, PLACE_TOP); + color[0] = 1; color[1] = 1; color[2] = 1; @@ -2797,6 +2922,8 @@ static void CG_DrawAmmoWarning( void ) { return; } + CG_SetScreenPlacement(PLACE_CENTER, PLACE_TOP); + if ( cg.lowAmmoWarning == 2 ) { s = "OUT OF AMMO"; } else { @@ -2824,6 +2951,8 @@ static void CG_DrawProxWarning( void ) { return; } + CG_SetScreenPlacement(PLACE_CENTER, PLACE_TOP); + if (proxTime == 0) { proxTime = cg.time; } @@ -2997,6 +3126,9 @@ static void CG_Draw2D(stereoFrame_t stereoFrame) #ifdef MISSIONPACK if ( cg_drawStatus.integer ) { + + CG_SetScreenPlacement(PLACE_CENTER, PLACE_BOTTOM); + Menu_PaintAll(); CG_DrawTimedMenus(); } diff --git a/engine/code/cgame/cg_drawtools.c b/engine/code/cgame/cg_drawtools.c index 9cc4b46d..96e22353 100644 --- a/engine/code/cgame/cg_drawtools.c +++ b/engine/code/cgame/cg_drawtools.c @@ -24,6 +24,56 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // cg_drawtools.c -- helper functions called by cg_draw, cg_scoreboard, cg_info, etc #include "cg_local.h" +static screenPlacement_e cg_horizontalPlacement = PLACE_CENTER; +static screenPlacement_e cg_verticalPlacement = PLACE_CENTER; +static screenPlacement_e cg_lastHorizontalPlacement = PLACE_CENTER; +static screenPlacement_e cg_lastVerticalPlacement = PLACE_CENTER; + +/* +================ +CG_SetScreenPlacement +================ +*/ +void CG_SetScreenPlacement(screenPlacement_e hpos, screenPlacement_e vpos) +{ + cg_lastHorizontalPlacement = cg_horizontalPlacement; + cg_lastVerticalPlacement = cg_verticalPlacement; + + cg_horizontalPlacement = hpos; + cg_verticalPlacement = vpos; +} + +/* +================ +CG_PopScreenPlacement +================ +*/ +void CG_PopScreenPlacement(void) +{ + cg_horizontalPlacement = cg_lastHorizontalPlacement; + cg_verticalPlacement = cg_lastVerticalPlacement; +} + +/* +================ +CG_GetScreenHorizontalPlacement +================ +*/ +screenPlacement_e CG_GetScreenHorizontalPlacement(void) +{ + return cg_horizontalPlacement; +} + +/* +================ +CG_GetScreenVerticalPlacement +================ +*/ +screenPlacement_e CG_GetScreenVerticalPlacement(void) +{ + return cg_verticalPlacement; +} + /* ================ CG_AdjustFrom640 @@ -32,6 +82,7 @@ Adjusted for resolution and screen aspect ratio ================ */ void CG_AdjustFrom640( float *x, float *y, float *w, float *h ) { +#if 0 #if 0 // adjust for wide screens if ( cgs.glconfig.vidWidth * 480 > cgs.glconfig.vidHeight * 640 ) { @@ -43,8 +94,40 @@ void CG_AdjustFrom640( float *x, float *y, float *w, float *h ) { *y *= cgs.screenYScale; *w *= cgs.screenXScale; *h *= cgs.screenYScale; +#endif + + if (cg_horizontalPlacement == PLACE_STRETCH || cg_stretch.integer) { + // scale for screen sizes (not aspect correct in wide screen) + *w *= cgs.screenXScaleStretch; + *x *= cgs.screenXScaleStretch; + } else { + // scale for screen sizes + *w *= cgs.screenXScale; + *x *= cgs.screenXScale; + + if (cg_horizontalPlacement == PLACE_CENTER) { + *x += cgs.screenXBias; + } else if (cg_horizontalPlacement == PLACE_RIGHT) { + *x += cgs.screenXBias*2; + } + } + + if (cg_verticalPlacement == PLACE_STRETCH || cg_stretch.integer) { + *h *= cgs.screenYScaleStretch; + *y *= cgs.screenYScaleStretch; + } else { + *h *= cgs.screenYScale; + *y *= cgs.screenYScale; + + if (cg_verticalPlacement == PLACE_CENTER) { + *y += cgs.screenYBias; + } else if (cg_verticalPlacement == PLACE_BOTTOM) { + *y += cgs.screenYBias*2; + } + } } + /* ================ CG_FillRect @@ -778,7 +861,7 @@ static void UI_DrawBannerString2( int x, int y, const char* str, vec4_t color ) trap_R_SetColor( color ); ax = x * cgs.screenXScale + cgs.screenXBias; - ay = y * cgs.screenYScale; + ay = y * cgs.screenYScale + cgs.screenYBias; s = str; while ( *s ) @@ -888,7 +971,7 @@ static void UI_DrawProportionalString2( int x, int y, const char* str, vec4_t co trap_R_SetColor( color ); ax = x * cgs.screenXScale + cgs.screenXBias; - ay = y * cgs.screenYScale; + ay = y * cgs.screenYScale + cgs.screenYBias; s = str; while ( *s ) diff --git a/engine/code/cgame/cg_info.c b/engine/code/cgame/cg_info.c index 12f0cea5..f46a35d4 100644 --- a/engine/code/cgame/cg_info.c +++ b/engine/code/cgame/cg_info.c @@ -173,7 +173,7 @@ void CG_DrawInformation( void ) { levelshot = trap_R_RegisterShaderNoMip( "menu/art/unknownmap" ); } trap_R_SetColor( NULL ); - CG_DrawPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, levelshot ); + trap_R_DrawStretchPic( 0, 0, cgs.glconfig.vidWidth, cgs.glconfig.vidHeight, 0, 0, 1, 1, levelshot ); // blend a detail texture over it detail = trap_R_RegisterShader( "levelShotDetail" ); diff --git a/engine/code/cgame/cg_local.h b/engine/code/cgame/cg_local.h index 93e46775..99b582a9 100644 --- a/engine/code/cgame/cg_local.h +++ b/engine/code/cgame/cg_local.h @@ -665,6 +665,7 @@ typedef struct { refdef_t mirrorRefdef; refdef_t mmapRefdef; // minimap rendering vec3_t refdefViewAngles; // will be converted to refdef.viewaxis + float fov; // either range checked cg_fov or forced value // zoom key qboolean zoomed; @@ -1199,6 +1200,9 @@ typedef struct { float screenXScale; // derived from glconfig float screenYScale; float screenXBias; + float screenYBias; + float screenXScaleStretch; + float screenYScaleStretch; int serverCommandSequence; // reliable command stream counter int processedSnapshotNum;// the number of snapshots cgame has requested @@ -1316,6 +1320,14 @@ extern vmCvar_t cg_drawCrosshair; extern vmCvar_t cg_drawCrosshairNames; extern vmCvar_t cg_drawRewards; extern vmCvar_t cg_drawTeamOverlay; +extern vmCvar_t cg_drawScores; +extern vmCvar_t cg_drawPickups; +extern vmCvar_t cg_drawWeaponBar; +extern vmCvar_t cg_drawStatusHead; +extern vmCvar_t cg_statusScale; +extern vmCvar_t cg_fovAspectAdjust; +extern vmCvar_t cg_fovGunAdjust; +extern vmCvar_t cg_stretch; extern vmCvar_t cg_teamOverlayUserinfo; extern vmCvar_t cg_crosshairX; extern vmCvar_t cg_crosshairY; @@ -1484,6 +1496,23 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demo // // cg_drawtools.c // +typedef enum { + PLACE_STRETCH, + PLACE_CENTER, + + // horizontal only + PLACE_LEFT, + PLACE_RIGHT, + + // vertical only + PLACE_TOP, + PLACE_BOTTOM +} screenPlacement_e; + +void CG_SetScreenPlacement(screenPlacement_e hpos, screenPlacement_e vpos); +void CG_PopScreenPlacement(void); +screenPlacement_e CG_GetScreenHorizontalPlacement(void); +screenPlacement_e CG_GetScreenVerticalPlacement(void); void CG_AdjustFrom640( float *x, float *y, float *w, float *h ); void CG_FillRect( float x, float y, float width, float height, const float *color ); void CG_DrawPic( float x, float y, float width, float height, qhandle_t hShader ); diff --git a/engine/code/cgame/cg_main.c b/engine/code/cgame/cg_main.c index 27f65afb..bf2f48c3 100644 --- a/engine/code/cgame/cg_main.c +++ b/engine/code/cgame/cg_main.c @@ -142,6 +142,14 @@ vmCvar_t cg_drawAmmoWarning; vmCvar_t cg_drawCrosshair; vmCvar_t cg_drawCrosshairNames; vmCvar_t cg_drawRewards; +vmCvar_t cg_drawScores; +vmCvar_t cg_drawPickups; +vmCvar_t cg_drawWeaponBar; +vmCvar_t cg_drawStatusHead; +vmCvar_t cg_statusScale; +vmCvar_t cg_fovAspectAdjust; +vmCvar_t cg_fovGunAdjust; +vmCvar_t cg_stretch; vmCvar_t cg_crosshairSize; vmCvar_t cg_crosshairX; vmCvar_t cg_crosshairY; @@ -299,6 +307,14 @@ static cvarTable_t cvarTable[] = { { &cg_drawCrosshair, "cg_drawCrosshair", "4", CVAR_ARCHIVE }, { &cg_drawCrosshairNames, "cg_drawCrosshairNames", "1", CVAR_ARCHIVE }, { &cg_drawRewards, "cg_drawRewards", "1", CVAR_ARCHIVE }, + { &cg_drawScores, "cg_drawScores", "1", CVAR_ARCHIVE }, + { &cg_drawPickups, "cg_drawPickups", "1", CVAR_ARCHIVE }, + { &cg_drawWeaponBar, "cg_drawWeaponBar", "1", CVAR_ARCHIVE }, + { &cg_drawStatusHead, "cg_drawStatusHead", "1", CVAR_ARCHIVE }, + { &cg_statusScale, "cg_statusScale", "1", CVAR_ARCHIVE }, + { &cg_fovAspectAdjust, "cg_fovAspectAdjust", "0", CVAR_ARCHIVE }, + { &cg_fovGunAdjust, "cg_fovGunAdjust", "0", CVAR_ARCHIVE }, + { &cg_stretch, "cg_stretch", "1", CVAR_ARCHIVE }, { &cg_crosshairSize, "cg_crosshairSize", "24", CVAR_ARCHIVE }, { &cg_crosshairHealth, "cg_crosshairHealth", "1", CVAR_ARCHIVE }, { &cg_crosshairX, "cg_crosshairX", "0", CVAR_ARCHIVE }, @@ -1312,7 +1328,10 @@ static void CG_RegisterGraphics( void ) { } } - // wall marks +// can be used by HUD so always load it + CG_RegisterItemVisuals( 6 /* item_health_large */ ); + +// wall marks cgs.media.bulletMarkShader = trap_R_RegisterShader( "gfx/damage/bullet_mrk" ); cgs.media.burnMarkShader = trap_R_RegisterShader( "gfx/damage/burn_med_mrk" ); // Q3Rally Code Start @@ -2181,8 +2200,25 @@ void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum ) { // old servers // get the rendering configuration from the client system trap_GetGlconfig( &cgs.glconfig ); - cgs.screenXScale = cgs.glconfig.vidWidth / 640.0; - cgs.screenYScale = cgs.glconfig.vidHeight / 480.0; + cgs.screenXScaleStretch = cgs.glconfig.vidWidth * (1.0/640.0); + cgs.screenYScaleStretch = cgs.glconfig.vidHeight * (1.0/480.0); + if ( cgs.glconfig.vidWidth * 480 > cgs.glconfig.vidHeight * 640 ) { + cgs.screenXScale = cgs.glconfig.vidWidth * (1.0/640.0); + cgs.screenYScale = cgs.glconfig.vidHeight * (1.0/480.0); + // wide screen + cgs.screenXBias = 0.5 * ( cgs.glconfig.vidWidth - ( cgs.glconfig.vidHeight * (640.0/480.0) ) ); + cgs.screenXScale = cgs.screenYScale; + // no narrow screen + cgs.screenYBias = 0; + } else { + cgs.screenXScale = cgs.glconfig.vidWidth * (1.0/640.0); + cgs.screenYScale = cgs.glconfig.vidHeight * (1.0/480.0); + // narrow screen + cgs.screenYBias = 0.5 * ( cgs.glconfig.vidHeight - ( cgs.glconfig.vidWidth * (480.0/640.0) ) ); + cgs.screenYScale = cgs.screenXScale; + // no wide screen + cgs.screenXBias = 0; + } // get the gamestate from the client system trap_GetGameState( &cgs.gameState ); diff --git a/engine/code/cgame/cg_scoreboard.c b/engine/code/cgame/cg_scoreboard.c index fb315745..5d09cd4b 100644 --- a/engine/code/cgame/cg_scoreboard.c +++ b/engine/code/cgame/cg_scoreboard.c @@ -370,10 +370,10 @@ qboolean CG_DrawOldScoreboard( void ) { int maxClients; int lineHeight; int topBorderSize, bottomBorderSize; -// Q3Rally Code Start int team; char *teamName; -// END + +CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER); // don't draw amuthing if the menu or console is up if ( cg_paused.integer ) { @@ -622,6 +622,8 @@ void CG_DrawTourneyScoreboard( void ) { int y; int i; +CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER); + // request more scores regularly if ( cg.scoresRequestTime + 2000 < cg.time ) { cg.scoresRequestTime = cg.time; @@ -631,8 +633,10 @@ void CG_DrawTourneyScoreboard( void ) { // draw the dialog background color[0] = color[1] = color[2] = 0; color[3] = 1; + CG_SetScreenPlacement(PLACE_STRETCH, PLACE_STRETCH); CG_FillRect( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, color ); - + CG_PopScreenPlacement(); + color[0] = 1; color[1] = 1; color[2] = 1; diff --git a/engine/code/cgame/cg_view.c b/engine/code/cgame/cg_view.c index 0a302ac0..59fb0b6d 100644 --- a/engine/code/cgame/cg_view.c +++ b/engine/code/cgame/cg_view.c @@ -501,6 +501,7 @@ static int CG_CalcFov( void ) { if ( cg.predictedPlayerState.pm_type == PM_INTERMISSION ) { // if in intermission, use a fixed value fov_x = 90; + cg.fov = fov_x = 90; } else { // user selectable if ( cgs.dmflags & DF_FIXED_FOV ) { @@ -515,6 +516,8 @@ static int CG_CalcFov( void ) { } } + cg.fov = fov_x; + // account for zooms zoomFov = cg_zoomFov.value; if ( zoomFov < 1 ) { @@ -538,6 +541,16 @@ static int CG_CalcFov( void ) { } } + if ( cg_fovAspectAdjust.integer ) { + // Based on LordHavoc's code for Darkplaces + // http://www.quakeworld.nu/forum/topic/53/what-does-your-qw-look-like/page/30 + const float baseAspect = 0.75f; // 3/4 + const float aspect = (float)cg.refdef.width/(float)cg.refdef.height; + const float desiredFov = fov_x; + + fov_x = atan2( tan( desiredFov*M_PI / 360.0f ) * baseAspect*aspect, 1 )*360.0f / M_PI; + } + x = cg.refdef.width / tan( fov_x / 360 * M_PI ); fov_y = atan2( cg.refdef.height, x ); fov_y = fov_y * 360 / M_PI; diff --git a/engine/code/cgame/cg_weapons.c b/engine/code/cgame/cg_weapons.c index 806a7795..643a5840 100644 --- a/engine/code/cgame/cg_weapons.c +++ b/engine/code/cgame/cg_weapons.c @@ -1435,7 +1435,7 @@ void CG_AddViewWeapon( playerState_t *ps ) { // centity_t *cent; // clientInfo_t *ci; // END - float fovOffset; + vec3_t fovOffset; vec3_t angles; weaponInfo_t *weapon; @@ -1472,11 +1472,19 @@ void CG_AddViewWeapon( playerState_t *ps ) { return; } - // drop gun lower at higher fov - if ( cg_fov.integer > 90 ) { - fovOffset = -0.2 * ( cg_fov.integer - 90 ); - } else { - fovOffset = 0; + VectorClear(fovOffset); + + if ( cg_fovGunAdjust.integer ) { + if ( cg.fov > 90 ) { + // drop gun lower at higher fov + fovOffset[2] = -0.2 * ( cg.fov - 90 ) * cg.refdef.fov_x / cg.fov; + } else if ( cg.fov < 90 ) { + // move gun forward at lowerer fov + fovOffset[0] = -0.2 * ( cg.fov - 90 ) * cg.refdef.fov_x / cg.fov; + } + } else if ( cg_fov.integer > 90 ) { + // Q3A's auto adjust + fovOffset[2] = -0.2 * ( cg_fov.integer - 90 ); } // SKWID( removed animations ) @@ -1492,9 +1500,9 @@ void CG_AddViewWeapon( playerState_t *ps ) { // CG_CalculateWeaponPosition( hand.origin, angles ); // END - VectorMA( hand.origin, cg_gun_x.value, cg.refdef.viewaxis[0], hand.origin ); - VectorMA( hand.origin, cg_gun_y.value, cg.refdef.viewaxis[1], hand.origin ); - VectorMA( hand.origin, (cg_gun_z.value+fovOffset), cg.refdef.viewaxis[2], hand.origin ); + VectorMA( hand.origin, (cg_gun_x.value+fovOffset[0]), cg.refdef.viewaxis[0], hand.origin ); + VectorMA( hand.origin, (cg_gun_y.value+fovOffset[1]), cg.refdef.viewaxis[1], hand.origin ); + VectorMA( hand.origin, (cg_gun_z.value+fovOffset[2]), cg.refdef.viewaxis[2], hand.origin ); AnglesToAxis( angles, hand.axis ); @@ -1543,7 +1551,14 @@ void CG_DrawWeaponSelect( void ) { int x, y, w; char *name; float *color; + float markerSize, iconSize, offsetSize, charWidth, charHeight; + CG_SetScreenPlacement(PLACE_CENTER, PLACE_BOTTOM); + + if ( cg_drawWeaponBar.value <= 0 ) { + return; + } + // don't display if dead if ( cg.predictedPlayerState.stats[STAT_HEALTH] <= 0 ) { return; @@ -1570,9 +1585,18 @@ void CG_DrawWeaponSelect( void ) { } } - x = 320 - count * 20; + x = 320 - count * 20 * cg_drawWeaponBar.value; y = 380; + markerSize = 40 * cg_drawWeaponBar.value; + iconSize = 32 * cg_drawWeaponBar.value; + offsetSize = (markerSize - iconSize) * 0.5f; + + charWidth = BIGCHAR_WIDTH * cg_drawWeaponBar.value; + charHeight = BIGCHAR_HEIGHT * cg_drawWeaponBar.value; + + + // Q3Rally Code Start // for ( i = 1 ; i < MAX_WEAPONS ; i++ ) { for ( i = 1 ; i < RWP_SMOKE ; i++ ) { @@ -1584,28 +1608,28 @@ void CG_DrawWeaponSelect( void ) { CG_RegisterWeapon( i ); // draw weapon icon - CG_DrawPic( x, y, 32, 32, cg_weapons[i].weaponIcon ); + CG_DrawPic( x, y, iconSize, iconSize, cg_weapons[i].weaponIcon ); // draw selection marker if ( i == cg.weaponSelect ) { - CG_DrawPic( x-4, y-4, 40, 40, cgs.media.selectShader ); + CG_DrawPic( x-offsetSize, y-offsetSize, markerSize, markerSize, cgs.media.selectShader ); } // no ammo cross on top if ( !cg.snap->ps.ammo[ i ] ) { - CG_DrawPic( x, y, 32, 32, cgs.media.noammoShader ); + CG_DrawPic( x, y, iconSize, iconSize, cgs.media.noammoShader ); } - x += 40; + x += markerSize; } // draw the selected name if ( cg_weapons[ cg.weaponSelect ].item ) { name = cg_weapons[ cg.weaponSelect ].item->pickup_name; if ( name ) { - w = CG_DrawStrlen( name ) * BIGCHAR_WIDTH; + w = CG_DrawStrlen( name ) * charWidth; x = ( SCREEN_WIDTH - w ) / 2; - CG_DrawBigStringColor(x, y - 22, name, color); + CG_DrawStringExt(x, y - 22*cg_drawWeaponBar.value, name, color, qfalse, qtrue, charWidth, charHeight, 0 ); } } diff --git a/engine/code/qcommon/q_shared.h b/engine/code/qcommon/q_shared.h index 90c5b597..0a6aa9a3 100644 --- a/engine/code/qcommon/q_shared.h +++ b/engine/code/qcommon/q_shared.h @@ -67,7 +67,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define BASETA "missionpack" #ifndef PRODUCT_VERSION -#define PRODUCT_VERSION "v0.4" +#define PRODUCT_VERSION "v0.4_r502" #endif diff --git a/q3rallycode.ppr b/q3rallycode.ppr index 60cfceaf..1c78e892 100644 --- a/q3rallycode.ppr +++ b/q3rallycode.ppr @@ -18,6 +18,8 @@ HTServer=localhost q3rallycode +engine +code + -renderercommon + engine\code\renderercommon\tr_common.h -renderergl1 engine\code\renderergl1\tr_world.c engine\code\renderergl1\tr_surface.c @@ -886,37 +888,77 @@ q3rallycode engine\cross-make-mingw64.sh [Open project files] 0=engine\code\qcommon\q_shared.h -1=engine\code\cgame\cg_ents.c -2=engine\code\cgame\cg_local.h -3=engine\code\cgame\cg_main.c -4=engine\code\cgame\cg_players.c -5=engine\code\cgame\cg_draw.c -6=engine\code\game\bg_public.h -7=engine\code\cgame\cg_rally_hud.c +1=engine\code\client\cl_main.c +2=engine\code\q3_ui\ui_video.c +3=engine\code\qcommon\q_shared.c +4=engine\code\renderercommon\tr_common.h +5=engine\code\renderergl1\tr_backend.c +6=engine\code\renderergl1\tr_image.c +7=engine\code\renderergl1\tr_init.c +8=engine\code\renderergl1\tr_local.h +9=engine\code\renderergl1\tr_model_iqm.c +10=engine\code\cgame\cg_draw.c +11=engine\code\cgame\cg_info.c +12=engine\code\cgame\cg_local.h +13=engine\code\cgame\cg_main.c +14=engine\code\cgame\cg_scoreboard.c +15=engine\code\cgame\cg_view.c +16=engine\code\cgame\cg_weapons.c +17=engine\code\cgame\cg_drawtools.c [Selected Project Files] Main= -Selected=engine\code\cgame\cg_rally_hud.c +Selected=engine\code\cgame\cg_drawtools.c [engine\code\qcommon\q_shared.h] -TopLine=58 -Caret=31,70 -[engine\code\cgame\cg_ents.c] -TopLine=144 -Caret=1,160 -[engine\code\cgame\cg_local.h] -TopLine=420 -Caret=1,436 -[engine\code\cgame\cg_main.c] -TopLine=1086 -Caret=1,1116 -[engine\code\cgame\cg_players.c] -TopLine=2407 -Caret=37,2422 +TopLine=610 +Caret=23,638 +[engine\code\client\cl_main.c] +TopLine=3069 +Caret=3,3108 +[engine\code\q3_ui\ui_video.c] +TopLine=557 +Caret=35,575 +[engine\code\qcommon\q_shared.c] +TopLine=15 +Caret=16,27 +[engine\code\renderercommon\tr_common.h] +TopLine=63 +Caret=34,83 +[engine\code\renderergl1\tr_backend.c] +TopLine=782 +Caret=103,797 +[engine\code\renderergl1\tr_image.c] +TopLine=844 +Caret=67,869 +[engine\code\renderergl1\tr_init.c] +TopLine=1290 +Caret=28,1298 +[engine\code\renderergl1\tr_local.h] +TopLine=600 +Caret=42,632 +[engine\code\renderergl1\tr_model_iqm.c] +TopLine=157 +Caret=29,182 [engine\code\cgame\cg_draw.c] -TopLine=320 -Caret=1,336 -[engine\code\game\bg_public.h] -TopLine=390 -Caret=3,408 -[engine\code\cgame\cg_rally_hud.c] -TopLine=532 -Caret=9,550 +TopLine=3108 +Caret=13,3131 +[engine\code\cgame\cg_info.c] +TopLine=143 +Caret=102,176 +[engine\code\cgame\cg_local.h] +TopLine=1479 +Caret=55,1515 +[engine\code\cgame\cg_main.c] +TopLine=2203 +Caret=1,2222 +[engine\code\cgame\cg_scoreboard.c] +TopLine=615 +Caret=5,639 +[engine\code\cgame\cg_view.c] +TopLine=522 +Caret=3,552 +[engine\code\cgame\cg_weapons.c] +TopLine=1607 +Caret=110,1632 +[engine\code\cgame\cg_drawtools.c] +TopLine=95 +Caret=1,129