/* Copyright (C) 2002-2003 Victor Luchits 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. */ #include "cg_local.h" /* =============================================================================== HELPER FUNCTIONS =============================================================================== */ int CG_HorizontalAlignForWidth( const int x, int align, int width ) { int nx = x; if( align % 3 == 0 ) // left nx = x; if( align % 3 == 1 ) // center nx = x - width / 2; if( align % 3 == 2 ) // right nx = x - width; return nx; } int CG_VerticalAlignForHeight( const int y, int align, int height ) { int ny = y; if( align / 3 == 0 ) // top ny = y; else if( align / 3 == 1 ) // middle ny = y - height / 2; else if( align / 3 == 2 ) // bottom ny = y - height; return ny; } /* =============================================================================== STRINGS DRAWING =============================================================================== */ /* ============= CG_FillRect ============= */ void CG_FillRect( int x, int y, int w, int h, vec4_t color ) { trap_R_DrawStretchPic( x, y, w, h, 0, 0, 1, 1, color, cgs.shaderWhite ); } /* ============== CG_DrawHUDNumeric ============== */ void CG_DrawHUDNumeric( int x, int y, int align, float *color, int charwidth, int charheight, int value ) { char num[16], *ptr; int length; int frame; // draw number string Q_snprintfz( num, sizeof(num), "%i", value ); length = strlen ( num ); if( !length ) return; x = CG_HorizontalAlignForWidth( x, align, charwidth * length ); y = CG_VerticalAlignForHeight( y, align, charheight ); ptr = num; while( *ptr && length ) { if( *ptr == '-' ) frame = STAT_MINUS; else frame = *ptr - '0'; trap_R_DrawStretchPic( x, y, charwidth, charheight, 0, 0, 1, 1, color, CG_MediaShader(cgs.media.sbNums[frame]) ); x += charwidth; ptr++; length--; } } /* ============== CG_DrawHUDField ============== */ void CG_DrawHUDField( int x, int y, int align, float *color, int size, int width, int value ) { char num[16], *ptr; int length, maxwidth, w, h; int frame; if( width < 0 ) return; maxwidth = 5; // draw number string Q_snprintfz( num, sizeof(num), "%i", value ); length = strlen ( num ); // FIXME: do something wise when length > maxwidth? if( !width ) width = length; else if( width > maxwidth ) width = maxwidth; w = (int)(size * cgs.vidWidth/800 ); h = (int)(size * cgs.vidHeight/600 ); x = CG_HorizontalAlignForWidth( x, align, w*width ); y = CG_VerticalAlignForHeight( y, align, h ); x += w * (width - length); ptr = num; while( *ptr && length ) { if( *ptr == '-' ) frame = STAT_MINUS; else frame = *ptr -'0'; trap_R_DrawStretchPic( x, y, w, h, 0, 0, 1, 1, color, CG_MediaShader(cgs.media.sbNums[frame]) ); x += w; ptr++; length--; } } /* ================ CG_DrawModel ================ */ void CG_DrawModel( int x, int y, int align, int w, int h, struct model_s *model, struct shader_s *shader, vec3_t origin, vec3_t angles ) { refdef_t refdef; entity_t entity; if( !model ) return; x = CG_HorizontalAlignForWidth( x, align, w ); y = CG_VerticalAlignForHeight( y, align, h ); memset( &refdef, 0, sizeof( refdef ) ); refdef.x = x; refdef.y = y; refdef.width = w; refdef.height = h; refdef.fov_x = 30; refdef.fov_y = 30; refdef.time = cg.time * 0.001; refdef.rdflags = RDF_NOWORLDMODEL; memset( &entity, 0, sizeof( entity ) ); entity.model = model; entity.customShader = shader; entity.scale = 1.0f; entity.flags = RF_FULLBRIGHT | RF_NOSHADOW | RF_FORCENOLOD; VectorCopy( origin, entity.origin ); VectorCopy( entity.origin, entity.oldorigin ); AnglesToAxis( angles, entity.axis ); trap_R_ClearScene(); CG_AddEntityToScene( &entity ); trap_R_RenderScene( &refdef ); } /* ================ CG_DrawHUDModel ================ */ void CG_DrawHUDModel( int x, int y, int align, int w, int h, struct model_s *model, struct shader_s *shader, float yawspeed ) { vec3_t mins, maxs; vec3_t origin, angles; // get model bounds trap_R_ModelBounds( model, mins, maxs ); // try to fill the the window with the model origin[0] = 0.5 * (maxs[2] - mins[2]) * (1.0 / 0.179); origin[1] = 0.5 * (mins[1] + maxs[1]); origin[2] = -0.5 * (mins[2] + maxs[2]); VectorSet( angles, 0, anglemod(yawspeed * ( cg.time & 2047 ) * (360.0 / 2048.0)), 0 ); // jalfixme: this isn't even barely right. We just can't add the outline // to every model, cause some models are transparent and it will make // them look completely weird. By now, the only models at the hud are the armors, // se we can let this on, but needs a real fix for sure. if( cg_outlineModels->integer ) { CG_DrawModel( x, y, align, w, h, model, CG_MediaShader( cgs.media.shaderBlackOutline ), origin, angles ); } CG_DrawModel( x, y, align, w, h, model, shader, origin, angles ); } /* ================ CG_DrawHUDRect ================ */ void CG_DrawHUDRect( int x, int y, int align, int w, int h, int val, int maxval, vec4_t color ) { float frac; if( val < 1 || maxval < 1 || w < 1 || h < 1 ) return; if( val >= maxval ) frac = 1.0f; else frac = (float)val / (float)maxval; if( h > w ) { h = (int)((float)h * frac + 0.5); } else w = (int)((float)w * frac + 0.5); x = CG_HorizontalAlignForWidth( x, align, w ); y = CG_VerticalAlignForHeight( y, align, h ); CG_FillRect( x, y, w, h, color ); }