cg_info.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake III Arena source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. //
  19. // cg_info.c -- display information while data is being loading
  20. #include "cg_local.h"
  21. #define MAX_LOADING_PLAYER_ICONS 16
  22. #define MAX_LOADING_ITEM_ICONS 26
  23. static int loadingPlayerIconCount;
  24. static int loadingItemIconCount;
  25. static qhandle_t loadingPlayerIcons[MAX_LOADING_PLAYER_ICONS];
  26. static qhandle_t loadingItemIcons[MAX_LOADING_ITEM_ICONS];
  27. /*
  28. ===================
  29. CG_DrawLoadingIcons
  30. ===================
  31. */
  32. static void CG_DrawLoadingIcons( void ) {
  33. int n;
  34. int x, y;
  35. for( n = 0; n < loadingPlayerIconCount; n++ ) {
  36. x = 16 + n * 78;
  37. y = 324-40;
  38. CG_DrawPic( x, y, 64, 64, loadingPlayerIcons[n] );
  39. }
  40. for( n = 0; n < loadingItemIconCount; n++ ) {
  41. y = 400-40;
  42. if( n >= 13 ) {
  43. y += 40;
  44. }
  45. x = 16 + n % 13 * 48;
  46. CG_DrawPic( x, y, 32, 32, loadingItemIcons[n] );
  47. }
  48. }
  49. /*
  50. ======================
  51. CG_LoadingString
  52. ======================
  53. */
  54. void CG_LoadingString( const char *s ) {
  55. Q_strncpyz( cg.infoScreenText, s, sizeof( cg.infoScreenText ) );
  56. trap_UpdateScreen();
  57. }
  58. /*
  59. ===================
  60. CG_LoadingItem
  61. ===================
  62. */
  63. void CG_LoadingItem( int itemNum ) {
  64. gitem_t *item;
  65. item = &bg_itemlist[itemNum];
  66. if ( item->icon && loadingItemIconCount < MAX_LOADING_ITEM_ICONS ) {
  67. loadingItemIcons[loadingItemIconCount++] = trap_R_RegisterShaderNoMip( item->icon );
  68. }
  69. CG_LoadingString( item->pickup_name );
  70. }
  71. /*
  72. ===================
  73. CG_LoadingClient
  74. ===================
  75. */
  76. void CG_LoadingClient( int clientNum ) {
  77. const char *info;
  78. char *skin;
  79. char personality[MAX_QPATH];
  80. char model[MAX_QPATH];
  81. char iconName[MAX_QPATH];
  82. info = CG_ConfigString( CS_PLAYERS + clientNum );
  83. if ( loadingPlayerIconCount < MAX_LOADING_PLAYER_ICONS ) {
  84. Q_strncpyz( model, Info_ValueForKey( info, "model" ), sizeof( model ) );
  85. skin = Q_strrchr( model, '/' );
  86. if ( skin ) {
  87. *skin++ = '\0';
  88. } else {
  89. skin = "default";
  90. }
  91. Com_sprintf( iconName, MAX_QPATH, "models/players/%s/icon_%s.tga", model, skin );
  92. loadingPlayerIcons[loadingPlayerIconCount] = trap_R_RegisterShaderNoMip( iconName );
  93. if ( !loadingPlayerIcons[loadingPlayerIconCount] ) {
  94. Com_sprintf( iconName, MAX_QPATH, "models/players/characters/%s/icon_%s.tga", model, skin );
  95. loadingPlayerIcons[loadingPlayerIconCount] = trap_R_RegisterShaderNoMip( iconName );
  96. }
  97. if ( !loadingPlayerIcons[loadingPlayerIconCount] ) {
  98. Com_sprintf( iconName, MAX_QPATH, "models/players/%s/icon_%s.tga", DEFAULT_MODEL, "default" );
  99. loadingPlayerIcons[loadingPlayerIconCount] = trap_R_RegisterShaderNoMip( iconName );
  100. }
  101. if ( loadingPlayerIcons[loadingPlayerIconCount] ) {
  102. loadingPlayerIconCount++;
  103. }
  104. }
  105. Q_strncpyz( personality, Info_ValueForKey( info, "n" ), sizeof(personality) );
  106. Q_CleanStr( personality );
  107. if( cgs.gametype == GT_SINGLE_PLAYER ) {
  108. trap_S_RegisterSound( va( "sound/player/announce/%s.wav", personality ), qtrue );
  109. }
  110. CG_LoadingString( personality );
  111. }
  112. /*
  113. ====================
  114. CG_DrawInformation
  115. Draw all the status / pacifier stuff during level loading
  116. ====================
  117. */
  118. void CG_DrawInformation( void ) {
  119. const char *s;
  120. const char *info;
  121. const char *sysInfo;
  122. int y;
  123. int value;
  124. qhandle_t levelshot;
  125. qhandle_t detail;
  126. char buf[1024];
  127. info = CG_ConfigString( CS_SERVERINFO );
  128. sysInfo = CG_ConfigString( CS_SYSTEMINFO );
  129. s = Info_ValueForKey( info, "mapname" );
  130. levelshot = trap_R_RegisterShaderNoMip( va( "levelshots/%s.tga", s ) );
  131. if ( !levelshot ) {
  132. levelshot = trap_R_RegisterShaderNoMip( "menu/art/unknownmap" );
  133. }
  134. trap_R_SetColor( NULL );
  135. CG_DrawPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, levelshot );
  136. // blend a detail texture over it
  137. detail = trap_R_RegisterShader( "levelShotDetail" );
  138. trap_R_DrawStretchPic( 0, 0, cgs.glconfig.vidWidth, cgs.glconfig.vidHeight, 0, 0, 2.5, 2, detail );
  139. // draw the icons of things as they are loaded
  140. CG_DrawLoadingIcons();
  141. // the first 150 rows are reserved for the client connection
  142. // screen to write into
  143. if ( cg.infoScreenText[0] ) {
  144. UI_DrawProportionalString( 320, 128-32, va("Loading... %s", cg.infoScreenText),
  145. UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
  146. } else {
  147. UI_DrawProportionalString( 320, 128-32, "Awaiting snapshot...",
  148. UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
  149. }
  150. // draw info string information
  151. y = 180-32;
  152. // don't print server lines if playing a local game
  153. trap_Cvar_VariableStringBuffer( "sv_running", buf, sizeof( buf ) );
  154. if ( !atoi( buf ) ) {
  155. // server hostname
  156. Q_strncpyz(buf, Info_ValueForKey( info, "sv_hostname" ), 1024);
  157. Q_CleanStr(buf);
  158. UI_DrawProportionalString( 320, y, buf,
  159. UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
  160. y += PROP_HEIGHT;
  161. // pure server
  162. s = Info_ValueForKey( sysInfo, "sv_pure" );
  163. if ( s[0] == '1' ) {
  164. UI_DrawProportionalString( 320, y, "Pure Server",
  165. UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
  166. y += PROP_HEIGHT;
  167. }
  168. // server-specific message of the day
  169. s = CG_ConfigString( CS_MOTD );
  170. if ( s[0] ) {
  171. UI_DrawProportionalString( 320, y, s,
  172. UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
  173. y += PROP_HEIGHT;
  174. }
  175. // some extra space after hostname and motd
  176. y += 10;
  177. }
  178. // map-specific message (long map name)
  179. s = CG_ConfigString( CS_MESSAGE );
  180. if ( s[0] ) {
  181. UI_DrawProportionalString( 320, y, s,
  182. UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
  183. y += PROP_HEIGHT;
  184. }
  185. // cheats warning
  186. s = Info_ValueForKey( sysInfo, "sv_cheats" );
  187. if ( s[0] == '1' ) {
  188. UI_DrawProportionalString( 320, y, "CHEATS ARE ENABLED",
  189. UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
  190. y += PROP_HEIGHT;
  191. }
  192. // game type
  193. switch ( cgs.gametype ) {
  194. case GT_FFA:
  195. s = "Free For All";
  196. break;
  197. case GT_SINGLE_PLAYER:
  198. s = "Single Player";
  199. break;
  200. case GT_TOURNAMENT:
  201. s = "Tournament";
  202. break;
  203. case GT_TEAM:
  204. s = "Team Deathmatch";
  205. break;
  206. case GT_CTF:
  207. s = "Capture The Flag";
  208. break;
  209. #ifdef MISSIONPACK
  210. case GT_1FCTF:
  211. s = "One Flag CTF";
  212. break;
  213. case GT_OBELISK:
  214. s = "Overload";
  215. break;
  216. case GT_HARVESTER:
  217. s = "Harvester";
  218. break;
  219. #endif
  220. default:
  221. s = "Unknown Gametype";
  222. break;
  223. }
  224. UI_DrawProportionalString( 320, y, s,
  225. UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
  226. y += PROP_HEIGHT;
  227. value = atoi( Info_ValueForKey( info, "timelimit" ) );
  228. if ( value ) {
  229. UI_DrawProportionalString( 320, y, va( "timelimit %i", value ),
  230. UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
  231. y += PROP_HEIGHT;
  232. }
  233. if (cgs.gametype < GT_CTF ) {
  234. value = atoi( Info_ValueForKey( info, "fraglimit" ) );
  235. if ( value ) {
  236. UI_DrawProportionalString( 320, y, va( "fraglimit %i", value ),
  237. UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
  238. y += PROP_HEIGHT;
  239. }
  240. }
  241. if (cgs.gametype >= GT_CTF) {
  242. value = atoi( Info_ValueForKey( info, "capturelimit" ) );
  243. if ( value ) {
  244. UI_DrawProportionalString( 320, y, va( "capturelimit %i", value ),
  245. UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
  246. y += PROP_HEIGHT;
  247. }
  248. }
  249. }