/** * @brief Activates the map render screen (ca_active) * @sa SCR_EndLoadingPlaque * @sa G_ClientBegin * @note EV_START */ void CL_StartGame (const eventRegister_t* self, dbuffer* msg) { const int isTeamPlay = NET_ReadByte(msg); /* init camera position and angles */ OBJZERO(cl.cam); VectorSet(cl.cam.angles, 60.0, 60.0, 0.0); VectorSet(cl.cam.omega, 0.0, 0.0, 0.0); cl.cam.zoom = 1.25; CL_ViewCalcFieldOfViewX(); Com_Printf("Starting the game...\n"); /* make sure selActor is null (after reconnect or server change this is needed) */ CL_ActorSelect(nullptr); /* center on first actor */ cl_worldlevel->modified = true; if (cl.numTeamList) { const le_t* le = cl.teamList[0]; CL_ViewCenterAtGridPosition(le->pos); } /* activate the renderer */ CL_SetClientState(ca_active); GAME_StartBattlescape(isTeamPlay); }
/** * @brief Called after tactical missions to wipe away the tactical-mission-only data. * @sa CL_ParseServerData * @sa CL_Disconnect * @sa R_ClearScene */ static void CL_ClearState (void) { LE_Cleanup(); /* wipe the entire cl structure */ OBJZERO(cl); cl.cam.zoom = 1.0; CL_ViewCalcFieldOfViewX(); /* wipe the particles with every new map */ r_numParticles = 0; /* reset ir goggle state with every new map */ refdef.rendererFlags &= ~RDF_IRGOGGLES; }
/** * @brief Zooms the scene of the battlefield out */ void CL_CameraZoomOut (void) { float quant; /* check zoom quant */ if (cl_camzoomquant->value < MIN_CAMZOOM_QUANT) quant = 1 + MIN_CAMZOOM_QUANT; else if (cl_camzoomquant->value > MAX_CAMZOOM_QUANT) quant = 1 + MAX_CAMZOOM_QUANT; else quant = 1 + cl_camzoomquant->value; /* change zoom */ cl.cam.zoom /= quant; /* ensure zoom isnt less than either MIN_ZOOM or cl_camzoommin */ cl.cam.zoom = std::max(std::max(MIN_ZOOM, cl_camzoommin->value), cl.cam.zoom); CL_ViewCalcFieldOfViewX(); }
/** * @brief Zooms the scene of the battlefield in */ void CL_CameraZoomIn (void) { float quant; /* check zoom quant */ if (cl_camzoomquant->value < MIN_CAMZOOM_QUANT) quant = 1 + MIN_CAMZOOM_QUANT; else if (cl_camzoomquant->value > MAX_CAMZOOM_QUANT) quant = 1 + MAX_CAMZOOM_QUANT; else quant = 1 + cl_camzoomquant->value; /* change zoom */ cl.cam.zoom *= quant; /* ensure zoom doesn't exceed either MAX_ZOOM or cl_camzoommax */ cl.cam.zoom = std::min(std::min(MAX_ZOOM, cl_camzoommax->value), cl.cam.zoom); CL_ViewCalcFieldOfViewX(); }
/** * @brief Set the camera values for a sequence * @sa CL_SequenceRender3D */ static void SEQ_SetCamera (sequenceContext_t *context) { if (!context->size[0] || !context->size[1]) return; /* advance time */ VectorMA(context->camera.origin, cls.frametime, context->camera.speed, context->camera.origin); VectorMA(context->camera.angles, cls.frametime, context->camera.omega, context->camera.angles); context->camera.zoom += cls.frametime * context->camera.dzoom; context->camera.dist += cls.frametime * context->camera.ddist; /* set camera */ VectorCopy(context->camera.origin, cl.cam.origin); VectorCopy(context->camera.angles, cl.cam.angles); AngleVectors(cl.cam.angles, cl.cam.axis[0], cl.cam.axis[1], cl.cam.axis[2]); VectorMA(cl.cam.origin, -context->camera.dist, cl.cam.axis[0], cl.cam.camorg); cl.cam.zoom = std::max(context->camera.zoom, MIN_ZOOM); /* fudge to get isometric and perspective modes looking similar */ if (cl_isometric->integer) cl.cam.zoom /= 1.35; CL_ViewCalcFieldOfViewX(); }
/** * @brief Update the camera position. This can be done in two different reasons. The first is the user input, the second * is an active camera route. The camera route overrides the user input and is lerping the movement until the final position * is reached. */ void CL_CameraMove (void) { float frac; vec3_t delta; int i; /* get relevant variables */ const float rotspeed = (cl_camrotspeed->value > MIN_CAMROT_SPEED) ? ((cl_camrotspeed->value < MAX_CAMROT_SPEED) ? cl_camrotspeed->value : MAX_CAMROT_SPEED) : MIN_CAMROT_SPEED; const float movespeed = (cl_cammovespeed->value > MIN_CAMMOVE_SPEED) ? ((cl_cammovespeed->value < MAX_CAMMOVE_SPEED) ? cl_cammovespeed->value / cl.cam.zoom : MAX_CAMMOVE_SPEED / cl.cam.zoom) : MIN_CAMMOVE_SPEED / cl.cam.zoom; const float moveaccel = (cl_cammoveaccel->value > MIN_CAMMOVE_ACCEL) ? ((cl_cammoveaccel->value < MAX_CAMMOVE_ACCEL) ? cl_cammoveaccel->value / cl.cam.zoom : MAX_CAMMOVE_ACCEL / cl.cam.zoom) : MIN_CAMMOVE_ACCEL / cl.cam.zoom; if (cls.state != ca_active) return; if (!viddef.viewWidth || !viddef.viewHeight) return; /* calculate camera omega */ /* stop acceleration */ frac = cls.frametime * moveaccel * 2.5; for (i = 0; i < 2; i++) { if (fabs(cl.cam.omega[i]) > frac) { if (cl.cam.omega[i] > 0) cl.cam.omega[i] -= frac; else cl.cam.omega[i] += frac; } else cl.cam.omega[i] = 0; /* rotational acceleration */ if (i == YAW) cl.cam.omega[i] += CL_GetKeyMouseState(STATE_ROT) * frac * 2; else cl.cam.omega[i] += CL_GetKeyMouseState(STATE_TILT) * frac * 2; if (cl.cam.omega[i] > rotspeed) cl.cam.omega[i] = rotspeed; if (-cl.cam.omega[i] > rotspeed) cl.cam.omega[i] = -rotspeed; } cl.cam.omega[ROLL] = 0; /* calculate new camera angles for this frame */ VectorMA(cl.cam.angles, cls.frametime, cl.cam.omega, cl.cam.angles); if (cl.cam.angles[PITCH] > cl_campitchmax->value) cl.cam.angles[PITCH] = cl_campitchmax->value; if (cl.cam.angles[PITCH] < cl_campitchmin->value) cl.cam.angles[PITCH] = cl_campitchmin->value; AngleVectors(cl.cam.angles, cl.cam.axis[0], cl.cam.axis[1], cl.cam.axis[2]); /* camera route overrides user input */ if (cameraRoute) { /* camera route */ frac = cls.frametime * moveaccel * 2; if (VectorDist(cl.cam.origin, routeFrom) > routeDist - 200) { VectorMA(cl.cam.speed, -frac, routeDelta, cl.cam.speed); VectorNormalize2(cl.cam.speed, delta); if (DotProduct(delta, routeDelta) < 0.05) { cameraRoute = false; CL_BlockBattlescapeEvents(false); } } else VectorMA(cl.cam.speed, frac, routeDelta, cl.cam.speed); } else { /* normal camera movement */ /* calculate ground-based movement vectors */ const float angle = cl.cam.angles[YAW] * torad; const float sy = sin(angle); const float cy = cos(angle); vec3_t g_forward, g_right; VectorSet(g_forward, cy, sy, 0.0); VectorSet(g_right, sy, -cy, 0.0); /* calculate camera speed */ /* stop acceleration */ frac = cls.frametime * moveaccel; if (VectorLength(cl.cam.speed) > frac) { VectorNormalize2(cl.cam.speed, delta); VectorMA(cl.cam.speed, -frac, delta, cl.cam.speed); } else VectorClear(cl.cam.speed); /* acceleration */ frac = cls.frametime * moveaccel * 3.5; VectorClear(delta); VectorScale(g_forward, CL_GetKeyMouseState(STATE_FORWARD), delta); VectorMA(delta, CL_GetKeyMouseState(STATE_RIGHT), g_right, delta); VectorNormalize(delta); VectorMA(cl.cam.speed, frac, delta, cl.cam.speed); /* lerp the level change */ if (cl.cam.lerplevel < cl_worldlevel->value) { cl.cam.lerplevel += LEVEL_SPEED * (cl_worldlevel->value - cl.cam.lerplevel + LEVEL_MIN) * cls.frametime; if (cl.cam.lerplevel > cl_worldlevel->value) cl.cam.lerplevel = cl_worldlevel->value; } else if (cl.cam.lerplevel > cl_worldlevel->value) { cl.cam.lerplevel -= LEVEL_SPEED * (cl.cam.lerplevel - cl_worldlevel->value + LEVEL_MIN) * cls.frametime; if (cl.cam.lerplevel < cl_worldlevel->value) cl.cam.lerplevel = cl_worldlevel->value; } } /* clamp speed */ frac = VectorLength(cl.cam.speed) / movespeed; if (frac > 1.0) VectorScale(cl.cam.speed, 1.0 / frac, cl.cam.speed); /* zoom change */ frac = CL_GetKeyMouseState(STATE_ZOOM); if (frac > 0.1) { cl.cam.zoom *= 1.0 + cls.frametime * cl_camzoomspeed->value * frac; /* ensure zoom isn't greater than either MAX_ZOOM or cl_camzoommax */ cl.cam.zoom = std::min(std::min(MAX_ZOOM, cl_camzoommax->value), cl.cam.zoom); } else if (frac < -0.1) { cl.cam.zoom /= 1.0 - cls.frametime * cl_camzoomspeed->value * frac; /* ensure zoom isn't less than either MIN_ZOOM or cl_camzoommin */ cl.cam.zoom = std::max(std::max(MIN_ZOOM, cl_camzoommin->value), cl.cam.zoom); } CL_ViewCalcFieldOfViewX(); /* calc new camera reference and new camera real origin */ VectorMA(cl.cam.origin, cls.frametime, cl.cam.speed, cl.cam.origin); cl.cam.origin[2] = 0.; if (cl_isometric->integer) { CL_ClampCamToMap(72.); VectorMA(cl.cam.origin, -CAMERA_START_DIST + cl.cam.lerplevel * CAMERA_LEVEL_HEIGHT, cl.cam.axis[0], cl.cam.camorg); cl.cam.camorg[2] += CAMERA_START_HEIGHT + cl.cam.lerplevel * CAMERA_LEVEL_HEIGHT; } else { const double border = 144.0 * (cl.cam.zoom - cl_camzoommin->value - 0.4) / cl_camzoommax->value; CL_ClampCamToMap(std::min(border, 86.0)); VectorMA(cl.cam.origin, -CAMERA_START_DIST / cl.cam.zoom , cl.cam.axis[0], cl.cam.camorg); cl.cam.camorg[2] += CAMERA_START_HEIGHT / cl.cam.zoom + cl.cam.lerplevel * CAMERA_LEVEL_HEIGHT; } }