openmohaa/code/cgame/cg_main.c

780 lines
22 KiB
C
Raw Normal View History

2016-03-27 11:49:47 +02:00
/*
===========================================================================
2023-04-30 00:02:16 +02:00
Copyright (C) 2023 the OpenMoHAA team
2016-03-27 11:49:47 +02:00
2023-04-30 00:02:16 +02:00
This file is part of OpenMoHAA source code.
2016-03-27 11:49:47 +02:00
2023-04-30 00:02:16 +02:00
OpenMoHAA source code is free software; you can redistribute it
2016-03-27 11:49:47 +02:00
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
2023-04-30 00:02:16 +02:00
OpenMoHAA source code is distributed in the hope that it will be
2016-03-27 11:49:47 +02:00
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
2023-04-30 00:02:16 +02:00
along with OpenMoHAA source code; if not, write to the Free Software
2016-03-27 11:49:47 +02:00
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
2023-04-30 00:02:16 +02:00
// DESCRIPTION:
// Init functions for the cgame
2016-03-27 11:49:47 +02:00
2023-04-30 00:02:16 +02:00
#include "cg_local.h"
2023-05-01 00:11:26 +02:00
#include "cg_parsemsg.h"
2016-03-27 11:49:47 +02:00
2023-04-30 00:02:16 +02:00
#ifdef _WIN32
#include <windows.h>
2016-03-27 11:49:47 +02:00
#endif
2023-04-30 00:02:16 +02:00
clientGameImport_t cgi;
2023-04-30 01:42:57 +02:00
cvar_t* paused;
cvar_t* developer;
2023-04-30 00:02:16 +02:00
cg_t cg;
cgs_t cgs;
centity_t cg_entities[MAX_GENTITIES];
2023-04-30 01:42:57 +02:00
cvar_t* cg_animSpeed;
cvar_t* cg_debugAnim;
cvar_t* cg_debugAnimWatch;
cvar_t* cg_errorDecay;
cvar_t* cg_nopredict;
cvar_t* cg_showmiss;
cvar_t* cg_addMarks;
cvar_t* cg_maxMarks;
cvar_t* cg_viewsize;
cvar_t* cg_3rd_person;
cvar_t* cg_drawviewmodel;
cvar_t* cg_synchronousClients;
cvar_t* cg_stereoSeparation;
cvar_t* cg_stats;
cvar_t* cg_lagometer;
cvar_t* r_lerpmodels;
cvar_t* cg_cameraheight;
cvar_t* cg_cameradist;
cvar_t* cg_cameraverticaldisplacement;
cvar_t* cg_camerascale;
cvar_t* cg_shadows;
cvar_t* cg_hidetempmodels;
cvar_t* cg_traceinfo;
cvar_t* cg_debugFootsteps;
cvar_t* cg_smoothClients;
cvar_t* cg_smoothClientsTime;
cvar_t* pmove_fixed;
cvar_t* pmove_msec;
cvar_t* cg_pmove_msec;
cvar_t* dm_playermodel;
cvar_t* dm_playergermanmodel;
cvar_t* cg_forceModel;
cvar_t* cg_animationviewmodel;
cvar_t* cg_hitmessages;
cvar_t* cg_acidtrip;
cvar_t* cg_hud;
cvar_t* cg_huddraw_force;
cvar_t* cg_drawsvlag;
cvar_t* vm_offset_max;
cvar_t* vm_offset_speed;
cvar_t* vm_sway_front;
cvar_t* vm_sway_side;
cvar_t* vm_sway_up;
cvar_t* vm_offset_air_front;
cvar_t* vm_offset_air_side;
cvar_t* vm_offset_air_up;
cvar_t* vm_offset_crouch_front;
cvar_t* vm_offset_crouch_side;
cvar_t* vm_offset_crouch_up;
cvar_t* vm_offset_rocketcrouch_front;
cvar_t* vm_offset_rocketcrouch_side;
cvar_t* vm_offset_rocketcrouch_up;
cvar_t* vm_offset_shotguncrouch_front;
cvar_t* vm_offset_shotguncrouch_side;
cvar_t* vm_offset_shotguncrouch_up;
cvar_t* vm_offset_vel_base;
cvar_t* vm_offset_vel_front;
cvar_t* vm_offset_vel_side;
cvar_t* vm_offset_vel_up;
cvar_t* vm_offset_upvel;
cvar_t* vm_lean_lower;
cvar_t* voiceChat;
cvar_t* cg_shadowscount;
cvar_t* cg_shadowdebug;
2016-03-27 11:49:47 +02:00
/*
=================
CG_RegisterCvars
=================
*/
void CG_RegisterCvars(void)
{
cvar_t* temp;
cgi.Cvar_Get("g_subtitle", "0", CVAR_ARCHIVE);
cg_viewsize = cgi.Cvar_Get("viewsize", "100", CVAR_ARCHIVE);
cg_addMarks = cgi.Cvar_Get("cg_marks_add", "0", CVAR_ARCHIVE);
cg_maxMarks = cgi.Cvar_Get("cg_marks_max", "256", CVAR_ARCHIVE | CVAR_LATCH);
cg_animSpeed = cgi.Cvar_Get("cg_animspeed", "1", CVAR_CHEAT);
cg_debugAnim = cgi.Cvar_Get("cg_debuganim", "0", CVAR_CHEAT);
cg_debugAnimWatch = cgi.Cvar_Get("cg_debuganimwatch", "0", CVAR_CHEAT);
cg_errorDecay = cgi.Cvar_Get("cg_errordecay", "100", 0);
cg_nopredict = cgi.Cvar_Get("cg_nopredict", "0", 0);
cg_showmiss = cgi.Cvar_Get("cg_showmiss", "0", 0);
cg_stats = cgi.Cvar_Get("cg_stats", "0", 0);
cg_hidetempmodels = cgi.Cvar_Get("cg_hidetempmodels", "0", 0);
cg_synchronousClients = cgi.Cvar_Get("g_synchronousClients", "0", 0);
cg_stereoSeparation = cgi.Cvar_Get("cg_stereosep", "0.4", CVAR_ARCHIVE);
cg_lagometer = cgi.Cvar_Get("cg_lagometer", "0", 0);
paused = cgi.Cvar_Get("paused", "0", 0);
r_lerpmodels = cgi.Cvar_Get("r_lerpmodels", "1", 0);
cg_3rd_person = cgi.Cvar_Get("cg_3rd_person", "0", CVAR_CHEAT);
cg_drawviewmodel = cgi.Cvar_Get("cg_drawviewmodel", "2", CVAR_ARCHIVE);
cg_cameraheight = cgi.Cvar_Get("cg_cameraheight", "18", CVAR_ARCHIVE);
cg_cameradist = cgi.Cvar_Get("cg_cameradist", "120", CVAR_ARCHIVE);
cg_cameraverticaldisplacement = cgi.Cvar_Get("cg_cameraverticaldisplacement", "-2", CVAR_ARCHIVE);
cg_camerascale = cgi.Cvar_Get("cg_camerascale", "0.3", CVAR_ARCHIVE);
cg_traceinfo = cgi.Cvar_Get("cg_traceinfo", "0", CVAR_ARCHIVE);
cg_debugFootsteps = cgi.Cvar_Get("cg_debugfootsteps", "0", CVAR_CHEAT);
cg_smoothClients = cgi.Cvar_Get("cg_smoothClients", "1", CVAR_ARCHIVE);
cg_smoothClientsTime = cgi.Cvar_Get("cg_smoothClientsTime", "100", CVAR_ARCHIVE);
pmove_fixed = cgi.Cvar_Get("pmove_fixed", "0", 0);
pmove_msec = cgi.Cvar_Get("pmove_msec", "8", 0);
cg_pmove_msec = cgi.Cvar_Get("cg_pmove_msec", "8", 0);
cg_shadows = cgi.Cvar_Get("cg_shadows", "0", CVAR_ARCHIVE);
cg_shadowscount = cgi.Cvar_Get("cg_shadowscount", "8", 0);
cg_shadowdebug = cgi.Cvar_Get("cg_shadowdebug", "0", 0);
developer = cgi.Cvar_Get("developer", "0", 0);
dm_playermodel = cgi.Cvar_Get("dm_playermodel", "american_army", 3);
dm_playergermanmodel = cgi.Cvar_Get("dm_playergermanmodel", "german_wehrmacht_soldier", 3);
cg_forceModel = cgi.Cvar_Get("cg_forceModel", "0", CVAR_ARCHIVE);
cg_animationviewmodel = cgi.Cvar_Get("cg_animationviewmodel", "0", 8);
cg_hitmessages = cgi.Cvar_Get("cg_hitmessages", "1", CVAR_ARCHIVE);
cg_acidtrip = cgi.Cvar_Get("cg_acidtrip", "0", CVAR_CHEAT);
cg_hud = cgi.Cvar_Get("cg_hud", "0", 0);
cg_huddraw_force = cgi.Cvar_Get("cg_huddraw_force", "0", CVAR_SAVEGAME);
cg_drawsvlag = cgi.Cvar_Get("cg_drawsvlag", "1", CVAR_ARCHIVE);
vm_offset_max = cgi.Cvar_Get("vm_offset_max", "8.0", 0);
vm_offset_speed = cgi.Cvar_Get("vm_offset_speed", "8.0", 0);
vm_sway_front = cgi.Cvar_Get("vm_sway_front", "0.1", 0);
vm_sway_side = cgi.Cvar_Get("vm_sway_side", "0.005", 0);
vm_sway_up = cgi.Cvar_Get("vm_sway_up", "0.003", 0);
vm_offset_air_front = cgi.Cvar_Get("vm_offset_air_front", "-3.0", 0);
vm_offset_air_side = cgi.Cvar_Get("vm_offset_air_side", "1.5", 0);
vm_offset_air_up = cgi.Cvar_Get("vm_offset_air_up", "-6.0", 0);
vm_offset_crouch_front = cgi.Cvar_Get("vm_offset_crouch_front", "-0.5", 0);
vm_offset_crouch_side = cgi.Cvar_Get("vm_offset_crouch_side", "2.25", 0);
vm_offset_crouch_up = cgi.Cvar_Get("vm_offset_crouch_up", "0.2", 0);
vm_offset_rocketcrouch_front = cgi.Cvar_Get("vm_offset_rocketcrouch_front", "0", 0);
vm_offset_rocketcrouch_side = cgi.Cvar_Get("vm_offset_rocketcrouch_side", "0", 0);
vm_offset_rocketcrouch_up = cgi.Cvar_Get("vm_offset_rocketcrouch_up", "0", 0);
vm_offset_shotguncrouch_front = cgi.Cvar_Get("vm_offset_shotguncrouch_front", "-1", 0);
vm_offset_shotguncrouch_side = cgi.Cvar_Get("vm_offset_shotguncrouch_side", "2.5", 0);
vm_offset_shotguncrouch_up = cgi.Cvar_Get("vm_offset_shotguncrouch_up", "-1.1", 0);
vm_offset_vel_base = cgi.Cvar_Get("vm_offset_vel_base", "100", 0);
vm_offset_vel_front = cgi.Cvar_Get("vm_offset_vel_front", "-2.0", 0);
vm_offset_vel_side = cgi.Cvar_Get("vm_offset_vel_side", "1.5", 0);
vm_offset_vel_up = cgi.Cvar_Get("vm_offset_vel_up", "-4.0", 0);
vm_offset_upvel = cgi.Cvar_Get("vm_offset_upvel", "0.0025", 0);
vm_lean_lower = cgi.Cvar_Get("vm_lean_lower", "0.1", 0);
voiceChat = cgi.Cvar_Get("cg_voicechat", "1", 0);
// see if we are also running the server on this machine
temp = cgi.Cvar_Get("sv_running", "0", 0);
cgs.localServer = temp->integer;
}
2016-03-27 11:49:47 +02:00
/*
=================
2023-04-30 00:02:16 +02:00
CG_RegisterSounds
called during a precache command
2016-03-27 11:49:47 +02:00
=================
*/
2023-05-01 00:11:26 +02:00
void CG_RegisterSounds( void )
{
int startTime;
int endTime;
char filename[MAX_QPATH];
2023-05-01 00:11:26 +02:00
Com_Printf("\n\n-----------PARSING UBERSOUND------------\n");
Com_Printf(
"Any SetCurrentTiki errors means that tiki wasn't prefetched and "
"tiki-specific sounds for it won't work. To fix prefe"
"tch the tiki. Ignore if you don't use that tiki on this level.\n");
Com_sprintf(filename, sizeof(filename), "ubersound/ubersound.scr");
2023-05-01 00:11:26 +02:00
startTime = cgi.Milliseconds();
CG_Command_ProcessFile(filename, 0, 0);
endTime = cgi.Milliseconds();
Com_Printf("Parse/Load time: %f seconds.\n", (endTime - startTime) / 1000.0f);
2023-05-01 00:11:26 +02:00
Com_Printf("-------------UBERSOUND DONE---------------\n\n");
Com_Printf("\n\n-----------PARSING UBERDIALOG------------\n");
Com_Printf(
"Any SetCurrentTiki errors means that tiki wasn't prefetched and "
"tiki-specific sounds for it won't work. To fix prefe"
"tch the tiki. Ignore if you don't use that tiki on this level.\n");
Com_sprintf(filename, sizeof(filename), "ubersound/uberdialog.scr");
2023-05-01 00:11:26 +02:00
startTime = cgi.Milliseconds();
CG_Command_ProcessFile(filename, 0, 0);
endTime = cgi.Milliseconds() - startTime;
Com_Printf("Parse/Load time: %f seconds.\n", endTime / 1000.0f);
2023-05-01 00:11:26 +02:00
Com_Printf("-------------UBERDIALOG DONE---------------\n\n");
2016-03-27 11:49:47 +02:00
}
/*
================
2023-04-30 00:02:16 +02:00
CG_ProcessConfigString
2016-03-27 11:49:47 +02:00
================
*/
void CG_ProcessConfigString(int num)
{
const char* str = CG_ConfigString(num);
int i;
2016-03-27 11:49:47 +02:00
switch (num)
{
case CS_RAIN_DENSITY:
2023-05-07 17:45:01 +02:00
cg.rain.density = atof(str);
return;
case CS_RAIN_SPEED:
2023-05-07 17:45:01 +02:00
cg.rain.speed = atof(str);
return;
case CS_RAIN_SPEEDVARY:
cg.rain.speed_vary = atoi(str);
return;
case CS_RAIN_SLANT:
cg.rain.slant = atoi(str);
return;
case CS_RAIN_LENGTH:
2023-05-07 17:45:01 +02:00
cg.rain.length = atof(str);
return;
case CS_RAIN_MINDIST:
2023-05-07 17:45:01 +02:00
cg.rain.min_dist = atof(str);
return;
case CS_RAIN_WIDTH:
2023-05-07 17:45:01 +02:00
cg.rain.width = atof(str);
return;
case CS_RAIN_SHADER:
if (cg.rain.numshaders)
{
for (i = 0; i < cg.rain.numshaders; i++)
{
sprintf(cg.rain.shader[i], "%s%i", str, i);
}
}
else {
strcpy(cg.rain.shader[0], str);
}
return;
case CS_RAIN_NUMSHADERS:
cg.rain.numshaders = atoi(str);
if (cg.rain.numshaders)
{
for (i = 0; i < cg.rain.numshaders; i++)
2023-04-30 00:02:16 +02:00
{
sprintf(cg.rain.shader[i], "%s%i", str, i);
2023-04-30 00:02:16 +02:00
}
}
return;
}
if (num >= CS_OBJECTIVES && num < CS_OBJECTIVES + MAX_OBJECTIVES)
{
cobjective_t* objective = &cg.Objectives[num - CS_OBJECTIVES];
objective->flags = atoi(Info_ValueForKey(str, "flags"));
strcpy(objective->text, Info_ValueForKey(str, "text"));
}
switch (num)
{
case CS_MUSIC:
cgi.MUSIC_NewSoundtrack(str);
return;
case CS_WARMUP:
cg.matchStartTime = atoi(str);
return;
case CS_FOGINFO:
sscanf
(
str,
"%d %f %f %f %f",
&cg.farplane_cull,
&cg.farplane_distance,
&cg.farplane_color[0],
&cg.farplane_color[1],
&cg.farplane_color[2]
);
return;
case CS_SKYINFO:
sscanf
(
str,
"%f %d",
&cg.sky_alpha,
&cg.sky_portal
);
return;
case CS_SERVERINFO:
CG_ParseServerinfo();
return;
case CS_LEVEL_START_TIME:
cgs.levelStartTime = atoi(str);
return;
case CS_MATCHEND:
cgs.matchEndTime = atoi(str);
return;
}
if (num >= CS_MODELS && num < CS_MODELS + MAX_MODELS)
{
qhandle_t hOldModel = cgs.model_draw[num - CS_MODELS];
if (str && str[0])
{
qhandle_t hModel = cgi.R_RegisterServerModel(str);
dtiki_t* tiki;
if (hModel != hOldModel)
{
if (hOldModel) {
cgi.R_UnregisterServerModel(hOldModel);
}
cgs.model_draw[num - CS_MODELS] = hModel;
}
tiki = cgi.R_Model_GetHandle(hModel);
if (tiki) {
2023-05-01 00:11:26 +02:00
CG_ProcessCacheInitCommands(tiki);
}
}
else
{
// clear out the model
if (hOldModel) {
cgi.R_UnregisterServerModel(hOldModel);
}
cgs.model_draw[num - CS_MODELS] = 0;
}
}
else if (num >= CS_SOUNDS && num < CS_SOUNDS + MAX_SOUNDS)
{
size_t len = strlen(str);
if (len)
{
qboolean streamed;
char buf[1024];
strcpy(buf, str);
streamed = buf[len - 1] != '0';
buf[len - 1] = 0;
if (buf[0] != '*') {
cgs.sound_precache[num - CS_SOUNDS] = cgi.S_RegisterSound(buf, streamed);
}
}
}
else if (num >= CS_LIGHTSTYLES && num < CS_LIGHTSTYLES + MAX_LIGHTSTYLES)
{
CG_SetLightStyle(num - CS_LIGHTSTYLES, str);
}
}
2016-03-27 11:49:47 +02:00
//===================================================================================
/*
=================
2023-04-30 00:02:16 +02:00
CG_PrepRefresh
2016-03-27 11:49:47 +02:00
2023-04-30 00:02:16 +02:00
Call before entering a new level, or after changing renderers
2016-03-27 11:49:47 +02:00
This function may execute for a couple of minutes with a slow disk.
=================
*/
2023-04-30 00:02:16 +02:00
void CG_PrepRefresh( void )
{
int i;
memset(&cg.refdef, 0, sizeof(cg.refdef));
cgi.R_LoadWorldMap(cgs.mapname);
// register the inline models
cgs.numInlineModels = cgi.CM_NumInlineModels();
for (i = 1; i < cgs.numInlineModels; i++)
{
char name[10];
vec3_t mins, maxs;
int j;
Com_sprintf(name, sizeof(name), "*%i", i);
cgs.inlineDrawModel[i] = cgi.R_RegisterModel(name);
cgi.R_ModelBounds(cgs.inlineDrawModel[i], mins, maxs);
for (j = 0; j < 3; j++)
{
cgs.inlineModelMidpoints[i][j] = mins[j] + 0.5 * (maxs[j] - mins[j]);
}
}
// register media shaders
cgs.media.shadowMarkShader = cgi.R_RegisterShader("markShadow");
cgs.media.footShadowMarkShader = cgi.R_RegisterShader("footShadow");
cgs.media.wakeMarkShader = cgi.R_RegisterShader("ripple.spr");
cgs.media.lagometerShader = cgi.R_RegisterShaderNoMip("gfx/2d/blank");
cgs.media.levelExitShader = cgi.R_RegisterShaderNoMip("textures/menu/exit");
cgs.media.pausedShader = cgi.R_RegisterShaderNoMip("textures/menu/paused");
cgs.media.backTileShader = cgi.R_RegisterShader("gfx/2d/backtile");
cgs.media.zoomOverlayShader = cgi.R_RegisterShaderNoMip("textures/hud/zoomoverlay");
cgs.media.kar98TopOverlayShader = cgi.R_RegisterShaderNoMip("textures/hud/kartop.tga");
cgs.media.kar98BottomOverlayShader = cgi.R_RegisterShaderNoMip("textures/hud/karbottom.tga");
cgs.media.binocularsOverlayShader = cgi.R_RegisterShaderNoMip("textures/hud/binocularsoverlay");
cgs.media.hudDrawFont = cgi.R_LoadFont("verdana-14");
cgs.media.attackerFont = cgi.R_LoadFont("facfont-20");
cgs.media.objectiveFont = cgi.R_LoadFont("courier-16");
cgs.media.objectivesBackShader = cgi.R_RegisterShaderNoMip("textures/hud/objectives_backdrop");
cgs.media.checkedBoxShader = cgi.R_RegisterShaderNoMip("textures/objectives/filledbox");
cgs.media.uncheckedBoxShader = cgi.R_RegisterShaderNoMip("textures/objectives/emptybox");
// go through all the configstrings and process them
for (i = CS_SYSTEMINFO + 1; i < MAX_CONFIGSTRINGS; i++)
{
CG_ProcessConfigString(i);
}
}
2016-03-27 11:49:47 +02:00
//===========================================================================
/*
=================
CG_ConfigString
=================
*/
const char *CG_ConfigString( int index ) {
if ( index < 0 || index >= MAX_CONFIGSTRINGS ) {
2023-04-30 00:02:16 +02:00
cgi.Error( ERR_DROP, "CG_ConfigString: bad index: %i", index );
2016-03-27 11:49:47 +02:00
}
return cgs.gameState.stringData + cgs.gameState.stringOffsets[ index ];
}
//==================================================================
void CG_GetRendererConfig(void)
{
// get the rendering configuration from the client system
cgi.GetGlconfig(&cgs.glconfig);
cgs.screenXScale = cgs.glconfig.vidWidth / 640.0;
cgs.screenYScale = cgs.glconfig.vidHeight / 480.0;
}
2016-03-27 11:49:47 +02:00
/*
2023-04-30 00:02:16 +02:00
======================
CG_GameStateReceived
2016-03-27 11:49:47 +02:00
2023-04-30 00:02:16 +02:00
Displays the info screen while loading media
======================
2016-03-27 11:49:47 +02:00
*/
2023-04-30 00:02:16 +02:00
void CG_GameStateReceived( void )
{
const char* s;
2016-03-27 11:49:47 +02:00
// clear everything
memset(&cg, 0, sizeof(cg));
memset(cg_entities, 0, sizeof(cg_entities));
2016-03-27 11:49:47 +02:00
// clear the light styles
CG_ClearLightStyles();
2016-03-27 11:49:47 +02:00
// get the rendering configuration from the client system
CG_GetRendererConfig();
2016-03-27 11:49:47 +02:00
// get the gamestate from the client system
cgi.GetGameState(&cgs.gameState);
2016-03-27 11:49:47 +02:00
// check version
s = CG_ConfigString(CS_GAME_VERSION);
if (strcmp(s, GAME_VERSION)) {
cgi.Error(ERR_DROP, "Client/Server game mismatch: %s/%s", GAME_VERSION, s);
}
s = CG_ConfigString(CS_LEVEL_START_TIME);
cgs.levelStartTime = atoi(s);
2016-03-27 11:49:47 +02:00
CG_ParseServerinfo();
2016-03-27 11:49:47 +02:00
// load the new map
cgi.CM_LoadMap(cgs.mapname);
2016-03-27 11:49:47 +02:00
CG_InitMarks();
2016-03-27 11:49:47 +02:00
CG_RegisterSounds();
2023-04-30 00:02:16 +02:00
CG_PrepRefresh();
2016-03-27 11:49:47 +02:00
CG_InitializeSpecialEffectsManager();
CG_InitializeObjectives();
}
2016-03-27 11:49:47 +02:00
2023-04-30 00:02:16 +02:00
/*
======================
CG_ServerRestarted
2016-03-27 11:49:47 +02:00
2023-04-30 00:02:16 +02:00
The server has beeen restarted, adjust our cgame data accordingly
======================
*/
void CG_ServerRestarted( void )
{
const char* s;
s = CG_ConfigString(CS_LEVEL_START_TIME);
cgs.levelStartTime = atoi(s);
CG_ParseServerinfo();
cg.thisFrameTeleport = qtrue;
// free up any temp models currently spawned
CG_RestartCommandManager();
// get rid of left over decals from the last game
CG_InitMarks();
// clear all the swipes
CG_ClearSwipes();
// Reset tempmodels
CG_ResetTempModels();
// Reset resources
CG_ResetVSSSources();
// Reset objectives
CG_InitializeObjectives();
}
2023-04-30 00:02:16 +02:00
void* CG_Malloc(int size)
{
return malloc(size);
}
void CG_Free(void *ptr)
{
free(ptr);
}
2023-04-30 00:02:16 +02:00
/*
=================
CG_Init
2016-03-27 11:49:47 +02:00
2023-04-30 00:02:16 +02:00
Called after every level change or subsystem restart
=================
*/
void CG_Init(clientGameImport_t* imported, int serverMessageNum,
int serverCommandSequence, int clientNum)
{
cgi = *imported;
#if _DEBUG
cgi.Malloc = &CG_Malloc;
cgi.Free = &CG_Free;
#endif
2016-03-27 11:49:47 +02:00
memset(&cg, 0, sizeof(cg));
memset(&cgs, 0, sizeof(cgs));
cg.clientNum = clientNum;
cgs.processedSnapshotNum = serverMessageNum;
cgs.serverCommandSequence = serverCommandSequence;
CG_RegisterCvars();
2016-03-27 11:49:47 +02:00
L_InitEvents();
2016-03-27 11:49:47 +02:00
// init swapping for endian conversion
Swap_Init();
2016-03-27 11:49:47 +02:00
CG_InitializeCommandManager();
2016-03-27 11:49:47 +02:00
CG_GameStateReceived();
2016-03-27 11:49:47 +02:00
CG_InitConsoleCommands();
2016-03-27 11:49:47 +02:00
cg.vEyeOffsetMax[0] = 40.0f;
cg.vEyeOffsetMax[1] = 45.0f;
cg.vEyeOffsetMax[2] = 60.0f;
cg.fEyeOffsetFrac = 0.1f;
cg.fCurrentViewHeight = 0.0f;
cg.fCurrentViewBobPhase = 0.0f;
cg.fCurrentViewBobAmp = 0.0f;
cg.pLastPlayerWorldModel = NULL;
cg.pPlayerFPSModel = NULL;
cg.hPlayerFPSModelHandle = 0;
cg.pAlliedPlayerModel = NULL;
cg.hAlliedPlayerModelHandle = 0;
cg.pAxisPlayerModel = NULL;
cg.hAxisPlayerModelHandle = 0;
cg.bFPSOnGround = qtrue;
2023-04-30 00:02:16 +02:00
// Pop the stats UI screen menu
cgi.UI_HideMenu("StatsScreen", 1);
2023-04-30 00:02:16 +02:00
// Scoreboard setup
CG_PrepScoreBoardInfo();
cgi.UI_HideScoreBoard();
// HUD setup
CG_RefreshHudDrawElements();
cgi.Cmd_Execute(EXEC_NOW, "ui_hud 1\n");
}
2016-03-27 11:49:47 +02:00
/*
=================
CG_Shutdown
Called before every level change or subsystem restart
=================
*/
void CG_Shutdown(void)
{
L_ShutdownEvents();
// some mods may need to do cleanup work here,
// like closing files or archiving session data
// hide the stats screen
cgi.UI_HideMenu("StatsScreen", 1);
// reset the scoreboard
CG_PrepScoreBoardInfo();
cgi.UI_HideScoreBoard();
}
2023-04-30 00:02:16 +02:00
2023-05-01 00:11:26 +02:00
int CG_GetParent(int entnum)
{
return cg_entities[entnum].currentState.parent;
}
float CG_GetObjectiveAlpha()
{
return cg.ObjectivesCurrentAlpha;
}
2016-03-27 11:49:47 +02:00
/*
================
GetCGameAPI
2023-04-30 00:02:16 +02:00
The only exported function from this module
2016-03-27 11:49:47 +02:00
================
*/
2023-04-30 23:29:21 +02:00
clientGameExport_t *GetCGameAPI(void)
{
static clientGameExport_t cge;
2016-03-27 11:49:47 +02:00
2023-04-30 23:29:21 +02:00
cge.CG_Init = CG_Init;
cge.CG_DrawActiveFrame = CG_DrawActiveFrame;
cge.CG_Shutdown = CG_Shutdown;
cge.CG_ConsoleCommand = CG_ConsoleCommand;
2023-04-30 00:02:16 +02:00
cge.CG_GetRendererConfig = CG_GetRendererConfig;
2023-04-30 23:29:21 +02:00
cge.CG_Draw2D = CG_Draw2D;
2023-05-01 00:11:26 +02:00
cge.CG_EyePosition = CG_EyePosition;
cge.CG_EyeOffset = CG_EyeOffset;
cge.CG_EyeAngles = CG_EyeAngles;
cge.CG_SensitivityScale = CG_SensitivityScale;
cge.CG_ParseCGMessage = CG_ParseCGMessage;
cge.CG_RefreshHudDrawElements = CG_RefreshHudDrawElements;
cge.CG_HudDrawShader = CG_HudDrawShader;
cge.CG_HudDrawFont = CG_HudDrawFont;
cge.CG_PermanentMark = CG_PermanentMark;
cge.CG_PermanentTreadMarkDecal = CG_PermanentTreadMarkDecal;
cge.CG_PermanentUpdateTreadMark = CG_PermanentUpdateTreadMark;
cge.CG_Command_ProcessFile = CG_Command_ProcessFile;
cge.CG_ProcessInitCommands = CG_ProcessInitCommands;
cge.CG_EndTiki = CG_EndTiki;
cge.CG_GetParent = CG_GetParent;
cge.CG_GetObjectiveAlpha = CG_GetObjectiveAlpha;
cge.CG_GetColumnName = CG_GetColumnName;
cge.CG_GetScoreBoardColor = CG_GetScoreBoardColor;
cge.CG_GetScoreBoardFontColor = CG_GetScoreBoardFontColor;
cge.CG_GetScoreBoardPosition = CG_GetScoreBoardPosition;
cge.CG_GetScoreBoardDrawHeader = CG_GetScoreBoardDrawHeader;
cge.CG_WeaponCommandButtonBits = CG_WeaponCommandButtonBits;
cge.CG_CheckCaptureKey = CG_CheckCaptureKey;
// FIXME
//cge.profStruct = NULL;
2016-03-27 11:49:47 +02:00
2023-04-30 23:29:21 +02:00
return &cge;
}
2016-03-27 11:49:47 +02:00
/*
2023-04-30 00:02:16 +02:00
=====================
CG_DrawActive
2016-03-27 11:49:47 +02:00
2023-04-30 00:02:16 +02:00
Perform all drawing needed to completely fill the screen
=====================
2016-03-27 11:49:47 +02:00
*/
void CG_DrawActive(stereoFrame_t stereoView)
{
float separation;
vec3_t baseOrg;
switch (stereoView) {
case STEREO_CENTER:
separation = 0;
break;
case STEREO_LEFT:
separation = -cg_stereoSeparation->value / 2;
break;
case STEREO_RIGHT:
separation = cg_stereoSeparation->value / 2;
break;
default:
separation = 0;
cgi.Error(ERR_DROP, "CG_DrawActive: Undefined stereoView");
}
// clear around the rendered view if sized down
CG_TileClear();
// offset vieworg appropriately if we're doing stereo separation
VectorCopy(cg.refdef.vieworg, baseOrg);
if (separation != 0) {
VectorMA(cg.refdef.vieworg, -separation, cg.refdef.viewaxis[1],
cg.refdef.vieworg);
}
// draw 3D view
cgi.R_RenderScene(&cg.refdef);
// restore original viewpoint if running stereo
if (separation != 0) {
VectorCopy(baseOrg, cg.refdef.vieworg);
}
}
2023-04-30 00:02:16 +02:00
#ifndef CGAME_HARD_LINKED
// this is only here so the functions in q_shared.c and bg_*.c can link (FIXME)
void Com_Error( int level, const char *error, ... ) {
va_list argptr;
char text[1024];
2016-03-27 11:49:47 +02:00
2023-04-30 00:02:16 +02:00
va_start (argptr, error);
vsprintf (text, error, argptr);
va_end (argptr);
2016-03-27 11:49:47 +02:00
2023-04-30 00:02:16 +02:00
cgi.Error( level, "%s", text);
2016-03-27 11:49:47 +02:00
}
2023-04-30 00:02:16 +02:00
void Com_Printf( const char *msg, ... ) {
va_list argptr;
char text[1024];
2016-03-27 11:49:47 +02:00
2023-04-30 00:02:16 +02:00
va_start (argptr, msg);
vsprintf (text, msg, argptr);
va_end (argptr);
2016-03-27 11:49:47 +02:00
2023-04-30 00:02:16 +02:00
cgi.Printf( "%s", text);
2016-03-27 11:49:47 +02:00
}
2023-04-30 00:02:16 +02:00
#endif
2016-03-27 11:49:47 +02:00