ui_mods.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  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. #include "ui_local.h"
  20. #define ART_BACK0 "menu/art/back_0"
  21. #define ART_BACK1 "menu/art/back_1"
  22. #define ART_FIGHT0 "menu/art/load_0"
  23. #define ART_FIGHT1 "menu/art/load_1"
  24. #define ART_FRAMEL "menu/art/frame2_l"
  25. #define ART_FRAMER "menu/art/frame1_r"
  26. #define MAX_MODS 64
  27. #define NAMEBUFSIZE ( MAX_MODS * 48 )
  28. #define GAMEBUFSIZE ( MAX_MODS * 16 )
  29. #define ID_BACK 10
  30. #define ID_GO 11
  31. #define ID_LIST 12
  32. typedef struct {
  33. menuframework_s menu;
  34. menutext_s banner;
  35. menubitmap_s framel;
  36. menubitmap_s framer;
  37. menulist_s list;
  38. menubitmap_s back;
  39. menubitmap_s go;
  40. char description[NAMEBUFSIZE];
  41. char fs_game[GAMEBUFSIZE];
  42. char *descriptionPtr;
  43. char *fs_gamePtr;
  44. char *descriptionList[MAX_MODS];
  45. char *fs_gameList[MAX_MODS];
  46. } mods_t;
  47. static mods_t s_mods;
  48. /*
  49. ===============
  50. UI_Mods_MenuEvent
  51. ===============
  52. */
  53. static void UI_Mods_MenuEvent( void *ptr, int event ) {
  54. if( event != QM_ACTIVATED ) {
  55. return;
  56. }
  57. switch ( ((menucommon_s*)ptr)->id ) {
  58. case ID_GO:
  59. trap_Cvar_Set( "fs_game", s_mods.fs_gameList[s_mods.list.curvalue] );
  60. trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart;" );
  61. UI_PopMenu();
  62. break;
  63. case ID_BACK:
  64. UI_PopMenu();
  65. break;
  66. }
  67. }
  68. /*
  69. ===============
  70. UI_Mods_ParseInfos
  71. ===============
  72. */
  73. static void UI_Mods_ParseInfos( char *modDir, char *modDesc ) {
  74. s_mods.fs_gameList[s_mods.list.numitems] = s_mods.fs_gamePtr;
  75. Q_strncpyz( s_mods.fs_gamePtr, modDir, 16 );
  76. s_mods.descriptionList[s_mods.list.numitems] = s_mods.descriptionPtr;
  77. Q_strncpyz( s_mods.descriptionPtr, modDesc, 48 );
  78. s_mods.list.itemnames[s_mods.list.numitems] = s_mods.descriptionPtr;
  79. s_mods.descriptionPtr += strlen( s_mods.descriptionPtr ) + 1;
  80. s_mods.fs_gamePtr += strlen( s_mods.fs_gamePtr ) + 1;
  81. s_mods.list.numitems++;
  82. }
  83. #if 0 // bk001204 - unused
  84. /*
  85. ===============
  86. UI_Mods_LoadModsFromFile
  87. ===============
  88. */
  89. static void UI_Mods_LoadModsFromFile( char *filename ) {
  90. int len;
  91. fileHandle_t f;
  92. char buf[1024];
  93. len = trap_FS_FOpenFile( filename, &f, FS_READ );
  94. if ( !f ) {
  95. trap_Print( va( S_COLOR_RED "file not found: %s\n", filename ) );
  96. return;
  97. }
  98. if ( len >= sizeof(buf) ) {
  99. trap_Print( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, sizeof(buf) ) );
  100. trap_FS_FCloseFile( f );
  101. return;
  102. }
  103. trap_FS_Read( buf, len, f );
  104. buf[len] = 0;
  105. trap_FS_FCloseFile( f );
  106. len = strlen( filename );
  107. if( !Q_stricmp(filename + len - 4,".mod") ) {
  108. filename[len-4] = '\0';
  109. }
  110. UI_Mods_ParseInfos( filename, buf );
  111. }
  112. #endif
  113. /*
  114. ===============
  115. UI_Mods_LoadMods
  116. ===============
  117. */
  118. static void UI_Mods_LoadMods( void ) {
  119. int numdirs;
  120. char dirlist[2048];
  121. char *dirptr;
  122. char *descptr;
  123. int i;
  124. int dirlen;
  125. s_mods.list.itemnames = (const char **)s_mods.descriptionList;
  126. s_mods.descriptionPtr = s_mods.description;
  127. s_mods.fs_gamePtr = s_mods.fs_game;
  128. // always start off with baseq3
  129. s_mods.list.numitems = 1;
  130. s_mods.list.itemnames[0] = s_mods.descriptionList[0] = "Quake III Arena";
  131. s_mods.fs_gameList[0] = "";
  132. numdirs = trap_FS_GetFileList( "$modlist", "", dirlist, sizeof(dirlist) );
  133. dirptr = dirlist;
  134. for( i = 0; i < numdirs; i++ ) {
  135. dirlen = strlen( dirptr ) + 1;
  136. descptr = dirptr + dirlen;
  137. UI_Mods_ParseInfos( dirptr, descptr);
  138. dirptr += dirlen + strlen(descptr) + 1;
  139. }
  140. trap_Print( va( "%i mods parsed\n", s_mods.list.numitems ) );
  141. if (s_mods.list.numitems > MAX_MODS) {
  142. s_mods.list.numitems = MAX_MODS;
  143. }
  144. }
  145. /*
  146. ===============
  147. UI_Mods_MenuInit
  148. ===============
  149. */
  150. static void UI_Mods_MenuInit( void ) {
  151. UI_ModsMenu_Cache();
  152. memset( &s_mods, 0 ,sizeof(mods_t) );
  153. s_mods.menu.wrapAround = qtrue;
  154. s_mods.menu.fullscreen = qtrue;
  155. s_mods.banner.generic.type = MTYPE_BTEXT;
  156. s_mods.banner.generic.x = 320;
  157. s_mods.banner.generic.y = 16;
  158. s_mods.banner.string = "MODS";
  159. s_mods.banner.color = color_white;
  160. s_mods.banner.style = UI_CENTER;
  161. s_mods.framel.generic.type = MTYPE_BITMAP;
  162. s_mods.framel.generic.name = ART_FRAMEL;
  163. s_mods.framel.generic.flags = QMF_INACTIVE;
  164. s_mods.framel.generic.x = 0;
  165. s_mods.framel.generic.y = 78;
  166. s_mods.framel.width = 256;
  167. s_mods.framel.height = 329;
  168. s_mods.framer.generic.type = MTYPE_BITMAP;
  169. s_mods.framer.generic.name = ART_FRAMER;
  170. s_mods.framer.generic.flags = QMF_INACTIVE;
  171. s_mods.framer.generic.x = 376;
  172. s_mods.framer.generic.y = 76;
  173. s_mods.framer.width = 256;
  174. s_mods.framer.height = 334;
  175. s_mods.back.generic.type = MTYPE_BITMAP;
  176. s_mods.back.generic.name = ART_BACK0;
  177. s_mods.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
  178. s_mods.back.generic.id = ID_BACK;
  179. s_mods.back.generic.callback = UI_Mods_MenuEvent;
  180. s_mods.back.generic.x = 0;
  181. s_mods.back.generic.y = 480-64;
  182. s_mods.back.width = 128;
  183. s_mods.back.height = 64;
  184. s_mods.back.focuspic = ART_BACK1;
  185. s_mods.go.generic.type = MTYPE_BITMAP;
  186. s_mods.go.generic.name = ART_FIGHT0;
  187. s_mods.go.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS;
  188. s_mods.go.generic.id = ID_GO;
  189. s_mods.go.generic.callback = UI_Mods_MenuEvent;
  190. s_mods.go.generic.x = 640;
  191. s_mods.go.generic.y = 480-64;
  192. s_mods.go.width = 128;
  193. s_mods.go.height = 64;
  194. s_mods.go.focuspic = ART_FIGHT1;
  195. // scan for mods
  196. s_mods.list.generic.type = MTYPE_SCROLLLIST;
  197. s_mods.list.generic.flags = QMF_PULSEIFFOCUS|QMF_CENTER_JUSTIFY;
  198. s_mods.list.generic.callback = UI_Mods_MenuEvent;
  199. s_mods.list.generic.id = ID_LIST;
  200. s_mods.list.generic.x = 320;
  201. s_mods.list.generic.y = 130;
  202. s_mods.list.width = 48;
  203. s_mods.list.height = 14;
  204. UI_Mods_LoadMods();
  205. Menu_AddItem( &s_mods.menu, &s_mods.banner );
  206. Menu_AddItem( &s_mods.menu, &s_mods.framel );
  207. Menu_AddItem( &s_mods.menu, &s_mods.framer );
  208. Menu_AddItem( &s_mods.menu, &s_mods.list );
  209. Menu_AddItem( &s_mods.menu, &s_mods.back );
  210. Menu_AddItem( &s_mods.menu, &s_mods.go );
  211. }
  212. /*
  213. =================
  214. UI_Mods_Cache
  215. =================
  216. */
  217. void UI_ModsMenu_Cache( void ) {
  218. trap_R_RegisterShaderNoMip( ART_BACK0 );
  219. trap_R_RegisterShaderNoMip( ART_BACK1 );
  220. trap_R_RegisterShaderNoMip( ART_FIGHT0 );
  221. trap_R_RegisterShaderNoMip( ART_FIGHT1 );
  222. trap_R_RegisterShaderNoMip( ART_FRAMEL );
  223. trap_R_RegisterShaderNoMip( ART_FRAMER );
  224. }
  225. /*
  226. ===============
  227. UI_ModsMenu
  228. ===============
  229. */
  230. void UI_ModsMenu( void ) {
  231. UI_Mods_MenuInit();
  232. UI_PushMenu( &s_mods.menu );
  233. }