00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "../client.h"
00030 #include "../cl_screen.h"
00031 #include "../cl_game.h"
00032 #include "cl_particle.h"
00033 #include "cl_localentity.h"
00034 #include "cl_actor.h"
00035 #include "cl_hud.h"
00036 #include "cl_spawn.h"
00037 #include "cl_view.h"
00038 #include "../renderer/r_main.h"
00039 #include "../renderer/r_entity.h"
00040
00041 cvar_t* cl_map_debug;
00042 static cvar_t *cl_precache;
00043
00047 void CL_ViewLoadMedia (void)
00048 {
00049 le_t *le;
00050 int i, max;
00051
00052 CL_ViewUpdateRenderData();
00053
00054 if (CL_GetConfigString(CS_TILES)[0] == '\0')
00055 return;
00056
00057 Com_sprintf(cls.loadingMessages, sizeof(cls.loadingMessages), _("loading %s"), _(CL_GetConfigString(CS_MAPTITLE)));
00058 cls.loadingPercent = 0;
00059
00060
00061 SCR_UpdateScreen();
00062 R_ModBeginLoading(CL_GetConfigString(CS_TILES), CL_GetConfigStringInteger(CS_LIGHTMAP), CL_GetConfigString(CS_POSITIONS), CL_GetConfigString(CS_NAME));
00063 CL_SpawnParseEntitystring();
00064
00065 Com_sprintf(cls.loadingMessages, sizeof(cls.loadingMessages), _("loading models..."));
00066 cls.loadingPercent += 10.0f;
00067 SCR_UpdateScreen();
00068
00069 LM_Register();
00070 CL_ParticleRegisterArt();
00071
00072 for (i = 1, max = 0; i < MAX_MODELS && CL_GetConfigString(CS_MODELS + i)[0] != '\0'; i++)
00073 max++;
00074
00075 max += csi.numODs;
00076
00077 for (i = 1; i < MAX_MODELS && CL_GetConfigString(CS_MODELS + i)[0] != '\0'; i++) {
00078 const char *name = CL_GetConfigString(CS_MODELS + i);
00079
00080 if (name[0] != '*') {
00081 Com_sprintf(cls.loadingMessages, sizeof(cls.loadingMessages),
00082 _("loading %s"), name);
00083 }
00084 SCR_UpdateScreen();
00085 IN_SendKeyEvents();
00086 cl.model_draw[i] = R_RegisterModelShort(name);
00087
00088 if (name[0] == '*')
00089 cl.model_clip[i] = CM_InlineModel(cl.mapTiles, name);
00090 else
00091 cl.model_clip[i] = NULL;
00092 if (!cl.model_draw[i])
00093 Com_Error(ERR_DROP, "Could not load model '%s'\n", name);
00094
00095 cls.loadingPercent += 100.0f / (float)max;
00096 }
00097
00098
00099 le = NULL;
00100 while ((le = LE_GetNextInUse(le))) {
00101 if (le->modelnum1) {
00102 le->model1 = cl.model_draw[le->modelnum1];
00103 if (!le->model1)
00104 Com_Error(ERR_DROP, "No model for %i", le->modelnum1);
00105 }
00106 if (le->modelnum2) {
00107 le->model2 = cl.model_draw[le->modelnum2];
00108 if (!le->model2)
00109 Com_Error(ERR_DROP, "No model for %i", le->modelnum2);
00110 }
00111 }
00112
00113 cls.loadingPercent = 100.0f;
00114 SCR_UpdateScreen();
00115
00116
00117 Com_sprintf(cls.loadingMessages, sizeof(cls.loadingMessages), _("Awaiting game start"));
00118 SCR_UpdateScreen();
00119 refdef.ready = qtrue;
00121 refdef.weather = WEATHER_NONE;
00122 refdef.fogColor[3] = 1.0;
00123 VectorSet(refdef.fogColor, 0.75, 0.75, 0.75);
00124 }
00125
00131 static void CL_PrecacheCharacterModels (void)
00132 {
00133 teamDef_t *td;
00134 int i, j, num;
00135 char model[MAX_QPATH];
00136 const char *path;
00137 float loading = cls.loadingPercent;
00138 linkedList_t *list;
00139 const float percent = 55.0f;
00140
00141
00142 for (i = 0, td = csi.teamDef; i < csi.numTeamDefs; i++, td++)
00143 for (j = NAME_NEUTRAL; j < NAME_LAST; j++) {
00144
00145 if (!td->numModels[j])
00146 continue;
00147
00148 list = td->models[j];
00149 assert(list);
00150 for (num = 0; num < td->numModels[j]; num++) {
00151 assert(list);
00152 path = (const char*)list->data;
00153 list = list->next;
00154
00155 Com_sprintf(model, sizeof(model), "%s/%s", path, list->data);
00156 if (!R_RegisterModelShort(model))
00157 Com_Printf("Com_PrecacheCharacterModels: Could not register model %s\n", model);
00158 list = list->next;
00159
00160 Com_sprintf(model, sizeof(model), "%s/%s", path, list->data);
00161 if (!R_RegisterModelShort(model))
00162 Com_Printf("Com_PrecacheCharacterModels: Could not register model %s\n", model);
00163
00164
00165 list = list->next;
00166
00167
00168 list = list->next;
00169
00170 cls.loadingPercent += percent / (td->numModels[j] * csi.numTeamDefs * NAME_LAST);
00171 SCR_DrawPrecacheScreen(qtrue);
00172 }
00173 }
00174
00175 cls.loadingPercent = loading + percent;
00176 }
00177
00181 void CL_ViewPrecacheModels (void)
00182 {
00183 int i;
00184 float percent = 40.0f;
00185
00186 cls.loadingPercent = 5.0f;
00187 SCR_DrawPrecacheScreen(qtrue);
00188
00189 if (cl_precache->integer)
00190 CL_PrecacheCharacterModels();
00191 else
00192 percent = 95.0f;
00193
00194 for (i = 0; i < csi.numODs; i++) {
00195 const objDef_t *od = INVSH_GetItemByIDX(i);
00196 if (od->type[0] == '\0' || od->isDummy)
00197 continue;
00198
00199 if (od->model[0] != '\0') {
00200 cls.modelPool[i] = R_RegisterModelShort(od->model);
00201 if (cls.modelPool[i])
00202 Com_DPrintf(DEBUG_CLIENT, "CL_PrecacheModels: Registered object model: '%s' (%i)\n", od->model, i);
00203 }
00204 cls.loadingPercent += percent / csi.numODs;
00205 SCR_DrawPrecacheScreen(qtrue);
00206 }
00207
00208 cls.loadingPercent = 100.0f;
00209 SCR_DrawPrecacheScreen(qtrue);
00210
00211
00212
00213 R_SwitchModelMemPoolTag();
00214
00215 SCR_DrawPrecacheScreen(qfalse);
00216 }
00217
00223 void CL_ViewCalcFieldOfViewX (void)
00224 {
00225 if (cl_isometric->integer) {
00226 const float zoom = 3.6 * (cl.cam.zoom - cl_camzoommin->value) + 0.3 * cl_camzoommin->value;
00227 refdef.fieldOfViewX = max(min(FOV / zoom, 140.0), 1.0);
00228 } else {
00229 refdef.fieldOfViewX = max(min(FOV / cl.cam.zoom, 95.0), 55.0);
00230 }
00231 }
00232
00236 static inline void CL_ViewCalcFieldOfViewY (const float width, const float height)
00237 {
00238 refdef.fieldOfViewY = atan(tan(refdef.fieldOfViewX * (M_PI / 360.0)) * (height / width)) * (360.0 / M_PI);
00239 }
00240
00244 void CL_ViewUpdateRenderData (void)
00245 {
00246 VectorCopy(cl.cam.camorg, refdef.viewOrigin);
00247 VectorCopy(cl.cam.angles, refdef.viewAngles);
00248
00249 CL_ViewCalcFieldOfViewY(viddef.viewWidth, viddef.viewHeight);
00250
00251
00252 refdef.time = cl.time * 0.001;
00253 refdef.worldlevel = cl_worldlevel->integer;
00254 }
00255
00259 void CL_ViewRender (void)
00260 {
00261 refdef.brushCount = 0;
00262 refdef.aliasCount = 0;
00263
00264 if (cls.state != ca_active)
00265 return;
00266
00267 if (!viddef.viewWidth || !viddef.viewHeight)
00268 return;
00269
00270
00271 if (!refdef.ready)
00272 return;
00273
00274 refdef.numEntities = 0;
00275 refdef.mapTiles = cl.mapTiles;
00276
00277
00278 r_threadstate.state = THREAD_BSP;
00279
00280 refdef.rendererFlags &= ~RDF_NOWORLDMODEL;
00281
00282 LM_AddToScene();
00283
00284 LE_AddToScene();
00285
00286 if (cl_map_debug->integer) {
00287 if (cl_map_debug->integer & MAPDEBUG_PATHING)
00288 CL_AddPathing();
00289
00290 if (cl_map_debug->integer & MAPDEBUG_CELLS)
00291 CL_DisplayFloorArrows();
00292
00293 if (cl_map_debug->integer & MAPDEBUG_WALLS)
00294 CL_DisplayObstructionArrows();
00295 }
00296
00297 CL_AddTargeting();
00298
00299
00300 CL_ViewUpdateRenderData();
00301
00302
00303 R_RenderFrame();
00304 }
00305
00312 void CL_ViewCenterAtGridPosition (const pos3_t pos)
00313 {
00314 vec3_t vec;
00315
00316 PosToVec(pos, vec);
00317 VectorCopy(vec, cl.cam.origin);
00318 Cvar_SetValue("cl_worldlevel", pos[2]);
00319 }
00320
00321 void CL_ViewInit (void)
00322 {
00323 cl_precache = Cvar_Get("cl_precache", "1", CVAR_ARCHIVE, "Precache character models at startup - more memory usage but smaller loading times in the game");
00324 }