PageRenderTime 57ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 2ms

/OJRP Source/Enhanced/source/ui/ui_main.c

https://github.com/theGster/OJRP
C | 11766 lines | 9629 code | 944 blank | 1193 comment | 1727 complexity | c4d6bbad0b25fbae46bf8471d817834e MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. // Copyright (C) 1999-2000 Id Software, Inc.
  2. //
  3. /*
  4. =======================================================================
  5. USER INTERFACE MAIN
  6. =======================================================================
  7. */
  8. // use this to get a demo build without an explicit demo build, i.e. to get the demo ui files to build
  9. //#define PRE_RELEASE_TADEMO
  10. #include "../ghoul2/G2.h"
  11. #include "ui_local.h"
  12. #include "../qcommon/qfiles.h"
  13. #include "../qcommon/game_version.h"
  14. #include "ui_force.h"
  15. #include "../cgame/animtable.h" //we want this to be compiled into the module because we access it in the shared module.
  16. #include "../game/bg_saga.h"
  17. //[Mac]
  18. #if MAC_PORT
  19. #include "../cgame/holocronicons.h"
  20. #else
  21. #include "..\cgame\holocronicons.h"
  22. #endif
  23. //[/Mac]
  24. extern void UI_SaberAttachToChar( itemDef_t *item );
  25. uiRank_t uiRank[NUM_TOTAL_SKILLS] =
  26. {
  27. {3,UI_FORCE_RANK_HEAL,FP_HEAL,FORCE_LIGHTSIDE,qfalse,0},
  28. {3,UI_FORCE_RANK_LEVITATION,FP_LEVITATION,0,qfalse,0},
  29. {3,UI_FORCE_RANK_SPEED,FP_SPEED,0,qfalse,0},
  30. {3,UI_FORCE_RANK_PUSH,FP_PUSH,0,qfalse,0},
  31. {3,UI_FORCE_RANK_PULL,FP_PULL,0,qfalse,0},
  32. {3,UI_FORCE_RANK_TELEPATHY,FP_TELEPATHY,FORCE_LIGHTSIDE,qfalse,0},
  33. {3,UI_FORCE_RANK_GRIP,FP_GRIP,FORCE_DARKSIDE,qfalse,0},
  34. {3,UI_FORCE_RANK_LIGHTNING,FP_LIGHTNING,FORCE_DARKSIDE,qfalse,0},
  35. {3,UI_FORCE_RANK_RAGE,FP_RAGE,FORCE_DARKSIDE,qfalse,0},
  36. {3,UI_FORCE_RANK_PROTECT,FP_PROTECT,FORCE_LIGHTSIDE,qfalse,0},
  37. {3,UI_FORCE_RANK_ABSORB,FP_ABSORB,FORCE_LIGHTSIDE,qfalse,0},
  38. {3,UI_FORCE_RANK_TEAM_HEAL,FP_TEAM_HEAL,FORCE_LIGHTSIDE,qfalse,0},
  39. {3,UI_FORCE_RANK_TEAM_FORCE,FP_TEAM_FORCE,FORCE_DARKSIDE,qfalse,0},
  40. {3,UI_FORCE_RANK_DRAIN,FP_DRAIN,FORCE_DARKSIDE,qfalse,0},
  41. {3,UI_FORCE_RANK_SEE,FP_SEE,0,qfalse,0},
  42. {3,UI_FORCE_RANK_SABERATTACK,FP_SABER_OFFENSE,0,qfalse,0},
  43. {3,UI_FORCE_RANK_SABERDEFEND,FP_SABER_DEFENSE,0,qfalse,0},
  44. {3,UI_FORCE_RANK_SABERTHROW,FP_SABERTHROW,0,qfalse,0},
  45. {1,UI_FORCE_RANK_JETPACK,NUM_FORCE_POWERS+SK_JETPACK,0,qfalse,0},
  46. {3,UI_FORCE_RANK_PISTOL,NUM_FORCE_POWERS+SK_PISTOL,0,qfalse,0},
  47. {3,UI_FORCE_RANK_BLASTER,NUM_FORCE_POWERS+SK_BLASTER,0,qfalse,0},
  48. {3,UI_FORCE_RANK_THERMALS,NUM_FORCE_POWERS+SK_THERMAL,0,qfalse,0},
  49. {3,UI_FORCE_RANK_ROCKETS,NUM_FORCE_POWERS+SK_ROCKET,0,qfalse,0},
  50. {2,UI_FORCE_RANK_BACTA,NUM_FORCE_POWERS+SK_BACTA,0,qfalse,0},
  51. {1,UI_FORCE_RANK_FLAMETHROWER,NUM_FORCE_POWERS+SK_FLAMETHROWER,0,qfalse,0},
  52. {3,UI_FORCE_RANK_BOWCASTER,NUM_FORCE_POWERS+SK_BOWCASTER,0,qfalse,0},
  53. {1,UI_FORCE_RANK_FORCEFIELD,NUM_FORCE_POWERS+SK_FORCEFIELD,0,qfalse,0},
  54. {1,UI_FORCE_RANK_CLOAK,NUM_FORCE_POWERS+SK_CLOAK,0,qfalse,0},
  55. {1,UI_FORCE_RANK_SEEKER,NUM_FORCE_POWERS+SK_SEEKER,0,qfalse,0},
  56. {1,UI_FORCE_RANK_SENTRY,NUM_FORCE_POWERS+SK_SENTRY,0,qfalse,0},
  57. {2,UI_FORCE_RANK_DETPACK,NUM_FORCE_POWERS+SK_DETPACK,0,qfalse,0},
  58. {3,UI_FORCE_RANK_REPEATER,NUM_FORCE_POWERS+SK_REPEATER,0,qfalse,0},
  59. {3,UI_FORCE_RANK_DISRUPTOR,NUM_FORCE_POWERS+SK_DISRUPTOR,0,qfalse,0},
  60. {1,UI_FORCE_RANK_BLUESTYLE,NUM_FORCE_POWERS+SK_BLUESTYLE,0,qfalse,0},
  61. {1,UI_FORCE_RANK_REDSTYLE,NUM_FORCE_POWERS+SK_REDSTYLE,0,qfalse,0},
  62. {1,UI_FORCE_RANK_PURPLESTYLE,NUM_FORCE_POWERS+SK_PURPLESTYLE,0,qfalse,0},
  63. {1,UI_FORCE_RANK_GREENSTYLE,NUM_FORCE_POWERS+SK_GREENSTYLE,0,qfalse,0},
  64. {1,UI_FORCE_RANK_DUALSTYLE,NUM_FORCE_POWERS+SK_DUALSTYLE,0,qfalse,0},
  65. {1,UI_FORCE_RANK_STAFFSTYLE,NUM_FORCE_POWERS+SK_STAFFSTYLE,0,qfalse,0},
  66. {1,UI_FORCE_RANK_REPEATERUPGRADE,NUM_FORCE_POWERS+SK_REPEATERUPGRADE,0,qfalse,0},
  67. {3,UI_FORCE_RANK_FLECHETTE,NUM_FORCE_POWERS+SK_FLECHETTE,0,qfalse,0},
  68. {1,UI_FORCE_RANK_BLASTERRATEOFFIRE,NUM_FORCE_POWERS+SK_BLASTERRATEOFFIREUPGRADE,0,qfalse,0}
  69. //Add new skills here
  70. };
  71. char *forcepowerDesc[NUM_FORCE_POWERS] =
  72. {
  73. "@MENUS_OF_EFFECT_JEDI_ONLY_NEFFECT",
  74. "@MENUS_DURATION_IMMEDIATE_NAREA",
  75. "@MENUS_DURATION_5_SECONDS_NAREA",
  76. "@MENUS_DURATION_INSTANTANEOUS",
  77. "@MENUS_INSTANTANEOUS_EFFECT_NAREA",
  78. "@MENUS_DURATION_VARIABLE_20",
  79. "@MENUS_DURATION_INSTANTANEOUS_NAREA",
  80. "@MENUS_OF_EFFECT_LIVING_PERSONS",
  81. "@MENUS_DURATION_VARIABLE_10",
  82. "@MENUS_DURATION_VARIABLE_NAREA",
  83. "@MENUS_DURATION_CONTINUOUS_NAREA",
  84. "@MENUS_OF_EFFECT_JEDI_ALLIES_NEFFECT",
  85. "@MENUS_EFFECT_JEDI_ALLIES_NEFFECT",
  86. "@MENUS_VARIABLE_NAREA_OF_EFFECT",
  87. "@MENUS_EFFECT_NAREA_OF_EFFECT",
  88. "@SP_INGAME_FORCE_SABER_OFFENSE_DESC",
  89. "@SP_INGAME_FORCE_SABER_DEFENSE_DESC",
  90. "@SP_INGAME_FORCE_SABER_THROW_DESC"
  91. };
  92. // Movedata Sounds
  93. typedef enum
  94. {
  95. MDS_NONE = 0,
  96. MDS_FORCE_JUMP,
  97. MDS_ROLL,
  98. MDS_SABER,
  99. MDS_MOVE_SOUNDS_MAX
  100. };
  101. typedef enum
  102. {
  103. MD_ACROBATICS = 0,
  104. MD_SINGLE_FAST,
  105. MD_SINGLE_MEDIUM,
  106. MD_SINGLE_STRONG,
  107. MD_DUAL_SABERS,
  108. MD_SABER_STAFF,
  109. MD_MOVE_TITLE_MAX
  110. };
  111. // Some hard coded badness
  112. // At some point maybe this should be externalized to a .dat file
  113. char *datapadMoveTitleData[MD_MOVE_TITLE_MAX] =
  114. {
  115. "@MENUS_ACROBATICS",
  116. "@MENUS_SINGLE_FAST",
  117. "@MENUS_SINGLE_MEDIUM",
  118. "@MENUS_SINGLE_STRONG",
  119. "@MENUS_DUAL_SABERS",
  120. "@MENUS_SABER_STAFF",
  121. };
  122. char *datapadMoveTitleBaseAnims[MD_MOVE_TITLE_MAX] =
  123. {
  124. "BOTH_RUN1",
  125. "BOTH_SABERFAST_STANCE",
  126. "BOTH_STAND2",
  127. "BOTH_SABERSLOW_STANCE",
  128. "BOTH_SABERDUAL_STANCE",
  129. "BOTH_SABERSTAFF_STANCE",
  130. };
  131. #define MAX_MOVES 16
  132. typedef struct
  133. {
  134. char *title;
  135. char *desc;
  136. char *anim;
  137. short sound;
  138. } datpadmovedata_t;
  139. static datpadmovedata_t datapadMoveData[MD_MOVE_TITLE_MAX][MAX_MOVES] =
  140. {
  141. // Acrobatics
  142. "@MENUS_FORCE_JUMP1", "@MENUS_FORCE_JUMP1_DESC", "BOTH_FORCEJUMP1", MDS_FORCE_JUMP,
  143. "@MENUS_FORCE_FLIP", "@MENUS_FORCE_FLIP_DESC", "BOTH_FLIP_F", MDS_FORCE_JUMP,
  144. "@MENUS_ROLL", "@MENUS_ROLL_DESC", "BOTH_ROLL_F", MDS_ROLL,
  145. "@MENUS_BACKFLIP_OFF_WALL", "@MENUS_BACKFLIP_OFF_WALL_DESC", "BOTH_WALL_FLIP_BACK1", MDS_FORCE_JUMP,
  146. "@MENUS_SIDEFLIP_OFF_WALL", "@MENUS_SIDEFLIP_OFF_WALL_DESC", "BOTH_WALL_FLIP_RIGHT", MDS_FORCE_JUMP,
  147. "@MENUS_WALL_RUN", "@MENUS_WALL_RUN_DESC", "BOTH_WALL_RUN_RIGHT", MDS_FORCE_JUMP,
  148. "@MENUS_WALL_GRAB_JUMP", "@MENUS_WALL_GRAB_JUMP_DESC", "BOTH_FORCEWALLREBOUND_FORWARD",MDS_FORCE_JUMP,
  149. "@MENUS_RUN_UP_WALL_BACKFLIP", "@MENUS_RUN_UP_WALL_BACKFLIP_DESC", "BOTH_FORCEWALLRUNFLIP_START", MDS_FORCE_JUMP,
  150. "@MENUS_JUMPUP_FROM_KNOCKDOWN", "@MENUS_JUMPUP_FROM_KNOCKDOWN_DESC","BOTH_KNOCKDOWN3", MDS_NONE,
  151. "@MENUS_JUMPKICK_FROM_KNOCKDOWN", "@MENUS_JUMPKICK_FROM_KNOCKDOWN_DESC","BOTH_KNOCKDOWN2", MDS_NONE,
  152. "@MENUS_ROLL_FROM_KNOCKDOWN", "@MENUS_ROLL_FROM_KNOCKDOWN_DESC", "BOTH_KNOCKDOWN1", MDS_NONE,
  153. NULL, NULL, 0, MDS_NONE,
  154. NULL, NULL, 0, MDS_NONE,
  155. NULL, NULL, 0, MDS_NONE,
  156. NULL, NULL, 0, MDS_NONE,
  157. NULL, NULL, 0, MDS_NONE,
  158. //Single Saber, Fast Style
  159. "@MENUS_STAB_BACK", "@MENUS_STAB_BACK_DESC", "BOTH_A2_STABBACK1", MDS_SABER,
  160. "@MENUS_LUNGE_ATTACK", "@MENUS_LUNGE_ATTACK_DESC", "BOTH_LUNGE2_B__T_", MDS_SABER,
  161. "@MENUS_FAST_ATTACK_KATA", "@MENUS_FAST_ATTACK_KATA_DESC", "BOTH_A1_SPECIAL", MDS_SABER,
  162. "@MENUS_ATTACK_ENEMYONGROUND", "@MENUS_ATTACK_ENEMYONGROUND_DESC", "BOTH_STABDOWN", MDS_FORCE_JUMP,
  163. "@MENUS_CARTWHEEL", "@MENUS_CARTWHEEL_DESC", "BOTH_ARIAL_RIGHT", MDS_FORCE_JUMP,
  164. "@MENUS_BOTH_ROLL_STAB", "@MENUS_BOTH_ROLL_STAB2_DESC", "BOTH_ROLL_STAB", MDS_SABER,
  165. NULL, NULL, 0, MDS_NONE,
  166. NULL, NULL, 0, MDS_NONE,
  167. NULL, NULL, 0, MDS_NONE,
  168. NULL, NULL, 0, MDS_NONE,
  169. NULL, NULL, 0, MDS_NONE,
  170. NULL, NULL, 0, MDS_NONE,
  171. NULL, NULL, 0, MDS_NONE,
  172. NULL, NULL, 0, MDS_NONE,
  173. NULL, NULL, 0, MDS_NONE,
  174. NULL, NULL, 0, MDS_NONE,
  175. //Single Saber, Medium Style
  176. "@MENUS_SLASH_BACK", "@MENUS_SLASH_BACK_DESC", "BOTH_ATTACK_BACK", MDS_SABER,
  177. "@MENUS_FLIP_ATTACK", "@MENUS_FLIP_ATTACK_DESC", "BOTH_JUMPFLIPSLASHDOWN1", MDS_FORCE_JUMP,
  178. "@MENUS_MEDIUM_ATTACK_KATA", "@MENUS_MEDIUM_ATTACK_KATA_DESC", "BOTH_A2_SPECIAL", MDS_SABER,
  179. "@MENUS_ATTACK_ENEMYONGROUND", "@MENUS_ATTACK_ENEMYONGROUND_DESC", "BOTH_STABDOWN", MDS_FORCE_JUMP,
  180. "@MENUS_CARTWHEEL", "@MENUS_CARTWHEEL_DESC", "BOTH_ARIAL_RIGHT", MDS_FORCE_JUMP,
  181. "@MENUS_BOTH_ROLL_STAB", "@MENUS_BOTH_ROLL_STAB2_DESC", "BOTH_ROLL_STAB", MDS_SABER,
  182. NULL, NULL, 0, MDS_NONE,
  183. NULL, NULL, 0, MDS_NONE,
  184. NULL, NULL, 0, MDS_NONE,
  185. NULL, NULL, 0, MDS_NONE,
  186. NULL, NULL, 0, MDS_NONE,
  187. NULL, NULL, 0, MDS_NONE,
  188. NULL, NULL, 0, MDS_NONE,
  189. NULL, NULL, 0, MDS_NONE,
  190. NULL, NULL, 0, MDS_NONE,
  191. NULL, NULL, 0, MDS_NONE,
  192. //Single Saber, Strong Style
  193. "@MENUS_SLASH_BACK", "@MENUS_SLASH_BACK_DESC", "BOTH_ATTACK_BACK", MDS_SABER,
  194. "@MENUS_JUMP_ATTACK", "@MENUS_JUMP_ATTACK_DESC", "BOTH_FORCELEAP2_T__B_", MDS_FORCE_JUMP,
  195. "@MENUS_STRONG_ATTACK_KATA", "@MENUS_STRONG_ATTACK_KATA_DESC", "BOTH_A3_SPECIAL", MDS_SABER,
  196. "@MENUS_ATTACK_ENEMYONGROUND", "@MENUS_ATTACK_ENEMYONGROUND_DESC", "BOTH_STABDOWN", MDS_FORCE_JUMP,
  197. "@MENUS_CARTWHEEL", "@MENUS_CARTWHEEL_DESC", "BOTH_ARIAL_RIGHT", MDS_FORCE_JUMP,
  198. "@MENUS_BOTH_ROLL_STAB", "@MENUS_BOTH_ROLL_STAB2_DESC", "BOTH_ROLL_STAB", MDS_SABER,
  199. NULL, NULL, 0, MDS_NONE,
  200. NULL, NULL, 0, MDS_NONE,
  201. NULL, NULL, 0, MDS_NONE,
  202. NULL, NULL, 0, MDS_NONE,
  203. NULL, NULL, 0, MDS_NONE,
  204. NULL, NULL, 0, MDS_NONE,
  205. NULL, NULL, 0, MDS_NONE,
  206. NULL, NULL, 0, MDS_NONE,
  207. NULL, NULL, 0, MDS_NONE,
  208. NULL, NULL, 0, MDS_NONE,
  209. //Dual Sabers
  210. "@MENUS_SLASH_BACK", "@MENUS_SLASH_BACK_DESC", "BOTH_ATTACK_BACK", MDS_SABER,
  211. "@MENUS_FLIP_FORWARD_ATTACK", "@MENUS_FLIP_FORWARD_ATTACK_DESC", "BOTH_JUMPATTACK6", MDS_FORCE_JUMP,
  212. "@MENUS_DUAL_SABERS_TWIRL", "@MENUS_DUAL_SABERS_TWIRL_DESC", "BOTH_SPINATTACK6", MDS_SABER,
  213. "@MENUS_ATTACK_ENEMYONGROUND", "@MENUS_ATTACK_ENEMYONGROUND_DESC", "BOTH_STABDOWN_DUAL", MDS_FORCE_JUMP,
  214. "@MENUS_DUAL_SABER_BARRIER", "@MENUS_DUAL_SABER_BARRIER_DESC", "BOTH_A6_SABERPROTECT", MDS_SABER,
  215. "@MENUS_DUAL_STAB_FRONT_BACK", "@MENUS_DUAL_STAB_FRONT_BACK_DESC", "BOTH_A6_FB", MDS_SABER,
  216. "@MENUS_DUAL_STAB_LEFT_RIGHT", "@MENUS_DUAL_STAB_LEFT_RIGHT_DESC", "BOTH_A6_LR", MDS_SABER,
  217. "@MENUS_CARTWHEEL", "@MENUS_CARTWHEEL_DESC", "BOTH_ARIAL_RIGHT", MDS_FORCE_JUMP,
  218. "@MENUS_BOTH_ROLL_STAB", "@MENUS_BOTH_ROLL_STAB_DESC", "BOTH_ROLL_STAB", MDS_SABER,
  219. NULL, NULL, 0, MDS_NONE,
  220. NULL, NULL, 0, MDS_NONE,
  221. NULL, NULL, 0, MDS_NONE,
  222. NULL, NULL, 0, MDS_NONE,
  223. NULL, NULL, 0, MDS_NONE,
  224. NULL, NULL, 0, MDS_NONE,
  225. NULL, NULL, 0, MDS_NONE,
  226. // Saber Staff
  227. "@MENUS_STAB_BACK", "@MENUS_STAB_BACK_DESC", "BOTH_A2_STABBACK1", MDS_SABER,
  228. "@MENUS_BACK_FLIP_ATTACK", "@MENUS_BACK_FLIP_ATTACK_DESC", "BOTH_JUMPATTACK7", MDS_FORCE_JUMP,
  229. "@MENUS_SABER_STAFF_TWIRL", "@MENUS_SABER_STAFF_TWIRL_DESC", "BOTH_SPINATTACK7", MDS_SABER,
  230. "@MENUS_ATTACK_ENEMYONGROUND", "@MENUS_ATTACK_ENEMYONGROUND_DESC", "BOTH_STABDOWN_STAFF", MDS_FORCE_JUMP,
  231. "@MENUS_SPINNING_KATA", "@MENUS_SPINNING_KATA_DESC", "BOTH_A7_SOULCAL", MDS_SABER,
  232. "@MENUS_KICK1", "@MENUS_KICK1_DESC", "BOTH_A7_KICK_F", MDS_FORCE_JUMP,
  233. "@MENUS_JUMP_KICK", "@MENUS_JUMP_KICK_DESC", "BOTH_A7_KICK_F_AIR", MDS_FORCE_JUMP,
  234. "@MENUS_BUTTERFLY_ATTACK", "@MENUS_BUTTERFLY_ATTACK_DESC", "BOTH_BUTTERFLY_FR1", MDS_SABER,
  235. "@MENUS_BOTH_ROLL_STAB", "@MENUS_BOTH_ROLL_STAB2_DESC", "BOTH_ROLL_STAB", MDS_SABER,
  236. NULL, NULL, 0, MDS_NONE,
  237. NULL, NULL, 0, MDS_NONE,
  238. NULL, NULL, 0, MDS_NONE,
  239. NULL, NULL, 0, MDS_NONE,
  240. NULL, NULL, 0, MDS_NONE,
  241. NULL, NULL, 0, MDS_NONE,
  242. NULL, NULL, 0, MDS_NONE,
  243. };
  244. /*
  245. ================
  246. vmMain
  247. This is the only way control passes into the module.
  248. !!! This MUST BE THE VERY FIRST FUNCTION compiled into the .qvm file !!!
  249. ================
  250. */
  251. vmCvar_t ui_debug;
  252. vmCvar_t ui_initialized;
  253. vmCvar_t ui_char_color_red;
  254. vmCvar_t ui_char_color_green;
  255. vmCvar_t ui_char_color_blue;
  256. vmCvar_t ui_PrecacheModels;
  257. vmCvar_t ui_char_anim;
  258. void _UI_Init( qboolean );
  259. void _UI_Shutdown( void );
  260. void _UI_KeyEvent( int key, qboolean down );
  261. void _UI_MouseEvent( int dx, int dy );
  262. void _UI_Refresh( int realtime );
  263. qboolean _UI_IsFullscreen( void );
  264. void UI_SetSiegeTeams(void);
  265. extern qboolean UI_SaberModelForSaber( const char *saberName, char *saberModel );
  266. void UI_SiegeSetCvarsForClass(siegeClass_t *scl);
  267. int UI_SiegeClassNum(siegeClass_t *scl);
  268. //[VS2005]
  269. //VS2005's C doesn't assume int type anymore.
  270. void UI_UpdateCvarsForClass(const int team,const int baseClass,const int index);
  271. //void UI_UpdateCvarsForClass(const int team,const baseClass,const int index);
  272. //[/VS2005]
  273. void UI_UpdateSiegeStatusIcons(void);
  274. void UI_ClampMaxPlayers(void);
  275. static void UI_CheckServerName( void );
  276. static qboolean UI_CheckPassword( void );
  277. static void UI_JoinServer( void );
  278. //[DynamicMemory_Sabers]
  279. void UI_AllocMem(void **ptr, int sze);
  280. void UI_FreeMem(void *ptr);
  281. void UI_ReaAllocMem(void **ptr, int sze, int count);
  282. char *UI_GetSaberHiltInfo(qboolean TwoHanded, int index);
  283. //[/DynamicMemory_Sabers]
  284. #include "../namespace_begin.h"
  285. // Functions in BG or ui_shared
  286. void Menu_ShowGroup (menuDef_t *menu, char *itemName, qboolean showFlag);
  287. void Menu_ItemDisable(menuDef_t *menu, char *name,int disableFlag);
  288. int Menu_ItemsMatchingGroup(menuDef_t *menu, const char *name);
  289. itemDef_t *Menu_GetMatchingItemByNumber(menuDef_t *menu, int index, const char *name);
  290. int BG_GetUIPortrait(const int team, const short classIndex, const short cntIndex);
  291. char *BG_GetUIPortraitFile(const int team, const short classIndex, const short cntIndex);
  292. siegeClass_t *BG_GetClassOnBaseClass(const int team, const short classIndex, const short cntIndex);
  293. int vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11 ) {
  294. char buffer[MAX_QPATH]="";//[AutoUpdate]
  295. switch ( command ) {
  296. case UI_GETAPIVERSION:
  297. return UI_API_VERSION;
  298. case UI_INIT:
  299. trap_Cvar_VariableStringBuffer("fs_basepath",buffer,sizeof(buffer));
  300. //system(va("%s\\ojpenhanced\\update.exe",buffer));//[AutoUpdate]
  301. _UI_Init(arg0);
  302. return 0;
  303. case UI_SHUTDOWN:
  304. _UI_Shutdown();
  305. return 0;
  306. case UI_KEY_EVENT:
  307. _UI_KeyEvent( arg0, arg1 );
  308. return 0;
  309. case UI_MOUSE_EVENT:
  310. _UI_MouseEvent( arg0, arg1 );
  311. return 0;
  312. case UI_REFRESH:
  313. _UI_Refresh( arg0 );
  314. return 0;
  315. case UI_IS_FULLSCREEN:
  316. return _UI_IsFullscreen();
  317. case UI_SET_ACTIVE_MENU:
  318. _UI_SetActiveMenu( arg0 );
  319. return 0;
  320. case UI_CONSOLE_COMMAND:
  321. return UI_ConsoleCommand(arg0);
  322. case UI_DRAW_CONNECT_SCREEN:
  323. UI_DrawConnectScreen( arg0 );
  324. return 0;
  325. case UI_HASUNIQUECDKEY: // mod authors need to observe this
  326. return qtrue; // bk010117 - change this to qfalse for mods!
  327. case UI_MENU_RESET:
  328. Menu_Reset();
  329. return 0;
  330. }
  331. return -1;
  332. }
  333. #include "../namespace_end.h"
  334. siegeClassDesc_t g_UIClassDescriptions[MAX_SIEGE_CLASSES];
  335. siegeTeam_t *siegeTeam1 = NULL;
  336. siegeTeam_t *siegeTeam2 = NULL;
  337. int g_UIGloballySelectedSiegeClass = -1;
  338. //Cut down version of the stuff used in the game code
  339. //This is just the bare essentials of what we need to load animations properly for ui ghoul2 models.
  340. //This function doesn't need to be sync'd with the BG_ version in bg_panimate.c unless some sort of fundamental change
  341. //is made. Just make sure the variables/functions accessed in ui_shared.c exist in both modules.
  342. qboolean UIPAFtextLoaded = qfalse;
  343. animation_t uiHumanoidAnimations[MAX_TOTALANIMATIONS]; //humanoid animations are the only ones that are statically allocated.
  344. #include "../namespace_begin.h"
  345. bgLoadedAnim_t bgAllAnims[MAX_ANIM_FILES];
  346. int uiNumAllAnims = 1; //start off at 0, because 0 will always be assigned to humanoid.
  347. #include "../namespace_end.h"
  348. animation_t *UI_AnimsetAlloc(void)
  349. {
  350. assert (uiNumAllAnims < MAX_ANIM_FILES);
  351. bgAllAnims[uiNumAllAnims].anims = (animation_t *) BG_Alloc(sizeof(animation_t)*MAX_TOTALANIMATIONS);
  352. return bgAllAnims[uiNumAllAnims].anims;
  353. }
  354. //[SIEGECVARFIX]
  355. char *siege_Str(void) {
  356. static int cur;
  357. static char strings[1024][256];
  358. return strings[cur++];
  359. }
  360. /*
  361. ===============
  362. siege_Cvar_Set
  363. replacement for the trap to reduce cvar usage
  364. ===============
  365. */
  366. void siege_Cvar_Set( const char *cvarName, const char *value )
  367. {
  368. char **tmp;
  369. char ui_siegeInfo[MAX_STRING_CHARS];
  370. int i;
  371. if(!ui_siegeStruct)
  372. {
  373. trap_Cvar_VariableStringBuffer( "ui_siegeInfo", ui_siegeInfo, MAX_STRING_CHARS );
  374. sscanf(ui_siegeInfo,"%p",&ui_siegeStruct);
  375. if(!ui_siegeStruct) return;
  376. }
  377. for(tmp=ui_siegeStruct;*tmp;tmp+=2)
  378. {
  379. if(*tmp && !strcmp(*tmp,cvarName)) { //cvar already exists, overwrite existing value
  380. Q_strncpyz(*(tmp+1),value,256); //:nervou
  381. return;
  382. }
  383. }
  384. i = tmp - ui_siegeStruct;
  385. ui_siegeStruct[i] = siege_Str();
  386. Q_strncpyz( ui_siegeStruct[i], cvarName, 256 );
  387. ui_siegeStruct[i+1] = siege_Str();
  388. Q_strncpyz( ui_siegeStruct[i+1], value, 256 );
  389. ui_siegeStruct[i+2] = 0;
  390. return;
  391. }
  392. void siege_Cvar_VariableStringBuffer( char *var_name, char *buffer, int bufsize )
  393. {
  394. char **tmp;
  395. char ui_siegeInfo[MAX_STRING_CHARS];
  396. if(!ui_siegeStruct)
  397. {
  398. trap_Cvar_VariableStringBuffer( "ui_siegeInfo", ui_siegeInfo, MAX_STRING_CHARS );
  399. sscanf(ui_siegeInfo,"%p",&ui_siegeStruct);
  400. if(!ui_siegeStruct) return;
  401. }
  402. for(tmp=ui_siegeStruct;*tmp;tmp+=2)
  403. {
  404. if(*tmp && !strcmp(*tmp,var_name)) {
  405. Q_strncpyz(buffer,*(tmp+1),bufsize);
  406. return;
  407. }
  408. }
  409. trap_Cvar_VariableStringBuffer( var_name, buffer, bufsize );
  410. return;
  411. }
  412. int siege_Cvar_VariableValue( char *var_name )
  413. {
  414. char **tmp;
  415. char ui_siegeInfo[MAX_STRING_CHARS];
  416. if(!ui_siegeStruct)
  417. {
  418. trap_Cvar_VariableStringBuffer( "ui_siegeInfo", ui_siegeInfo, MAX_STRING_CHARS );
  419. sscanf(ui_siegeInfo,"%p",&ui_siegeStruct);
  420. if(!ui_siegeStruct) return trap_Cvar_VariableValue( var_name );
  421. }
  422. for(tmp=ui_siegeStruct;*tmp;tmp+=2)
  423. {
  424. if(*tmp && !strcmp(*tmp,var_name)) {
  425. return atoi(*(tmp+1));
  426. }
  427. }
  428. return trap_Cvar_VariableValue( var_name );
  429. }
  430. //[/SIEGECVARFIX]
  431. /*
  432. ======================
  433. UI_ParseAnimationFile
  434. Read a configuration file containing animation coutns and rates
  435. models/players/visor/animation.cfg, etc
  436. ======================
  437. */
  438. #include "../namespace_begin.h"
  439. static char UIPAFtext[60000];
  440. int UI_ParseAnimationFile(const char *filename, animation_t *animset, qboolean isHumanoid)
  441. {
  442. char *text_p;
  443. int len;
  444. int i;
  445. char *token;
  446. float fps;
  447. int skip;
  448. int usedIndex = -1;
  449. int nextIndex = uiNumAllAnims;
  450. fileHandle_t f;
  451. int animNum;
  452. if (!isHumanoid)
  453. {
  454. i = 1;
  455. while (i < uiNumAllAnims)
  456. { //see if it's been loaded already
  457. if (!Q_stricmp(bgAllAnims[i].filename, filename))
  458. {
  459. animset = bgAllAnims[i].anims;
  460. return i; //alright, we already have it.
  461. }
  462. i++;
  463. }
  464. //Looks like it has not yet been loaded. Allocate space for the anim set if we need to, and continue along.
  465. if (!animset)
  466. {
  467. if (strstr(filename, "players/_humanoid/"))
  468. { //then use the static humanoid set.
  469. animset = uiHumanoidAnimations;
  470. isHumanoid = qtrue;
  471. nextIndex = 0;
  472. }
  473. else
  474. {
  475. animset = UI_AnimsetAlloc();
  476. if (!animset)
  477. {
  478. assert(!"Anim set alloc failed!");
  479. return -1;
  480. }
  481. }
  482. }
  483. }
  484. #ifdef _DEBUG
  485. else
  486. {
  487. assert(animset);
  488. }
  489. #endif
  490. // load the file
  491. if (!UIPAFtextLoaded || !isHumanoid)
  492. { //rww - We are always using the same animation config now. So only load it once.
  493. len = trap_FS_FOpenFile( filename, &f, FS_READ );
  494. if ( (len <= 0) || (len >= sizeof( UIPAFtext ) - 1) )
  495. {
  496. if (len > 0)
  497. {
  498. Com_Error(ERR_DROP, "%s exceeds the allowed ui-side animation buffer!", filename);
  499. }
  500. return -1;
  501. }
  502. trap_FS_Read( UIPAFtext, len, f );
  503. UIPAFtext[len] = 0;
  504. trap_FS_FCloseFile( f );
  505. }
  506. else
  507. {
  508. return 0; //humanoid index
  509. }
  510. // parse the text
  511. text_p = UIPAFtext;
  512. skip = 0; // quiet the compiler warning
  513. //FIXME: have some way of playing anims backwards... negative numFrames?
  514. //initialize anim array so that from 0 to MAX_ANIMATIONS, set default values of 0 1 0 100
  515. for(i = 0; i < MAX_ANIMATIONS; i++)
  516. {
  517. animset[i].firstFrame = 0;
  518. animset[i].numFrames = 0;
  519. animset[i].loopFrames = -1;
  520. animset[i].frameLerp = 100;
  521. // animset[i].initialLerp = 100;
  522. }
  523. // read information for each frame
  524. while(1)
  525. {
  526. token = COM_Parse( (const char **)(&text_p) );
  527. if ( !token || !token[0])
  528. {
  529. break;
  530. }
  531. animNum = GetIDForString(animTable, token);
  532. if(animNum == -1)
  533. {
  534. //#ifndef FINAL_BUILD
  535. #ifdef _DEBUG
  536. //Com_Printf(S_COLOR_RED"WARNING: Unknown token %s in %s\n", token, filename);
  537. #endif
  538. continue;
  539. }
  540. token = COM_Parse( (const char **)(&text_p) );
  541. if ( !token[0] ) //[TicketFix143]
  542. {
  543. break;
  544. }
  545. animset[animNum].firstFrame = atoi( token );
  546. token = COM_Parse( (const char **)(&text_p) );
  547. if ( !token[0] ) //[TicketFix143]
  548. {
  549. break;
  550. }
  551. animset[animNum].numFrames = atoi( token );
  552. token = COM_Parse( (const char **)(&text_p) );
  553. if ( !token[0] ) //[TicketFix143]
  554. {
  555. break;
  556. }
  557. animset[animNum].loopFrames = atoi( token );
  558. token = COM_Parse( (const char **)(&text_p) );
  559. if ( !token[0] ) //[TicketFix143]
  560. {
  561. break;
  562. }
  563. fps = atof( token );
  564. if ( fps == 0 )
  565. {
  566. fps = 1;//Don't allow divide by zero error
  567. }
  568. if ( fps < 0 )
  569. {//backwards
  570. animset[animNum].frameLerp = floor(1000.0f / fps);
  571. }
  572. else
  573. {
  574. animset[animNum].frameLerp = ceil(1000.0f / fps);
  575. }
  576. // animset[animNum].initialLerp = ceil(1000.0f / fabs(fps));
  577. }
  578. #ifdef _DEBUG
  579. //Check the array, and print the ones that have nothing in them.
  580. /*
  581. for(i = 0; i < MAX_ANIMATIONS; i++)
  582. {
  583. if (animTable[i].name != NULL) // This animation reference exists.
  584. {
  585. if (animset[i].firstFrame <= 0 && animset[i].numFrames <=0)
  586. { // This is an empty animation reference.
  587. Com_Printf("***ANIMTABLE reference #%d (%s) is empty!\n", i, animTable[i].name);
  588. }
  589. }
  590. }
  591. */
  592. #endif // _DEBUG
  593. if (isHumanoid)
  594. {
  595. bgAllAnims[0].anims = animset;
  596. strcpy(bgAllAnims[0].filename, filename);
  597. UIPAFtextLoaded = qtrue;
  598. usedIndex = 0;
  599. }
  600. else
  601. {
  602. bgAllAnims[nextIndex].anims = animset;
  603. strcpy(bgAllAnims[nextIndex].filename, filename);
  604. usedIndex = nextIndex;
  605. if (nextIndex)
  606. { //don't bother increasing the number if this ended up as a humanoid load.
  607. uiNumAllAnims++;
  608. }
  609. else
  610. {
  611. UIPAFtextLoaded = qtrue;
  612. usedIndex = 0;
  613. }
  614. }
  615. return usedIndex;
  616. }
  617. //menuDef_t *Menus_FindByName(const char *p);
  618. void Menu_ShowItemByName(menuDef_t *menu, const char *p, qboolean bShow);
  619. #include "../namespace_end.h"
  620. void UpdateForceUsed();
  621. char holdSPString[MAX_STRING_CHARS]={0};
  622. char holdSPString2[MAX_STRING_CHARS]={0};
  623. uiInfo_t uiInfo;
  624. static void UI_StartServerRefresh(qboolean full);
  625. static void UI_StopServerRefresh( void );
  626. static void UI_DoServerRefresh( void );
  627. static void UI_BuildServerDisplayList(qboolean force);
  628. static void UI_BuildServerStatus(qboolean force);
  629. static void UI_BuildFindPlayerList(qboolean force);
  630. static int QDECL UI_ServersQsortCompare( const void *arg1, const void *arg2 );
  631. static int UI_MapCountByGameType(qboolean singlePlayer);
  632. static int UI_HeadCountByColor( void );
  633. static void UI_ParseGameInfo(const char *teamFile);
  634. static const char *UI_SelectedMap(int index, int *actual);
  635. static int UI_GetIndexFromSelection(int actual);
  636. static void UI_SiegeClassCnt( const int team );
  637. int ProcessNewUI( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6 );
  638. int uiSkinColor=TEAM_FREE;
  639. int uiHoldSkinColor=TEAM_FREE; // Stores the skin color so that in non-team games, the player screen remembers the team you chose, in case you're coming back from the force powers screen.
  640. static const serverFilter_t serverFilters[] = {
  641. //[SERVERFILTERS]
  642. //since OJP Enhanced only works with OJP Enhanced servers, only show them.
  643. {"OJP_MENUS_OJP_ENHANCED", "ojpenhanced"},
  644. //{"MENUS_ALL", "" },
  645. //{"MENUS_JEDI_ACADEMY", "" },
  646. //[/SERVERFILTERS]
  647. };
  648. static const int numServerFilters = sizeof(serverFilters) / sizeof(serverFilter_t);
  649. static const char *skillLevels[] = {
  650. "SKILL1",//"I Can Win",
  651. "SKILL2",//"Bring It On",
  652. "SKILL3",//"Hurt Me Plenty",
  653. "SKILL4",//"Hardcore",
  654. "SKILL5"//"Nightmare"
  655. };
  656. static const int numSkillLevels = sizeof(skillLevels) / sizeof(const char*);
  657. static const char *teamArenaGameTypes[] = {
  658. "FFA",
  659. "Holocron",
  660. "JediMaster",
  661. "Duel",
  662. "PowerDuel",
  663. "SP",
  664. "Team FFA",
  665. "Siege",
  666. "CTF",
  667. "CTY",
  668. "TeamTournament"
  669. };
  670. static int const numTeamArenaGameTypes = sizeof(teamArenaGameTypes) / sizeof(const char*);
  671. static char* netnames[] = {
  672. "???",
  673. "UDP",
  674. "IPX",
  675. NULL
  676. };
  677. static int gamecodetoui[] = {4,2,3,0,5,1,6};
  678. static int uitogamecode[] = {4,6,2,3,1,5,7};
  679. const char *UI_GetStringEdString(const char *refSection, const char *refName);
  680. const char *UI_TeamName(int team) {
  681. if (team==TEAM_RED)
  682. return "RED";
  683. else if (team==TEAM_BLUE)
  684. return "BLUE";
  685. else if (team==TEAM_SPECTATOR)
  686. return "SPECTATOR";
  687. return "FREE";
  688. }
  689. // returns either string or NULL for OOR...
  690. //
  691. static const char *GetCRDelineatedString( const char *psStripFileRef, const char *psStripStringRef, int iIndex)
  692. {
  693. static char sTemp[256];
  694. const char *psList = UI_GetStringEdString(psStripFileRef, psStripStringRef);
  695. char *p;
  696. while (iIndex--)
  697. {
  698. psList = strchr(psList,'\n');
  699. if (!psList){
  700. return NULL; // OOR
  701. }
  702. psList++;
  703. }
  704. strcpy(sTemp,psList);
  705. p = strchr(sTemp,'\n');
  706. if (p) {
  707. *p = '\0';
  708. }
  709. return sTemp;
  710. }
  711. static const char *GetMonthAbbrevString( int iMonth )
  712. {
  713. const char *p = GetCRDelineatedString("MP_INGAME","MONTHS", iMonth);
  714. return p ? p : "Jan"; // sanity
  715. }
  716. /*
  717. static const char *netSources[] = {
  718. "Local",
  719. "Internet",
  720. "Favorites"
  721. // "Mplayer"
  722. };
  723. static const int numNetSources = sizeof(netSources) / sizeof(const char*);
  724. */
  725. static const int numNetSources = 3; // now hard-entered in StringEd file
  726. static const char *GetNetSourceString(int iSource)
  727. {
  728. const char *p = GetCRDelineatedString("MP_INGAME","NET_SOURCES", iSource);
  729. return p ? p : "??";
  730. }
  731. void AssetCache() {
  732. int n;
  733. //if (Assets.textFont == NULL) {
  734. //}
  735. //Assets.background = trap_R_RegisterShaderNoMip( ASSET_BACKGROUND );
  736. //Com_Printf("Menu Size: %i bytes\n", sizeof(Menus));
  737. uiInfo.uiDC.Assets.gradientBar = trap_R_RegisterShaderNoMip( ASSET_GRADIENTBAR );
  738. uiInfo.uiDC.Assets.fxBasePic = trap_R_RegisterShaderNoMip( ART_FX_BASE );
  739. uiInfo.uiDC.Assets.fxPic[0] = trap_R_RegisterShaderNoMip( ART_FX_RED );
  740. uiInfo.uiDC.Assets.fxPic[1] = trap_R_RegisterShaderNoMip( ART_FX_ORANGE );//trap_R_RegisterShaderNoMip( ART_FX_YELLOW );
  741. uiInfo.uiDC.Assets.fxPic[2] = trap_R_RegisterShaderNoMip( ART_FX_YELLOW );//trap_R_RegisterShaderNoMip( ART_FX_GREEN );
  742. uiInfo.uiDC.Assets.fxPic[3] = trap_R_RegisterShaderNoMip( ART_FX_GREEN );//trap_R_RegisterShaderNoMip( ART_FX_TEAL );
  743. uiInfo.uiDC.Assets.fxPic[4] = trap_R_RegisterShaderNoMip( ART_FX_BLUE );
  744. uiInfo.uiDC.Assets.fxPic[5] = trap_R_RegisterShaderNoMip( ART_FX_PURPLE );//trap_R_RegisterShaderNoMip( ART_FX_CYAN );
  745. uiInfo.uiDC.Assets.fxPic[6] = trap_R_RegisterShaderNoMip( ART_FX_WHITE );
  746. uiInfo.uiDC.Assets.scrollBar = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR );
  747. uiInfo.uiDC.Assets.scrollBarArrowDown = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWDOWN );
  748. uiInfo.uiDC.Assets.scrollBarArrowUp = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWUP );
  749. uiInfo.uiDC.Assets.scrollBarArrowLeft = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWLEFT );
  750. uiInfo.uiDC.Assets.scrollBarArrowRight = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWRIGHT );
  751. uiInfo.uiDC.Assets.scrollBarThumb = trap_R_RegisterShaderNoMip( ASSET_SCROLL_THUMB );
  752. uiInfo.uiDC.Assets.sliderBar = trap_R_RegisterShaderNoMip( ASSET_SLIDER_BAR );
  753. uiInfo.uiDC.Assets.sliderThumb = trap_R_RegisterShaderNoMip( ASSET_SLIDER_THUMB );
  754. // Icons for various server settings.
  755. uiInfo.uiDC.Assets.needPass = trap_R_RegisterShaderNoMip( "gfx/menus/needpass" );
  756. uiInfo.uiDC.Assets.noForce = trap_R_RegisterShaderNoMip( "gfx/menus/noforce" );
  757. uiInfo.uiDC.Assets.forceRestrict = trap_R_RegisterShaderNoMip( "gfx/menus/forcerestrict" );
  758. uiInfo.uiDC.Assets.saberOnly = trap_R_RegisterShaderNoMip( "gfx/menus/saberonly" );
  759. uiInfo.uiDC.Assets.trueJedi = trap_R_RegisterShaderNoMip( "gfx/menus/truejedi" );
  760. for( n = 0; n < NUM_CROSSHAIRS; n++ ) {
  761. uiInfo.uiDC.Assets.crosshairShader[n] = trap_R_RegisterShaderNoMip( va("gfx/2d/crosshair%c", 'a' + n ) );
  762. }
  763. uiInfo.newHighScoreSound = 0;//trap_S_RegisterSound("sound/feedback/voc_newhighscore.wav");
  764. }
  765. void _UI_DrawSides(float x, float y, float w, float h, float size) {
  766. size *= uiInfo.uiDC.xscale;
  767. trap_R_DrawStretchPic( x, y, size, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
  768. trap_R_DrawStretchPic( x + w - size, y, size, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
  769. }
  770. void _UI_DrawTopBottom(float x, float y, float w, float h, float size) {
  771. size *= uiInfo.uiDC.yscale;
  772. trap_R_DrawStretchPic( x, y, w, size, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
  773. trap_R_DrawStretchPic( x, y + h - size, w, size, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
  774. }
  775. /*
  776. ================
  777. UI_DrawRect
  778. Coordinates are 640*480 virtual values
  779. =================
  780. */
  781. void _UI_DrawRect( float x, float y, float width, float height, float size, const float *color ) {
  782. trap_R_SetColor( color );
  783. _UI_DrawTopBottom(x, y, width, height, size);
  784. _UI_DrawSides(x, y, width, height, size);
  785. trap_R_SetColor( NULL );
  786. }
  787. #include "../namespace_begin.h"
  788. int MenuFontToHandle(int iMenuFont)
  789. {
  790. switch (iMenuFont)
  791. {
  792. case 1: return uiInfo.uiDC.Assets.qhSmallFont;
  793. case 2: return uiInfo.uiDC.Assets.qhMediumFont;
  794. case 3: return uiInfo.uiDC.Assets.qhBigFont;
  795. case 4: return uiInfo.uiDC.Assets.qhSmall2Font;
  796. }
  797. return uiInfo.uiDC.Assets.qhMediumFont; // 0;
  798. }
  799. #include "../namespace_end.h"
  800. int Text_Width(const char *text, float scale, int iMenuFont)
  801. {
  802. int iFontIndex = MenuFontToHandle(iMenuFont);
  803. return trap_R_Font_StrLenPixels(text, iFontIndex, scale);
  804. }
  805. int Text_Height(const char *text, float scale, int iMenuFont)
  806. {
  807. int iFontIndex = MenuFontToHandle(iMenuFont);
  808. return trap_R_Font_HeightPixels(iFontIndex, scale);
  809. }
  810. void Text_Paint(float x, float y, float scale, vec4_t color, const char *text, float adjust, int limit, int style, int iMenuFont)
  811. {
  812. int iStyleOR = 0;
  813. int iFontIndex = MenuFontToHandle(iMenuFont);
  814. //
  815. // kludge.. convert JK2 menu styles to SOF2 printstring ctrl codes...
  816. //
  817. switch (style)
  818. {
  819. case ITEM_TEXTSTYLE_NORMAL: iStyleOR = 0;break; // JK2 normal text
  820. case ITEM_TEXTSTYLE_BLINK: iStyleOR = (int)STYLE_BLINK;break; // JK2 fast blinking
  821. case ITEM_TEXTSTYLE_PULSE: iStyleOR = (int)STYLE_BLINK;break; // JK2 slow pulsing
  822. case ITEM_TEXTSTYLE_SHADOWED: iStyleOR = (int)STYLE_DROPSHADOW;break; // JK2 drop shadow
  823. case ITEM_TEXTSTYLE_OUTLINED: iStyleOR = (int)STYLE_DROPSHADOW;break; // JK2 drop shadow
  824. case ITEM_TEXTSTYLE_OUTLINESHADOWED: iStyleOR = (int)STYLE_DROPSHADOW;break; // JK2 drop shadow
  825. case ITEM_TEXTSTYLE_SHADOWEDMORE: iStyleOR = (int)STYLE_DROPSHADOW;break; // JK2 drop shadow
  826. }
  827. trap_R_Font_DrawString( x, // int ox
  828. y, // int oy
  829. text, // const char *text
  830. color, // paletteRGBA_c c
  831. iStyleOR | iFontIndex, // const int iFontHandle
  832. !limit?-1:limit, // iCharLimit (-1 = none)
  833. scale // const float scale = 1.0f
  834. );
  835. }
  836. void Text_PaintWithCursor(float x, float y, float scale, vec4_t color, const char *text, int cursorPos, char cursor, int limit, int style, int iMenuFont)
  837. {
  838. Text_Paint(x, y, scale, color, text, 0, limit, style, iMenuFont);
  839. // now print the cursor as well... (excuse the braces, it's for porting C++ to C)
  840. //
  841. {
  842. char sTemp[1024];
  843. int iCopyCount = limit ? min(strlen(text), limit) : strlen(text);
  844. iCopyCount = min(iCopyCount,cursorPos);
  845. iCopyCount = min(iCopyCount,sizeof(sTemp));
  846. // copy text into temp buffer for pixel measure...
  847. //
  848. strncpy(sTemp,text,iCopyCount);
  849. sTemp[iCopyCount] = '\0';
  850. {
  851. int iFontIndex = MenuFontToHandle( iMenuFont );
  852. int iNextXpos = trap_R_Font_StrLenPixels(sTemp, iFontIndex, scale );
  853. Text_Paint(x+iNextXpos, y, scale, color, va("%c",cursor), 0, limit, style|ITEM_TEXTSTYLE_BLINK, iMenuFont);
  854. }
  855. }
  856. }
  857. // maxX param is initially an X limit, but is also used as feedback. 0 = text was clipped to fit within, else maxX = next pos
  858. //
  859. static void Text_Paint_Limit(float *maxX, float x, float y, float scale, vec4_t color, const char* text, float adjust, int limit, int iMenuFont)
  860. {
  861. // this is kinda dirty, but...
  862. //
  863. int iFontIndex = MenuFontToHandle(iMenuFont);
  864. //float fMax = *maxX;
  865. int iPixelLen = trap_R_Font_StrLenPixels(text, iFontIndex, scale);
  866. if (x + iPixelLen > *maxX)
  867. {
  868. // whole text won't fit, so we need to print just the amount that does...
  869. // Ok, this is slow and tacky, but only called occasionally, and it works...
  870. //
  871. char sTemp[4096]={0}; // lazy assumption
  872. const char *psText = text;
  873. char *psOut = &sTemp[0];
  874. char *psOutLastGood = psOut;
  875. unsigned int uiLetter;
  876. while (*psText && (x + trap_R_Font_StrLenPixels(sTemp, iFontIndex, scale)<=*maxX)
  877. && psOut < &sTemp[sizeof(sTemp)-1] // sanity
  878. )
  879. {
  880. int iAdvanceCount;
  881. psOutLastGood = psOut;
  882. uiLetter = trap_AnyLanguage_ReadCharFromString(psText, &iAdvanceCount, NULL);
  883. psText += iAdvanceCount;
  884. if (uiLetter > 255)
  885. {
  886. *psOut++ = uiLetter>>8;
  887. *psOut++ = uiLetter&0xFF;
  888. }
  889. else
  890. {
  891. *psOut++ = uiLetter&0xFF;
  892. }
  893. }
  894. *psOutLastGood = '\0';
  895. *maxX = 0; // feedback
  896. Text_Paint(x, y, scale, color, sTemp, adjust, limit, ITEM_TEXTSTYLE_NORMAL, iMenuFont);
  897. }
  898. else
  899. {
  900. // whole text fits fine, so print it all...
  901. //
  902. *maxX = x + iPixelLen; // feedback the next position, as the caller expects
  903. Text_Paint(x, y, scale, color, text, adjust, limit, ITEM_TEXTSTYLE_NORMAL, iMenuFont);
  904. }
  905. }
  906. void UI_ShowPostGame(qboolean newHigh) {
  907. trap_Cvar_Set ("cg_cameraOrbit", "0");
  908. trap_Cvar_Set("cg_thirdPerson", "0");
  909. trap_Cvar_Set( "sv_killserver", "1" );
  910. uiInfo.soundHighScore = newHigh;
  911. _UI_SetActiveMenu(UIMENU_POSTGAME);
  912. }
  913. /*
  914. =================
  915. _UI_Refresh
  916. =================
  917. */
  918. void UI_DrawCenteredPic(qhandle_t image, int w, int h) {
  919. int x, y;
  920. x = (SCREEN_WIDTH - w) / 2;
  921. y = (SCREEN_HEIGHT - h) / 2;
  922. UI_DrawHandlePic(x, y, w, h, image);
  923. }
  924. int frameCount = 0;
  925. int startTime;
  926. vmCvar_t ui_rankChange;
  927. static void UI_BuildPlayerList();
  928. //[UITweaks]
  929. /* not used in basejka code
  930. //char parsedFPMessage[1024];
  931. #include "../namespace_begin.h"
  932. extern int FPMessageTime;
  933. #include "../namespace_end.h"
  934. */
  935. //[/UITweaks]
  936. void Text_PaintCenter(float x, float y, float scale, vec4_t color, const char *text, float adjust, int iMenuFont);
  937. const char *UI_GetStringEdString(const char *refSection, const char *refName)
  938. {
  939. static char text[1024]={0};
  940. trap_SP_GetStringTextString(va("%s_%s", refSection, refName), text, sizeof(text));
  941. return text;
  942. }
  943. #define UI_FPS_FRAMES 4
  944. void _UI_Refresh( int realtime )
  945. {
  946. static int index;
  947. static int previousTimes[UI_FPS_FRAMES];
  948. //if ( !( trap_Key_GetCatcher() & KEYCATCH_UI ) ) {
  949. // return;
  950. //}
  951. trap_G2API_SetTime(realtime, 0);
  952. trap_G2API_SetTime(realtime, 1);
  953. //ghoul2 timer must be explicitly updated during ui rendering.
  954. uiInfo.uiDC.frameTime = realtime - uiInfo.uiDC.realTime;
  955. uiInfo.uiDC.realTime = realtime;
  956. previousTimes[index % UI_FPS_FRAMES] = uiInfo.uiDC.frameTime;
  957. index++;
  958. if ( index > UI_FPS_FRAMES ) {
  959. int i, total;
  960. // average multiple frames together to smooth changes out a bit
  961. total = 0;
  962. for ( i = 0 ; i < UI_FPS_FRAMES ; i++ ) {
  963. total += previousTimes[i];
  964. }
  965. if ( !total ) {
  966. total = 1;
  967. }
  968. uiInfo.uiDC.FPS = 1000 * UI_FPS_FRAMES / total;
  969. }
  970. UI_UpdateCvars();
  971. if (Menu_Count() > 0) {
  972. // paint all the menus
  973. Menu_PaintAll();
  974. // refresh server browser list
  975. UI_DoServerRefresh();
  976. // refresh server status
  977. UI_BuildServerStatus(qfalse);
  978. // refresh find player list
  979. UI_BuildFindPlayerList(qfalse);
  980. }
  981. // draw cursor
  982. UI_SetColor( NULL );
  983. if (Menu_Count() > 0) {
  984. uiClientState_t cstate;
  985. trap_GetClientState( &cstate );
  986. if(cstate.connState <= CA_DISCONNECTED || cstate.connState >= CA_ACTIVE) {
  987. UI_DrawHandlePic( uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory, 48, 48, uiInfo.uiDC.Assets.cursor);
  988. }
  989. }
  990. #ifndef NDEBUG
  991. if (uiInfo.uiDC.debug)
  992. {
  993. // cursor coordinates
  994. //FIXME
  995. //UI_DrawString( 0, 0, va("(%d,%d)",uis.cursorx,uis.cursory), UI_LEFT|UI_SMALLFONT, colorRed );
  996. }
  997. #endif
  998. //[ExpSys]
  999. //only do this stuff when the your point total has changed.
  1000. if (ui_rankChange.integer != uiMaxRank)
  1001. //if (ui_rankChange.integer)
  1002. //[/ExpSys]
  1003. {
  1004. //[UITweaks]
  1005. //not used in basejka code
  1006. /*
  1007. FPMessageTime = realtime + 3000;
  1008. if (!parsedFPMessage[0] /*&& uiMaxRank > ui_rankChange.integer*//*)
  1009. {
  1010. const char *printMessage = UI_GetStringEdString("MP_INGAME", "SET_NEW_RANK");
  1011. int i = 0;
  1012. int p = 0;
  1013. int linecount = 0;
  1014. while (printMessage[i] && p < 1024)
  1015. {
  1016. parsedFPMessage[p] = printMessage[i];
  1017. p++;
  1018. i++;
  1019. linecount++;
  1020. if (linecount > 64 && printMessage[i] == ' ')
  1021. {
  1022. parsedFPMessage[p] = '\n';
  1023. p++;
  1024. linecount = 0;
  1025. }
  1026. }
  1027. parsedFPMessage[p] = '\0';
  1028. }
  1029. */
  1030. //[/UITweaks]
  1031. //if (uiMaxRank > ui_rankChange.integer)
  1032. {
  1033. uiMaxRank = ui_rankChange.integer;
  1034. uiForceRank = uiMaxRank;
  1035. /*
  1036. while (x < NUM_FORCE_POWERS)
  1037. {
  1038. //For now just go ahead and clear force powers upon rank change
  1039. uiRank[x].uiForcePowersRank = 0;
  1040. x++;
  1041. }
  1042. uiRank[FP_LEVITATION].uiForcePowersRank = 1;
  1043. uiForceUsed = 0;
  1044. */
  1045. //Use BG_LegalizedForcePowers and transfer the result into the UI force settings
  1046. UI_ReadLegalForce();
  1047. }
  1048. if (ui_freeSaber.integer && uiRank[FP_SABER_OFFENSE].uiForcePowersRank < 1)
  1049. {
  1050. uiRank[FP_SABER_OFFENSE].uiForcePowersRank = 1;
  1051. }
  1052. if (ui_freeSaber.integer && uiRank[FP_SABER_DEFENSE].uiForcePowersRank < 1)
  1053. {
  1054. uiRank[FP_SABER_DEFENSE].uiForcePowersRank = 1;
  1055. }
  1056. //[ExpSys]
  1057. //ui_rankChange is now treated like a variable rather than a message sender
  1058. //trap_Cvar_Set("ui_rankChange", "0");
  1059. //[/ExpSys]
  1060. //remember to update the force power count after changing the max rank
  1061. UpdateForceUsed();
  1062. }
  1063. if (ui_freeSaber.integer)
  1064. {
  1065. bgForcePowerCost[FP_SABER_OFFENSE][FORCE_LEVEL_1] = 0;
  1066. bgForcePowerCost[FP_SABER_DEFENSE][FORCE_LEVEL_1] = 0;
  1067. }
  1068. else
  1069. {
  1070. //[ExpSys]
  1071. //use defines since we're tweaking these values for the experience system.
  1072. bgForcePowerCost[FP_SABER_OFFENSE][FORCE_LEVEL_1] = SABER_OFFENSE_L1;
  1073. bgForcePowerCost[FP_SABER_DEFENSE][FORCE_LEVEL_1] = SABER_DEFENSE_L1;
  1074. //bgForcePowerCost[FP_SABER_OFFENSE][FORCE_LEVEL_1] = 1;
  1075. //bgForcePowerCost[FP_SABER_DEFENSE][FORCE_LEVEL_1] = 1;
  1076. //[/ExpSys]
  1077. }
  1078. /*
  1079. if (parsedFPMessage[0] && FPMessageTime > realtime)
  1080. {
  1081. vec4_t txtCol;
  1082. int txtStyle = ITEM_TEXTSTYLE_SHADOWED;
  1083. if ((FPMessageTime - realtime) < 2000)
  1084. {
  1085. txtCol[0] = colorWhite[0];
  1086. txtCol[1] = colorWhite[1];
  1087. txtCol[2] = colorWhite[2];
  1088. txtCol[3] = (((float)FPMessageTime - (float)realtime)/2000);
  1089. txtStyle = 0;
  1090. }
  1091. else
  1092. {
  1093. txtCol[0] = colorWhite[0];
  1094. txtCol[1] = colorWhite[1];
  1095. txtCol[2] = colorWhite[2];
  1096. txtCol[3] = colorWhite[3];
  1097. }
  1098. Text_Paint(10, 0, 1, txtCol, parsedFPMessage, 0, 1024, txtStyle, FONT_MEDIUM);
  1099. }
  1100. */
  1101. //For now, don't bother.
  1102. }
  1103. /*
  1104. =================
  1105. _UI_Shutdown
  1106. =================
  1107. */
  1108. #include "../namespace_begin.h"
  1109. void UI_CleanupGhoul2(void);
  1110. #include "../namespace_end.h"
  1111. //[DynamicMemory_Sabers]
  1112. void UI_FreeSabers(void);
  1113. //[/DynamicMemory_Sabers]
  1114. void _UI_Shutdown( void ) {
  1115. trap_LAN_SaveCachedServers();
  1116. UI_CleanupGhoul2();
  1117. //[DynamicMemory_Sabers]
  1118. UI_FreeSabers();
  1119. //[/DynamicMemory_Sabers]
  1120. }
  1121. char *defaultMenu = NULL;
  1122. char *GetMenuBuffer(const char *filename) {
  1123. int len;
  1124. fileHandle_t f;
  1125. static char buf[MAX_MENUFILE];
  1126. len = trap_FS_FOpenFile( filename, &f, FS_READ );
  1127. if ( !f ) {
  1128. trap_Print( va( S_COLOR_RED "menu file not found: %s, using default\n", filename ) );
  1129. return defaultMenu;
  1130. }
  1131. if ( len >= MAX_MENUFILE ) {
  1132. trap_Print( va( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i", filename, len, MAX_MENUFILE ) );
  1133. trap_FS_FCloseFile( f );
  1134. return defaultMenu;
  1135. }
  1136. trap_FS_Read( buf, len, f );
  1137. buf[len] = 0;
  1138. trap_FS_FCloseFile( f );
  1139. //COM_Compress(buf);
  1140. return buf;
  1141. }
  1142. qboolean Asset_Parse(int handle) {
  1143. pc_token_t token;
  1144. if (!trap_PC_ReadToken(handle, &token))
  1145. return qfalse;
  1146. if (Q_stricmp(token.string, "{") != 0) {
  1147. return qfalse;
  1148. }
  1149. while ( 1 ) {
  1150. memset(&token, 0, sizeof(pc_token_t));
  1151. if (!trap_PC_ReadToken(handle, &token))
  1152. return qfalse;
  1153. if (Q_stricmp(token.string, "}") == 0) {
  1154. return qtrue;
  1155. }
  1156. // font
  1157. if (Q_stricmp(token.string, "font") == 0) {
  1158. int pointSize;
  1159. if (!trap_PC_ReadToken(handle, &token) || !PC_Int_Parse(handle,&pointSize)) {
  1160. return qfalse;
  1161. }
  1162. //trap_R_RegisterFont(tempStr, pointSize, &uiInfo.uiDC.Assets.textFont);
  1163. uiInfo.uiDC.Assets.qhMediumFont = trap_R_RegisterFont(token.string);
  1164. uiInfo.uiDC.Assets.fontRegistered = qtrue;
  1165. continue;
  1166. }
  1167. if (Q_stricmp(token.string, "smallFont") == 0) {
  1168. int pointSize;
  1169. if (!trap_PC_ReadToken(handle, &token) || !PC_Int_Parse(handle,&pointSize)) {
  1170. return qfalse;
  1171. }
  1172. //trap_R_RegisterFont(token, pointSize, &uiInfo.uiDC.Assets.smallFont);
  1173. uiInfo.uiDC.Assets.qhSmallFont = trap_R_RegisterFont(token.string);
  1174. continue;
  1175. }
  1176. if (Q_stricmp(token.string, "small2Font") == 0) {
  1177. int pointSize;
  1178. if (!trap_PC_ReadToken(handle, &token) || !PC_Int_Parse(handle,&pointSize)) {
  1179. return qfalse;
  1180. }
  1181. //trap_R_RegisterFont(token, pointSize, &uiInfo.uiDC.Assets.smallFont);
  1182. uiInfo.uiDC.Assets.qhSmall2Font = trap_R_RegisterFont(token.string);
  1183. continue;
  1184. }
  1185. if (Q_stricmp(token.string, "bigFont") == 0) {
  1186. int pointSize;
  1187. if (!trap_PC_ReadToken(handle, &token) || !PC_Int_Parse(handle,&pointSize)) {
  1188. return qfalse;
  1189. }
  1190. //trap_R_RegisterFont(token, pointSize, &uiInfo.uiDC.Assets.bigFont);
  1191. uiInfo.uiDC.Assets.qhBigFont = trap_R_RegisterFont(token.string);
  1192. continue;
  1193. }
  1194. if (Q_stricmp(token.string, "cursor") == 0)
  1195. {
  1196. if (!PC_String_Parse(handle, &uiInfo.uiDC.Assets.cursorStr))
  1197. {
  1198. Com_Printf(S_COLOR_YELLOW,"Bad 1st parameter for keyword 'cursor'");
  1199. return qfalse;
  1200. }
  1201. uiInfo.uiDC.Assets.cursor = trap_R_RegisterShaderNoMip( uiInfo.uiDC.Assets.cursorStr);
  1202. continue;
  1203. }
  1204. // gradientbar
  1205. if (Q_stricmp(token.string, "gradientbar") == 0) {
  1206. if (!trap_PC_ReadToken(handle, &token)) {
  1207. return qfalse;
  1208. }
  1209. uiInfo.uiDC.Assets.gradientBar = trap_R_RegisterShaderNoMip(token.string);
  1210. continue;
  1211. }
  1212. // enterMenuSound
  1213. if (Q_stricmp(token.string, "menuEnterSound") == 0) {
  1214. if (!trap_PC_ReadToken(handle, &token)) {
  1215. return qfalse;
  1216. }
  1217. uiInfo.uiDC.Assets.menuEnterSound = trap_S_RegisterSound( token.string );
  1218. continue;
  1219. }
  1220. // exitMenuSound
  1221. if (Q_stricmp(token.string, "menuExitSound") == 0) {
  1222. if (!trap_PC_ReadToken(handle, &token)) {
  1223. return qfalse;
  1224. }
  1225. uiInfo.uiDC.Assets.menuExitSound = trap_S_RegisterSound( token.string );
  1226. continue;
  1227. }
  1228. // itemFocusSound
  1229. if (Q_stricmp(token.string, "itemFocusSound") == 0) {
  1230. if (!trap_PC_ReadToken(handle, &token)) {
  1231. return qfalse;
  1232. }
  1233. uiInfo.uiDC.Assets.itemFocusSound = trap_S_RegisterSound( token.string );
  1234. continue;
  1235. }
  1236. // menuBuzzSound
  1237. if (Q_stricmp(token.string, "menuBuzzSound") == 0) {
  1238. if (!trap_PC_ReadToken(handle, &token)) {
  1239. return qfalse;
  1240. }
  1241. uiInfo.uiDC.Assets.menuBuzzSound = trap_S_RegisterSound( token.string );
  1242. continue;
  1243. }
  1244. if (Q_stricmp(token.string, "fadeClamp") == 0) {
  1245. if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.fadeClamp)) {
  1246. return qfalse;
  1247. }
  1248. continue;
  1249. }
  1250. if (Q_stricmp(token.string, "fadeCycle") == 0) {
  1251. if (!PC_Int_Parse(handle, &uiInfo.uiDC.Assets.fadeCycle)) {
  1252. return qfalse;
  1253. }
  1254. continue;
  1255. }
  1256. if (Q_stricmp(token.string, "fadeAmount") == 0) {
  1257. if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.fadeAmount)) {
  1258. return qfalse;
  1259. }
  1260. continue;
  1261. }
  1262. if (Q_stricmp(token.string, "shadowX") == 0) {
  1263. if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.shadowX)) {
  1264. return qfalse;
  1265. }
  1266. continue;
  1267. }
  1268. if (Q_stricmp(token.string, "shadowY") == 0) {
  1269. if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.shadowY)) {
  1270. return qfalse;
  1271. }
  1272. continue;
  1273. }
  1274. if (Q_stricmp(token.string, "shadowColor") == 0) {
  1275. if (!PC_Color_Parse(handle, &uiInfo.uiDC.Assets.shadowColor)) {
  1276. return qfalse;
  1277. }
  1278. uiInfo.uiDC.Assets.shadowFadeClamp = uiInfo.uiDC.Assets.shadowColor[3];
  1279. continue;
  1280. }
  1281. if (Q_stricmp(token.string, "moveRollSound") == 0)
  1282. {
  1283. if (trap_PC_ReadToken(handle,&token))
  1284. {
  1285. uiInfo.uiDC.Assets.moveRollSound = trap_S_RegisterSound( token.string );
  1286. }
  1287. continue;
  1288. }
  1289. if (Q_stricmp(token.string, "moveJumpSound") == 0)
  1290. {
  1291. if (trap_PC_ReadToken(handle,&token))
  1292. {
  1293. uiInfo.uiDC.Assets.moveJumpSound = trap_S_RegisterSound( token.string );
  1294. }
  1295. continue;
  1296. }
  1297. if (Q_stricmp(token.string, "datapadmoveSaberSound1") == 0)
  1298. {
  1299. if (trap_PC_ReadToken(handle,&token))
  1300. {
  1301. uiInfo.uiDC.Assets.datapadmoveSaberSound1 = trap_S_RegisterSound( token.string );
  1302. }
  1303. continue;
  1304. }
  1305. if (Q_stricmp(token.string, "datapadmoveSaberSound2") == 0)
  1306. {
  1307. if (trap_PC_ReadToken(handle,&token))
  1308. {
  1309. uiInfo.uiDC.Assets.datapadmoveSaberSound2 = trap_S_RegisterSound( token.string );
  1310. }
  1311. continue;
  1312. }
  1313. if (Q_stricmp(token.string, "datapadmoveSaberSound3") == 0)
  1314. {
  1315. if (trap_PC_ReadToken(handle,&token))
  1316. {
  1317. uiInfo.uiDC.Assets.datapadmoveSaberSound3 = trap_S_RegisterSound( token.string );
  1318. }
  1319. continue;
  1320. }
  1321. if (Q_stricmp(token.string, "datapadmoveSaberSound4") == 0)
  1322. {
  1323. if (trap_PC_ReadToken(handle,&token))
  1324. {
  1325. uiInfo.uiDC.Assets.datapadmoveSaberSound4 = trap_S_RegisterSound( token.string );
  1326. }
  1327. continue;
  1328. }
  1329. if (Q_stricmp(token.string, "datapadmoveSaberSound5") == 0)
  1330. {
  1331. if (trap_PC_ReadToken(handle,&token))
  1332. {
  1333. uiInfo.uiDC.Assets.datapadmoveSaberSound5 = trap_S_RegisterSound( token.string );
  1334. }
  1335. continue;
  1336. }
  1337. if (Q_stricmp(token.string, "datapadmoveSaberSound6") == 0)
  1338. {
  1339. if (trap_PC_ReadToken(handle,&token))
  1340. {
  1341. uiInfo.uiDC.Assets.datapadmoveSaberSound6 = trap_S_RegisterSound( token.string );
  1342. }
  1343. continue;
  1344. }
  1345. // precaching various sound files used in the menus
  1346. if (Q_stricmp(token.string, "precacheSound") == 0)
  1347. {
  1348. const char *tempStr;
  1349. if (PC_Script_Parse(handle, &tempStr))
  1350. {
  1351. char *soundFile;
  1352. do
  1353. {
  1354. soundFile = COM_ParseExt(&tempStr, qfalse);
  1355. if (soundFile[0] != 0 && soundFile[0] != ';') {
  1356. trap_S_RegisterSound( soundFile);
  1357. }
  1358. } while (soundFile[0]);
  1359. }
  1360. continue;
  1361. }
  1362. }
  1363. return qfalse;
  1364. }
  1365. void UI_Report() {
  1366. String_Report();
  1367. //Font_Report();
  1368. }
  1369. void UI_ParseMenu(const char *menuFile) {
  1370. int handle;
  1371. pc_token_t token;
  1372. //Com_Printf("Parsing menu file: %s\n", menuFile);
  1373. handle = trap_PC_LoadSource(menuFile);
  1374. if (!handle) {
  1375. return;
  1376. }
  1377. while ( 1 ) {
  1378. memset(&token, 0, sizeof(pc_token_t));
  1379. if (!trap_PC_ReadToken( handle, &token )) {
  1380. break;
  1381. }
  1382. //if ( Q_stricmp( token, "{" ) ) {
  1383. // Com_Printf( "Missing { in menu file\n" );
  1384. // break;
  1385. //}
  1386. //if ( menuCount == MAX_MENUS ) {
  1387. // Com_Printf( "Too many menus!\n" );
  1388. // break;
  1389. //}
  1390. if ( token.string[0] == '}' ) {
  1391. break;
  1392. }
  1393. if (Q_stricmp(token.string, "assetGlobalDef") == 0) {
  1394. if (Asset_Parse(handle)) {
  1395. continue;
  1396. } else {
  1397. break;
  1398. }
  1399. }
  1400. if (Q_stricmp(token.string, "menudef") == 0) {
  1401. // start a new menu
  1402. Menu_New(handle);
  1403. }
  1404. }
  1405. trap_PC_FreeSource(handle);
  1406. }
  1407. //[CoOp]
  1408. void UI_LoadSingleMenuFile(const char *menuFile)
  1409. {//load in a single menu file
  1410. trap_PC_LoadGlobalDefines ( "ui/jamp/menudef.h" ); //Load globaldefines for parsing.
  1411. UI_ParseMenu(menuFile);
  1412. trap_PC_RemoveAllGlobalDefines ( ); //Close globaldefines.
  1413. }
  1414. //[/CoOp]
  1415. qboolean Load_Menu(int handle) {
  1416. pc_token_t token;
  1417. if (!trap_PC_ReadToken(handle, &token))
  1418. return qfalse;
  1419. if (token.string[0] != '{') {
  1420. return qfalse;
  1421. }
  1422. while ( 1 ) {
  1423. if (!trap_PC_ReadToken(handle, &token))
  1424. return qfalse;
  1425. if ( token.string[0] == 0 ) {
  1426. return qfalse;
  1427. }
  1428. if ( token.string[0] == '}' ) {
  1429. return qtrue;
  1430. }
  1431. UI_ParseMenu(token.string);
  1432. }
  1433. return qfalse;
  1434. }
  1435. void UI_LoadMenus(const char *menuFile, qboolean reset) {
  1436. pc_token_t token;
  1437. int handle;
  1438. int start;
  1439. start = trap_Milliseconds();
  1440. trap_PC_LoadGlobalDefines ( "ui/jamp/menudef.h" );
  1441. handle = trap_PC_LoadSource( menuFile );
  1442. if (!handle) {
  1443. Com_Printf( S_COLOR_YELLOW "menu file not found: %s, using default\n", menuFile );
  1444. handle = trap_PC_LoadSource( "ui/jampmenus.txt" );
  1445. if (!handle) {
  1446. trap_Error( va( S_COLOR_RED "default menu file not found: ui/menus.txt, unable to continue!\n", menuFile ) );
  1447. }
  1448. }
  1449. if (reset) {
  1450. Menu_Reset();
  1451. }
  1452. while ( 1 ) {
  1453. if (!trap_PC_ReadToken(handle, &token))
  1454. break;
  1455. if( token.string[0] == 0 || token.string[0] == '}') {
  1456. break;
  1457. }
  1458. if ( token.string[0] == '}' ) {
  1459. break;
  1460. }
  1461. if (Q_stricmp(token.string, "loadmenu") == 0) {
  1462. if (Load_Menu(handle)) {
  1463. continue;
  1464. } else {
  1465. break;
  1466. }
  1467. }
  1468. }
  1469. // Com_Printf("UI menu load time = %d milli seconds\n", trap_Milliseconds() - start);
  1470. trap_PC_FreeSource( handle );
  1471. trap_PC_RemoveAllGlobalDefines ( );
  1472. }
  1473. void UI_Load() {
  1474. char *menuSet;
  1475. char lastName[1024];
  1476. menuDef_t *menu = Menu_GetFocused();
  1477. if (menu && menu->window.name) {
  1478. strcpy(lastName, menu->window.name);
  1479. }
  1480. else
  1481. {
  1482. lastName[0] = 0;
  1483. }
  1484. if (uiInfo.inGameLoad)
  1485. {
  1486. menuSet= "ui/jampingame.txt";
  1487. }
  1488. else
  1489. {
  1490. menuSet= UI_Cvar_VariableString("ui_menuFilesMP");
  1491. }
  1492. if (menuSet == NULL || menuSet[0] == '\0') {
  1493. menuSet = "ui/jampmenus.txt";
  1494. }
  1495. String_Init();
  1496. #ifdef PRE_RELEASE_TADEMO
  1497. UI_ParseGameInfo("demogameinfo.txt");
  1498. #else
  1499. UI_ParseGameInfo("ui/jamp/gameinfo.txt");
  1500. #endif
  1501. UI_LoadArenas();
  1502. UI_LoadBots();
  1503. UI_LoadMenus(menuSet, qtrue);
  1504. Menus_CloseAll();
  1505. Menus_ActivateByName(lastName);
  1506. }
  1507. static const char *handicapValues[] = {"None","95","90","85","80","75","70","65","60","55","50","45","40","35","30","25","20","15","10","5",NULL};
  1508. static void UI_DrawHandicap(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) {
  1509. int i, h;
  1510. h = Com_Clamp( 5, 100, trap_Cvar_VariableValue("handicap") );
  1511. i = 20 - h / 5;
  1512. Text_Paint(rect->x, rect->y, scale, color, handicapValues[i], 0, 0, textStyle, iMenuFont);
  1513. }
  1514. static void UI_DrawClanName(rectDef_t *rect, float sca

Large files files are truncated, but you can click here to view the full file