mirror of
https://github.com/bearstonem/openmohaa-vr.git
synced 2026-10-17 22:00:21 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93e56d968e | ||
|
|
b4e22d3040 | ||
|
|
351f601986 | ||
|
|
41fdd28d8b | ||
|
|
d7c6cc0157 | ||
|
|
f1b83f1dab | ||
|
|
bb401d8d3c | ||
|
|
8bb9cd46f8 | ||
|
|
c27695247e | ||
|
|
7b9835a118 | ||
|
|
2dc75b7527 | ||
|
|
6c577a7251 | ||
|
|
5031402c2c | ||
|
|
a4bd37af8c | ||
|
|
4dc60b9aa4 | ||
|
|
ce89399824 | ||
|
|
b92d2972f6 | ||
|
|
f53680983b | ||
|
|
d6fd337a07 | ||
|
|
95230a8d0a | ||
|
|
04524e9de9 | ||
|
|
df4f6f9515 | ||
|
|
e9c7a1f959 | ||
|
|
c4502469f4 | ||
|
|
c2cb15a1d1 | ||
|
|
4d108a272f | ||
|
|
f523c32044 | ||
|
|
5ac5632e59 | ||
|
|
80f3296854 | ||
|
|
1b1433dd1b | ||
|
|
7647bbaf36 | ||
|
|
f00fd281b3 | ||
|
|
b5ea1ddb53 | ||
|
|
b16ce90be3 | ||
|
|
4c0f7a34de | ||
|
|
2e11cd4ea2 | ||
|
|
c2ad608508 | ||
|
|
5ec8c901e2 | ||
|
|
e6bbbdb79e | ||
|
|
f5fa8d15d1 | ||
|
|
7aee02ba8d | ||
|
|
cf51e14cf5 | ||
|
|
7fb383c810 | ||
|
|
34f66963e3 | ||
|
|
6059063b67 | ||
|
|
8bf57017ac | ||
|
|
9f1d35a11b | ||
|
|
aa51987077 | ||
|
|
64055d2580 | ||
|
|
45e82c590e | ||
|
|
0c92890ef2 | ||
|
|
03e8a64283 | ||
|
|
4e14535f08 | ||
|
|
356e7c51fc | ||
|
|
52a146d664 |
No files matched your search
@@ -70,7 +70,7 @@ These are the tools required for all platforms :
|
||||
|
||||
The installation directory can be set to MOHAA directory.
|
||||
|
||||
The client build and successfully be built by adding `-DWITH_CLIENT=1` to the CMake command line.
|
||||
The client build can be built by adding `-DWITH_CLIENT=1` to the CMake command line. This will compile the cgame module and the full app with rendering, ui and sound suppport, alongside the dedicated server version.
|
||||
|
||||
### Linux
|
||||
|
||||
@@ -85,6 +85,11 @@ These are the tools required on Unix :
|
||||
|
||||
Visual Studio (2019 or 2022) is generally preferred.
|
||||
|
||||
## Screenshots
|
||||
|
||||

|
||||

|
||||
|
||||
## Third party
|
||||
|
||||
### SDL
|
||||
@@ -121,8 +126,8 @@ https://xiph.org/vorbis/
|
||||
|
||||
https://opus-codec.org/
|
||||
|
||||
## URL
|
||||
## URLs and communities
|
||||
|
||||
- https://openmohaa.sourceforge.net/
|
||||
- https://github.com/openmoh/openmohaa/
|
||||
- https://mohaaaa.co.uk/AAAAMOHAA/index.php
|
||||
- https://x-null.net/
|
||||
|
||||
+177
-34
@@ -1795,6 +1795,10 @@ void ClientGameCommandManager::SetAlignStretch(Event* ev)
|
||||
void ClientGameCommandManager::SetDecalRadius(Event* ev)
|
||||
|
||||
{
|
||||
if (!m_spawnthing) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_spawnthing->cgd.decal_radius = ev->GetFloat(1);
|
||||
}
|
||||
|
||||
@@ -1806,6 +1810,10 @@ void ClientGameCommandManager::SetDecalOrientation(Event* ev)
|
||||
{
|
||||
str deg;
|
||||
|
||||
if (!m_spawnthing) {
|
||||
return;
|
||||
}
|
||||
|
||||
deg = ev->GetString(1);
|
||||
|
||||
if (!deg.icmp("random")) {
|
||||
@@ -1820,6 +1828,10 @@ void ClientGameCommandManager::SetDecalOrientation(Event* ev)
|
||||
//===============
|
||||
void ClientGameCommandManager::SetBounceDecal(Event* ev)
|
||||
{
|
||||
if (!m_spawnthing) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_spawnthing->cgd.flags2 |= T2_BOUNCE_DECAL;
|
||||
if (ev->NumArgs() > 1) {
|
||||
m_spawnthing->cgd.maxbouncecount = ev->GetInteger(1);
|
||||
@@ -1837,8 +1849,11 @@ void ClientGameCommandManager::SetBounceDecal(Event* ev)
|
||||
// SetParallel
|
||||
//===============
|
||||
void ClientGameCommandManager::SetParallel(Event* ev)
|
||||
|
||||
{
|
||||
if (!m_spawnthing) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_spawnthing->cgd.flags2 |= T2_PARALLEL;
|
||||
}
|
||||
|
||||
@@ -1846,10 +1861,13 @@ void ClientGameCommandManager::SetParallel(Event* ev)
|
||||
// PhysicsRate
|
||||
//===============
|
||||
void ClientGameCommandManager::SetPhysicsRate(Event* ev)
|
||||
|
||||
{
|
||||
str rate;
|
||||
|
||||
if (!m_spawnthing) {
|
||||
return;
|
||||
}
|
||||
|
||||
rate = ev->GetString(1);
|
||||
|
||||
if (!rate.icmp(rate, "every")) {
|
||||
@@ -1863,8 +1881,11 @@ void ClientGameCommandManager::SetPhysicsRate(Event* ev)
|
||||
// SetLightstyle
|
||||
//===============
|
||||
void ClientGameCommandManager::SetLightstyle(Event* ev)
|
||||
|
||||
{
|
||||
if (!m_spawnthing) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_spawnthing->cgd.lightstyle = CG_RegisterLightStyle(ev->GetString(1));
|
||||
}
|
||||
|
||||
@@ -1872,8 +1893,11 @@ void ClientGameCommandManager::SetLightstyle(Event* ev)
|
||||
// SetBeamSphere
|
||||
//===============
|
||||
void ClientGameCommandManager::SetBeamSphere(Event* ev)
|
||||
|
||||
{
|
||||
if (!m_spawnthing) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_spawnthing->numspherebeams = ev->GetInteger(1);
|
||||
m_spawnthing->beamflags = BEAM_SPHERE_EFFECT;
|
||||
}
|
||||
@@ -1882,8 +1906,11 @@ void ClientGameCommandManager::SetBeamSphere(Event* ev)
|
||||
// SetBeamSpread
|
||||
//===============
|
||||
void ClientGameCommandManager::SetSpread(Event* ev)
|
||||
|
||||
{
|
||||
if (!m_spawnthing) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_spawnthing->spreadx = ev->GetFloat(1);
|
||||
m_spawnthing->spready = ev->GetFloat(2);
|
||||
}
|
||||
@@ -1892,8 +1919,11 @@ void ClientGameCommandManager::SetSpread(Event* ev)
|
||||
// SetUseLastTraceEnd
|
||||
//===============
|
||||
void ClientGameCommandManager::SetUseLastTraceEnd(Event* ev)
|
||||
|
||||
{
|
||||
if (!m_spawnthing) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_spawnthing->use_last_trace_end = qtrue;
|
||||
}
|
||||
|
||||
@@ -1901,8 +1931,11 @@ void ClientGameCommandManager::SetUseLastTraceEnd(Event* ev)
|
||||
// SetSubdivisions
|
||||
//===============
|
||||
void ClientGameCommandManager::SetSubdivisions(Event* ev)
|
||||
|
||||
{
|
||||
if (!m_spawnthing) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_spawnthing->numSubdivisions = ev->GetInteger(1);
|
||||
}
|
||||
|
||||
@@ -1910,8 +1943,11 @@ void ClientGameCommandManager::SetSubdivisions(Event* ev)
|
||||
// SetBeamPersist
|
||||
//===============
|
||||
void ClientGameCommandManager::SetBeamPersist(Event* ev)
|
||||
|
||||
{
|
||||
if (!m_spawnthing) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_spawnthing->beamflags |= BEAM_PERSIST_EFFECT;
|
||||
}
|
||||
|
||||
@@ -1919,8 +1955,11 @@ void ClientGameCommandManager::SetBeamPersist(Event* ev)
|
||||
// SetBeamOffsetEndponts
|
||||
//===============
|
||||
void ClientGameCommandManager::SetBeamOffsetEndpoints(Event* ev)
|
||||
|
||||
{
|
||||
if (!m_spawnthing) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_spawnthing->beamflags |= BEAM_OFFSET_ENDPOINTS;
|
||||
}
|
||||
|
||||
@@ -1928,8 +1967,11 @@ void ClientGameCommandManager::SetBeamOffsetEndpoints(Event* ev)
|
||||
// SetBeamDelay
|
||||
//===============
|
||||
void ClientGameCommandManager::SetBeamDelay(Event* ev)
|
||||
|
||||
{
|
||||
if (!m_spawnthing) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ev->NumArgs() > 1) {
|
||||
str r = ev->GetString(1);
|
||||
if (r.icmp("random")) {
|
||||
@@ -1945,8 +1987,11 @@ void ClientGameCommandManager::SetBeamDelay(Event* ev)
|
||||
// SetBeamToggleDelay
|
||||
//===============
|
||||
void ClientGameCommandManager::SetBeamToggleDelay(Event* ev)
|
||||
|
||||
{
|
||||
if (!m_spawnthing) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_spawnthing->beamflags |= BEAM_TOGGLE;
|
||||
if (ev->NumArgs() > 1) {
|
||||
str r = ev->GetString(1);
|
||||
@@ -1964,8 +2009,11 @@ void ClientGameCommandManager::SetBeamToggleDelay(Event* ev)
|
||||
// SetBeamLength
|
||||
//===============
|
||||
void ClientGameCommandManager::SetLength(Event* ev)
|
||||
|
||||
{
|
||||
if (!m_spawnthing) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_spawnthing->length = ev->GetFloat(1);
|
||||
}
|
||||
|
||||
@@ -1973,8 +2021,11 @@ void ClientGameCommandManager::SetLength(Event* ev)
|
||||
// SetShader
|
||||
//===============
|
||||
void ClientGameCommandManager::SetShader(Event* ev)
|
||||
|
||||
{
|
||||
if (!m_spawnthing) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_spawnthing->cgd.shadername = ev->GetString(1);
|
||||
}
|
||||
|
||||
@@ -1982,8 +2033,11 @@ void ClientGameCommandManager::SetShader(Event* ev)
|
||||
// SetMinOffset
|
||||
//===============
|
||||
void ClientGameCommandManager::SetMinOffset(Event* ev)
|
||||
|
||||
{
|
||||
if (!m_spawnthing) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_spawnthing->min_offset = ev->GetInteger(1);
|
||||
}
|
||||
|
||||
@@ -1991,8 +2045,11 @@ void ClientGameCommandManager::SetMinOffset(Event* ev)
|
||||
// SetSubdivisions
|
||||
//===============
|
||||
void ClientGameCommandManager::SetMaxOffset(Event* ev)
|
||||
|
||||
{
|
||||
if (!m_spawnthing) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_spawnthing->max_offset = ev->GetInteger(1);
|
||||
}
|
||||
|
||||
@@ -2000,8 +2057,11 @@ void ClientGameCommandManager::SetMaxOffset(Event* ev)
|
||||
// SetAnim
|
||||
//===============
|
||||
void ClientGameCommandManager::SetAnim(Event* ev)
|
||||
|
||||
{
|
||||
if (!m_spawnthing) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_spawnthing->animName = ev->GetString(1);
|
||||
}
|
||||
|
||||
@@ -2009,8 +2069,11 @@ void ClientGameCommandManager::SetAnim(Event* ev)
|
||||
// AnimateOnce
|
||||
//===============
|
||||
void ClientGameCommandManager::AnimateOnce(Event* ev)
|
||||
|
||||
{
|
||||
if (!m_spawnthing) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_spawnthing->cgd.flags |= T_ANIMATEONCE;
|
||||
}
|
||||
|
||||
@@ -2018,8 +2081,11 @@ void ClientGameCommandManager::AnimateOnce(Event* ev)
|
||||
// EmitterStartOff
|
||||
//===============
|
||||
void ClientGameCommandManager::EmitterStartOff(Event* ev)
|
||||
|
||||
{
|
||||
if (!m_spawnthing) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_spawnthing->startoff = qtrue;
|
||||
}
|
||||
|
||||
@@ -5160,10 +5226,37 @@ void AliasResource(dtiki_t* pmdl, const char* alias, const char* realname,
|
||||
}
|
||||
}
|
||||
|
||||
int bLoadForMap__FPCcT0(char* psMapsBuffer, char* name)
|
||||
qboolean bLoadForMap(const char* psMapsBuffer, const char* name)
|
||||
{
|
||||
// FIXME: stub
|
||||
return 0;
|
||||
const char* token;
|
||||
const char* mapname;
|
||||
const char* override;
|
||||
|
||||
mapname = cgs.mapname;
|
||||
if (!strncmp("test", mapname, strlen("test"))) {
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
token = COM_GetToken((char**)&psMapsBuffer, qtrue);
|
||||
override = token;
|
||||
if (token && *token)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
if (!Q_stricmpn(token, mapname, strlen(token)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
token = COM_GetToken((char**)&psMapsBuffer, qtrue);
|
||||
if (!token || !token[0]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Com_Printf("ERROR bLoadForMap: %s alias with empty maps specification.\n", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
//===============
|
||||
@@ -5173,8 +5266,9 @@ void ClientGameCommandManager::AliasCache(Event* ev)
|
||||
|
||||
{
|
||||
int i;
|
||||
char parmbuffer[512]; // this holds the parameters to be passed into the
|
||||
char parmbuffer[2048]; // this holds the parameters to be passed into the
|
||||
// alias command
|
||||
const char* psMapsBuffer;
|
||||
|
||||
if (ev->NumArgs() < 2) {
|
||||
return;
|
||||
@@ -5185,14 +5279,23 @@ void ClientGameCommandManager::AliasCache(Event* ev)
|
||||
// any additional parameters are in arguments 3-n
|
||||
|
||||
parmbuffer[0] = 0;
|
||||
psMapsBuffer = NULL;
|
||||
|
||||
for (i = 3; i <= ev->NumArgs(); i++) {
|
||||
strcat(parmbuffer, ev->GetToken(i));
|
||||
strcat(parmbuffer, " ");
|
||||
if (strcmp(ev->GetToken(i).c_str(), "maps")) {
|
||||
strcat(parmbuffer, ev->GetToken(i));
|
||||
strcat(parmbuffer, " ");
|
||||
}
|
||||
else {
|
||||
psMapsBuffer = ev->GetToken(i++);
|
||||
}
|
||||
}
|
||||
|
||||
AliasResource(current_tiki, ev->GetString(1), ev->GetString(2), parmbuffer);
|
||||
CacheResource(ev->GetString(2));
|
||||
if (bLoadForMap(psMapsBuffer, ev->GetString(1)))
|
||||
{
|
||||
AliasResource(current_tiki, ev->GetString(1), ev->GetString(2), parmbuffer);
|
||||
CacheResource(ev->GetString(2));
|
||||
}
|
||||
}
|
||||
|
||||
//===============
|
||||
@@ -5202,8 +5305,10 @@ void ClientGameCommandManager::Alias(Event* ev)
|
||||
|
||||
{
|
||||
int i;
|
||||
char parmbuffer[512]; // this holds the parameters to be passed into the
|
||||
char parmbuffer[2048]; // this holds the parameters to be passed into the
|
||||
// alias command
|
||||
qboolean subtitle;
|
||||
const char* psMapsBuffer;
|
||||
|
||||
if (ev->NumArgs() < 2) {
|
||||
return;
|
||||
@@ -5213,14 +5318,43 @@ void ClientGameCommandManager::Alias(Event* ev)
|
||||
// real path is argument 2
|
||||
// any additional parameters are in arguments 3-n
|
||||
|
||||
parmbuffer[0] = 0;
|
||||
parmbuffer[0] = 0;
|
||||
subtitle = qfalse;
|
||||
psMapsBuffer = NULL;
|
||||
|
||||
for (i = 3; i <= ev->NumArgs(); i++) {
|
||||
strcat(parmbuffer, ev->GetToken(i));
|
||||
strcat(parmbuffer, " ");
|
||||
}
|
||||
for (i = 3; i <= ev->NumArgs(); i++)
|
||||
{
|
||||
if (strcmp(ev->GetToken(i).c_str(), "maps"))
|
||||
{
|
||||
if (!subtitle)
|
||||
{
|
||||
if (!Q_stricmp(ev->GetToken(i), "subtitle")) {
|
||||
subtitle = qtrue;
|
||||
strcat(parmbuffer, ev->GetToken(i));
|
||||
}
|
||||
else {
|
||||
strcat(parmbuffer, ev->GetToken(i));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strcat(parmbuffer, "\"");
|
||||
strcat(parmbuffer, ev->GetToken(i));
|
||||
strcat(parmbuffer, "\"");
|
||||
subtitle = qfalse;
|
||||
}
|
||||
|
||||
AliasResource(current_tiki, ev->GetString(1), ev->GetString(2), parmbuffer);
|
||||
strcat(parmbuffer, " ");
|
||||
}
|
||||
else {
|
||||
psMapsBuffer = ev->GetToken(i++);
|
||||
}
|
||||
}
|
||||
|
||||
if (bLoadForMap(psMapsBuffer, ev->GetString(1)))
|
||||
{
|
||||
AliasResource(current_tiki, ev->GetString(1), ev->GetString(2), parmbuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void CacheAliasList(AliasList_t* alias_list, str& name)
|
||||
@@ -6363,6 +6497,7 @@ qboolean CG_Command_ProcessFile(const char* filename, qboolean quiet, dtiki_t *c
|
||||
char* buffer;
|
||||
const char* bufstart;
|
||||
char com_token[MAX_STRING_CHARS];
|
||||
char tempName[MAX_QPATH + 1];
|
||||
|
||||
if (cgi.FS_ReadFile(filename, (void**)&buffer, quiet) == -1) {
|
||||
return qfalse;
|
||||
@@ -6375,6 +6510,10 @@ qboolean CG_Command_ProcessFile(const char* filename, qboolean quiet, dtiki_t *c
|
||||
// we are not setting up for a tiki
|
||||
current_tiki = NULL;
|
||||
|
||||
// Update the loading screen
|
||||
sprintf(tempName, "m%s", filename);
|
||||
cgi.LoadResource(tempName);
|
||||
|
||||
bufstart = buffer;
|
||||
|
||||
while (1) {
|
||||
@@ -6409,10 +6548,14 @@ qboolean CG_Command_ProcessFile(const char* filename, qboolean quiet, dtiki_t *c
|
||||
|
||||
ev->AddToken(com_token);
|
||||
}
|
||||
commandManager.ProcessEvent(ev);
|
||||
commandManager.SelectProcessEvent(ev);
|
||||
}
|
||||
cgi.FS_FreeFile((void*)bufstart);
|
||||
|
||||
// Update the loading screen
|
||||
sprintf(tempName, "o%s", filename);
|
||||
cgi.LoadResource(tempName);
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
|
||||
@@ -558,8 +558,7 @@ int CG_WeaponCommandButtonBits(void)
|
||||
{
|
||||
int iShiftedWeaponCommand;
|
||||
|
||||
iShiftedWeaponCommand = cg.iWeaponCommand;
|
||||
if (!iShiftedWeaponCommand) {
|
||||
if (!cg.iWeaponCommand) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -568,5 +567,6 @@ int CG_WeaponCommandButtonBits(void)
|
||||
cg.iWeaponCommand = 0;
|
||||
}
|
||||
|
||||
return (iShiftedWeaponCommand << 7) & WEAPON_COMMAND_MASK;
|
||||
iShiftedWeaponCommand = cg.iWeaponCommand << 7;
|
||||
return iShiftedWeaponCommand & WEAPON_COMMAND_MASK;
|
||||
}
|
||||
+30
-14
@@ -414,6 +414,25 @@ void CG_Portal(centity_t* cent)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
BG_EvaluateTrajectory
|
||||
================
|
||||
*/
|
||||
void BG_EvaluateTrajectory(const trajectory_t* tr, int atTime, const vec3_t base, vec3_t result) {
|
||||
float deltaTime;
|
||||
|
||||
if (atTime > cg_smoothClientsTime->integer + tr->trTime) {
|
||||
atTime = cg_smoothClientsTime->integer + tr->trTime;
|
||||
}
|
||||
|
||||
deltaTime = (float)(atTime - tr->trTime) / 1000.0;
|
||||
|
||||
result[0] = tr->trDelta[0] * deltaTime + base[0];
|
||||
result[1] = tr->trDelta[1] * deltaTime + base[1];
|
||||
result[2] = tr->trDelta[2] * deltaTime + base[2];
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CG_CalcEntityLerpPositions
|
||||
@@ -477,8 +496,8 @@ void CG_CalcEntityLerpPositions( centity_t *cent )
|
||||
|
||||
// this will linearize a sine or parabolic curve, but it is important
|
||||
// to not extrapolate player positions if more recent data is available
|
||||
BG_EvaluateTrajectory(¢->currentState.pos, cg.snap->serverTime, current);
|
||||
BG_EvaluateTrajectory(¢->nextState.pos, cg.nextSnap->serverTime, next);
|
||||
BG_EvaluateTrajectory(¢->currentState.pos, cg.snap->serverTime, cent->currentState.origin, current);
|
||||
BG_EvaluateTrajectory(¢->nextState.pos, cg.nextSnap->serverTime, cent->nextState.origin, next);
|
||||
|
||||
cent->lerpOrigin[0] = current[0] + f * (next[0] - current[0]);
|
||||
cent->lerpOrigin[1] = current[1] + f * (next[1] - current[1]);
|
||||
@@ -494,17 +513,11 @@ void CG_CalcEntityLerpPositions( centity_t *cent )
|
||||
QuatToMat(quat, mat);
|
||||
MatrixToEulerAngles(mat, cent->lerpAngles);
|
||||
}
|
||||
|
||||
// Lerp legs, torso, and head angles
|
||||
for (i = 0; i < 3; i++) {
|
||||
cent->lerpAngles[i] = LerpAngle(current[i], next[i], f);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// just use the current frame and evaluate as best we can
|
||||
BG_EvaluateTrajectory(¢->currentState.pos, cg.time, cent->lerpOrigin);
|
||||
BG_EvaluateTrajectory(¢->currentState.pos, cg.time, cent->currentState.origin, cent->lerpOrigin);
|
||||
VectorCopy(cent->currentState.angles, cent->lerpAngles);
|
||||
//BG_EvaluateTrajectory(¢->currentState.apos, cg.time, cent->lerpAngles);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -545,10 +558,10 @@ void CG_AddCEntity(centity_t* cent)
|
||||
CG_ModelAnim(cent, qtrue);
|
||||
break;
|
||||
case ET_PLAYER:
|
||||
CG_Player(cent);
|
||||
case ET_ITEM:
|
||||
case ET_EXEC_COMMANDS:
|
||||
CG_ModelAnim(cent, qfalse);
|
||||
CG_Player(cent);
|
||||
CG_Splash(cent);
|
||||
case ET_ITEM:
|
||||
CG_ModelAnim(cent, qfalse);
|
||||
break;
|
||||
case ET_GENERAL:
|
||||
CG_General(cent);
|
||||
@@ -575,7 +588,10 @@ void CG_AddCEntity(centity_t* cent)
|
||||
break;
|
||||
case ET_ROPE: // skip
|
||||
CG_Rope(cent);
|
||||
break;
|
||||
break;
|
||||
case ET_EXEC_COMMANDS:
|
||||
CG_ModelAnim(cent, qfalse);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -495,7 +495,7 @@ void CG_SetLightStyle( int num, const char *s )
|
||||
cg_lightstyle[ num ].map[ k ][ 1 ] = t / 255.0f;
|
||||
k++;
|
||||
}
|
||||
n = max( n, k );
|
||||
n = Q_max( n, k );
|
||||
}
|
||||
while( k < MAX_LIGHTSTYLE_LENGTH )
|
||||
{
|
||||
@@ -518,7 +518,7 @@ void CG_SetLightStyle( int num, const char *s )
|
||||
cg_lightstyle[ num ].map[ k ][ 2 ] = t / 255.0f;
|
||||
k++;
|
||||
}
|
||||
n = max( n, k );
|
||||
n = Q_max( n, k );
|
||||
}
|
||||
while( k < MAX_LIGHTSTYLE_LENGTH )
|
||||
{
|
||||
@@ -541,7 +541,7 @@ void CG_SetLightStyle( int num, const char *s )
|
||||
cg_lightstyle[ num ].map[ k ][ 3 ] = t / 255.0f;
|
||||
k++;
|
||||
}
|
||||
n = max( n, k );
|
||||
n = Q_max( n, k );
|
||||
}
|
||||
while( k < MAX_LIGHTSTYLE_LENGTH )
|
||||
{
|
||||
|
||||
@@ -590,6 +590,7 @@ void CG_PredictPlayerState( void );
|
||||
//
|
||||
// cg_ents.c
|
||||
//
|
||||
void BG_EvaluateTrajectory(const trajectory_t* tr, int atTime, const vec3_t base, vec3_t result);
|
||||
void CG_SetEntitySoundPosition( centity_t *cent );
|
||||
void CG_AddPacketEntities( void );
|
||||
void CG_Beam( centity_t *cent );
|
||||
@@ -632,8 +633,8 @@ void CG_ImpactMarkSimple(
|
||||
);
|
||||
void CG_InitTestTreadMark();
|
||||
int CG_PermanentMark(
|
||||
vec_t* origin,
|
||||
vec_t* dir,
|
||||
const vec3_t origin,
|
||||
const vec3_t dir,
|
||||
float orientation,
|
||||
float fSScale,
|
||||
float fTScale,
|
||||
|
||||
+8
-10
@@ -194,23 +194,22 @@ called during a precache command
|
||||
*/
|
||||
void CG_RegisterSounds( void )
|
||||
{
|
||||
int startTime; // esi MAPDST
|
||||
int endTime; // eax MAPDST
|
||||
char filename[64]; // [esp+28h] [ebp-40h] BYREF
|
||||
int startTime;
|
||||
int endTime;
|
||||
char filename[MAX_QPATH];
|
||||
|
||||
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, 64, "ubersound/ubersound.scr");
|
||||
Com_sprintf(filename, sizeof(filename), "ubersound/ubersound.scr");
|
||||
|
||||
startTime = cgi.Milliseconds();
|
||||
CG_Command_ProcessFile(filename, 0, 0);
|
||||
endTime = cgi.Milliseconds();
|
||||
|
||||
Com_Printf("Parse/Load time: %f seconds.\n",
|
||||
(double)((long double)(endTime - startTime) / 1000.0));
|
||||
Com_Printf("Parse/Load time: %f seconds.\n", (endTime - startTime) / 1000.0f);
|
||||
|
||||
Com_Printf("-------------UBERSOUND DONE---------------\n\n");
|
||||
Com_Printf("\n\n-----------PARSING UBERDIALOG------------\n");
|
||||
@@ -218,14 +217,13 @@ void CG_RegisterSounds( void )
|
||||
"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, 64, "ubersound/uberdialog.scr");
|
||||
Com_sprintf(filename, sizeof(filename), "ubersound/uberdialog.scr");
|
||||
|
||||
startTime = cgi.Milliseconds();
|
||||
CG_Command_ProcessFile(filename, 0, 0);
|
||||
endTime = cgi.Milliseconds() - startTime;
|
||||
|
||||
Com_Printf("Parse/Load time: %f seconds.\n",
|
||||
(double)((long double)endTime / 1000.0));
|
||||
Com_Printf("Parse/Load time: %f seconds.\n", endTime / 1000.0f);
|
||||
Com_Printf("-------------UBERDIALOG DONE---------------\n\n");
|
||||
}
|
||||
|
||||
@@ -366,7 +364,7 @@ void CG_ProcessConfigString(int num)
|
||||
}
|
||||
else if (num >= CS_SOUNDS && num < CS_SOUNDS + MAX_SOUNDS)
|
||||
{
|
||||
int len = strlen(str);
|
||||
size_t len = strlen(str);
|
||||
if (len)
|
||||
{
|
||||
qboolean streamed;
|
||||
|
||||
@@ -444,8 +444,8 @@ void CG_AddTreadMarks()
|
||||
}
|
||||
|
||||
int CG_PermanentMark(
|
||||
vec_t* origin,
|
||||
vec_t* dir,
|
||||
const vec3_t origin,
|
||||
const vec3_t dir,
|
||||
float orientation,
|
||||
float fSScale,
|
||||
float fTScale,
|
||||
|
||||
@@ -956,7 +956,7 @@ void CG_ModelAnim(centity_t* cent, qboolean bDoShaderTime)
|
||||
VectorCopy(model.origin, cg.sky_origin);
|
||||
}
|
||||
|
||||
model.reType = ET_MODELANIM_SKEL;
|
||||
model.reType = RT_MODEL;
|
||||
if (!(s1->renderfx & RF_DONTDRAW))
|
||||
{
|
||||
cgi.R_Model_GetHandle(model.hModel);
|
||||
|
||||
@@ -580,13 +580,15 @@ void CG_ParseCGMessage()
|
||||
cgi.HudDrawElements[iInfo].bVirtualScreen = cgi.MSG_ReadBits(1);
|
||||
break;
|
||||
|
||||
case 31:
|
||||
case 31:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
cgi.HudDrawElements[iInfo].vColor[0] = cgi.MSG_ReadByte() / 255.0;
|
||||
cgi.HudDrawElements[iInfo].vColor[1] = cgi.MSG_ReadByte() / 255.0;
|
||||
cgi.HudDrawElements[iInfo].vColor[2] = cgi.MSG_ReadByte() / 255.0;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
case 32:
|
||||
iInfo = cgi.MSG_ReadByte();
|
||||
cgi.HudDrawElements[iInfo].vColor[3] = cgi.MSG_ReadByte() / 255.0;
|
||||
break;
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
// refdef flags
|
||||
#define RDF_NOWORLDMODEL 1 // used for player configuration screen
|
||||
#define RDF_FULLBRIGHT 2 // fullbright intensity
|
||||
#define RDF_HYPERSPACE 4 // teleportation effect
|
||||
|
||||
typedef struct
|
||||
|
||||
+65
-21
@@ -158,6 +158,10 @@ CL_GetSnapshot
|
||||
qboolean CL_GetSnapshot( int snapshotNumber, snapshot_t *snapshot ) {
|
||||
clSnapshot_t *clSnap;
|
||||
int i, count;
|
||||
int pnum;
|
||||
int parents[MAX_ENTITIES_IN_SNAPSHOT];
|
||||
entityState_t *s1;
|
||||
int pcount = 0;
|
||||
|
||||
if ( snapshotNumber > cl.snap.messageNum ) {
|
||||
Com_Error( ERR_DROP, "CL_GetSnapshot: snapshotNumber > cl.snapshot.messageNum" );
|
||||
@@ -187,41 +191,81 @@ qboolean CL_GetSnapshot( int snapshotNumber, snapshot_t *snapshot ) {
|
||||
snapshot->serverTime = clSnap->serverTime;
|
||||
Com_Memcpy( snapshot->areamask, clSnap->areamask, sizeof( snapshot->areamask ) );
|
||||
snapshot->ps = clSnap->ps;
|
||||
|
||||
// wombat: sounds
|
||||
count = clSnap->number_of_sounds;
|
||||
if (snapshot->number_of_sounds > MAX_SERVER_SOUNDS) {
|
||||
Com_DPrintf("CL_GetSnapshot: truncated %i sounds to %i\n", count, MAX_SERVER_SOUNDS);
|
||||
count = MAX_SERVER_SOUNDS;
|
||||
}
|
||||
|
||||
snapshot->number_of_sounds = count;
|
||||
Com_Memcpy(snapshot->sounds, clSnap->sounds, sizeof(snapshot->sounds[0])* count);
|
||||
|
||||
count = clSnap->numEntities;
|
||||
if ( count > MAX_ENTITIES_IN_SNAPSHOT ) {
|
||||
Com_DPrintf( "CL_GetSnapshot: truncated %i visible entities to %i\n", count, MAX_ENTITIES_IN_SNAPSHOT );
|
||||
count = MAX_ENTITIES_IN_SNAPSHOT;
|
||||
}
|
||||
snapshot->numEntities = count;
|
||||
|
||||
snapshot->numEntities = 0;
|
||||
for ( i = 0 ; i < count ; i++ ) {
|
||||
snapshot->entities[i] =
|
||||
cl.parseEntities[ ( clSnap->parseEntitiesNum + i ) & (MAX_PARSE_ENTITIES-1) ];
|
||||
s1 = &cl.parseEntities[(clSnap->parseEntitiesNum + i) & (MAX_PARSE_ENTITIES - 1)];
|
||||
pnum = s1->parent;
|
||||
|
||||
if (pnum == ENTITYNUM_NONE) {
|
||||
parents[s1->number] = -2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parents[pnum] == -2) {
|
||||
parents[s1->number] = -2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// add it later
|
||||
parents[s1->number] = pnum;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
snapshot->entities[snapshot->numEntities++] = *s1;
|
||||
}
|
||||
|
||||
// wombat: sounds
|
||||
count = clSnap->number_of_sounds;
|
||||
if ( snapshot->number_of_sounds > MAX_SERVER_SOUNDS) {
|
||||
Com_DPrintf( "CL_GetSnapshot: truncated %i sounds to %i\n", count, MAX_SERVER_SOUNDS);
|
||||
count = MAX_SERVER_SOUNDS;
|
||||
for(pcount = 0; pcount < 8 && snapshot->numEntities != count; pcount++)
|
||||
{
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
s1 = &cl.parseEntities[(clSnap->parseEntitiesNum + i) & (MAX_PARSE_ENTITIES - 1)];
|
||||
pnum = parents[s1->number];
|
||||
if (pnum >= 0 && parents[pnum] == -2) {
|
||||
snapshot->entities[snapshot->numEntities++] = *s1;
|
||||
}
|
||||
}
|
||||
}
|
||||
snapshot->number_of_sounds = count;
|
||||
Com_Memcpy( snapshot->sounds, clSnap->sounds, sizeof(snapshot->sounds[0])*count );
|
||||
|
||||
// FIXME: configstring changes and server commands!!!
|
||||
if (pcount >= 8)
|
||||
{
|
||||
for (i = count; i < snapshot->numEntities; i++)
|
||||
{
|
||||
s1 = &cl.parseEntities[(clSnap->parseEntitiesNum + i) & (MAX_PARSE_ENTITIES - 1)];
|
||||
if (parents[s1->number] >= 0) {
|
||||
Com_DPrintf(
|
||||
"CL_GetSnapshot: entity %d with parent %d and model '%s' at %.2f %.2f %.2f, could not find parent.\n",
|
||||
s1->number,
|
||||
s1->parent,
|
||||
CL_ConfigString(CS_MODELS + s1->modelindex),
|
||||
s1->origin[0],
|
||||
s1->origin[1],
|
||||
s1->origin[2]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_SetUserCmdValue
|
||||
=====================
|
||||
*/
|
||||
void CL_SetUserCmdValue( int userCmdValue, float sensitivityScale ) {
|
||||
cl.cgameUserCmdValue = userCmdValue;
|
||||
cl.cgameSensitivity = sensitivityScale;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_AddCgameCommand
|
||||
|
||||
@@ -566,7 +566,7 @@ CL_CmdButtons
|
||||
*/
|
||||
void CL_CmdButtons( usercmd_t *cmd ) {
|
||||
int i;
|
||||
|
||||
|
||||
//
|
||||
// figure button bits
|
||||
// send a button bit even if the key was pressed and released in
|
||||
@@ -579,18 +579,28 @@ void CL_CmdButtons( usercmd_t *cmd ) {
|
||||
in_buttons[i].wasPressed = qfalse;
|
||||
}
|
||||
|
||||
// if ( Key_GetCatcher( ) ) {
|
||||
// cmd->buttons |= BUTTON_TALK; // su44: is there a TALK button in MoHAA?
|
||||
// }
|
||||
if (UI_MenuActive() || UI_ConsoleIsOpen()) {
|
||||
cmd->buttons |= BUTTON_TALK;
|
||||
}
|
||||
|
||||
if (in_speed.active == !cl_run->integer) {
|
||||
cmd->buttons |= BUTTON_RUN;
|
||||
}
|
||||
|
||||
if (cge) {
|
||||
// send weapon commands from cg
|
||||
cmd->buttons |= cge->CG_WeaponCommandButtonBits();
|
||||
}
|
||||
|
||||
// allow the game to know if any key at all is
|
||||
// currently pressed, even if it isn't bound to anything
|
||||
if ( anykeydown && Key_GetCatcher( ) == 0 ) {
|
||||
cmd->buttons |= BUTTON_ANY;
|
||||
if ( anykeydown && Key_GetCatcher() == 0) {
|
||||
cmd->buttons |= BUTTON_ANY2;
|
||||
}
|
||||
|
||||
// su44: add weapon command bits
|
||||
cmd->buttons |= cl.cgameUserCmdValue;
|
||||
if (anykeydown) {
|
||||
cmd->buttons |= BUTTON_ANY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+11
-141
@@ -29,14 +29,10 @@ key up events are sent even if in console mode
|
||||
|
||||
*/
|
||||
|
||||
field_t historyEditLines[COMMAND_HISTORY];
|
||||
|
||||
int nextHistoryLine; // the last line in the history buffer, not masked
|
||||
int historyLine; // the line being displayed from history buffer
|
||||
// will be <= nextHistoryLine
|
||||
|
||||
field_t g_consoleField;
|
||||
field_t chatField;
|
||||
qboolean chat_team;
|
||||
|
||||
int chat_playerNum;
|
||||
@@ -951,7 +947,13 @@ void CL_KeyEvent (int key, qboolean down, unsigned time) {
|
||||
ctrl_down = down;
|
||||
}
|
||||
|
||||
if( cls.state > CA_DISCONNECTED && cge && !cls.keyCatchers && cge->CG_CheckCaptureKey( key, down, time ) && key != K_ESCAPE )
|
||||
if (down && !CL_FinishedIntro())
|
||||
{
|
||||
UI_StartStageKeyEvent();
|
||||
return;
|
||||
}
|
||||
|
||||
if( cls.state > CA_DISCONNECTED && cge && !Key_GetCatcher() && cge->CG_CheckCaptureKey( key, down, time ) && key != K_ESCAPE )
|
||||
{
|
||||
if( key != '`' && key != '~' )
|
||||
return;
|
||||
@@ -962,6 +964,7 @@ void CL_KeyEvent (int key, qboolean down, unsigned time) {
|
||||
if( !down ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( Cvar_VariableIntegerValue( "ui_console" ) )
|
||||
{
|
||||
UI_ToggleConsole();
|
||||
@@ -1015,10 +1018,10 @@ void CL_KeyEvent (int key, qboolean down, unsigned time) {
|
||||
}
|
||||
}
|
||||
|
||||
if( in_guimouse || key <= K_MOUSE3 || key > K_JOY1 )
|
||||
if (!in_guimouse || key <= K_MOUSE3 || key > K_JOY1)
|
||||
{
|
||||
// keys can still be used for bound actions
|
||||
if( down && ( key < 128 || key == K_MOUSE4 ) &&
|
||||
if (down && (key <= K_BACKSPACE || key == K_MOUSE4) &&
|
||||
( clc.demoplaying || cls.state == CA_CINEMATIC ) && Key_GetCatcher() == 0 ) {
|
||||
Cvar_Set( "nextdemo", "" );
|
||||
key = K_ESCAPE;
|
||||
@@ -1061,7 +1064,7 @@ void CL_KeyEvent (int key, qboolean down, unsigned time) {
|
||||
UI_KeyEvent( key, time );
|
||||
} else if( cls.loading & KEYCATCH_MESSAGE ) {
|
||||
Message_Key( key );
|
||||
} else if( cls.state != CA_DISCONNECTED ) {
|
||||
} else if( cls.state != CA_DISCONNECTED || menubound[key]) {
|
||||
// send the bound action
|
||||
kb = altkeys[ key ].binding;
|
||||
if( !kb || !altkeys[ key ].down ) {
|
||||
@@ -1198,136 +1201,3 @@ Key_SetCatcher
|
||||
void Key_SetCatcher( int catcher ) {
|
||||
keyCatchers = catcher;
|
||||
}
|
||||
|
||||
// This must not exceed MAX_CMD_LINE
|
||||
#define MAX_CONSOLE_SAVE_BUFFER 1024
|
||||
#define CONSOLE_HISTORY_FILE "omhistory"
|
||||
static char consoleSaveBuffer[ MAX_CONSOLE_SAVE_BUFFER ];
|
||||
static int consoleSaveBufferSize = 0;
|
||||
|
||||
/*
|
||||
================
|
||||
CL_LoadConsoleHistory
|
||||
|
||||
Load the console history from cl_consoleHistory
|
||||
================
|
||||
*/
|
||||
void CL_LoadConsoleHistory( void )
|
||||
{
|
||||
const char *token;
|
||||
char *text_p;
|
||||
int i, numChars, numLines = 0;
|
||||
fileHandle_t f;
|
||||
|
||||
consoleSaveBufferSize = FS_FOpenFileRead( CONSOLE_HISTORY_FILE, &f, qfalse, qtrue );
|
||||
if( !f )
|
||||
{
|
||||
Com_Printf( "Couldn't read %s.\n", CONSOLE_HISTORY_FILE );
|
||||
return;
|
||||
}
|
||||
|
||||
if( consoleSaveBufferSize <= MAX_CONSOLE_SAVE_BUFFER &&
|
||||
FS_Read( consoleSaveBuffer, consoleSaveBufferSize, f ) == consoleSaveBufferSize )
|
||||
{
|
||||
text_p = consoleSaveBuffer;
|
||||
|
||||
for( i = COMMAND_HISTORY - 1; i >= 0; i-- )
|
||||
{
|
||||
if( !*( token = COM_Parse( &text_p ) ) )
|
||||
break;
|
||||
|
||||
historyEditLines[ i ].cursor = atoi( token );
|
||||
|
||||
if( !*( token = COM_Parse( &text_p ) ) )
|
||||
break;
|
||||
|
||||
historyEditLines[ i ].scroll = atoi( token );
|
||||
|
||||
if( !*( token = COM_Parse( &text_p ) ) )
|
||||
break;
|
||||
|
||||
numChars = atoi( token );
|
||||
text_p++;
|
||||
if( numChars > ( strlen( consoleSaveBuffer ) - ( text_p - consoleSaveBuffer ) ) )
|
||||
{
|
||||
Com_DPrintf( S_COLOR_YELLOW "WARNING: probable corrupt history\n" );
|
||||
break;
|
||||
}
|
||||
Com_Memcpy( historyEditLines[ i ].buffer,
|
||||
text_p, numChars );
|
||||
historyEditLines[ i ].buffer[ numChars ] = '\0';
|
||||
text_p += numChars;
|
||||
|
||||
numLines++;
|
||||
}
|
||||
|
||||
memmove( &historyEditLines[ 0 ], &historyEditLines[ i + 1 ],
|
||||
numLines * sizeof( field_t ) );
|
||||
for( i = numLines; i < COMMAND_HISTORY; i++ )
|
||||
Field_Clear( &historyEditLines[ i ] );
|
||||
|
||||
historyLine = nextHistoryLine = numLines;
|
||||
}
|
||||
else
|
||||
Com_Printf( "Couldn't read %s.\n", CONSOLE_HISTORY_FILE );
|
||||
|
||||
FS_FCloseFile( f );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CL_SaveConsoleHistory
|
||||
|
||||
Save the console history into the cvar cl_consoleHistory
|
||||
so that it persists across invocations of q3
|
||||
================
|
||||
*/
|
||||
void CL_SaveConsoleHistory( void )
|
||||
{
|
||||
int i;
|
||||
int lineLength, saveBufferLength, additionalLength;
|
||||
fileHandle_t f;
|
||||
|
||||
consoleSaveBuffer[ 0 ] = '\0';
|
||||
|
||||
i = ( nextHistoryLine - 1 ) % COMMAND_HISTORY;
|
||||
do
|
||||
{
|
||||
if( historyEditLines[ i ].buffer[ 0 ] )
|
||||
{
|
||||
lineLength = strlen( historyEditLines[ i ].buffer );
|
||||
saveBufferLength = strlen( consoleSaveBuffer );
|
||||
|
||||
//ICK
|
||||
additionalLength = lineLength + strlen( "999 999 999 " );
|
||||
|
||||
if( saveBufferLength + additionalLength < MAX_CONSOLE_SAVE_BUFFER )
|
||||
{
|
||||
Q_strcat( consoleSaveBuffer, MAX_CONSOLE_SAVE_BUFFER,
|
||||
va( "%d %d %d %s ",
|
||||
historyEditLines[ i ].cursor,
|
||||
historyEditLines[ i ].scroll,
|
||||
lineLength,
|
||||
historyEditLines[ i ].buffer ) );
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
i = ( i - 1 + COMMAND_HISTORY ) % COMMAND_HISTORY;
|
||||
}
|
||||
while( i != ( nextHistoryLine - 1 ) % COMMAND_HISTORY );
|
||||
|
||||
consoleSaveBufferSize = strlen( consoleSaveBuffer );
|
||||
|
||||
f = FS_FOpenFileWrite( CONSOLE_HISTORY_FILE );
|
||||
if( !f )
|
||||
{
|
||||
Com_Printf( "Couldn't write %s.\n", CONSOLE_HISTORY_FILE );
|
||||
return;
|
||||
}
|
||||
|
||||
if( FS_Write( consoleSaveBuffer, consoleSaveBufferSize, f ) < consoleSaveBufferSize )
|
||||
Com_Printf( "Couldn't write %s.\n", CONSOLE_HISTORY_FILE );
|
||||
|
||||
FS_FCloseFile( f );
|
||||
}
|
||||
+26
-13
@@ -1421,6 +1421,10 @@ void CL_ResetPureClientAtServer( void ) {
|
||||
CL_AddReliableCommand( va("vdr") );
|
||||
}
|
||||
|
||||
qboolean CL_Allowed_Vid_Restart() {
|
||||
return cls.state == CA_DISCONNECTED || cls.state == CA_ACTIVE;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_Vid_Restart_f
|
||||
@@ -1432,29 +1436,28 @@ because the renderer doesn't know what graphics to reload
|
||||
=================
|
||||
*/
|
||||
void CL_Vid_Restart_f( void ) {
|
||||
|
||||
// Settings may have changed so stop recording now
|
||||
if( CL_VideoRecording( ) ) {
|
||||
CL_CloseAVI( );
|
||||
if (!CL_Allowed_Vid_Restart()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(clc.demorecording)
|
||||
CL_StopRecord_f();
|
||||
Com_Printf("-------- CL_Vid_Restart_f --------\n");
|
||||
cls.vid_restart = qtrue;
|
||||
|
||||
// don't let them loop during the restart
|
||||
S_StopAllSounds( qtrue );
|
||||
S_StopAllSounds(qtrue);
|
||||
|
||||
SV_ClearSvsTimeFixups();
|
||||
|
||||
S_BeginRegistration();
|
||||
|
||||
// shutdown the renderer and clear the renderer interface
|
||||
CL_ShutdownRef();
|
||||
// shutdown the CGame
|
||||
CL_ShutdownCGame();
|
||||
// initialize the renderer interface
|
||||
CL_InitRef();
|
||||
// client is no longer pure untill new checksums are sent
|
||||
CL_ResetPureClientAtServer();
|
||||
// clear pak references
|
||||
FS_ClearPakReferences( FS_UI_REF | FS_CGAME_REF );
|
||||
// reinitialize the filesystem if the game directory or checksum has changed
|
||||
FS_ConditionalRestart( clc.checksumFeed );
|
||||
// initialize the ui library
|
||||
UI_ResolutionChange();
|
||||
|
||||
cls.rendererRegistered = qfalse;
|
||||
cls.uiStarted = qfalse;
|
||||
@@ -1469,6 +1472,8 @@ void CL_Vid_Restart_f( void ) {
|
||||
|
||||
S_Init();
|
||||
|
||||
cls.vid_restart = qfalse;
|
||||
Com_Printf("----- finished CL_Vid_Restart_f ----\n");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4307,4 +4312,12 @@ qboolean CL_CDKeyValidate( const char *key, const char *checksum ) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
void TIKI_CG_Command_ProcessFile(char* filename, qboolean quiet, dtiki_t* curTiki)
|
||||
{
|
||||
if (cge) {
|
||||
cge->CG_Command_ProcessFile(filename, quiet, curTiki);
|
||||
return;
|
||||
}
|
||||
|
||||
Com_Printf("NO CGE \n");
|
||||
}
|
||||
@@ -527,6 +527,7 @@ void CL_ParseGamestate( msg_t *msg ) {
|
||||
// reinitialize the filesystem if the game directory has changed
|
||||
FS_ConditionalRestart( clc.checksumFeed );
|
||||
|
||||
cls.state = CA_LOADING;
|
||||
if (!com_sv_running->integer)
|
||||
{
|
||||
const char *info = cl.gameState.stringData + cl.gameState.stringOffsets[CS_SERVERINFO];
|
||||
|
||||
+86
-67
@@ -1881,7 +1881,7 @@ void UI_Update(void) {
|
||||
{
|
||||
UI_ForceMenuOff(true);
|
||||
UI_DeactiveFloatingWindows();
|
||||
UI_ForceMenu("");
|
||||
UI_ForceMenu(ui_sCurrentLoadingMenu);
|
||||
uWinMan.showCursor(false);
|
||||
}
|
||||
|
||||
@@ -4485,8 +4485,14 @@ ScoreboardListItem::ScoreboardListItem()
|
||||
void ScoreboardListItem::DrawListItem( int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont )
|
||||
{
|
||||
DrawBox( drawRect, backColor, 1.0 );
|
||||
pFont->setColor( textColor );
|
||||
pFont->Print( drawRect.pos.x + 1, drawRect.pos.y, Sys_LV_CL_ConvertString( getListItemString( iColumn ) ), iColumn, -1 );
|
||||
pFont->setColor(textColor);
|
||||
pFont->Print(
|
||||
drawRect.pos.x + 1,
|
||||
drawRect.pos.y,
|
||||
Sys_LV_CL_ConvertString(getListItemString(iColumn)),
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
|
||||
if( bTitleItem )
|
||||
{
|
||||
@@ -4588,10 +4594,11 @@ void UI_SetScoreBoardItem( int iItemNumber,
|
||||
{
|
||||
cge->CG_GetScoreBoardPosition( &x, &y, &w, &h );
|
||||
|
||||
if( scoreboard_x == x
|
||||
|| scoreboard_y == y
|
||||
|| scoreboard_w == w
|
||||
|| scoreboard_h == h
|
||||
// Recreate the scoreboard if it has different rect
|
||||
if( scoreboard_x != x
|
||||
|| scoreboard_y != y
|
||||
|| scoreboard_w != w
|
||||
|| scoreboard_h != h
|
||||
|| scoreboard_header != cge->CG_GetScoreBoardDrawHeader() )
|
||||
{
|
||||
delete scoreboardlist;
|
||||
@@ -4606,11 +4613,12 @@ void UI_SetScoreBoardItem( int iItemNumber,
|
||||
|
||||
if( scoreboardlist )
|
||||
{
|
||||
if( iItemNumber + 1 > scoreboardlist->getNumItems() ) {
|
||||
if (iItemNumber + 1 > scoreboardlist->getNumItems()) {
|
||||
pItem = new ScoreboardListItem;
|
||||
scoreboardlist->AddItem( pItem );
|
||||
} else {
|
||||
pItem = ( ScoreboardListItem * )scoreboardlist->GetItem( iItemNumber );
|
||||
scoreboardlist->AddItem(pItem);
|
||||
}
|
||||
else {
|
||||
pItem = (ScoreboardListItem*)scoreboardlist->GetItem(iItemNumber + 1);
|
||||
}
|
||||
|
||||
if( pItem )
|
||||
@@ -5565,23 +5573,23 @@ UI_LoadResource
|
||||
====================
|
||||
*/
|
||||
void UI_LoadResource( const char *name ) {
|
||||
if( cls.loading == SS_DEAD ) {
|
||||
if (cls.loading == SS_DEAD) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( cls.loading == 3 )
|
||||
if (cls.loading == SS_GAME)
|
||||
{
|
||||
UI_EndLoadResource();
|
||||
UI_EndLoadResource( name );
|
||||
UI_EndLoadResource(name);
|
||||
UI_BeginLoadResource();
|
||||
}
|
||||
else if( cls.loading == 2 )
|
||||
else if (cls.loading == SS_LOADING2)
|
||||
{
|
||||
UI_RegisterLoadResource( name );
|
||||
Cvar_SetValue( "loadingbar", currentLoadTime / totalLoadTime );
|
||||
UI_RegisterLoadResource(name);
|
||||
Cvar_SetValue("loadingbar", (float)currentLoadTime / (float)totalLoadTime);
|
||||
}
|
||||
|
||||
UI_TestUpdateScreen( 333u );
|
||||
UI_TestUpdateScreen(333u);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -5746,7 +5754,65 @@ void UI_BeginLoad( const char *pszMapName ) {
|
||||
UI_ForceMenuOff( true );
|
||||
UI_DeactiveFloatingWindows();
|
||||
|
||||
if( !ui_pLoadingMenu )
|
||||
if (ui_pLoadingMenu)
|
||||
{
|
||||
if (!developer->integer && UI_ConsoleIsVisible()) {
|
||||
UI_CloseConsole();
|
||||
}
|
||||
|
||||
ui_pLoadingMenu->PassEventToWidget("continuebutton", new Event(EV_Widget_Disable));
|
||||
|
||||
loadName = "maps/";
|
||||
loadName += pszMapName;
|
||||
loadName += ".min";
|
||||
mapfile = loadName + ".bsp";
|
||||
|
||||
if (UI_ArchiveLoadMapinfo(mapfile)) {
|
||||
cls.loading = SS_LOADING2;
|
||||
}
|
||||
else {
|
||||
cls.loading = SS_GAME;
|
||||
}
|
||||
|
||||
if (cls.loading == SS_LOADING2)
|
||||
{
|
||||
ui_pLoadingMenu->PassEventToWidget("loadingflasher", new Event(EV_Widget_Disable));
|
||||
ui_pLoadingMenu->PassEventToWidget("loadingbar", new Event(EV_Widget_Enable));
|
||||
ui_pLoadingMenu->PassEventToWidget("loadingbar_border", new Event(EV_Widget_Enable));
|
||||
|
||||
currentLoadTime = 0;
|
||||
Cvar_SetValue("loadingbar", 0);
|
||||
|
||||
L_ProcessPendingEvents();
|
||||
|
||||
lastTime = Sys_Milliseconds();
|
||||
if (com_sv_running->integer) {
|
||||
SCR_UpdateScreen();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ui_pLoadingMenu->PassEventToWidget("loadingflasher", new Event(EV_Widget_Enable));
|
||||
ui_pLoadingMenu->PassEventToWidget("loadingbar", new Event(EV_Widget_Disable));
|
||||
ui_pLoadingMenu->PassEventToWidget("loadingbar_border", new Event(EV_Widget_Disable));
|
||||
|
||||
UI_BeginLoadResource();
|
||||
loadCountLow = 0;
|
||||
loadCountHigh = 0;
|
||||
loadHead = NULL;
|
||||
loadNumber = 0;
|
||||
|
||||
cls.loading = SS_LOADING;
|
||||
|
||||
L_ProcessPendingEvents();
|
||||
lastTime = Sys_Milliseconds();
|
||||
|
||||
if (com_sv_running->integer) {
|
||||
SCR_UpdateScreen();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cls.loading = SS_LOADING;
|
||||
|
||||
@@ -5755,56 +5821,9 @@ void UI_BeginLoad( const char *pszMapName ) {
|
||||
|
||||
lastTime = Sys_Milliseconds();
|
||||
|
||||
if( com_sv_running->integer ) {
|
||||
if (com_sv_running->integer) {
|
||||
SCR_UpdateScreen();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if( !developer->integer && UI_ConsoleIsVisible() ) {
|
||||
UI_CloseConsole();
|
||||
}
|
||||
|
||||
ui_pLoadingMenu->PassEventToWidget( "continuebutton", new Event( EV_Widget_Disable ) );
|
||||
|
||||
loadName = "maps/";
|
||||
loadName += pszMapName;
|
||||
loadName += ".min";
|
||||
mapfile = loadName + ".bsp";
|
||||
|
||||
if( UI_ArchiveLoadMapinfo( mapfile ) ) {
|
||||
cls.loading = SS_LOADING2;
|
||||
} else {
|
||||
cls.loading = SS_GAME;
|
||||
}
|
||||
|
||||
if( cls.loading != SS_LOADING2 )
|
||||
{
|
||||
ui_pLoadingMenu->PassEventToWidget( "loadingflasher", new Event( EV_Widget_Enable ) );
|
||||
ui_pLoadingMenu->PassEventToWidget( "loadingbar", new Event( EV_Widget_Disable ) );
|
||||
ui_pLoadingMenu->PassEventToWidget( "loadingbar_border", new Event( EV_Widget_Disable ) );
|
||||
|
||||
UI_BeginLoadResource();
|
||||
loadCountLow = 0;
|
||||
loadCountHigh = 0;
|
||||
loadHead = NULL;
|
||||
loadNumber = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ui_pLoadingMenu->PassEventToWidget( "loadingflasher", new Event( EV_Widget_Disable ) );
|
||||
ui_pLoadingMenu->PassEventToWidget( "loadingbar", new Event( EV_Widget_Enable ) );
|
||||
ui_pLoadingMenu->PassEventToWidget( "loadingbar_border", new Event( EV_Widget_Enable ) );
|
||||
|
||||
currentLoadTime = 0;
|
||||
Cvar_SetValue( "loadingbar", 0 );
|
||||
}
|
||||
|
||||
L_ProcessPendingEvents();
|
||||
lastTime = Sys_Milliseconds();
|
||||
|
||||
if( com_sv_running->integer ) {
|
||||
SCR_UpdateScreen();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ void CL_ShutdownUI( void );
|
||||
//
|
||||
extern inventory_t client_inv;
|
||||
extern bind_t client_bind;
|
||||
extern cvar_t* cl_greenfps;
|
||||
|
||||
const char *CvarGetForUI( const char *name, const char *defval );
|
||||
void UI_ClearState( void );
|
||||
|
||||
+380
-12
@@ -438,7 +438,173 @@ void UIFakkLabel::LayoutRenderModelAnim( Event *ev )
|
||||
|
||||
void UIFakkLabel::DrawStatbar( float frac )
|
||||
{
|
||||
// FIXME: stub
|
||||
vec4_t col;
|
||||
float alpha;
|
||||
|
||||
col[0] = col[1] = col[2] = col[3] = 1.0;
|
||||
|
||||
switch (m_statbar_or)
|
||||
{
|
||||
case L_STATBAR_CIRCULAR:
|
||||
DrawStatCircle(frac);
|
||||
return;
|
||||
case L_STATBAR_NEEDLE:
|
||||
DrawStatNeedle(frac);
|
||||
return;
|
||||
case L_STATBAR_ROTATOR:
|
||||
DrawStatRotator(frac);
|
||||
return;
|
||||
case L_STATBAR_COMPASS:
|
||||
DrawStatCompass(frac);
|
||||
return;
|
||||
case L_STATBAR_SPINNER:
|
||||
case L_STATBAR_HEADING_SPINNER:
|
||||
DrawStatSpinner(frac);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!frac) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (frac != m_lastfrac) {
|
||||
m_flashtime = uid.time;
|
||||
}
|
||||
m_lastfrac = frac;
|
||||
|
||||
alpha = 1.0 - ((float)uid.time - m_flashtime) / 1500.0;
|
||||
if (alpha < 0.0) alpha = 0.0;
|
||||
else if (alpha > 1.0) alpha = 1.0;
|
||||
|
||||
col[3] = alpha;
|
||||
|
||||
if (m_statbar_material)
|
||||
{
|
||||
if (m_flags & WF_TILESHADER)
|
||||
{
|
||||
switch (m_statbar_or)
|
||||
{
|
||||
case L_STATBAR_HORIZONTAL:
|
||||
{
|
||||
float width = frac * m_frame.size.width;
|
||||
|
||||
m_statbar_material->ReregisterMaterial();
|
||||
re.DrawTilePic(0.0, 0.0, width, m_frame.size.height, m_statbar_material->GetMaterial());
|
||||
|
||||
if (alpha != 0.0 && m_statbar_material_flash)
|
||||
{
|
||||
re.SetColor(col);
|
||||
m_statbar_material_flash->ReregisterMaterial();
|
||||
re.DrawTilePic(0.0, 0.0, width, m_frame.size.height, m_statbar_material_flash->GetMaterial());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case L_STATBAR_VERTICAL:
|
||||
case L_STATBAR_VERTICAL_REVERSE:
|
||||
case L_STATBAR_VERTICAL_STAGGER_EVEN:
|
||||
case L_STATBAR_VERTICAL_STAGGER_ODD:
|
||||
{
|
||||
float y = m_frame.size.height * (1.0 - frac);
|
||||
|
||||
m_statbar_material->ReregisterMaterial();
|
||||
re.DrawTilePic(0.0, y, m_frame.size.width, m_frame.size.height, m_statbar_material->GetMaterial());
|
||||
|
||||
if (alpha != 0.0 && m_statbar_material_flash)
|
||||
{
|
||||
re.SetColor(col);
|
||||
m_statbar_material_flash->ReregisterMaterial();
|
||||
re.DrawTilePic(0.0, y, m_frame.size.width, m_frame.size.height, m_statbar_material_flash->GetMaterial());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (m_statbar_or)
|
||||
{
|
||||
case L_STATBAR_HORIZONTAL:
|
||||
{
|
||||
float width = frac * m_frame.size.width;
|
||||
|
||||
m_statbar_material->ReregisterMaterial();
|
||||
re.DrawStretchPic(0.0, 0.0, width, m_frame.size.height, 0.0, 0.0, 1.0, 1.0, m_statbar_material->GetMaterial());
|
||||
|
||||
if(alpha != 0.0 && m_statbar_material_flash)
|
||||
{
|
||||
re.SetColor(col);
|
||||
m_statbar_material_flash->ReregisterMaterial();
|
||||
re.DrawStretchPic(0.0, 0.0, width, m_frame.size.height, 0.0, 0.0, 1.0, 1.0, m_statbar_material_flash->GetMaterial());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case L_STATBAR_VERTICAL:
|
||||
case L_STATBAR_VERTICAL_STAGGER_EVEN:
|
||||
case L_STATBAR_VERTICAL_STAGGER_ODD:
|
||||
{
|
||||
float y = m_frame.size.height * (1.0 - frac);
|
||||
float height = m_frame.size.height * frac;
|
||||
|
||||
m_statbar_material->ReregisterMaterial();
|
||||
re.DrawStretchPic(0.0, y, m_frame.size.width, height, 0.0, 1.0 - frac, 1.0, 1.0, m_statbar_material->GetMaterial());
|
||||
|
||||
if (alpha != 0.0 && m_statbar_material_flash)
|
||||
{
|
||||
re.SetColor(col);
|
||||
m_statbar_material_flash->ReregisterMaterial();
|
||||
re.DrawStretchPic(0.0, y, m_frame.size.width, height, 0.0, 1.0 - frac, 1.0, 1.0, m_statbar_material_flash->GetMaterial());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case L_STATBAR_VERTICAL_REVERSE:
|
||||
{
|
||||
float height = m_frame.size.height * frac;
|
||||
|
||||
m_statbar_material->ReregisterMaterial();
|
||||
re.DrawStretchPic(0.0, 0.0, m_frame.size.width, height, 0.0, 0.0, 1.0, frac, m_statbar_material->GetMaterial());
|
||||
|
||||
if (alpha != 0.0 && m_statbar_material_flash)
|
||||
{
|
||||
re.SetColor(col);
|
||||
m_statbar_material_flash->ReregisterMaterial();
|
||||
re.DrawStretchPic(0.0, 0.0, m_frame.size.width, height, 0.0, 0.0, 1.0, frac, m_statbar_material_flash->GetMaterial());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (m_statbar_or)
|
||||
{
|
||||
case L_STATBAR_VERTICAL:
|
||||
case L_STATBAR_VERTICAL_STAGGER_EVEN:
|
||||
case L_STATBAR_VERTICAL_STAGGER_ODD:
|
||||
DrawBox(
|
||||
0.0,
|
||||
m_frame.size.height * (1.0 - frac),
|
||||
m_frame.size.width,
|
||||
m_frame.size.height,
|
||||
m_foreground_color,
|
||||
1.0
|
||||
);
|
||||
break;
|
||||
case L_STATBAR_HORIZONTAL:
|
||||
DrawBox(
|
||||
0.0,
|
||||
0.0,
|
||||
frac * m_frame.size.width,
|
||||
m_frame.size.height,
|
||||
m_foreground_color,
|
||||
1.0
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UIFakkLabel::DrawStatCircle( float frac )
|
||||
@@ -458,7 +624,212 @@ void UIFakkLabel::DrawStatRotator( float frac )
|
||||
|
||||
void UIFakkLabel::DrawStatCompass( float frac )
|
||||
{
|
||||
// FIXME: stub
|
||||
vec4_t col;
|
||||
float fTargAng;
|
||||
float fSinVal, fCosVal;
|
||||
vec2_t vCenter;
|
||||
vec2_t vVerts[3];
|
||||
vec2_t vTexCoords[3];
|
||||
vec2_t vCompassDir;
|
||||
vec2_t vSideDir;
|
||||
|
||||
col[0] = col[1] = col[2] = col[3] = 1.0;
|
||||
|
||||
if (!cge) {
|
||||
return;
|
||||
}
|
||||
|
||||
static int iLastCompassTime = -9999, iLastTimeDelta = 0;
|
||||
static float fLastPitch = 0, fLastYaw = 0, fLastYawDelta = 0;
|
||||
static float fYawOffset = 0, fYawSpeed = 0;
|
||||
static float fNeedleOffset = 0, fNeedleSpeed = 0;
|
||||
int iTimeCount, iTimeDelta;
|
||||
float fYawDelta, fYawDeltaDiff;
|
||||
vec3_t vViewAngles;
|
||||
|
||||
cge->CG_EyeAngles(&vViewAngles);
|
||||
|
||||
vViewAngles[1] -= cl.snap.ps.stats[STAT_COMPASSNORTH] / 182.0f;
|
||||
|
||||
iTimeCount = uid.time - iLastCompassTime;
|
||||
if (iTimeCount <= 1000)
|
||||
{
|
||||
fYawDelta = AngleSubtract(vViewAngles[1], fLastYaw);
|
||||
if (fYawDelta > 0.1)
|
||||
{
|
||||
if ((fYawDelta > 0.0 && fLastYawDelta < fYawDelta)
|
||||
|| (fYawDelta < 0.0 && fLastYawDelta > fYawDelta))
|
||||
{
|
||||
|
||||
fYawSpeed += (fYawDelta - fLastYawDelta) * 0.75;
|
||||
fYawOffset += (fYawDelta - fLastYawDelta) * 0.75;
|
||||
}
|
||||
|
||||
if (fYawSpeed > 90.0) {
|
||||
fYawSpeed = 90.0;
|
||||
}
|
||||
else if (fYawSpeed < 0.05) {
|
||||
fYawSpeed = 0.05;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
while (iTimeCount > 0)
|
||||
{
|
||||
iTimeDelta = iTimeCount;
|
||||
if (iTimeCount > 15) {
|
||||
iTimeDelta = 15;
|
||||
}
|
||||
iTimeCount -= iTimeDelta;
|
||||
|
||||
if (fabs(fYawOffset) >= 0.1 || fabs(fYawSpeed) >= 0.01)
|
||||
{
|
||||
fYawOffset += fYawSpeed * iTimeDelta;
|
||||
if (fYawOffset > 0.0) {
|
||||
fYawSpeed -= iTimeDelta * 0.00175;
|
||||
}
|
||||
else if (fYawOffset < 0.0) {
|
||||
fYawSpeed += iTimeDelta * 0.00175;
|
||||
}
|
||||
|
||||
if (fYawOffset > 40.0) {
|
||||
fYawOffset = 40.0;
|
||||
fYawSpeed = 0.0;
|
||||
}
|
||||
else if (fYawOffset < -40.0) {
|
||||
fYawOffset = -40.0;
|
||||
fYawSpeed = 0.0;
|
||||
}
|
||||
|
||||
fYawSpeed -= iTimeDelta * 0.003;
|
||||
if (fYawSpeed > 0.0) {
|
||||
fYawSpeed -= iTimeDelta * 0.0004;
|
||||
}
|
||||
else {
|
||||
fYawSpeed += iTimeDelta * 0.0004;
|
||||
if (fYawSpeed > 0.0) {
|
||||
fYawSpeed = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iTimeCount = 0;
|
||||
fYawOffset = 0.0;
|
||||
fYawSpeed = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
fLastYawDelta = fYawDelta;
|
||||
iLastTimeDelta = uid.time - iLastCompassTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
fLastYawDelta = 0;
|
||||
fYawOffset = 0;
|
||||
fYawSpeed = 0;
|
||||
iLastTimeDelta = 0;
|
||||
}
|
||||
|
||||
fLastPitch = vViewAngles[0];
|
||||
fLastYaw = vViewAngles[1];
|
||||
iLastCompassTime = uid.time;
|
||||
|
||||
if (iLastTimeDelta)
|
||||
{
|
||||
if (fabs(fLastYawDelta) > 0.1) {
|
||||
fNeedleOffset -= fLastYawDelta;
|
||||
}
|
||||
|
||||
iTimeCount = iLastTimeDelta;
|
||||
while (iTimeCount > 0)
|
||||
{
|
||||
iTimeDelta = iTimeCount;
|
||||
if (iTimeCount > 15) {
|
||||
iTimeDelta = 15;
|
||||
}
|
||||
iTimeCount -= iTimeDelta;
|
||||
|
||||
if (fabs(fNeedleOffset) >= 0.1 || fabs(fNeedleSpeed) >= 0.01) {
|
||||
|
||||
fNeedleOffset += iTimeDelta * fNeedleSpeed;
|
||||
if (fNeedleOffset > 180.0) {
|
||||
fNeedleOffset -= 360.0;
|
||||
}
|
||||
else if (fNeedleOffset < -180.0) {
|
||||
fNeedleOffset += 360.0;
|
||||
}
|
||||
|
||||
if (fNeedleOffset > 0.0) {
|
||||
fNeedleSpeed -= iTimeDelta * 0.00175;
|
||||
}
|
||||
else if (fNeedleOffset < 0.0) {
|
||||
fNeedleSpeed += iTimeDelta * 0.00175;
|
||||
}
|
||||
|
||||
fNeedleSpeed -= fNeedleSpeed * 0.0025 * iTimeDelta;
|
||||
if (fNeedleSpeed > 0.0) {
|
||||
fNeedleSpeed -= iTimeDelta * 0.00035;
|
||||
if (fNeedleSpeed < 0.0) {
|
||||
fNeedleSpeed = 0.0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
fNeedleSpeed += iTimeDelta * 0.00035;
|
||||
if (fNeedleSpeed > 0.0) {
|
||||
fNeedleSpeed = 0.0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
iTimeCount = 0;
|
||||
fNeedleOffset = 0.0;
|
||||
fNeedleSpeed = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fNeedleOffset = 0.0;
|
||||
fNeedleSpeed = 0.0;
|
||||
}
|
||||
|
||||
fSinVal = sin(anglemod(fNeedleOffset + fLastYaw) / (180 / M_PI));
|
||||
fCosVal = cos(anglemod(fNeedleOffset + fLastYaw) / (180 / M_PI));
|
||||
|
||||
vCompassDir[0] = fSinVal;
|
||||
vCompassDir[1] = -fCosVal;
|
||||
|
||||
vCenter[0] = m_frame.size.width * 0.5;
|
||||
vCenter[1] = m_frame.size.height * 0.5;
|
||||
vTexCoords[0][0] = 0.0;
|
||||
vTexCoords[0][1] = 0.0;
|
||||
vTexCoords[1][0] = 1.0;
|
||||
vTexCoords[1][1] = 0.0;
|
||||
vTexCoords[2][0] = 0.0;
|
||||
vTexCoords[2][1] = 1.0;
|
||||
|
||||
vVerts[0][0] = vCenter[0] + vCompassDir[0] * vCenter[0] - fCosVal * vCenter[1];
|
||||
vVerts[1][0] = vCenter[0] + vCompassDir[0] * vCenter[0] + fCosVal * vCenter[1];
|
||||
vVerts[2][0] = vCenter[0] - vCompassDir[0] * vCenter[0] - fCosVal * vCenter[1];
|
||||
vVerts[0][1] = vCenter[1] + vCompassDir[1] * vCenter[1] - fSinVal * vCenter[0];
|
||||
vVerts[1][1] = vCenter[1] + vCompassDir[1] * vCenter[1] + fSinVal * vCenter[0];
|
||||
vVerts[2][1] = vCenter[1] - vCompassDir[1] * vCenter[1] - fSinVal * vCenter[0];
|
||||
|
||||
m_statbar_material->ReregisterMaterial();
|
||||
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
|
||||
|
||||
vVerts[0][0] = vVerts[2][0];
|
||||
vVerts[0][1] = vVerts[2][1];
|
||||
vTexCoords[0][0] = vTexCoords[2][0];
|
||||
vTexCoords[0][1] = vTexCoords[2][1];
|
||||
vTexCoords[2][0] = 1.0;
|
||||
vTexCoords[2][1] = 1.0;
|
||||
|
||||
vVerts[2][0] = vCenter[0] + fCosVal * vCenter[1] - vCompassDir[0] * vCenter[0];
|
||||
vVerts[2][1] = vCenter[1] * fSinVal + vCenter[0] - vCompassDir[1] * vCenter[1];
|
||||
|
||||
m_statbar_material->ReregisterMaterial();
|
||||
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
|
||||
}
|
||||
|
||||
void UIFakkLabel::DrawStatSpinner( float frac )
|
||||
@@ -506,7 +877,7 @@ void UIFakkLabel::Draw( void )
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_stat != -1 )
|
||||
if( m_stat == -1 )
|
||||
{
|
||||
float scale;
|
||||
qhandle_t handle;
|
||||
@@ -516,7 +887,7 @@ void UIFakkLabel::Draw( void )
|
||||
vec3_t angles;
|
||||
vec3_t offset;
|
||||
vec3_t rotateoffset;
|
||||
vec3_t color;
|
||||
vec4_t color;
|
||||
str sAnimName;
|
||||
float height;
|
||||
|
||||
@@ -686,23 +1057,20 @@ _shitlabel01:
|
||||
|
||||
float frac;
|
||||
|
||||
if( m_maxstat )
|
||||
if( m_maxstat >= 0 )
|
||||
{
|
||||
frac = delta / ( m_statbar_max - m_statbar_min );
|
||||
frac = (float)delta / (float)cl.snap.ps.stats[m_maxstat];
|
||||
}
|
||||
else
|
||||
{
|
||||
frac = delta / cl.snap.ps.stats[ m_maxstat ];
|
||||
frac = (float)delta / (float)(m_statbar_max - m_statbar_min);
|
||||
}
|
||||
|
||||
if( frac > 1.0 )
|
||||
frac = 1.0;
|
||||
if( frac < 0.0 )
|
||||
frac = 0.0;
|
||||
if( frac > 1.0 ) frac = 1.0;
|
||||
else if( frac < 0.0 ) frac = 0.0;
|
||||
|
||||
DrawStatbar( frac );
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -126,7 +126,72 @@ void View3D::DrawFPS
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
char string[128];
|
||||
|
||||
setFont("verdana-14");
|
||||
if (fps->integer == 2)
|
||||
{
|
||||
re.SetColor(UBlack);
|
||||
re.DrawBox(
|
||||
0.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 4.0,
|
||||
m_frame.pos.x + m_frame.size.width,
|
||||
m_font->getHeight(qfalse) * 4.0
|
||||
);
|
||||
}
|
||||
|
||||
sprintf(string, "FPS %4.1f", currentfps);
|
||||
if (currentfps > 23.94) {
|
||||
if (cl_greenfps->integer) {
|
||||
m_font->setColor(UGreen);
|
||||
} else {
|
||||
m_font->setColor(UWhite);
|
||||
}
|
||||
} else if (currentfps > 18.0) {
|
||||
m_font->setColor(UYellow);
|
||||
} else {
|
||||
// low fps
|
||||
m_font->setColor(URed);
|
||||
}
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 3.0,
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
|
||||
// Draw elements count
|
||||
if (cl_greenfps->integer) {
|
||||
m_font->setColor(UGreen);
|
||||
}
|
||||
else {
|
||||
m_font->setColor(UWhite);
|
||||
}
|
||||
|
||||
sprintf(string, "wt%5d wv%5d cl%d", cls.world_tris, cls.world_verts, cls.character_lights);
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 2.0,
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
|
||||
sprintf(string, "t%5d v%5d Mtex%5.2f", cls.total_tris, cls.total_verts, (float)cls.total_texels * 0.00000095367432);
|
||||
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse),
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
|
||||
m_font->setColor(UBlack);
|
||||
}
|
||||
|
||||
void View3D::DrawProf
|
||||
|
||||
@@ -126,10 +126,6 @@ typedef struct {
|
||||
|
||||
int joystickAxis[MAX_JOYSTICK_AXIS]; // set by joystick events
|
||||
|
||||
// cgame communicates a few values to the client system
|
||||
int cgameUserCmdValue; // current weapon to add to usercmd_t
|
||||
float cgameSensitivity;
|
||||
|
||||
// cmds[cmdNumber] is the predicted command, [cmdNumber-1] is the last
|
||||
// properly generated command
|
||||
usercmd_t cmds[CMD_BACKUP]; // each mesage will send several old cmds
|
||||
@@ -145,9 +141,6 @@ typedef struct {
|
||||
// and teleport direction changes
|
||||
vec3_t viewangles;
|
||||
|
||||
vec3_t eyeAngles;
|
||||
vec3_t eyeOrigin;
|
||||
|
||||
int serverId; // included in each client message so the server
|
||||
// can tell if it is for a prior map_restart
|
||||
// big stuff at end of structure so most offsets are 15 bits or less
|
||||
@@ -578,9 +571,6 @@ void Con_PageDown( void );
|
||||
void Con_Top( void );
|
||||
void Con_Bottom( void );
|
||||
|
||||
void CL_LoadConsoleHistory( void );
|
||||
void CL_SaveConsoleHistory( void );
|
||||
|
||||
//
|
||||
// cl_scrn.c
|
||||
//
|
||||
|
||||
@@ -34,17 +34,6 @@ typedef struct {
|
||||
extern qboolean key_overstrikeMode;
|
||||
extern qkey_t keys[K_LASTKEY];
|
||||
|
||||
// NOTE TTimo the declaration of field_t and Field_Clear is now in qcommon/qcommon.h
|
||||
void Field_KeyDownEvent( field_t *edit, int key );
|
||||
void Field_CharEvent( field_t *edit, int ch );
|
||||
void Field_Draw(fontInfo_t *font, field_t *edit, int x, int y, int width, qboolean showCursor, qboolean noColorEscape );
|
||||
void Field_BigDraw(fontInfo_t *font, field_t *edit, int x, int y, int width, qboolean showCursor, qboolean noColorEscape );
|
||||
|
||||
#define COMMAND_HISTORY 32
|
||||
extern field_t historyEditLines[COMMAND_HISTORY];
|
||||
|
||||
extern field_t g_consoleField;
|
||||
extern field_t chatField;
|
||||
extern int anykeydown;
|
||||
extern qboolean chat_team;
|
||||
extern int chat_playerNum;
|
||||
|
||||
@@ -25,15 +25,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "../qcommon/q_shared.h"
|
||||
#include "bg_public.h"
|
||||
|
||||
/*
|
||||
================
|
||||
BG_EvaluateTrajectory
|
||||
================
|
||||
*/
|
||||
void BG_EvaluateTrajectory( const trajectory_t *tr, int atTime, vec3_t result ) {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
BG_EvaluateTrajectoryDelta
|
||||
|
||||
@@ -1423,7 +1423,7 @@ void PmoveSingle( pmove_t *pmove )
|
||||
if( pm->ps->pm_type == PM_CLIMBWALL )
|
||||
{
|
||||
pm->ps->fLeanAngle = 0.0f;
|
||||
pm->cmd.buttons &= ~( BUTTON_LEANLEFT | BUTTON_LEANRIGHT );
|
||||
pm->cmd.buttons &= ~( BUTTON_LEAN_LEFT | BUTTON_LEAN_RIGHT );
|
||||
}
|
||||
|
||||
// clear all pmove local vars
|
||||
@@ -1447,10 +1447,10 @@ void PmoveSingle( pmove_t *pmove )
|
||||
|
||||
pml.frametime = pml.msec * 0.001;
|
||||
|
||||
if( ( pm->cmd.buttons & ( BUTTON_LEANLEFT | BUTTON_LEANRIGHT ) &&
|
||||
( pm->cmd.buttons & ( BUTTON_LEANLEFT | BUTTON_LEANRIGHT ) ) != ( BUTTON_LEANLEFT | BUTTON_LEANRIGHT ) ) )
|
||||
if( ( pm->cmd.buttons & ( BUTTON_LEAN_LEFT | BUTTON_LEAN_RIGHT ) &&
|
||||
( pm->cmd.buttons & ( BUTTON_LEAN_LEFT | BUTTON_LEAN_RIGHT ) ) != ( BUTTON_LEAN_LEFT | BUTTON_LEAN_RIGHT ) ) )
|
||||
{
|
||||
if( pm->cmd.buttons & BUTTON_LEANLEFT )
|
||||
if( pm->cmd.buttons & BUTTON_LEAN_LEFT )
|
||||
{
|
||||
if( pm->ps->fLeanAngle <= -40.0f )
|
||||
{
|
||||
|
||||
@@ -609,9 +609,6 @@ typedef enum {
|
||||
ET_EXEC_COMMANDS
|
||||
} entityType_t;
|
||||
|
||||
// su44; yes, I know there is no q3 trajectory_t in MoHAA,
|
||||
// but I need it for fgame rotating doors code.
|
||||
void BG_EvaluateTrajectory( const trajectory_t *tr, int atTime, vec3_t result );
|
||||
void BG_EvaluateTrajectoryDelta( const trajectory_t *tr, int atTime, vec3_t result );
|
||||
|
||||
void BG_PlayerStateToEntityState( playerState_t *ps, entityState_t *s, qboolean snap );
|
||||
|
||||
+16
-16
@@ -1907,11 +1907,11 @@ qboolean Player::checkattackleft
|
||||
return false;
|
||||
}
|
||||
|
||||
if( last_ucmd.buttons & BUTTON_ATTACK )
|
||||
if( last_ucmd.buttons & BUTTON_ATTACKLEFT )
|
||||
{
|
||||
Weapon *weapon;
|
||||
|
||||
last_attack_button = BUTTON_ATTACK;
|
||||
last_attack_button = BUTTON_ATTACKLEFT;
|
||||
|
||||
weapon = GetActiveWeapon( WEAPON_MAIN );
|
||||
if( weapon )
|
||||
@@ -1939,7 +1939,7 @@ qboolean Player::checkattackbuttonleft
|
||||
return false;
|
||||
}
|
||||
|
||||
return ( last_ucmd.buttons & BUTTON_ATTACK );
|
||||
return ( last_ucmd.buttons & BUTTON_ATTACKLEFT );
|
||||
}
|
||||
|
||||
|
||||
@@ -1954,11 +1954,11 @@ qboolean Player::checkattackright
|
||||
return false;
|
||||
}
|
||||
|
||||
if( last_ucmd.buttons & BUTTON_ATTACK2 )
|
||||
if( last_ucmd.buttons & BUTTON_ATTACKRIGHT )
|
||||
{
|
||||
Weapon *weapon;
|
||||
|
||||
last_attack_button = BUTTON_ATTACK2;
|
||||
last_attack_button = BUTTON_ATTACKRIGHT;
|
||||
|
||||
weapon = GetActiveWeapon( WEAPON_MAIN );
|
||||
if( weapon )
|
||||
@@ -1986,7 +1986,7 @@ qboolean Player::checkattackbuttonright
|
||||
return false;
|
||||
}
|
||||
|
||||
return ( last_ucmd.buttons & BUTTON_ATTACK2 );
|
||||
return ( last_ucmd.buttons & BUTTON_ATTACKRIGHT );
|
||||
}
|
||||
|
||||
qboolean Player::checksneak
|
||||
@@ -6957,7 +6957,7 @@ void Player::ClientThink
|
||||
client->ps.pm_flags |= PMF_FROZEN;
|
||||
client->ps.pm_flags |= PMF_INTERMISSION;
|
||||
|
||||
if( level.time - level.intermissiontime > 5.0f && ( new_buttons & ( BUTTON_ATTACK | BUTTON_ATTACK2 ) ) )
|
||||
if( level.time - level.intermissiontime > 5.0f && ( new_buttons & ( BUTTON_ATTACKLEFT | BUTTON_ATTACKRIGHT ) ) )
|
||||
{
|
||||
level.exitintermission = true;
|
||||
}
|
||||
@@ -6998,7 +6998,7 @@ void Player::ClientThink
|
||||
{
|
||||
if( level.intermissiontype )
|
||||
{
|
||||
if( ( new_buttons & BUTTON_ATTACK ) || ( new_buttons & BUTTON_ATTACK2 ) )
|
||||
if( ( new_buttons & BUTTON_ATTACKLEFT ) || ( new_buttons & BUTTON_ATTACKRIGHT ) )
|
||||
{
|
||||
if( level.intermissiontype == TRANS_MISSION_FAILED )
|
||||
{
|
||||
@@ -7044,7 +7044,7 @@ void Player::ClientThink
|
||||
return;
|
||||
}
|
||||
|
||||
if( new_buttons & BUTTON_ATTACK2 )
|
||||
if( new_buttons & BUTTON_ATTACKRIGHT )
|
||||
{
|
||||
Weapon *weapon = GetActiveWeapon( WEAPON_MAIN );
|
||||
|
||||
@@ -7252,7 +7252,7 @@ void Player::Think
|
||||
if (g_gametype->integer == GT_SINGLE_PLAYER)
|
||||
{
|
||||
|
||||
if (((server_new_buttons & BUTTON_ATTACK) || (server_new_buttons & BUTTON_ATTACK2)) &&
|
||||
if (((server_new_buttons & BUTTON_ATTACKLEFT) || (server_new_buttons & BUTTON_ATTACKRIGHT)) &&
|
||||
(!GetActiveWeapon(WEAPON_MAIN)) &&
|
||||
(!IsDead()) &&
|
||||
(!IsNewActiveWeapon()) &&
|
||||
@@ -7270,7 +7270,7 @@ void Player::Think
|
||||
{
|
||||
if (dmManager.AllowRespawn())
|
||||
{
|
||||
if (((server_new_buttons & BUTTON_ATTACK) || (server_new_buttons & BUTTON_ATTACK2)) ||
|
||||
if (((server_new_buttons & BUTTON_ATTACKLEFT) || (server_new_buttons & BUTTON_ATTACKRIGHT)) ||
|
||||
(g_forcerespawn->integer > 0 && level.time > g_forcerespawn->integer + respawn_time))
|
||||
{
|
||||
m_bSpectator = false;
|
||||
@@ -7288,7 +7288,7 @@ void Player::Think
|
||||
|
||||
if (IsSpectator() && !m_bTempSpectator)
|
||||
{
|
||||
if (level.time <= respawn_time || !((server_new_buttons & BUTTON_ATTACK) || (server_new_buttons & BUTTON_ATTACK2)))
|
||||
if (level.time <= respawn_time || !((server_new_buttons & BUTTON_ATTACKLEFT) || (server_new_buttons & BUTTON_ATTACKRIGHT)))
|
||||
{
|
||||
if (level.time - 10.0f > m_fWeapSelectTime)
|
||||
{
|
||||
@@ -11544,7 +11544,7 @@ void Player::EventGetFireHeld
|
||||
)
|
||||
|
||||
{
|
||||
ev->AddInteger( buttons & ( BUTTON_ATTACK | BUTTON_ATTACK2 ) ? qtrue : qfalse );
|
||||
ev->AddInteger( buttons & ( BUTTON_ATTACKLEFT | BUTTON_ATTACKRIGHT ) ? qtrue : qfalse );
|
||||
}
|
||||
|
||||
void Player::Score
|
||||
@@ -14202,7 +14202,7 @@ void Player::LeanLeftHeld
|
||||
|
||||
player = ( Player * )this;
|
||||
|
||||
buttonheld = !!( player->buttons & BUTTON_LEANLEFT );
|
||||
buttonheld = !!( player->buttons & BUTTON_LEAN_LEFT );
|
||||
|
||||
ev->AddInteger( buttonheld );
|
||||
}
|
||||
@@ -14218,7 +14218,7 @@ void Player::LeanRightHeld
|
||||
|
||||
player = ( Player * )this;
|
||||
|
||||
buttonheld = !!( player->buttons & BUTTON_LEANRIGHT );
|
||||
buttonheld = !!( player->buttons & BUTTON_LEAN_RIGHT );
|
||||
|
||||
ev->AddInteger( buttonheld );
|
||||
}
|
||||
@@ -14362,7 +14362,7 @@ void Player::SecFireHeld
|
||||
|
||||
player = ( Player * )this;
|
||||
|
||||
buttonheld = !!( player->buttons & BUTTON_ATTACK2 );
|
||||
buttonheld = !!( player->buttons & BUTTON_ATTACKRIGHT );
|
||||
|
||||
ev->AddInteger( buttonheld );
|
||||
}
|
||||
|
||||
+12
-12
@@ -503,7 +503,7 @@ void PlayerBot::UpdateBotStates
|
||||
if( IsDead() )
|
||||
{
|
||||
// The bot should respawn
|
||||
m_botCmd.buttons ^= BUTTON_ATTACK;
|
||||
m_botCmd.buttons ^= BUTTON_ATTACKLEFT;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1419,7 +1419,7 @@ void PlayerBot::State_EndAttack
|
||||
)
|
||||
|
||||
{
|
||||
m_botCmd.buttons &= ~( BUTTON_ATTACK | BUTTON_ATTACK2 );
|
||||
m_botCmd.buttons &= ~( BUTTON_ATTACKLEFT | BUTTON_ATTACKRIGHT );
|
||||
}
|
||||
|
||||
void PlayerBot::State_Attack
|
||||
@@ -1470,16 +1470,16 @@ void PlayerBot::State_Attack
|
||||
{
|
||||
if( pWeap->IsSemiAuto() )
|
||||
{
|
||||
m_botCmd.buttons ^= BUTTON_ATTACK;
|
||||
m_botCmd.buttons ^= BUTTON_ATTACKLEFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_botCmd.buttons |= BUTTON_ATTACK;
|
||||
m_botCmd.buttons |= BUTTON_ATTACKLEFT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_botCmd.buttons &= ~BUTTON_ATTACK;
|
||||
m_botCmd.buttons &= ~BUTTON_ATTACKLEFT;
|
||||
}
|
||||
}
|
||||
else if( pWeap->GetFireType( FIRE_SECONDARY ) == FT_MELEE )
|
||||
@@ -1488,21 +1488,21 @@ void PlayerBot::State_Attack
|
||||
|
||||
if( fDistanceSquared <= fSecondaryBulletRangeSquared )
|
||||
{
|
||||
m_botCmd.buttons ^= BUTTON_ATTACK2;
|
||||
m_botCmd.buttons ^= BUTTON_ATTACKRIGHT;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_botCmd.buttons &= ~BUTTON_ATTACK2;
|
||||
m_botCmd.buttons &= ~BUTTON_ATTACKRIGHT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_botCmd.buttons &= ~( BUTTON_ATTACK | BUTTON_ATTACK2 );
|
||||
m_botCmd.buttons &= ~( BUTTON_ATTACKLEFT | BUTTON_ATTACKRIGHT );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_botCmd.buttons &= ~( BUTTON_ATTACK | BUTTON_ATTACK2 );
|
||||
m_botCmd.buttons &= ~( BUTTON_ATTACKLEFT | BUTTON_ATTACKRIGHT );
|
||||
fMinDistanceSquared = 0;
|
||||
}
|
||||
|
||||
@@ -1634,10 +1634,10 @@ void PlayerBot::Killed
|
||||
Player::Killed( ev );
|
||||
|
||||
// send the respawn buttons
|
||||
if( !( m_botCmd.buttons & BUTTON_ATTACK ) )
|
||||
m_botCmd.buttons |= BUTTON_ATTACK;
|
||||
if( !( m_botCmd.buttons & BUTTON_ATTACKLEFT ) )
|
||||
m_botCmd.buttons |= BUTTON_ATTACKLEFT;
|
||||
else
|
||||
m_botCmd.buttons &= ~BUTTON_ATTACK;
|
||||
m_botCmd.buttons &= ~BUTTON_ATTACKLEFT;
|
||||
|
||||
m_botEyes.ofs[ 0 ] = 0;
|
||||
m_botEyes.ofs[ 1 ] = 0;
|
||||
|
||||
@@ -772,7 +772,7 @@ qboolean TurretGun::UserAim
|
||||
|
||||
m_vUserLastCmdAng = vNewCmdAng;
|
||||
|
||||
if( ( ucmd->buttons & BUTTON_ATTACK ) || ( ucmd->buttons & BUTTON_ATTACK2 ) )
|
||||
if( ( ucmd->buttons & BUTTON_ATTACKLEFT ) || ( ucmd->buttons & BUTTON_ATTACKRIGHT ) )
|
||||
{
|
||||
if( !m_iFiring ) {
|
||||
m_iFiring = 1;
|
||||
|
||||
+97
-159
@@ -200,168 +200,109 @@ void Alias_ListAddParms(AliasListNode_t* node, const char* parameters)
|
||||
return;
|
||||
}
|
||||
|
||||
while (1)
|
||||
for (;;)
|
||||
{
|
||||
while (1)
|
||||
token = nptr = COM_GetToken((char**)¶meters, qtrue);
|
||||
if (!token || !token[0])
|
||||
{
|
||||
while (1)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!Q_stricmp(token, "stop"))
|
||||
{
|
||||
node->stop_flag = 1;
|
||||
}
|
||||
else if (!Q_stricmp(token, "soundparms"))
|
||||
{
|
||||
node->volume = getTokenFloat(¶meters, "volume", node);
|
||||
node->volumeMod = getTokenFloat(¶meters, "volumeMod", node);
|
||||
node->pitch = getTokenFloat(¶meters, "pitch", node);
|
||||
node->pitchMod = getTokenFloat(¶meters, "pitchMod", node);
|
||||
node->dist = getTokenFloat(¶meters, "dist", node);
|
||||
node->maxDist = getTokenFloat(¶meters, "maxDist", node);
|
||||
|
||||
token = COM_GetToken((char**)¶meters, qtrue);
|
||||
if (!token || !*token)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
token = nptr = COM_GetToken((char**)¶meters, qtrue);
|
||||
if (!token || !*token)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Q_stricmp(nptr, "weight"))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
node->stop_flag = 1;
|
||||
}
|
||||
|
||||
if (Q_stricmp(nptr, "weight"))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
token = COM_GetToken((char**)¶meters, 1);
|
||||
if (!token || !*token)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
temp_float = atof(token);
|
||||
|
||||
if (temp_float < 0.0f)
|
||||
{
|
||||
Com_Printf("Weight value out of range in %s alias\n", node->alias_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
node->weight = temp_float;
|
||||
}
|
||||
|
||||
if (Q_stricmp(nptr, "soundparms"))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
node->volume = getTokenFloat(¶meters, "volume", node);
|
||||
node->volumeMod = getTokenFloat(¶meters, "volumeMod", node);
|
||||
node->pitch = getTokenFloat(¶meters, "pitch", node);
|
||||
node->pitchMod = getTokenFloat(¶meters, "pitchMod", node);
|
||||
node->dist = getTokenFloat(¶meters, "dist", node);
|
||||
node->maxDist = getTokenFloat(¶meters, "maxDist", node);
|
||||
|
||||
token = COM_GetToken((char**)¶meters, 1);
|
||||
if (!token || !*token)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
node->channel = S_ChannelNameToNum(token);
|
||||
if (node->channel == -1)
|
||||
{
|
||||
Com_Printf("%s is not avalid channel on %s alias.\n", token, node->alias_name);
|
||||
node->channel = 0;
|
||||
}
|
||||
|
||||
token = COM_GetToken((char**)¶meters, 1);
|
||||
if (!token || !*token)
|
||||
{
|
||||
Com_Printf("ERROR: defaulting %s to not streamed - please setup alias properly.\n", node->alias_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Q_stricmp(token, "streamed"))
|
||||
{
|
||||
node->streamed = 1;
|
||||
}
|
||||
else if (!Q_stricmp(token, "loaded"))
|
||||
{
|
||||
node->streamed = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_Printf("ERROR: Expecting streamed or loaded in ubersound and got %s on alias %s\n", token, node->alias_name);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (Q_stricmp(nptr, "subtitle"))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
token = COM_GetToken((char**)¶meters, qtrue);
|
||||
if (!token || !*token)
|
||||
{
|
||||
Com_Printf("NULL subtitle on %s alias.\n", node->alias_name);
|
||||
return;
|
||||
}
|
||||
|
||||
node->subtitle = Z_TagMalloc(strlen(token) + 1, TAG_TIKI);
|
||||
strcpy(node->subtitle, token);
|
||||
}
|
||||
|
||||
if (Q_stricmp(nptr, "pitch"))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
token = COM_GetToken((char**)¶meters, qtrue);
|
||||
if (!token || !*token)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
temp_float = atof(token);
|
||||
if (temp_float < 0.0f)
|
||||
{
|
||||
Com_Printf("Pitch value out of range in %s alias\n", node->alias_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
node->pitch = temp_float;
|
||||
}
|
||||
|
||||
if (Q_stricmp(nptr, "pitchmod"))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
token = COM_GetToken((char**)¶meters, qtrue);
|
||||
if (!token || !*token)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
temp_float = atof(token);
|
||||
if (temp_float < 0.0f)
|
||||
{
|
||||
Com_Printf("PitchMod value out of range in %s alias\n", node->alias_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
node->pitchMod = temp_float;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Q_stricmp(nptr, "volumemod"))
|
||||
node->channel = S_ChannelNameToNum(token);
|
||||
if (node->channel == -1)
|
||||
{
|
||||
break;
|
||||
Com_Printf("%s is not avalid channel on %s alias.\n", token, node->alias_name);
|
||||
node->channel = 0;
|
||||
}
|
||||
|
||||
token = COM_GetToken((char**)¶meters, qtrue);
|
||||
if (!token || !*token)
|
||||
{
|
||||
Com_Printf("ERROR: defaulting %s to not streamed - please setup alias properly.\n", node->alias_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Q_stricmp(token, "streamed"))
|
||||
{
|
||||
node->streamed = qtrue;
|
||||
}
|
||||
else if (!Q_stricmp(token, "loaded"))
|
||||
{
|
||||
node->streamed = qfalse;
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_Printf("ERROR: Expecting streamed or loaded in ubersound and got %s on alias %s\n", token, node->alias_name);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (!Q_stricmp(token, "subtitle"))
|
||||
{
|
||||
token = COM_GetToken((char**)¶meters, qtrue);
|
||||
if (!token || !*token)
|
||||
{
|
||||
Com_Printf("NULL subtitle on %s alias.\n", node->alias_name);
|
||||
return;
|
||||
}
|
||||
|
||||
node->subtitle = Z_TagMalloc(strlen(token) + 1, TAG_TIKI);
|
||||
strcpy(node->subtitle, token);
|
||||
}
|
||||
else if (!Q_stricmp(token, "pitch"))
|
||||
{
|
||||
token = COM_GetToken((char**)¶meters, qtrue);
|
||||
if (!token || !*token)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
temp_float = atof(token);
|
||||
if (temp_float < 0.0f)
|
||||
{
|
||||
Com_Printf("Pitch value out of range in %s alias\n", node->alias_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
node->pitch = temp_float;
|
||||
}
|
||||
else if (!Q_stricmp(token, "pitchmod"))
|
||||
{
|
||||
token = COM_GetToken((char**)¶meters, qtrue);
|
||||
if (!token || !*token)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
temp_float = atof(token);
|
||||
if (temp_float < 0.0f)
|
||||
{
|
||||
Com_Printf("PitchMod value out of range in %s alias\n", node->alias_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
node->pitchMod = temp_float;
|
||||
}
|
||||
else if (!Q_stricmp(token, "volumemod"))
|
||||
{
|
||||
token = COM_GetToken((char**)¶meters, qtrue);
|
||||
if (!token || !*token)
|
||||
{
|
||||
@@ -377,8 +318,7 @@ void Alias_ListAddParms(AliasListNode_t* node, const char* parameters)
|
||||
|
||||
node->volumeMod = temp_float;
|
||||
}
|
||||
|
||||
if (!Q_stricmp(nptr, "dist"))
|
||||
else if (!Q_stricmp(token, "dist"))
|
||||
{
|
||||
token = COM_GetToken((char**)¶meters, qtrue);
|
||||
if (!token || !*token)
|
||||
@@ -396,7 +336,7 @@ void Alias_ListAddParms(AliasListNode_t* node, const char* parameters)
|
||||
|
||||
node->dist = temp_float;
|
||||
}
|
||||
else if (!Q_stricmp(nptr, "channel"))
|
||||
else if (!Q_stricmp(token, "channel"))
|
||||
{
|
||||
token = COM_GetToken((char**)¶meters, qtrue);
|
||||
if (!token || !*token)
|
||||
@@ -418,8 +358,6 @@ void Alias_ListAddParms(AliasListNode_t* node, const char* parameters)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
qboolean Alias_ListAdd(AliasList_t* list, const char* alias, const char* name, const char* parameters)
|
||||
|
||||
@@ -609,6 +609,7 @@ void CMod_LoadPatches( gamelump_t *surfs, gamelump_t *verts, int *shaderSubdivis
|
||||
vec3_t points[MAX_PATCH_VERTS];
|
||||
int width, height;
|
||||
int shaderNum;
|
||||
char tempName[MAX_QPATH + 1];
|
||||
|
||||
in = ( dsurface_t * )surfs->buffer;
|
||||
if( surfs->length % sizeof( *in ) )
|
||||
@@ -668,6 +669,9 @@ void CMod_LoadPatches( gamelump_t *surfs, gamelump_t *verts, int *shaderSubdivis
|
||||
|
||||
// create the internal facet structure
|
||||
patch->pc = CM_GeneratePatchCollide( width, height, points, patch->subdivisions );
|
||||
|
||||
sprintf(tempName, "s%d", i);
|
||||
UI_LoadResource(tempName);
|
||||
}
|
||||
|
||||
Hunk_FreeTempMemory( shaderSubdivisions );
|
||||
|
||||
+31
-210
@@ -31,6 +31,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
|
||||
// FPS
|
||||
#include <chrono>
|
||||
|
||||
#include <tiki.h>
|
||||
|
||||
qboolean CL_FinishedIntro(void);
|
||||
@@ -72,7 +75,6 @@ fileHandle_t com_journalDataFile; // config files are written here
|
||||
cvar_t *paused;
|
||||
cvar_t *config;
|
||||
cvar_t *fps;
|
||||
float currentfps;
|
||||
cvar_t *com_speeds;
|
||||
cvar_t *developer;
|
||||
cvar_t *com_dedicated;
|
||||
@@ -126,6 +128,18 @@ static char *rd_buffer;
|
||||
static int rd_buffersize;
|
||||
static void (*rd_flush)( char *buffer );
|
||||
|
||||
#define MAX_FPS_TIMES 16
|
||||
|
||||
using fps_clock_t = std::chrono::high_resolution_clock;
|
||||
using fps_time_t = fps_clock_t::time_point;
|
||||
using fps_delta_t = fps_clock_t::duration;
|
||||
|
||||
static int fpsindex;
|
||||
static fps_delta_t fpstimes[MAX_FPS_TIMES];
|
||||
static fps_delta_t fpstotal;
|
||||
static fps_time_t fpslasttime;
|
||||
float currentfps;
|
||||
|
||||
void Com_BeginRedirect (char *buffer, int buffersize, void (*flush)( char *) )
|
||||
{
|
||||
if (!buffer || !buffersize || !flush)
|
||||
@@ -1752,6 +1766,22 @@ void Com_Frame( void ) {
|
||||
com_frameNumber, all, sv, ev, cl, time_game, time_frontend, time_backend );
|
||||
}
|
||||
|
||||
if (fps->integer) {
|
||||
fps_time_t fpstime = fps_clock_t::now();
|
||||
fps_delta_t delta = fpstime - fpslasttime;
|
||||
|
||||
fpstotal = (fpstime - fpslasttime) + (fpstotal - fpstimes[fpsindex]);
|
||||
fpstimes[fpsindex] = fpstime - fpslasttime;
|
||||
fpsindex = (fpsindex + 1) % MAX_FPS_TIMES;
|
||||
fpslasttime = fpstime;
|
||||
|
||||
if (fpstotal.count()) {
|
||||
currentfps = 16.0 / std::chrono::duration<long double>(fpstotal).count();
|
||||
} else {
|
||||
currentfps = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// trace optimization tracking
|
||||
//
|
||||
@@ -1893,23 +1923,10 @@ command line completion
|
||||
===========================================
|
||||
*/
|
||||
|
||||
/*
|
||||
==================
|
||||
Field_Clear
|
||||
==================
|
||||
*/
|
||||
void Field_Clear( field_t *edit ) {
|
||||
memset(edit->buffer, 0, MAX_EDIT_LINE);
|
||||
edit->cursor = 0;
|
||||
edit->scroll = 0;
|
||||
}
|
||||
|
||||
static const char *completionString;
|
||||
static char shortestMatch[MAX_TOKEN_CHARS];
|
||||
static int matchCount;
|
||||
// field we are working on, passed to Field_AutoComplete(&g_consoleCommand for instance)
|
||||
static field_t *completionField;
|
||||
|
||||
/*
|
||||
===============
|
||||
FindMatches
|
||||
@@ -1968,200 +1985,4 @@ static void PrintCvarMatches( const char *s ) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Field_FindFirstSeparator
|
||||
===============
|
||||
*/
|
||||
static char *Field_FindFirstSeparator( char *s )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < strlen( s ); i++ )
|
||||
{
|
||||
if( s[ i ] == ';' )
|
||||
return &s[ i ];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef DEDICATED
|
||||
/*
|
||||
===============
|
||||
Field_CompleteKeyname
|
||||
===============
|
||||
*/
|
||||
static void Field_CompleteKeyname( void )
|
||||
{
|
||||
matchCount = 0;
|
||||
shortestMatch[ 0 ] = 0;
|
||||
|
||||
Key_KeynameCompletion( FindMatches );
|
||||
|
||||
if( matchCount == 0 )
|
||||
return;
|
||||
|
||||
Q_strncpyz( &completionField->buffer[ strlen( completionField->buffer ) -
|
||||
strlen( completionString ) ], shortestMatch,
|
||||
sizeof( completionField->buffer ) );
|
||||
completionField->cursor = ( int )strlen( completionField->buffer );
|
||||
|
||||
if( matchCount == 1 )
|
||||
{
|
||||
Q_strcat( completionField->buffer, sizeof( completionField->buffer ), " " );
|
||||
completionField->cursor++;
|
||||
return;
|
||||
}
|
||||
|
||||
Com_Printf( "]%s\n", completionField->buffer );
|
||||
|
||||
Key_KeynameCompletion( PrintMatches );
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
===============
|
||||
Field_CompleteFilename
|
||||
===============
|
||||
*/
|
||||
static void Field_CompleteFilename( const char *dir,
|
||||
const char *ext, qboolean stripExt )
|
||||
{
|
||||
size_t pos;
|
||||
|
||||
matchCount = 0;
|
||||
shortestMatch[ 0 ] = 0;
|
||||
|
||||
FS_FilenameCompletion( dir, ext, stripExt, FindMatches );
|
||||
|
||||
if( matchCount == 0 )
|
||||
return;
|
||||
|
||||
pos = strlen( completionField->buffer ) - strlen( completionString );
|
||||
Q_strncpyz( &completionField->buffer[ pos ], shortestMatch,
|
||||
sizeof( completionField->buffer ) - pos );
|
||||
completionField->cursor = ( int )strlen( completionField->buffer );
|
||||
|
||||
if( matchCount == 1 )
|
||||
{
|
||||
Q_strcat( completionField->buffer, sizeof( completionField->buffer ), " " );
|
||||
completionField->cursor++;
|
||||
return;
|
||||
}
|
||||
|
||||
Com_Printf( "]%s\n", completionField->buffer );
|
||||
|
||||
FS_FilenameCompletion( dir, ext, stripExt, PrintMatches );
|
||||
}
|
||||
|
||||
static void keyConcatArgs(void) {
|
||||
int i;
|
||||
char* arg;
|
||||
|
||||
for (i = 1; i < Cmd_Argc(); i++) {
|
||||
Q_strcat(completionField->buffer, sizeof(completionField->buffer), " ");
|
||||
arg = Cmd_Argv(i);
|
||||
while (*arg) {
|
||||
if (*arg == ' ') {
|
||||
Q_strcat(completionField->buffer, sizeof(completionField->buffer), "\"");
|
||||
break;
|
||||
}
|
||||
arg++;
|
||||
}
|
||||
Q_strcat(completionField->buffer, sizeof(completionField->buffer), Cmd_Argv(i));
|
||||
if (*arg == ' ') {
|
||||
Q_strcat(completionField->buffer, sizeof(completionField->buffer), "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ConcatRemaining(const char* src, const char* start) {
|
||||
const char* str;
|
||||
|
||||
str = strstr(src, start);
|
||||
if (!str) {
|
||||
keyConcatArgs();
|
||||
return;
|
||||
}
|
||||
|
||||
str += strlen(start);
|
||||
Q_strcat(completionField->buffer, sizeof(completionField->buffer), str);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Field_CompleteCommand
|
||||
|
||||
perform Tab expansion
|
||||
NOTE TTimo this was originally client code only
|
||||
moved to common code when writing tty console for *nix dedicated server
|
||||
===============
|
||||
*/
|
||||
void Field_CompleteCommand(field_t* field) {
|
||||
field_t temp;
|
||||
|
||||
completionField = field;
|
||||
|
||||
// only look at the first token for completion purposes
|
||||
Cmd_TokenizeString(completionField->buffer);
|
||||
|
||||
completionString = Cmd_Argv(0);
|
||||
if (completionString[0] == '\\' || completionString[0] == '/') {
|
||||
completionString++;
|
||||
}
|
||||
matchCount = 0;
|
||||
shortestMatch[0] = 0;
|
||||
|
||||
if (strlen(completionString) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Cmd_CommandCompletion(FindMatches);
|
||||
Cvar_CommandCompletion(FindMatches);
|
||||
|
||||
if (matchCount == 0) {
|
||||
return; // no matches
|
||||
}
|
||||
|
||||
Com_Memcpy(&temp, completionField, sizeof(field_t));
|
||||
|
||||
if (matchCount == 1) {
|
||||
Com_sprintf(completionField->buffer, sizeof(completionField->buffer), "\\%s", shortestMatch);
|
||||
if (Cmd_Argc() == 1) {
|
||||
Q_strcat(completionField->buffer, sizeof(completionField->buffer), " ");
|
||||
}
|
||||
else {
|
||||
ConcatRemaining(temp.buffer, completionString);
|
||||
}
|
||||
completionField->cursor = strlen(completionField->buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
// multiple matches, complete to shortest
|
||||
Com_sprintf(completionField->buffer, sizeof(completionField->buffer), "\\%s", shortestMatch);
|
||||
completionField->cursor = strlen(completionField->buffer);
|
||||
ConcatRemaining(temp.buffer, completionString);
|
||||
|
||||
Com_Printf("]%s\n", completionField->buffer);
|
||||
|
||||
// run through again, printing matches
|
||||
Cmd_CommandCompletion(PrintMatches);
|
||||
Cvar_CommandCompletion(PrintMatches);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Field_AutoComplete
|
||||
|
||||
Perform Tab expansion
|
||||
===============
|
||||
*/
|
||||
void Field_AutoComplete( field_t *field )
|
||||
{
|
||||
completionField = field;
|
||||
|
||||
Field_CompleteCommand(field);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -108,7 +108,7 @@ void* MEM_TempAlloc::CreateBlock(size_t len)
|
||||
// allocate a new block
|
||||
tempBlock_t* prev_block = m_CurrentMemoryBlock;
|
||||
m_CurrentMemoryBlock = (tempBlock_t*)MEM_TempAllocate(
|
||||
sizeof(tempBlock_t) + max(m_BlockSize, len));
|
||||
sizeof(tempBlock_t) + Q_max(m_BlockSize, len));
|
||||
m_CurrentMemoryBlock->prev = prev_block;
|
||||
return m_CurrentMemoryBlock->GetData();
|
||||
}
|
||||
|
||||
+33
-18
@@ -2202,15 +2202,22 @@ void MSG_ReadDeltaEntity( msg_t *msg, entityState_t *from, entityState_t *to,
|
||||
}
|
||||
else bits = field->bits;
|
||||
|
||||
result = MSG_ReadBits( msg, bits );
|
||||
if ( bits == 12 )
|
||||
*(float *)toF = result * 0.087890625f * tmp;
|
||||
else if ( bits == 8 )
|
||||
*(float *)toF = result * 1.411764705882353f * tmp;
|
||||
else if ( bits == 16 )
|
||||
*(float *)toF = result * 0.0054931640625f * tmp;
|
||||
else
|
||||
*(float *)toF = result * (1 << bits) * tmp / 360.0f;
|
||||
result = MSG_ReadBits(msg, bits);
|
||||
switch (bits)
|
||||
{
|
||||
case 8:
|
||||
*(float*)toF = tmp * 360.f / 256.f;
|
||||
break;
|
||||
case 12:
|
||||
*(float*)toF = tmp * result * 360.f / 4096.f;
|
||||
break;
|
||||
case 16:
|
||||
*(float*)toF = tmp * result * 360.f / 65536.f;
|
||||
break;
|
||||
default:
|
||||
*(float*)toF = tmp * 360.f / (1 << bits) * result;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case netFieldType_e::animTime: // time
|
||||
*(float *)toF = MSG_ReadBits( msg, 15 ) * 0.0099999998f;
|
||||
@@ -2842,15 +2849,23 @@ void MSG_ReadDeltaPlayerstate(msg_t *msg, playerState_t *from, playerState_t *to
|
||||
}
|
||||
else bits = field->bits;
|
||||
|
||||
result = MSG_ReadBits( msg, bits );
|
||||
if ( field->bits == 12 )
|
||||
*(float *)toF = result * 0.087890625f * tmp;
|
||||
else if ( field->bits == 8 )
|
||||
*(float *)toF = result * 1.411764705882353f * tmp;
|
||||
else if ( field->bits == 16 )
|
||||
*(float *)toF = result * 0.0054931640625f * tmp;
|
||||
else
|
||||
*(float *)toF = result * (1 << bits) * tmp / 360.0f;
|
||||
result = MSG_ReadBits(msg, bits);
|
||||
|
||||
switch (bits)
|
||||
{
|
||||
case 8:
|
||||
*(float*)toF = tmp * 360.f / 256.f;
|
||||
break;
|
||||
case 12:
|
||||
*(float*)toF = tmp * result * 360.f / 4096.f;
|
||||
break;
|
||||
case 16:
|
||||
*(float*)toF = tmp * result * 360.f / 65536.f;
|
||||
break;
|
||||
default:
|
||||
*(float*)toF = tmp * 360.f / (1 << bits) * result;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case netFieldType_e::coord:
|
||||
tmp = 1.0f;
|
||||
|
||||
+32
-41
@@ -30,7 +30,9 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#define PRODUCT_NAME "OpenMoHAA"
|
||||
#define PRODUCT_VERSION "0.50-alpha"
|
||||
#define PRODUCT_VERSION_NUMBER "0.51"
|
||||
#define PRODUCT_VERSION_STAGE "alpha"
|
||||
#define PRODUCT_VERSION PRODUCT_VERSION_NUMBER "-" PRODUCT_VERSION_STAGE
|
||||
#define PRODUCT_DATE __DATE__
|
||||
|
||||
#if TARGET_GAME_TYPE == 1
|
||||
@@ -501,11 +503,11 @@ extern vec4_t g_color_table[8];
|
||||
#define LERP( a, b, w ) ( ( a ) * ( 1.0f - ( w ) ) + ( b ) * ( w ) )
|
||||
#define LUMA( red, green, blue ) ( 0.2126f * ( red ) + 0.7152f * ( green ) + 0.0722f * ( blue ) )
|
||||
|
||||
#ifndef min
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#ifndef Q_min
|
||||
#define Q_min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef max
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#ifndef Q_max
|
||||
#define Q_max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#define bound(a,minval,maxval) ( ((a) > (minval)) ? ( ((a) < (maxval)) ? (a) : (maxval) ) : (minval) )
|
||||
@@ -1608,7 +1610,7 @@ typedef struct {
|
||||
|
||||
// maybe this is better put somewhere else...
|
||||
typedef struct server_sound_s {
|
||||
float origin[3];
|
||||
vec3_t origin;
|
||||
int entity_number;
|
||||
int channel;
|
||||
short int sound_index;
|
||||
@@ -1712,44 +1714,33 @@ typedef struct playerState_s {
|
||||
|
||||
//====================================================================
|
||||
|
||||
#define BUTTON_ATTACKRIGHT_BITINDEX 0
|
||||
#define BUTTON_ATTACKLEFT_BITINDEX 1
|
||||
#define BUTTON_SNEAK_BITINDEX 2
|
||||
#define BUTTON_RUN_BITINDEX 3
|
||||
#define BUTTON_HOLSTERWEAPON_BITINDEX 4
|
||||
#define BUTTON_USE_BITINDEX 5
|
||||
#define BUTTON_TALK_BITINDEX 6 // displays talk balloon and disables actions
|
||||
#define BUTTON_ANY_BITINDEX 11 // any key whatsoever
|
||||
#define BUTTON_MOUSE_BITINDEX 14 // mouse move
|
||||
|
||||
//
|
||||
// usercmd_t->button bits, many of which are generated by the client system,
|
||||
// so they aren't game/cgame only definitions
|
||||
// so they aren't game-only definitions
|
||||
//
|
||||
#define BUTTON_ATTACK 1 // +/-attackprimary
|
||||
#define BUTTON_ATTACK2 2 // +/-attacksecondary
|
||||
#define BUTTON_RUN 4 // +/-speed
|
||||
// walking can't just be infered from MOVE_RUN
|
||||
// because a key pressed late in the frame will
|
||||
// only generate a small move value for that frame
|
||||
// walking will use different animations and
|
||||
// won't generate footsteps
|
||||
#define BUTTON_ATTACKLEFT_BITINDEX 0
|
||||
#define BUTTON_ATTACKRIGHT_BITINDEX 1
|
||||
#define BUTTON_RUN_BITINDEX 2
|
||||
#define BUTTON_USE_BITINDEX 3
|
||||
#define BUTTON_LEAN_LEFT_BITINDEX 4
|
||||
#define BUTTON_LEAN_RIGHT_BITINDEX 5
|
||||
#define BUTTON_TALK_BITINDEX 6 // displays talk balloon and disables actions
|
||||
#define BUTTON_ANY_BITINDEX 10 // any key whatsoever
|
||||
#define BUTTON_ANY2_BITINDEX 11 // any key whatsoever (regardless of keycatcher)
|
||||
#define BUTTON_MOUSE_BITINDEX 14 // mouse move
|
||||
#define BUTTON_HOLSTER_BITINDEX 15
|
||||
|
||||
#define BUTTON_USE 8
|
||||
#define BUTTON_LEANLEFT 16 // +/-leanleft
|
||||
#define BUTTON_LEANRIGHT 32 // +/-leanright
|
||||
#define BUTTON_NEGATIVE 64
|
||||
|
||||
#define BUTTON_GETFLAG 128
|
||||
#define BUTTON_GUARDBASE 256
|
||||
#define BUTTON_PATROL 512
|
||||
#define BUTTON_FOLLOWME 1024
|
||||
|
||||
#define BUTTON_HOLSTER 32768
|
||||
|
||||
#define BUTTON_TALK ( 1 << BUTTON_TALK_BITINDEX ) // displays talk balloon and disables actions
|
||||
#define BUTTON_ANY ( 1 << BUTTON_ANY_BITINDEX ) // any key whatsoever
|
||||
#define BUTTON_MOUSE ( 1 << BUTTON_MOUSE_BITINDEX )
|
||||
#define BUTTON_ATTACKLEFT (1 << BUTTON_ATTACKLEFT_BITINDEX)
|
||||
#define BUTTON_ATTACKRIGHT (1 << BUTTON_ATTACKRIGHT_BITINDEX)
|
||||
#define BUTTON_RUN (1 << BUTTON_RUN_BITINDEX)
|
||||
#define BUTTON_USE (1 << BUTTON_USE_BITINDEX)
|
||||
#define BUTTON_LEAN_LEFT (1 << BUTTON_LEAN_LEFT_BITINDEX)
|
||||
#define BUTTON_LEAN_RIGHT (1 << BUTTON_LEAN_RIGHT_BITINDEX)
|
||||
#define BUTTON_TALK (1 << BUTTON_TALK_BITINDEX) // displays talk balloon and disables actions
|
||||
#define BUTTON_ANY (1 << BUTTON_ANY_BITINDEX) // any key whatsoever
|
||||
#define BUTTON_ANY2 (1 << BUTTON_ANY_BITINDEX) // any key whatsoever (regardless of keycatcher)
|
||||
#define BUTTON_MOUSE (1 << BUTTON_MOUSE_BITINDEX)
|
||||
#define BUTTON_HOLSTER (1 << BUTTON_HOLSTER_BITINDEX)
|
||||
|
||||
#define WEAPON_COMMAND_USE_PISTOL 1
|
||||
#define WEAPON_COMMAND_USE_RIFLE 2
|
||||
@@ -1767,7 +1758,7 @@ typedef struct playerState_s {
|
||||
#define WEAPON_COMMAND_HOLSTER 14
|
||||
#define WEAPON_COMMAND_DROP 15
|
||||
#define WEAPON_COMMAND_MAX 15
|
||||
#define WEAPON_COMMAND_MASK WEAPON_COMMAND_MAX << 7
|
||||
#define WEAPON_COMMAND_MASK (WEAPON_COMMAND_MAX << 7)
|
||||
|
||||
|
||||
#define MOVE_RUN 120 // if forwardmove or rightmove are >= MOVE_RUN,
|
||||
|
||||
+1
-21
@@ -798,26 +798,6 @@ MISC
|
||||
/*
|
||||
==============================================================
|
||||
|
||||
Edit fields and command line history/completion
|
||||
|
||||
==============================================================
|
||||
*/
|
||||
|
||||
#define MAX_EDIT_LINE 256
|
||||
typedef struct {
|
||||
int cursor;
|
||||
int scroll;
|
||||
int widthInChars;
|
||||
char buffer[MAX_EDIT_LINE];
|
||||
} field_t;
|
||||
|
||||
void Field_Clear( field_t *edit );
|
||||
void Field_CompleteCommand( field_t *edit );
|
||||
void Field_AutoComplete( field_t *edit );
|
||||
|
||||
/*
|
||||
==============================================================
|
||||
|
||||
MISC
|
||||
|
||||
==============================================================
|
||||
@@ -882,10 +862,10 @@ void Com_StartupVariable( const char *match );
|
||||
// only a set with the exact name. Only used during startup.
|
||||
|
||||
|
||||
extern float currentfps;
|
||||
extern cvar_t *paused;
|
||||
extern cvar_t *config;
|
||||
extern cvar_t *fps;
|
||||
extern float currentfps;
|
||||
extern cvar_t *developer;
|
||||
extern cvar_t *com_dedicated;
|
||||
extern cvar_t *com_speeds;
|
||||
|
||||
+15
-29
@@ -708,6 +708,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
|
||||
depthRange = qfalse;
|
||||
|
||||
backEnd.pc.c_surfaces += numDrawSurfs;
|
||||
backEnd.numSpheresUsed = 0;
|
||||
|
||||
for (i = 0, drawSurf = drawSurfs ; i < numDrawSurfs ; i++, drawSurf++) {
|
||||
if ( drawSurf->sort == oldSort ) {
|
||||
@@ -716,7 +717,14 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
|
||||
continue;
|
||||
}
|
||||
oldSort = drawSurf->sort;
|
||||
R_DecomposeSort( drawSurf->sort, &entityNum, &shader, &dlightMap, &bStaticModel );
|
||||
if (*drawSurf->surface != SF_SPRITE) {
|
||||
R_DecomposeSort(drawSurf->sort, &entityNum, &shader, &dlightMap, &bStaticModel);
|
||||
} else {
|
||||
shader = tr.sortedShaders[((refSprite_t*)drawSurf->surface)->shaderNum];
|
||||
entityNum = ENTITYNUM_WORLD;
|
||||
dlightMap = 0;
|
||||
bStaticModel = qfalse;
|
||||
}
|
||||
|
||||
//
|
||||
// change the tess parameters if needed
|
||||
@@ -742,6 +750,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
|
||||
oldDlightMap = dlightMap;
|
||||
}
|
||||
|
||||
backEnd.currentSphere = &backEnd.spareSphere;
|
||||
//
|
||||
// change the modelview matrix if needed
|
||||
//
|
||||
@@ -852,7 +861,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
|
||||
}
|
||||
else
|
||||
{
|
||||
backEnd.currentSphere = &backEnd.spheres[backEnd.currentEntity->lightingSphere];
|
||||
backEnd.currentSphere = &backEnd.spheres[backEnd.numSpheresUsed];
|
||||
backEnd.currentEntity->lightingSphere = backEnd.numSpheresUsed++;
|
||||
backEnd.currentEntity->sphereCalculated = 1;
|
||||
}
|
||||
@@ -969,12 +978,12 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, int componen
|
||||
ri.Error (ERR_DROP, "Draw_StretchRaw: size not a power of 2: %i by %i", cols, rows);
|
||||
}
|
||||
|
||||
GL_Bind( tr.scratchImage[0] );
|
||||
GL_Bind( tr.scratchImage );
|
||||
|
||||
// if the scratchImage isn't in the format we want, specify it as a new texture
|
||||
if ( cols != tr.scratchImage[0]->width || rows != tr.scratchImage[0]->height ) {
|
||||
tr.scratchImage[0]->width = tr.scratchImage[0]->uploadWidth = cols;
|
||||
tr.scratchImage[0]->height = tr.scratchImage[0]->uploadHeight = rows;
|
||||
if ( cols != tr.scratchImage->width || rows != tr.scratchImage->height ) {
|
||||
tr.scratchImage->width = tr.scratchImage->uploadWidth = cols;
|
||||
tr.scratchImage->height = tr.scratchImage->uploadHeight = rows;
|
||||
qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
|
||||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||
@@ -1007,29 +1016,6 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, int componen
|
||||
qglEnd ();
|
||||
}
|
||||
|
||||
void RE_UploadCinematic (int w, int h, int cols, int rows, const byte *data, int client, qboolean dirty) {
|
||||
|
||||
GL_Bind( tr.scratchImage[client] );
|
||||
|
||||
// if the scratchImage isn't in the format we want, specify it as a new texture
|
||||
if ( cols != tr.scratchImage[client]->width || rows != tr.scratchImage[client]->height ) {
|
||||
tr.scratchImage[client]->width = tr.scratchImage[client]->uploadWidth = cols;
|
||||
tr.scratchImage[client]->height = tr.scratchImage[client]->uploadHeight = rows;
|
||||
qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
|
||||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
|
||||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
|
||||
} else {
|
||||
if (dirty) {
|
||||
// otherwise, just subimage upload it so that drivers can tell we are going to be changing
|
||||
// it and don't try and do a texture compression
|
||||
qglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
RB_SetColor
|
||||
|
||||
+92
-145
@@ -261,6 +261,14 @@ static void R_LoadLightmaps(gamelump_t* l) {
|
||||
if ( r_lightmap->integer == 2 ) {
|
||||
ri.Printf( PRINT_ALL, "Brightest lightmap value: %d\n", ( int ) ( maxIntensity * 255 ) );
|
||||
}
|
||||
|
||||
if (r_fastdlights->integer) {
|
||||
s_worldData.lighting = NULL;
|
||||
}
|
||||
else {
|
||||
s_worldData.lighting = ri.Hunk_Alloc(l->length);
|
||||
Com_Memcpy(s_worldData.lighting, l->buffer, l->length);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -478,7 +486,7 @@ void R_UnpackTerraPatch(cTerraPatch_t* pPacked, cTerraPatchUnpacked_t* pUnpacked
|
||||
pUnpacked->t = ((float)pPacked->t + 0.5) * 0.0078125;
|
||||
|
||||
if( s_worldData.lighting ) {
|
||||
pUnpacked->drawinfo.lmData = &s_worldData.lighting[ 3 * ( ( pPacked->t << 7 ) + pPacked->s + ( pPacked->iLightMap << 14 ) ) ];
|
||||
pUnpacked->drawinfo.lmData = &s_worldData.lighting[pPacked->iLightMap * (LIGHTMAP_SIZE * LIGHTMAP_SIZE * 3) + 3 * pPacked->s + 3 * 128 * pPacked->t];
|
||||
} else {
|
||||
pUnpacked->drawinfo.lmData = NULL;
|
||||
}
|
||||
@@ -607,9 +615,6 @@ static void ParseFace( dsurface_t *ds, drawVert_t *verts, msurface_t *surf, int
|
||||
|
||||
lightmapNum = LittleLong( ds->lightmapNum );
|
||||
|
||||
// get fog volume
|
||||
surf->fogIndex = LittleLong( ds->fogNum ) + 1;
|
||||
|
||||
// get shader value
|
||||
surf->shader = ShaderForShaderNum( ds->shaderNum, lightmapNum );
|
||||
if ( r_singleShader->integer && !surf->shader->isSky ) {
|
||||
@@ -661,6 +666,42 @@ static void ParseFace( dsurface_t *ds, drawVert_t *verts, msurface_t *surf, int
|
||||
SetPlaneSignbits( &cv->plane );
|
||||
cv->plane.type = PlaneTypeForNormal( cv->plane.normal );
|
||||
|
||||
if (tr.numLightmaps && lightmapNum != -1 && surf->shader->lightmapIndex >= 0)
|
||||
{
|
||||
float inv;
|
||||
|
||||
cv->lmX = LittleLong(ds->lightmapX);
|
||||
cv->lmY = LittleLong(ds->lightmapY);
|
||||
cv->lmWidth = LittleLong(ds->lightmapWidth);
|
||||
cv->lmHeight = LittleLong(ds->lightmapHeight);
|
||||
|
||||
if (s_worldData.lighting) {
|
||||
cv->lmData = &s_worldData.lighting[lightmapNum * (LIGHTMAP_SIZE * LIGHTMAP_SIZE * 3) + 3 * cv->lmX + 3 * 128 * cv->lmY];
|
||||
} else {
|
||||
cv->lmData = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
cv->lmOrigin[j] = LittleFloat(ds->lightmapOrigin[j]);
|
||||
cv->lmVecs[0][j] = LittleFloat(ds->lightmapVecs[0][j]);
|
||||
cv->lmVecs[1][j] = LittleFloat(ds->lightmapVecs[1][j]);
|
||||
}
|
||||
|
||||
inv = VectorNormalize2(cv->lmVecs[0], cv->lmInverseVecs[0]);
|
||||
cv->lmInverseVecs[0][0] *= 1.0 / inv;
|
||||
cv->lmInverseVecs[0][1] *= 1.0 / inv;
|
||||
cv->lmInverseVecs[0][2] *= 1.0 / inv;
|
||||
|
||||
inv = VectorNormalize2(cv->lmVecs[1], cv->lmInverseVecs[1]);
|
||||
cv->lmInverseVecs[1][0] *= 1.0 / inv;
|
||||
cv->lmInverseVecs[1][1] *= 1.0 / inv;
|
||||
cv->lmInverseVecs[1][2] *= 1.0 / inv;
|
||||
}
|
||||
else
|
||||
{
|
||||
cv->lmData = NULL;
|
||||
}
|
||||
surf->data = (surfaceType_t *)cv;
|
||||
}
|
||||
|
||||
@@ -719,6 +760,19 @@ static void ParseMesh ( dsurface_t *ds, drawVert_t *verts, msurface_t *surf ) {
|
||||
grid = R_SubdividePatchToGrid( width, height, points );
|
||||
surf->data = (surfaceType_t *)grid;
|
||||
|
||||
if (tr.numLightmaps && lightmapNum != -1 && surf->shader->lightmapIndex >= 0)
|
||||
{
|
||||
grid->lmX = LittleLong(ds->lightmapX);
|
||||
grid->lmY = LittleLong(ds->lightmapY);
|
||||
grid->lmWidth = LittleLong(ds->lightmapWidth);
|
||||
grid->lmHeight = LittleLong(ds->lightmapHeight);
|
||||
if (s_worldData.lighting) {
|
||||
grid->lmData = &s_worldData.lighting[lightmapNum * (LIGHTMAP_SIZE * LIGHTMAP_SIZE * 3) + 3 * grid->lmX + 3 * 128 * grid->lmY];
|
||||
} else {
|
||||
grid->lmData = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// copy the level of detail origin, which is the center
|
||||
// of the group of all curves that must subdivide the same
|
||||
// to avoid cracking
|
||||
@@ -1903,129 +1957,13 @@ static void R_LoadPlanes(gamelump_t* l) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_LoadFogs
|
||||
|
||||
=================
|
||||
*/
|
||||
static void R_LoadFogs(gamelump_t* l, gamelump_t* brushesLump, gamelump_t* sidesLump) {
|
||||
int i;
|
||||
fog_t* out;
|
||||
dfog_t* fogs;
|
||||
dbrush_t* brushes, * brush;
|
||||
dbrushside_t* sides;
|
||||
int count, brushesCount, sidesCount;
|
||||
int sideNum;
|
||||
int planeNum;
|
||||
shader_t* shader;
|
||||
float d;
|
||||
int firstSide;
|
||||
|
||||
fogs = l->buffer;
|
||||
if (l->length % sizeof(*fogs)) {
|
||||
ri.Error(ERR_DROP, "LoadMap: funny lump size in %s", s_worldData.name);
|
||||
}
|
||||
count = l->length / sizeof(*fogs);
|
||||
|
||||
// create fog strucutres for them
|
||||
s_worldData.numfogs = count + 1;
|
||||
s_worldData.fogs = ri.Hunk_Alloc(s_worldData.numfogs * sizeof(*out));
|
||||
out = s_worldData.fogs + 1;
|
||||
|
||||
if (!count) {
|
||||
return;
|
||||
}
|
||||
|
||||
brushes = brushesLump->buffer;
|
||||
if (brushesLump->length % sizeof(*brushes)) {
|
||||
ri.Error(ERR_DROP, "LoadMap: funny lump size in %s", s_worldData.name);
|
||||
}
|
||||
brushesCount = brushesLump->length / sizeof(*brushes);
|
||||
|
||||
sides = sidesLump->buffer;
|
||||
if (sidesLump->length % sizeof(*sides)) {
|
||||
ri.Error(ERR_DROP, "LoadMap: funny lump size in %s", s_worldData.name);
|
||||
}
|
||||
sidesCount = sidesLump->length / sizeof(*sides);
|
||||
|
||||
for (i = 0; i < count; i++, fogs++) {
|
||||
out->originalBrushNumber = LittleLong(fogs->brushNum);
|
||||
|
||||
if ((unsigned)out->originalBrushNumber >= brushesCount) {
|
||||
ri.Error(ERR_DROP, "fog brushNumber out of range");
|
||||
}
|
||||
brush = brushes + out->originalBrushNumber;
|
||||
|
||||
firstSide = LittleLong(brush->firstSide);
|
||||
|
||||
if ((unsigned)firstSide > sidesCount - 6) {
|
||||
ri.Error(ERR_DROP, "fog brush sideNumber out of range");
|
||||
}
|
||||
|
||||
// brushes are always sorted with the axial sides first
|
||||
sideNum = firstSide + 0;
|
||||
planeNum = LittleLong(sides[sideNum].planeNum);
|
||||
out->bounds[0][0] = -s_worldData.planes[planeNum].dist;
|
||||
|
||||
sideNum = firstSide + 1;
|
||||
planeNum = LittleLong(sides[sideNum].planeNum);
|
||||
out->bounds[1][0] = s_worldData.planes[planeNum].dist;
|
||||
|
||||
sideNum = firstSide + 2;
|
||||
planeNum = LittleLong(sides[sideNum].planeNum);
|
||||
out->bounds[0][1] = -s_worldData.planes[planeNum].dist;
|
||||
|
||||
sideNum = firstSide + 3;
|
||||
planeNum = LittleLong(sides[sideNum].planeNum);
|
||||
out->bounds[1][1] = s_worldData.planes[planeNum].dist;
|
||||
|
||||
sideNum = firstSide + 4;
|
||||
planeNum = LittleLong(sides[sideNum].planeNum);
|
||||
out->bounds[0][2] = -s_worldData.planes[planeNum].dist;
|
||||
|
||||
sideNum = firstSide + 5;
|
||||
planeNum = LittleLong(sides[sideNum].planeNum);
|
||||
out->bounds[1][2] = s_worldData.planes[planeNum].dist;
|
||||
|
||||
// get information from the shader for fog parameters
|
||||
shader = R_FindShader(fogs->shader, LIGHTMAP_NONE, qtrue, qtrue, qtrue, qtrue);
|
||||
|
||||
out->parms = shader->fogParms;
|
||||
|
||||
out->colorInt = ColorBytes4(shader->fogParms.color[0] * tr.identityLight,
|
||||
shader->fogParms.color[1] * tr.identityLight,
|
||||
shader->fogParms.color[2] * tr.identityLight, 1.0);
|
||||
|
||||
d = shader->fogParms.depthForOpaque < 1 ? 1 : shader->fogParms.depthForOpaque;
|
||||
out->tcScale = 1.0f / (d * 8);
|
||||
|
||||
// set the gradient vector
|
||||
sideNum = LittleLong(fogs->visibleSide);
|
||||
|
||||
if (sideNum == -1) {
|
||||
out->hasSurface = qfalse;
|
||||
}
|
||||
else {
|
||||
out->hasSurface = qtrue;
|
||||
planeNum = LittleLong(sides[firstSide + sideNum].planeNum);
|
||||
VectorSubtract(vec3_origin, s_worldData.planes[planeNum].normal, out->surface);
|
||||
out->surface[3] = -s_worldData.planes[planeNum].dist;
|
||||
}
|
||||
|
||||
out++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_LoadLightGrid
|
||||
|
||||
================
|
||||
*/
|
||||
void R_LoadLightGrid(gamelump_t* l) {
|
||||
void R_LoadLightGrid(gamelump_t* plPal, gamelump_t* plOffsets, gamelump_t* plData) {
|
||||
int i;
|
||||
vec3_t maxs;
|
||||
int numGridPoints;
|
||||
@@ -2034,35 +1972,51 @@ void R_LoadLightGrid(gamelump_t* l) {
|
||||
|
||||
w = &s_worldData;
|
||||
|
||||
w->lightGridInverseSize[0] = 1.0f / w->lightGridSize[0];
|
||||
w->lightGridInverseSize[1] = 1.0f / w->lightGridSize[1];
|
||||
w->lightGridInverseSize[2] = 1.0f / w->lightGridSize[2];
|
||||
if (!plPal->buffer || !plOffsets->buffer || !plData->buffer) {
|
||||
ri.Printf(PRINT_WARNING, "WARNING: No light grid data present\n");
|
||||
w->lightGridOffsets = 0;
|
||||
w->lightGridData = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
w->lightGridSize[0] = 32.0;
|
||||
w->lightGridSize[1] = 32.0;
|
||||
w->lightGridSize[2] = 32.0;
|
||||
w->lightGridOOSize[0] = 1.0f / w->lightGridSize[0];
|
||||
w->lightGridOOSize[1] = 1.0f / w->lightGridSize[1];
|
||||
w->lightGridOOSize[2] = 1.0f / w->lightGridSize[2];
|
||||
|
||||
wMins = w->bmodels[0].bounds[0];
|
||||
wMaxs = w->bmodels[0].bounds[1];
|
||||
|
||||
for ( i = 0 ; i < 3 ; i++ ) {
|
||||
w->lightGridOrigin[i] = w->lightGridSize[i] * ceil( wMins[i] / w->lightGridSize[i] );
|
||||
w->lightGridMins[i] = w->lightGridSize[i] * ceil( wMins[i] / w->lightGridSize[i] );
|
||||
maxs[i] = w->lightGridSize[i] * floor( wMaxs[i] / w->lightGridSize[i] );
|
||||
w->lightGridBounds[i] = (maxs[i] - w->lightGridOrigin[i])/w->lightGridSize[i] + 1;
|
||||
w->lightGridBounds[i] = (maxs[i] - w->lightGridMins[i])/w->lightGridSize[i] + 1;
|
||||
}
|
||||
|
||||
numGridPoints = w->lightGridBounds[0] * w->lightGridBounds[1] * w->lightGridBounds[2];
|
||||
numGridPoints = w->lightGridBounds[0] * w->lightGridBounds[1] + w->lightGridBounds[0];
|
||||
|
||||
if (l->length != numGridPoints * 8) {
|
||||
ri.Printf(PRINT_WARNING, "WARNING: light grid mismatch\n");
|
||||
if (plOffsets->length != numGridPoints * 2) {
|
||||
ri.Printf(PRINT_WARNING, "WARNING: light grid offset size mismatch\n");
|
||||
w->lightGridOffsets = NULL;
|
||||
w->lightGridData = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
w->lightGridData = ri.Hunk_Alloc(l->length);
|
||||
Com_Memcpy(w->lightGridData, (void*)l->buffer, l->length);
|
||||
|
||||
// deal with overbright bits
|
||||
for ( i = 0 ; i < numGridPoints ; i++ ) {
|
||||
R_ColorShiftLightingBytesAlpha( &w->lightGridData[i*8], &w->lightGridData[i*8] );
|
||||
R_ColorShiftLightingBytesAlpha( &w->lightGridData[i*8+3], &w->lightGridData[i*8+3] );
|
||||
if (plPal->length != 768) {
|
||||
ri.Printf(PRINT_WARNING, "WARNING: light grid palette size mismatch\n");
|
||||
w->lightGridOffsets = NULL;
|
||||
w->lightGridData = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
w->lightGridOffsets = ri.Hunk_Alloc(plOffsets->length);
|
||||
Com_Memcpy(w->lightGridOffsets, plOffsets->buffer, plOffsets->length);
|
||||
Com_Memcpy(w->lightGridPalette, plPal->buffer, sizeof(s_worldData.lightGridPalette));
|
||||
|
||||
w->lightGridData = ri.Hunk_Alloc(plData->length);
|
||||
Com_Memcpy(w->lightGridData, plData->buffer, plData->length);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2339,13 +2293,7 @@ void RE_LoadWorldMap( const char *name ) {
|
||||
_R(75);
|
||||
R_FreeLump(&lump2);
|
||||
_R(76);
|
||||
numbrushsides = R_LoadLump(h, &header.lumps[LUMP_BRUSHSIDES], &lump2, sizeof(dbrushside_t));
|
||||
numbrushes = R_LoadLump(h, &header.lumps[LUMP_BRUSHES], &lump, sizeof(dbrush_t));
|
||||
numFogs = R_LoadLump(h, &header.lumps[LUMP_DUMMY10], &lump3, sizeof(dfog_t));
|
||||
R_LoadFogs(&lump3, &lump, &lump2);
|
||||
R_FreeLump(&lump);
|
||||
R_FreeLump(&lump2);
|
||||
R_FreeLump(&lump3);
|
||||
numFogs = 0;
|
||||
nummodels = R_LoadLump(h, &header.lumps[LUMP_MODELS], &lump, sizeof(bmodel_t));
|
||||
_R(77);
|
||||
R_LoadSubmodels(&lump);
|
||||
@@ -2364,8 +2312,7 @@ void RE_LoadWorldMap( const char *name ) {
|
||||
_R(84);
|
||||
g_iGridDataSize = R_LoadLump(h, &header.lumps[LUMP_LIGHTGRIDDATA], &lump3, sizeof(byte));
|
||||
_R(85);
|
||||
//R_LoadLightGrid( &lump, &lump2, &lump3 );
|
||||
R_LoadLightGrid(&lump3);
|
||||
R_LoadLightGrid( &lump, &lump2, &lump3 );
|
||||
_R(86);
|
||||
R_FreeLump(&lump);
|
||||
_R(87);
|
||||
|
||||
@@ -42,6 +42,16 @@ R_PerformanceCounters
|
||||
=====================
|
||||
*/
|
||||
void R_PerformanceCounters( void ) {
|
||||
if (fps->integer) {
|
||||
ri.SetPerformanceCounters(
|
||||
backEnd.pc.c_totalIndexes / 3,
|
||||
backEnd.pc.c_vertexes,
|
||||
R_SumOfUsedImages(),
|
||||
pc_save.c_totalIndexes / 3,
|
||||
pc_save.c_vertexes,
|
||||
backEnd.pc.c_characterlights
|
||||
);
|
||||
}
|
||||
if ( !r_speeds->integer ) {
|
||||
// clear the counters even if we aren't printing
|
||||
Com_Memset( &tr.pc, 0, sizeof( tr.pc ) );
|
||||
|
||||
@@ -236,17 +236,17 @@ void RE_DrawBackground_TexSubImage(int cols, int rows, int bgr, byte* data) {
|
||||
format = GL_RGB;
|
||||
}
|
||||
|
||||
GL_Bind(tr.scratchImage[0]);
|
||||
GL_Bind(tr.scratchImage);
|
||||
|
||||
if (cols == tr.scratchImage[0]->width && rows == tr.scratchImage[0]->height && format == tr.scratchImage[0]->internalFormat)
|
||||
if (cols == tr.scratchImage->width && rows == tr.scratchImage->height && format == tr.scratchImage->internalFormat)
|
||||
{
|
||||
qglTexSubImage2D(3553, 0, 0, 0, cols, rows, format, 5121, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
tr.scratchImage[0]->uploadWidth = cols;
|
||||
tr.scratchImage[0]->uploadHeight = rows;
|
||||
tr.scratchImage[0]->internalFormat = format;
|
||||
tr.scratchImage->uploadWidth = cols;
|
||||
tr.scratchImage->uploadHeight = rows;
|
||||
tr.scratchImage->internalFormat = format;
|
||||
qglTexImage2D(GL_TEXTURE_2D, 0, 3, cols, rows, 0, format, 5121, data);
|
||||
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 9729.0);
|
||||
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 9729.0);
|
||||
|
||||
@@ -197,32 +197,13 @@ RB_AddDlightFlares
|
||||
void RB_AddDlightFlares( void ) {
|
||||
dlight_t *l;
|
||||
int i, j, k;
|
||||
fog_t *fog;
|
||||
|
||||
if ( !r_flares->integer ) {
|
||||
return;
|
||||
}
|
||||
|
||||
l = backEnd.refdef.dlights;
|
||||
fog = tr.world->fogs;
|
||||
for (i=0 ; i<backEnd.refdef.num_dlights ; i++, l++) {
|
||||
|
||||
// find which fog volume the light is in
|
||||
for ( j = 1 ; j < tr.world->numfogs ; j++ ) {
|
||||
fog = &tr.world->fogs[j];
|
||||
for ( k = 0 ; k < 3 ; k++ ) {
|
||||
if ( l->origin[k] < fog->bounds[0][k] || l->origin[k] > fog->bounds[1][k] ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( k == 3 ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( j == tr.world->numfogs ) {
|
||||
j = 0;
|
||||
}
|
||||
|
||||
RB_AddFlare( (void *)l, j, l->origin, l->color, NULL );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,8 @@ int gl_filter_max = GL_LINEAR;
|
||||
#define FILE_HASH_SIZE 1024
|
||||
static image_t* hashTable[FILE_HASH_SIZE];
|
||||
|
||||
extern qboolean scr_initialized;
|
||||
|
||||
/*
|
||||
** R_GammaCorrect
|
||||
*/
|
||||
@@ -297,6 +299,10 @@ lighting range
|
||||
*/
|
||||
void R_LightScaleTexture (unsigned *in, int inwidth, int inheight, qboolean only_gamma )
|
||||
{
|
||||
if (!tr.needsLightScale) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( only_gamma )
|
||||
{
|
||||
if ( !glConfig.deviceSupportsGamma )
|
||||
@@ -1881,6 +1887,7 @@ Loads any of the supported image types into a cannonical
|
||||
*/
|
||||
static void R_LoadImage(const char* name, byte** pic, int* width, int* height, qboolean* hasAlpha, int* glCompressMode, int* numMipmaps, int* piMipmapsAvailable) {
|
||||
int len;
|
||||
char tempName[MAX_STRING_TOKENS + 1];
|
||||
|
||||
*hasAlpha = qfalse;
|
||||
*glCompressMode = 0;
|
||||
@@ -1918,6 +1925,12 @@ static void R_LoadImage(const char* name, byte** pic, int* width, int* height, q
|
||||
LoadJPG(name, pic, width, height);
|
||||
*piMipmapsAvailable = 1;
|
||||
}
|
||||
|
||||
if (scr_initialized)
|
||||
{
|
||||
sprintf(tempName, "n%s", name);
|
||||
UI_LoadResource(tempName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2091,6 +2104,7 @@ static void R_CreateDefaultImage( void ) {
|
||||
data[x][DEFAULT_SIZE-1][3] = 255;
|
||||
}
|
||||
tr.defaultImage = R_CreateImage("*default", (byte *)data, DEFAULT_SIZE, DEFAULT_SIZE, 1, 1, qfalse, qfalse, qfalse, qfalse, GL_REPEAT, GL_REPEAT);
|
||||
tr.defaultImage->r_sequence = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2100,6 +2114,8 @@ R_CreateBuiltinImages
|
||||
*/
|
||||
void R_CreateBuiltinImages( void ) {
|
||||
int x,y;
|
||||
int i;
|
||||
byte lightmap_buffer[128 * 128 * 4];
|
||||
byte data[DEFAULT_SIZE][DEFAULT_SIZE][4];
|
||||
|
||||
R_CreateDefaultImage();
|
||||
@@ -2107,6 +2123,7 @@ void R_CreateBuiltinImages( void ) {
|
||||
// we use a solid white image instead of disabling texturing
|
||||
Com_Memset( data, 255, sizeof( data ) );
|
||||
tr.whiteImage = R_CreateImage("*white", (byte *)data, 8, 8, 0, 1, qfalse, qfalse, qfalse, qfalse, GL_REPEAT, GL_REPEAT);
|
||||
tr.whiteImage->r_sequence = -1;
|
||||
|
||||
// with overbright bits active, we need an image which is some fraction of full color,
|
||||
// for default lightmaps, etc
|
||||
@@ -2119,14 +2136,18 @@ void R_CreateBuiltinImages( void ) {
|
||||
}
|
||||
}
|
||||
|
||||
tr.identityLightImage = R_CreateImage("*identityLight", (byte *)data, 8, 8, 0, 1, qfalse, qfalse, qfalse, qfalse, GL_REPEAT, GL_REPEAT);
|
||||
|
||||
|
||||
for(x=0;x<32;x++) {
|
||||
// scratchimage is usually used for cinematic drawing
|
||||
tr.scratchImage[x] = R_CreateImage("*scratch", (byte *)data, DEFAULT_SIZE, DEFAULT_SIZE, 0, 1, qtrue, qfalse, qfalse, qfalse, GL_REPEAT, GL_REPEAT);
|
||||
Com_Memset(lightmap_buffer, 0xFFFFFFFF, sizeof(lightmap_buffer));
|
||||
for (i = 0; i < 15; i++) {
|
||||
tr.dlightImages[i] = R_CreateImage("*lightmapD%i", lightmap_buffer, LIGHTMAP_SIZE, LIGHTMAP_SIZE, 0, 1, qfalse, qfalse, qfalse, 0, GL_CLAMP, GL_CLAMP);
|
||||
tr.dlightImages[i]->r_sequence = -1;
|
||||
}
|
||||
|
||||
tr.identityLightImage = R_CreateImage("*identityLight", (byte *)data, 8, 8, 0, 1, qfalse, qfalse, qfalse, qfalse, GL_REPEAT, GL_REPEAT);
|
||||
tr.identityLightImage->r_sequence = -1;
|
||||
|
||||
tr.scratchImage = R_CreateImage("*scratch", (byte*)data, DEFAULT_SIZE, DEFAULT_SIZE, 0, 1, qtrue, qfalse, qfalse, qfalse, GL_CLAMP, GL_CLAMP);
|
||||
tr.scratchImage->r_sequence = -1;
|
||||
|
||||
R_CreateDlightImage();
|
||||
}
|
||||
|
||||
@@ -2173,7 +2194,6 @@ void R_SetColorMappings( void ) {
|
||||
tr.identityLight = 1.0f / (1 << tr.overbrightBits);
|
||||
tr.identityLightByte = 255 * tr.identityLight;
|
||||
|
||||
|
||||
if ( r_intensity->value <= 1 ) {
|
||||
ri.Cvar_Set( "r_intensity", "1" );
|
||||
}
|
||||
@@ -2185,6 +2205,15 @@ void R_SetColorMappings( void ) {
|
||||
}
|
||||
|
||||
g = r_gamma->value;
|
||||
if (!glConfig.deviceSupportsGamma && g != 1.0) {
|
||||
tr.needsLightScale = qtrue;
|
||||
}
|
||||
else if (r_intensity->value != 1.0) {
|
||||
tr.needsLightScale = qtrue;
|
||||
}
|
||||
else {
|
||||
tr.needsLightScale = qfalse;
|
||||
}
|
||||
|
||||
shift = tr.overbrightBits;
|
||||
|
||||
@@ -2225,6 +2254,10 @@ R_InitImages
|
||||
*/
|
||||
void R_InitImages( void ) {
|
||||
Com_Memset(hashTable, 0, sizeof(hashTable));
|
||||
// clear images
|
||||
Com_Memset(tr.images, 0, sizeof(tr.images));
|
||||
tr.numImages = 0;
|
||||
|
||||
// build brightness translation tables
|
||||
R_SetColorMappings();
|
||||
|
||||
|
||||
@@ -1016,7 +1016,7 @@ void R_Register( void )
|
||||
#else
|
||||
r_smp = ri.Cvar_Get( "r_smp", "0", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
#endif
|
||||
r_ignoreFastPath = ri.Cvar_Get("r_ignoreFastPath", "1", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
r_ignoreFastPath = ri.Cvar_Get("r_ignoreFastPath", "0", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
r_subdivisions = ri.Cvar_Get("r_subdivisions", "4", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
|
||||
//
|
||||
|
||||
+208
-246
@@ -47,6 +47,8 @@ typedef struct {
|
||||
|
||||
dlightInfo_t dli;
|
||||
|
||||
void R_SetupEntityLightingGrid(trRefEntity_t* ent);
|
||||
|
||||
/*
|
||||
===============
|
||||
R_TransformDlights
|
||||
@@ -126,12 +128,17 @@ static byte* R_GetLightGridPalettedColor(int iColor)
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void R_GetLightingGridValue(vec3_t vPos, vec3_t vLight)
|
||||
void R_GetLightingGridValue(const vec3_t vPos, vec3_t vLight)
|
||||
{
|
||||
if (!tr.world || !tr.world->lightGridData || !tr.world->lightGridOffsets) {
|
||||
vLight[0] = vLight[1] = vLight[2] = tr.identityLightByte;
|
||||
}
|
||||
|
||||
vLight[0] = vLight[1] = vLight[2] = tr.identityLightByte;
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void R_GetLightingGridValueFast(vec3_t vPos, vec3_t vLight)
|
||||
void R_GetLightingGridValueFast(const vec3_t vPos, vec3_t vLight)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
@@ -146,6 +153,205 @@ void R_GetLightingForSmoke(vec3_t vLight, vec3_t vOrigin)
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static int RB_GetEntityGridLighting()
|
||||
{
|
||||
int iColor;
|
||||
int i;
|
||||
dlight_t* dl;
|
||||
float power;
|
||||
vec3_t vLight;
|
||||
vec3_t dir;
|
||||
float d;
|
||||
float* lightOrigin;
|
||||
|
||||
lightOrigin = backEnd.currentSphere->traceOrigin;
|
||||
if (!(backEnd.refdef.rdflags & RDF_NOWORLDMODEL) && tr.world->lightGridData) {
|
||||
R_GetLightingGridValue(backEnd.currentSphere->traceOrigin, vLight);
|
||||
} else {
|
||||
vLight[0] = vLight[1] = vLight[2] = tr.identityLight * 150.0;
|
||||
}
|
||||
|
||||
for (i = 0; i < backEnd.refdef.num_dlights; i++) {
|
||||
dl = &backEnd.refdef.dlights[i];
|
||||
VectorSubtract(dl->origin, lightOrigin, dir);
|
||||
d = VectorLengthSquared(dir);
|
||||
|
||||
power = dl->radius * dl->radius;
|
||||
if (power >= d) {
|
||||
d = dl->radius * 7500.0 / d;
|
||||
VectorMA(vLight, d, dl->color, vLight);
|
||||
}
|
||||
}
|
||||
|
||||
if (tr.overbrightShift)
|
||||
{
|
||||
vLight[0] = tr.overbrightMult * vLight[0];
|
||||
vLight[1] = tr.overbrightMult * vLight[1];
|
||||
vLight[2] = tr.overbrightMult * vLight[2];
|
||||
}
|
||||
|
||||
// normalize
|
||||
if (vLight[0] < 255.0 || vLight[1] < 255.0 || vLight[2] < 255.0) {
|
||||
float scale = 255.0 / fmin(vLight[0], fmin(vLight[1], vLight[2]));
|
||||
VectorScale(vLight, scale, vLight);
|
||||
}
|
||||
|
||||
// clamp ambient
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (vLight[i] > tr.identityLightByte) {
|
||||
vLight[i] = tr.identityLightByte;
|
||||
}
|
||||
}
|
||||
|
||||
// save out the byte packet version
|
||||
((byte*)&iColor)[0] = myftol(vLight[0]);
|
||||
((byte*)&iColor)[1] = myftol(vLight[1]);
|
||||
((byte*)&iColor)[2] = myftol(vLight[2]);
|
||||
((byte*)&iColor)[3] = 0xff;
|
||||
|
||||
return iColor;
|
||||
|
||||
#if 0
|
||||
int i;
|
||||
dlight_t* dl;
|
||||
float power;
|
||||
vec3_t dir;
|
||||
float d;
|
||||
vec3_t lightDir;
|
||||
vec3_t lightOrigin;
|
||||
int ambientlightInt = 0;
|
||||
trRefEntity_t *ent = backEnd.currentEntity;
|
||||
trRefdef_t *refdef = &backEnd.refdef;
|
||||
|
||||
//
|
||||
// trace a sample point down to find ambient light
|
||||
//
|
||||
if (ent->e.renderfx & RF_LIGHTING_ORIGIN) {
|
||||
// seperate lightOrigins are needed so an object that is
|
||||
// sinking into the ground can still be lit, and so
|
||||
// multi-part models can be lit identically
|
||||
VectorCopy(ent->e.lightingOrigin, lightOrigin);
|
||||
}
|
||||
else {
|
||||
VectorCopy(ent->e.origin, lightOrigin);
|
||||
}
|
||||
|
||||
// if NOWORLDMODEL, only use dynamic lights (menu system, etc)
|
||||
if (!(refdef->rdflags & RDF_NOWORLDMODEL)
|
||||
&& tr.world->lightGridData) {
|
||||
R_SetupEntityLightingGrid(ent);
|
||||
}
|
||||
else {
|
||||
ent->ambientLight[0] = ent->ambientLight[1] =
|
||||
ent->ambientLight[2] = tr.identityLight * 150;
|
||||
ent->directedLight[0] = ent->directedLight[1] =
|
||||
ent->directedLight[2] = tr.identityLight * 150;
|
||||
VectorCopy(tr.sunDirection, ent->lightDir);
|
||||
}
|
||||
|
||||
// bonus items and view weapons have a fixed minimum add
|
||||
if (1 /* ent->e.renderfx & RF_MINLIGHT */) {
|
||||
// give everything a minimum light add
|
||||
ent->ambientLight[0] += tr.identityLight * 32;
|
||||
ent->ambientLight[1] += tr.identityLight * 32;
|
||||
ent->ambientLight[2] += tr.identityLight * 32;
|
||||
}
|
||||
|
||||
//
|
||||
// modify the light by dynamic lights
|
||||
//
|
||||
d = VectorLength(ent->directedLight);
|
||||
VectorScale(ent->lightDir, d, lightDir);
|
||||
|
||||
for (i = 0; i < refdef->num_dlights; i++) {
|
||||
dl = &refdef->dlights[i];
|
||||
VectorSubtract(dl->origin, lightOrigin, dir);
|
||||
d = VectorNormalize(dir);
|
||||
|
||||
power = DLIGHT_AT_RADIUS * (dl->radius * dl->radius);
|
||||
if (d < DLIGHT_MINIMUM_RADIUS) {
|
||||
d = DLIGHT_MINIMUM_RADIUS;
|
||||
}
|
||||
d = power / (d * d);
|
||||
|
||||
VectorMA(ent->directedLight, d, dl->color, ent->directedLight);
|
||||
VectorMA(lightDir, d, dir, lightDir);
|
||||
}
|
||||
|
||||
// clamp ambient
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (ent->ambientLight[i] > tr.identityLightByte) {
|
||||
ent->ambientLight[i] = tr.identityLightByte;
|
||||
}
|
||||
}
|
||||
|
||||
// save out the byte packet version
|
||||
((byte*)&ambientlightInt)[0] = myftol(ent->ambientLight[0]);
|
||||
((byte*)&ambientlightInt)[1] = myftol(ent->ambientLight[1]);
|
||||
((byte*)&ambientlightInt)[2] = myftol(ent->ambientLight[2]);
|
||||
((byte*)&ambientlightInt)[3] = 0xff;
|
||||
|
||||
// transform the direction to local space
|
||||
VectorNormalize(lightDir);
|
||||
ent->lightDir[0] = DotProduct(lightDir, ent->e.axis[0]);
|
||||
ent->lightDir[1] = DotProduct(lightDir, ent->e.axis[1]);
|
||||
ent->lightDir[2] = DotProduct(lightDir, ent->e.axis[2]);
|
||||
|
||||
return ambientlightInt;
|
||||
#endif
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void RB_SetupEntityGridLighting()
|
||||
{
|
||||
trRefEntity_t* ent;
|
||||
int iColor;
|
||||
|
||||
if (backEnd.currentEntity->bLightGridCalculated) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (ent = backEnd.currentEntity; ent->e.parentEntity != ENTITYNUM_NONE; ent = &backEnd.refdef.entities[ent->e.parentEntity])
|
||||
{
|
||||
trRefEntity_t* newref = &backEnd.refdef.entities[ent->e.parentEntity];
|
||||
if (newref == ent) {
|
||||
assert(!"backEnd.refdef.entities[ent->e.parentEntity] refers to itself\n");
|
||||
iColor = newref->iGridLighting;
|
||||
break;
|
||||
}
|
||||
|
||||
if (newref->bLightGridCalculated) {
|
||||
iColor = newref->iGridLighting;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ent->e.parentEntity == ENTITYNUM_NONE) {
|
||||
iColor = RB_GetEntityGridLighting();
|
||||
}
|
||||
|
||||
ent = backEnd.currentEntity;
|
||||
for (;;)
|
||||
{
|
||||
ent->bLightGridCalculated = 1;
|
||||
ent->iGridLighting = iColor;
|
||||
if (ent->e.parentEntity == ENTITYNUM_NONE) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (ent == &backEnd.refdef.entities[ent->e.parentEntity]) {
|
||||
assert(!"backEnd.refdef.entities[ent->e.parentEntity] refers to itself\n");
|
||||
break;
|
||||
}
|
||||
|
||||
ent = &backEnd.refdef.entities[ent->e.parentEntity];
|
||||
}
|
||||
}
|
||||
|
||||
void RB_SetupStaticModelGridLighting(trRefdef_t* refdef, cStaticModelUnpacked_t* ent, const vec3_t lightOrigin)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
@@ -158,131 +364,6 @@ LIGHT SAMPLING
|
||||
extern cvar_t *r_ambientScale;
|
||||
extern cvar_t *r_directedScale;
|
||||
|
||||
/*
|
||||
=================
|
||||
R_SetupEntityLightingGrid
|
||||
|
||||
=================
|
||||
*/
|
||||
static void R_SetupEntityLightingGrid( trRefEntity_t *ent ) {
|
||||
vec3_t lightOrigin;
|
||||
int pos[3];
|
||||
int i, j;
|
||||
byte *gridData;
|
||||
float frac[3];
|
||||
int gridStep[3];
|
||||
vec3_t direction;
|
||||
float totalFactor;
|
||||
|
||||
if ( ent->e.renderfx & RF_LIGHTING_ORIGIN ) {
|
||||
// seperate lightOrigins are needed so an object that is
|
||||
// sinking into the ground can still be lit, and so
|
||||
// multi-part models can be lit identically
|
||||
VectorCopy( ent->e.lightingOrigin, lightOrigin );
|
||||
} else {
|
||||
VectorCopy( ent->e.origin, lightOrigin );
|
||||
}
|
||||
|
||||
VectorSubtract( lightOrigin, tr.world->lightGridOrigin, lightOrigin );
|
||||
for ( i = 0 ; i < 3 ; i++ ) {
|
||||
float v;
|
||||
|
||||
v = lightOrigin[i]*tr.world->lightGridInverseSize[i];
|
||||
pos[i] = floor( v );
|
||||
frac[i] = v - pos[i];
|
||||
if ( pos[i] < 0 ) {
|
||||
pos[i] = 0;
|
||||
} else if ( pos[i] >= tr.world->lightGridBounds[i] - 1 ) {
|
||||
pos[i] = tr.world->lightGridBounds[i] - 1;
|
||||
}
|
||||
}
|
||||
|
||||
VectorClear( ent->ambientLight );
|
||||
VectorClear( ent->directedLight );
|
||||
VectorClear( direction );
|
||||
|
||||
assert( tr.world->lightGridData ); // bk010103 - NULL with -nolight maps
|
||||
|
||||
// trilerp the light value
|
||||
gridStep[0] = 8;
|
||||
gridStep[1] = 8 * tr.world->lightGridBounds[0];
|
||||
gridStep[2] = 8 * tr.world->lightGridBounds[0] * tr.world->lightGridBounds[1];
|
||||
gridData = tr.world->lightGridData + pos[0] * gridStep[0]
|
||||
+ pos[1] * gridStep[1] + pos[2] * gridStep[2];
|
||||
|
||||
totalFactor = 0;
|
||||
for ( i = 0 ; i < 8 ; i++ ) {
|
||||
float factor;
|
||||
byte *data;
|
||||
int lat, lng;
|
||||
vec3_t normal;
|
||||
#if idppc
|
||||
float d0, d1, d2, d3, d4, d5;
|
||||
#endif
|
||||
factor = 1.0;
|
||||
data = gridData;
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
if ( i & (1<<j) ) {
|
||||
factor *= frac[j];
|
||||
data += gridStep[j];
|
||||
} else {
|
||||
factor *= (1.0f - frac[j]);
|
||||
}
|
||||
}
|
||||
|
||||
if ( !(data[0]+data[1]+data[2]) ) {
|
||||
continue; // ignore samples in walls
|
||||
}
|
||||
totalFactor += factor;
|
||||
#if idppc
|
||||
d0 = data[0]; d1 = data[1]; d2 = data[2];
|
||||
d3 = data[3]; d4 = data[4]; d5 = data[5];
|
||||
|
||||
ent->ambientLight[0] += factor * d0;
|
||||
ent->ambientLight[1] += factor * d1;
|
||||
ent->ambientLight[2] += factor * d2;
|
||||
|
||||
ent->directedLight[0] += factor * d3;
|
||||
ent->directedLight[1] += factor * d4;
|
||||
ent->directedLight[2] += factor * d5;
|
||||
#else
|
||||
ent->ambientLight[0] += factor * data[0];
|
||||
ent->ambientLight[1] += factor * data[1];
|
||||
ent->ambientLight[2] += factor * data[2];
|
||||
|
||||
ent->directedLight[0] += factor * data[3];
|
||||
ent->directedLight[1] += factor * data[4];
|
||||
ent->directedLight[2] += factor * data[5];
|
||||
#endif
|
||||
lat = data[7];
|
||||
lng = data[6];
|
||||
lat *= (FUNCTABLE_SIZE/256);
|
||||
lng *= (FUNCTABLE_SIZE/256);
|
||||
|
||||
// decode X as cos( lat ) * sin( long )
|
||||
// decode Y as sin( lat ) * sin( long )
|
||||
// decode Z as cos( long )
|
||||
|
||||
normal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
|
||||
normal[1] = tr.sinTable[lat] * tr.sinTable[lng];
|
||||
normal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
|
||||
|
||||
VectorMA( direction, factor, normal, direction );
|
||||
}
|
||||
|
||||
if ( totalFactor > 0 && totalFactor < 0.99 ) {
|
||||
totalFactor = 1.0f / totalFactor;
|
||||
VectorScale( ent->ambientLight, totalFactor, ent->ambientLight );
|
||||
VectorScale( ent->directedLight, totalFactor, ent->directedLight );
|
||||
}
|
||||
|
||||
VectorScale( ent->ambientLight, r_ambientScale->value, ent->ambientLight );
|
||||
VectorScale( ent->directedLight, r_directedScale->value, ent->directedLight );
|
||||
|
||||
VectorNormalize2( direction, ent->lightDir );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
LogLight
|
||||
@@ -312,125 +393,6 @@ static void LogLight( trRefEntity_t *ent ) {
|
||||
ri.Printf( PRINT_ALL, "amb:%i dir:%i\n", max1, max2 );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_SetupEntityLighting
|
||||
|
||||
Calculates all the lighting values that will be used
|
||||
by the Calc_* functions
|
||||
=================
|
||||
*/
|
||||
void R_SetupEntityLighting( const trRefdef_t *refdef, trRefEntity_t *ent ) {
|
||||
int i;
|
||||
dlight_t *dl;
|
||||
float power;
|
||||
vec3_t dir;
|
||||
float d;
|
||||
vec3_t lightDir;
|
||||
vec3_t lightOrigin;
|
||||
|
||||
// lighting calculations
|
||||
if ( ent->lightingCalculated ) {
|
||||
return;
|
||||
}
|
||||
ent->lightingCalculated = qtrue;
|
||||
|
||||
//
|
||||
// trace a sample point down to find ambient light
|
||||
//
|
||||
if ( ent->e.renderfx & RF_LIGHTING_ORIGIN ) {
|
||||
// seperate lightOrigins are needed so an object that is
|
||||
// sinking into the ground can still be lit, and so
|
||||
// multi-part models can be lit identically
|
||||
VectorCopy( ent->e.lightingOrigin, lightOrigin );
|
||||
} else {
|
||||
VectorCopy( ent->e.origin, lightOrigin );
|
||||
}
|
||||
|
||||
// if NOWORLDMODEL, only use dynamic lights (menu system, etc)
|
||||
if ( !(refdef->rdflags & RDF_NOWORLDMODEL )
|
||||
&& tr.world->lightGridData ) {
|
||||
R_SetupEntityLightingGrid( ent );
|
||||
} else {
|
||||
ent->ambientLight[0] = ent->ambientLight[1] =
|
||||
ent->ambientLight[2] = tr.identityLight * 150;
|
||||
ent->directedLight[0] = ent->directedLight[1] =
|
||||
ent->directedLight[2] = tr.identityLight * 150;
|
||||
VectorCopy( tr.sunDirection, ent->lightDir );
|
||||
}
|
||||
|
||||
// bonus items and view weapons have a fixed minimum add
|
||||
if ( 1 /* ent->e.renderfx & RF_MINLIGHT */ ) {
|
||||
// give everything a minimum light add
|
||||
ent->ambientLight[0] += tr.identityLight * 32;
|
||||
ent->ambientLight[1] += tr.identityLight * 32;
|
||||
ent->ambientLight[2] += tr.identityLight * 32;
|
||||
}
|
||||
|
||||
//
|
||||
// modify the light by dynamic lights
|
||||
//
|
||||
d = VectorLength( ent->directedLight );
|
||||
VectorScale( ent->lightDir, d, lightDir );
|
||||
|
||||
for ( i = 0 ; i < refdef->num_dlights ; i++ ) {
|
||||
dl = &refdef->dlights[i];
|
||||
VectorSubtract( dl->origin, lightOrigin, dir );
|
||||
d = VectorNormalize( dir );
|
||||
|
||||
power = DLIGHT_AT_RADIUS * ( dl->radius * dl->radius );
|
||||
if ( d < DLIGHT_MINIMUM_RADIUS ) {
|
||||
d = DLIGHT_MINIMUM_RADIUS;
|
||||
}
|
||||
d = power / ( d * d );
|
||||
|
||||
VectorMA( ent->directedLight, d, dl->color, ent->directedLight );
|
||||
VectorMA( lightDir, d, dir, lightDir );
|
||||
}
|
||||
|
||||
// clamp ambient
|
||||
for ( i = 0 ; i < 3 ; i++ ) {
|
||||
if ( ent->ambientLight[i] > tr.identityLightByte ) {
|
||||
ent->ambientLight[i] = tr.identityLightByte;
|
||||
}
|
||||
}
|
||||
|
||||
// save out the byte packet version
|
||||
((byte *)&ent->ambientLightInt)[0] = myftol( ent->ambientLight[0] );
|
||||
((byte *)&ent->ambientLightInt)[1] = myftol( ent->ambientLight[1] );
|
||||
((byte *)&ent->ambientLightInt)[2] = myftol( ent->ambientLight[2] );
|
||||
((byte *)&ent->ambientLightInt)[3] = 0xff;
|
||||
|
||||
// transform the direction to local space
|
||||
VectorNormalize( lightDir );
|
||||
ent->lightDir[0] = DotProduct( lightDir, ent->e.axis[0] );
|
||||
ent->lightDir[1] = DotProduct( lightDir, ent->e.axis[1] );
|
||||
ent->lightDir[2] = DotProduct( lightDir, ent->e.axis[2] );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_LightForPoint
|
||||
=================
|
||||
*/
|
||||
int R_LightForPoint( vec3_t point, vec3_t ambientLight, vec3_t directedLight, vec3_t lightDir )
|
||||
{
|
||||
trRefEntity_t ent;
|
||||
|
||||
// bk010103 - this segfaults with -nolight maps
|
||||
if ( tr.world->lightGridData == NULL )
|
||||
return qfalse;
|
||||
|
||||
Com_Memset(&ent, 0, sizeof(ent));
|
||||
VectorCopy( point, ent.e.origin );
|
||||
R_SetupEntityLightingGrid( &ent );
|
||||
VectorCopy(ent.ambientLight, ambientLight);
|
||||
VectorCopy(ent.directedLight, directedLight);
|
||||
VectorCopy(ent.lightDir, lightDir);
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
void R_ClearRealDlights() {
|
||||
memset(dli.allocated, 0, sizeof(dli.allocated));
|
||||
dli.dlightMap = 0;
|
||||
|
||||
+32
-23
@@ -129,7 +129,7 @@ typedef struct {
|
||||
vec3_t traceOrigin;
|
||||
float radius;
|
||||
struct mnode_s* leaves[8];
|
||||
void(*TessFunction) ();
|
||||
void(*TessFunction) (unsigned char* dstColors);
|
||||
union {
|
||||
unsigned char level[4];
|
||||
int value;
|
||||
@@ -170,17 +170,19 @@ typedef struct {
|
||||
float axisLength; // compensate for non-normalized axis
|
||||
|
||||
qboolean needDlights; // true for bmodels that touch a dlight
|
||||
qboolean lightingCalculated;
|
||||
vec3_t lightDir; // normalized direction towards light
|
||||
vec3_t ambientLight; // color normalized to 0-255
|
||||
int ambientLightInt; // 32 bit rgba packed
|
||||
vec3_t directedLight;
|
||||
|
||||
qboolean bLightGridCalculated;
|
||||
int iGridLighting;
|
||||
float lodpercentage[2];
|
||||
qboolean sphereCalculated;
|
||||
int lightingSphere;
|
||||
|
||||
//
|
||||
// old lighting variables
|
||||
//
|
||||
vec3_t lightDir; // normalized direction towards light
|
||||
vec3_t ambientLight; // color normalized to 0-255
|
||||
int ambientLightInt; // 32 bit rgba packed
|
||||
vec3_t directedLight;
|
||||
} trRefEntity_t;
|
||||
|
||||
typedef struct refSprite_s {
|
||||
@@ -724,9 +726,9 @@ typedef struct drawSurf_s {
|
||||
typedef struct srfPoly_s {
|
||||
surfaceType_t surfaceType;
|
||||
qhandle_t hShader;
|
||||
int fogIndex;
|
||||
int numVerts;
|
||||
polyVert_t *verts;
|
||||
int renderfx;
|
||||
} srfPoly_t;
|
||||
|
||||
typedef struct srfMarkFragment_s {
|
||||
@@ -1048,13 +1050,11 @@ typedef struct {
|
||||
int nummarksurfaces;
|
||||
msurface_t **marksurfaces;
|
||||
|
||||
int numfogs;
|
||||
fog_t *fogs;
|
||||
|
||||
vec3_t lightGridOrigin;
|
||||
vec3_t lightGridMins;
|
||||
vec3_t lightGridSize;
|
||||
vec3_t lightGridInverseSize;
|
||||
vec3_t lightGridOOSize;
|
||||
int lightGridBounds[3];
|
||||
unsigned short* lightGridOffsets;
|
||||
byte *lightGridData;
|
||||
byte lightGridPalette[768];
|
||||
|
||||
@@ -1257,7 +1257,7 @@ typedef struct {
|
||||
const byte *externalVisData; // from RE_SetWorldVisData, shared with CM_Load
|
||||
|
||||
image_t *defaultImage;
|
||||
image_t *scratchImage[32];
|
||||
image_t *scratchImage;
|
||||
image_t *fogImage;
|
||||
image_t *dlightImage; // inverse-quare highlight for projective adding
|
||||
image_t *flareImage;
|
||||
@@ -1820,8 +1820,8 @@ void RB_CheckOverflow( int verts, int indexes );
|
||||
|
||||
void RB_StageIteratorGeneric( void );
|
||||
void RB_StageIteratorSky( void );
|
||||
void RB_StageIteratorVertexLitTexture( void );
|
||||
void RB_StageIteratorLightmappedMultitexture( void );
|
||||
void RB_StageIteratorVertexLitTextureUnfogged( void );
|
||||
void RB_StageIteratorLightmappedMultitextureUnfogged( void );
|
||||
|
||||
void RB_AddQuadStamp( vec3_t origin, vec3_t left, vec3_t up, byte *color );
|
||||
void RB_AddQuadStampExt( vec3_t origin, vec3_t left, vec3_t up, byte *color, float s1, float t1, float s2, float t2 );
|
||||
@@ -1842,6 +1842,7 @@ extern terrainVert_t* g_pVert;
|
||||
|
||||
void R_AddBrushModelSurfaces( trRefEntity_t *e );
|
||||
void R_GetInlineModelBounds(int iIndex, vec3_t vMins, vec3_t vMaxs);
|
||||
int R_SphereInLeafs(vec_t* p, float r, mnode_t** nodes, int nMaxNodes);
|
||||
mnode_t* R_PointInLeaf(const vec3_t p);
|
||||
int R_DlightTerrain(cTerraPatchUnpacked_t* surf, int dlightBits);
|
||||
int R_CheckDlightTerrain(cTerraPatchUnpacked_t* surf, int dlightBits);
|
||||
@@ -1872,17 +1873,18 @@ LIGHTS
|
||||
*/
|
||||
|
||||
void R_DlightBmodel( bmodel_t *bmodel );
|
||||
void R_GetLightingGridValue(const vec3_t vPos, vec3_t vLight);
|
||||
void R_GetLightingForDecal(vec3_t vLight, vec3_t vFacing, vec3_t vOrigin);
|
||||
void R_GetLightingForSmoke(vec3_t vLight, vec3_t vOrigin);
|
||||
void R_SetupEntityLighting( const trRefdef_t *refdef, trRefEntity_t *ent );
|
||||
void RB_SetupEntityGridLighting();
|
||||
void R_TransformDlights( int count, dlight_t *dl, orientationr_t *ori );
|
||||
int R_LightForPoint( vec3_t point, vec3_t ambientLight, vec3_t directedLight, vec3_t lightDir );
|
||||
void RB_Light_Real(const color4ub_t colors);
|
||||
void RB_Light_Real(unsigned char* colors);
|
||||
void RB_Sphere_BuildDLights();
|
||||
void RB_Sphere_SetupEntity();
|
||||
void RB_Grid_SetupEntity();
|
||||
void RB_Grid_SetupStaticModel();
|
||||
void RB_Light_Fullbright(const color4ub_t colors);
|
||||
void RB_Light_Fullbright(unsigned char* colors);
|
||||
void R_Sphere_InitLights();
|
||||
int R_GatherLightSources(const vec3_t vPos, vec3_t* pvLightPos, vec3_t* pvLightIntensity, int iMaxLights);
|
||||
void R_UploadDlights();
|
||||
@@ -1962,7 +1964,7 @@ void RE_AddRefEntityToScene( const refEntity_t *ent, int parentEntityNumber);
|
||||
void RE_AddRefSpriteToScene(const refEntity_t* ent);
|
||||
void RE_AddTerrainMarkToScene(int iTerrainIndex, qhandle_t hShader, int numVerts, const polyVert_t* verts, int renderfx);
|
||||
refEntity_t* RE_GetRenderEntity(int entityNumber);
|
||||
qboolean RE_AddPolyToScene(qhandle_t hShader, int numVerts, const polyVert_t* verts, int numPolys);
|
||||
qboolean RE_AddPolyToScene(qhandle_t hShader, int numVerts, polyVert_t* verts, int renderfx);
|
||||
void RE_AddLightToScene( const vec3_t org, float intensity, float r, float g, float b, int type );
|
||||
void RE_AddAdditiveLightToScene( const vec3_t org, float intensity, float r, float g, float b );
|
||||
void RE_RenderScene( const refdef_t *fd );
|
||||
@@ -2132,7 +2134,6 @@ void R_TransformClipToWindow( const vec4_t clip, const viewParms_t *view, vec4_t
|
||||
void RB_DeformTessGeometry( void );
|
||||
|
||||
void RB_CalcEnvironmentTexCoords( float *dstTexCoords );
|
||||
void RB_CalcFogTexCoords( float *dstTexCoords );
|
||||
void RB_CalcScrollTexCoords( const float scroll[2], float *dstTexCoords );
|
||||
void RB_CalcRotateTexCoords( float rotSpeed, float *dstTexCoords );
|
||||
void RB_CalcScaleTexCoords( const float scale[2], float *dstTexCoords );
|
||||
@@ -2180,6 +2181,14 @@ RENDERER BACK END COMMAND QUEUE
|
||||
|
||||
#define MAX_RENDER_COMMANDS 0x40000
|
||||
|
||||
typedef struct suninfo_s {
|
||||
vec3_t color;
|
||||
vec3_t direction;
|
||||
vec3_t flaredirection;
|
||||
char szFlareName[64];
|
||||
qboolean exists;
|
||||
} suninfo_t;
|
||||
|
||||
typedef struct {
|
||||
byte cmds[MAX_RENDER_COMMANDS];
|
||||
int used;
|
||||
@@ -2253,8 +2262,8 @@ typedef enum {
|
||||
// these are sort of arbitrary limits.
|
||||
// the limits apply to the sum of all scenes in a frame --
|
||||
// the main view, all the 3D icons, etc
|
||||
#define MAX_POLYS 600
|
||||
#define MAX_POLYVERTS 3000
|
||||
#define MAX_POLYS 4096
|
||||
#define MAX_POLYVERTS 16384
|
||||
#define MAX_TERMARKS 1024
|
||||
|
||||
// all of the information needed by the back end must be
|
||||
|
||||
@@ -1094,39 +1094,6 @@ qboolean R_MirrorViewBySurface (drawSurf_t *drawSurf, int entityNum) {
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_SpriteFogNum
|
||||
|
||||
See if a sprite is inside a fog volume
|
||||
=================
|
||||
*/
|
||||
int R_SpriteFogNum( trRefEntity_t *ent ) {
|
||||
int i, j;
|
||||
fog_t *fog;
|
||||
|
||||
if ( tr.refdef.rdflags & RDF_NOWORLDMODEL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for ( i = 1 ; i < tr.world->numfogs ; i++ ) {
|
||||
fog = &tr.world->fogs[i];
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
if ( ent->e.origin[j] - ent->e.radius >= fog->bounds[1][j] ) {
|
||||
break;
|
||||
}
|
||||
if ( ent->e.origin[j] + ent->e.radius <= fog->bounds[0][j] ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( j == 3 ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
==========================================================================================
|
||||
|
||||
|
||||
@@ -871,13 +871,6 @@ void R_AddSkelSurfaces( trRefEntity_t *ent ) {
|
||||
ent->e.hasMorph = qtrue;
|
||||
}
|
||||
|
||||
//
|
||||
// set up lighting now that we know we aren't culled
|
||||
//
|
||||
if( !personalModel || r_shadows->integer > 1 ) {
|
||||
R_SetupEntityLighting( &tr.refdef, ent );
|
||||
}
|
||||
|
||||
//
|
||||
// draw all meshes
|
||||
//
|
||||
|
||||
+39
-68
@@ -131,83 +131,28 @@ RE_AddPolyToScene
|
||||
|
||||
=====================
|
||||
*/
|
||||
qboolean RE_AddPolyToScene( qhandle_t hShader, int numVerts, const polyVert_t *verts, int numPolys ) {
|
||||
qboolean RE_AddPolyToScene(qhandle_t hShader, int numVerts, polyVert_t* verts, int renderfx) {
|
||||
srfPoly_t *poly;
|
||||
int i, j;
|
||||
int fogIndex;
|
||||
fog_t *fog;
|
||||
vec3_t bounds[2];
|
||||
|
||||
if ( !tr.registered ) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if ( !hShader ) {
|
||||
ri.Printf( PRINT_WARNING, "WARNING: RE_AddPolyToScene: NULL poly shader\n");
|
||||
if (numVerts + r_numpolyverts > max_polyverts || r_numpolys >= max_polys) {
|
||||
ri.Printf(PRINT_WARNING, "Exceeded MAX POLYS\n");
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
for ( j = 0; j < numPolys; j++ ) {
|
||||
if ( r_numpolyverts + numVerts > max_polyverts || r_numpolys >= max_polys ) {
|
||||
/*
|
||||
NOTE TTimo this was initially a PRINT_WARNING
|
||||
but it happens a lot with high fighting scenes and particles
|
||||
since we don't plan on changing the const and making for room for those effects
|
||||
simply cut this message to developer only
|
||||
*/
|
||||
ri.Printf( PRINT_DEVELOPER, "WARNING: RE_AddPolyToScene: r_max_polys or r_max_polyverts reached\n");
|
||||
return qfalse;
|
||||
}
|
||||
poly = &backEndData[tr.smpFrame]->polys[r_numpolys];
|
||||
poly->surfaceType = SF_POLY;
|
||||
poly->hShader = hShader;
|
||||
poly->numVerts = numVerts;
|
||||
poly->verts = &backEndData[tr.smpFrame]->polyVerts[r_numpolyverts];
|
||||
poly->renderfx = renderfx;
|
||||
|
||||
poly = &backEndData[tr.smpFrame]->polys[r_numpolys];
|
||||
poly->surfaceType = SF_POLY;
|
||||
poly->hShader = hShader;
|
||||
poly->numVerts = numVerts;
|
||||
poly->verts = &backEndData[tr.smpFrame]->polyVerts[r_numpolyverts];
|
||||
|
||||
Com_Memcpy( poly->verts, &verts[numVerts*j], numVerts * sizeof( *verts ) );
|
||||
|
||||
if ( glConfig.hardwareType == GLHW_RAGEPRO ) {
|
||||
poly->verts->modulate[0] = 255;
|
||||
poly->verts->modulate[1] = 255;
|
||||
poly->verts->modulate[2] = 255;
|
||||
poly->verts->modulate[3] = 255;
|
||||
}
|
||||
// done.
|
||||
r_numpolys++;
|
||||
r_numpolyverts += numVerts;
|
||||
|
||||
// if no world is loaded
|
||||
if ( tr.world == NULL ) {
|
||||
fogIndex = 0;
|
||||
}
|
||||
// see if it is in a fog volume
|
||||
else if ( tr.world->numfogs == 1 ) {
|
||||
fogIndex = 0;
|
||||
} else {
|
||||
// find which fog volume the poly is in
|
||||
VectorCopy( poly->verts[0].xyz, bounds[0] );
|
||||
VectorCopy( poly->verts[0].xyz, bounds[1] );
|
||||
for ( i = 1 ; i < poly->numVerts ; i++ ) {
|
||||
AddPointToBounds( poly->verts[i].xyz, bounds[0], bounds[1] );
|
||||
}
|
||||
for ( fogIndex = 1 ; fogIndex < tr.world->numfogs ; fogIndex++ ) {
|
||||
fog = &tr.world->fogs[fogIndex];
|
||||
if ( bounds[1][0] >= fog->bounds[0][0]
|
||||
&& bounds[1][1] >= fog->bounds[0][1]
|
||||
&& bounds[1][2] >= fog->bounds[0][2]
|
||||
&& bounds[0][0] <= fog->bounds[1][0]
|
||||
&& bounds[0][1] <= fog->bounds[1][1]
|
||||
&& bounds[0][2] <= fog->bounds[1][2] ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( fogIndex == tr.world->numfogs ) {
|
||||
fogIndex = 0;
|
||||
}
|
||||
}
|
||||
poly->fogIndex = fogIndex;
|
||||
}
|
||||
Com_Memcpy(poly->verts, verts, sizeof(polyVert_t) * numVerts);
|
||||
++r_numpolys;
|
||||
r_numpolyverts += numVerts;
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
@@ -268,7 +213,33 @@ void RE_AddRefEntityToScene( const refEntity_t *ent, int parentEntityNumber) {
|
||||
}
|
||||
|
||||
backEndData[tr.smpFrame]->entities[r_numentities].e = *ent;
|
||||
backEndData[tr.smpFrame]->entities[r_numentities].lightingCalculated = qfalse;
|
||||
backEndData[tr.smpFrame]->entities[r_numentities].bLightGridCalculated = qfalse;
|
||||
backEndData[tr.smpFrame]->entities[r_numentities].sphereCalculated = qfalse;
|
||||
|
||||
if (parentEntityNumber != ENTITYNUM_NONE)
|
||||
{
|
||||
int i;
|
||||
|
||||
//
|
||||
// Find the parent entity to attach to
|
||||
//
|
||||
for (i = r_firstSceneEntity; i < r_numentities; i++)
|
||||
{
|
||||
if (backEndData[tr.smpFrame]->entities[i].e.entityNumber == parentEntityNumber)
|
||||
{
|
||||
backEndData[tr.smpFrame]->entities[r_numentities].e.parentEntity = i - r_firstSceneEntity;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == r_numentities) {
|
||||
backEndData[tr.smpFrame]->entities[i].e.parentEntity = ENTITYNUM_NONE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
backEndData[tr.smpFrame]->entities[r_numentities].e.parentEntity = ENTITYNUM_NONE;
|
||||
}
|
||||
|
||||
r_numentities++;
|
||||
}
|
||||
|
||||
+103
-62
@@ -682,43 +682,6 @@ static void ProjectDlightTexture( void ) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===================
|
||||
RB_FogPass
|
||||
|
||||
Blends a fog texture on top of everything else
|
||||
===================
|
||||
*/
|
||||
static void RB_FogPass( void ) {
|
||||
fog_t *fog;
|
||||
int i;
|
||||
|
||||
qglEnableClientState( GL_COLOR_ARRAY );
|
||||
qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.svars.colors );
|
||||
|
||||
qglEnableClientState( GL_TEXTURE_COORD_ARRAY);
|
||||
qglTexCoordPointer( 2, GL_FLOAT, 0, tess.svars.texcoords[0] );
|
||||
|
||||
fog = tr.world->fogs + tess.fogNum;
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++ ) {
|
||||
* ( int * )&tess.svars.colors[i] = fog->colorInt;
|
||||
}
|
||||
|
||||
RB_CalcFogTexCoords( ( float * ) tess.svars.texcoords[0] );
|
||||
|
||||
GL_Bind( tr.fogImage );
|
||||
|
||||
if ( tess.shader->fogPass == FP_EQUAL ) {
|
||||
GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_EQUAL );
|
||||
} else {
|
||||
GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA );
|
||||
}
|
||||
|
||||
R_DrawElements( tess.numIndexes, tess.indexes );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
ComputeColors
|
||||
@@ -810,9 +773,98 @@ static void ComputeColors( shaderStage_t *pStage )
|
||||
break;
|
||||
case CGEN_LIGHTING_SPHERICAL:
|
||||
case CGEN_STATIC:
|
||||
if (!r_drawspherelights->integer)
|
||||
if (!r_drawspherelights->integer) {
|
||||
break;
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
if (!backEnd.currentStaticModel) {
|
||||
if (backEnd.currentSphere->TessFunction) {
|
||||
backEnd.currentSphere->TessFunction((unsigned char*)tess.svars.colors);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!tess.vertexColorValid) {
|
||||
ri.Printf(PRINT_WARNING, "Vertex color specified for shader '%s', but vertex colors are not valid for this model\n", tess.shader->name);
|
||||
}
|
||||
|
||||
if (backEnd.currentStaticModel->useSpecialLighting)
|
||||
{
|
||||
for (i = 0; i < tess.numVertexes; i++)
|
||||
{
|
||||
int j;
|
||||
vec3_t colorout;
|
||||
int r, g, b;
|
||||
|
||||
colorout[0] = tess.vertexColors[i][0];
|
||||
colorout[1] = tess.vertexColors[i][1];
|
||||
colorout[2] = tess.vertexColors[i][2];
|
||||
|
||||
for (j = 0; j < backEnd.currentStaticModel->numdlights; j++)
|
||||
{
|
||||
float ooLightDistSquared;
|
||||
float dot;
|
||||
vec3_t diff;
|
||||
dlight_t* dl;
|
||||
|
||||
dl = &backEnd.refdef.dlights[backEnd.currentStaticModel->dlights[j].index];
|
||||
VectorSubtract(backEnd.currentStaticModel->dlights[j].transformed, tess.xyz[i], diff);
|
||||
|
||||
dot = DotProduct(diff, tess.normal[i]);
|
||||
if (dot >= 0)
|
||||
{
|
||||
float ooLen;
|
||||
|
||||
ooLen = 1.0 / VectorLengthSquared(diff);
|
||||
ooLightDistSquared = dot * (7500.0 * dl->radius * ooLen * sqrt(ooLen));
|
||||
colorout[0] = dl->color[0] * ooLightDistSquared + colorout[0];
|
||||
colorout[1] = dl->color[1] * ooLightDistSquared + colorout[1];
|
||||
colorout[2] = dl->color[2] * ooLightDistSquared + colorout[2];
|
||||
}
|
||||
}
|
||||
|
||||
r = colorout[0];
|
||||
g = colorout[1];
|
||||
b = colorout[2];
|
||||
|
||||
if (tr.overbrightShift)
|
||||
{
|
||||
r = (int)((float)r * tr.overbrightMult);
|
||||
g = (int)((float)g * tr.overbrightMult);
|
||||
b = (int)((float)b * tr.overbrightMult);
|
||||
}
|
||||
|
||||
if (r > 0xFF || g > 0xFF || b > 0xFF)
|
||||
{
|
||||
float t;
|
||||
|
||||
t = 255.0 / (float)Q_max(r, Q_max(g, b));
|
||||
|
||||
r = (int)((float)r * t);
|
||||
g = (int)((float)g * t);
|
||||
b = (int)((float)b * t);
|
||||
}
|
||||
|
||||
tess.svars.colors[i][0] = r;
|
||||
tess.svars.colors[i][1] = g;
|
||||
tess.svars.colors[i][2] = b;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tr.identityLight == 1.0)
|
||||
{
|
||||
Com_Memcpy(tess.svars.colors, tess.vertexColors, tess.numVertexes * sizeof(tess.vertexColors[0]));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < tess.numVertexes; i++) {
|
||||
tess.svars.colors[i][0] = tess.vertexColors[i][0] * tr.identityLight;
|
||||
tess.svars.colors[i][1] = tess.vertexColors[i][1] * tr.identityLight;
|
||||
tess.svars.colors[i][2] = tess.vertexColors[i][2] * tr.identityLight;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CGEN_CONSTANT:
|
||||
RB_CalcColorFromConstant((unsigned char*)tess.svars.colors, pStage->colorConst);
|
||||
@@ -1024,9 +1076,6 @@ static void ComputeTexCoords( shaderStage_t *pStage ) {
|
||||
tess.svars.texcoords[b][i][1] = DotProduct( tess.xyz[i], pStage->bundle[b].tcGenVectors[1] );
|
||||
}
|
||||
break;
|
||||
case TCGEN_FOG:
|
||||
RB_CalcFogTexCoords( ( float * ) tess.svars.texcoords[b] );
|
||||
break;
|
||||
case TCGEN_ENVIRONMENT_MAPPED:
|
||||
RB_CalcEnvironmentTexCoords( ( float * ) tess.svars.texcoords[b] );
|
||||
break;
|
||||
@@ -1284,7 +1333,7 @@ void RB_StageIteratorGeneric( void )
|
||||
/*
|
||||
** RB_StageIteratorVertexLitTexture
|
||||
*/
|
||||
void RB_StageIteratorVertexLitTexture( void )
|
||||
void RB_StageIteratorVertexLitTextureUnfogged( void )
|
||||
{
|
||||
shaderCommands_t *input;
|
||||
shader_t *shader;
|
||||
@@ -1293,10 +1342,16 @@ void RB_StageIteratorVertexLitTexture( void )
|
||||
|
||||
shader = input->shader;
|
||||
|
||||
//
|
||||
// compute colors
|
||||
//
|
||||
RB_CalcDiffuseColor( ( unsigned char * ) tess.svars.colors );
|
||||
if (backEnd.currentSphere->TessFunction && r_drawspherelights->integer) {
|
||||
backEnd.currentSphere->TessFunction((unsigned char*)tess.svars.colors);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// compute colors
|
||||
//
|
||||
RB_CalcLightGridColor((unsigned char*)tess.svars.colors);
|
||||
}
|
||||
|
||||
//
|
||||
// log this call
|
||||
@@ -1343,13 +1398,6 @@ void RB_StageIteratorVertexLitTexture( void )
|
||||
ProjectDlightTexture();
|
||||
}
|
||||
|
||||
//
|
||||
// now do fog
|
||||
//
|
||||
if ( tess.fogNum && tess.shader->fogPass ) {
|
||||
RB_FogPass();
|
||||
}
|
||||
|
||||
//
|
||||
// unlock arrays
|
||||
//
|
||||
@@ -1362,7 +1410,7 @@ void RB_StageIteratorVertexLitTexture( void )
|
||||
|
||||
//define REPLACE_MODE
|
||||
|
||||
void RB_StageIteratorLightmappedMultitexture( void ) {
|
||||
void RB_StageIteratorLightmappedMultitextureUnfogged( void ) {
|
||||
shaderCommands_t *input;
|
||||
|
||||
input = &tess;
|
||||
@@ -1448,13 +1496,6 @@ void RB_StageIteratorLightmappedMultitexture( void ) {
|
||||
ProjectDlightTexture();
|
||||
}
|
||||
|
||||
//
|
||||
// now do fog
|
||||
//
|
||||
if ( tess.fogNum && tess.shader->fogPass ) {
|
||||
RB_FogPass();
|
||||
}
|
||||
|
||||
//
|
||||
// unlock arrays
|
||||
//
|
||||
|
||||
@@ -801,95 +801,6 @@ TEX COORDS
|
||||
====================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
========================
|
||||
RB_CalcFogTexCoords
|
||||
|
||||
To do the clipped fog plane really correctly, we should use
|
||||
projected textures, but I don't trust the drivers and it
|
||||
doesn't fit our shader data.
|
||||
========================
|
||||
*/
|
||||
void RB_CalcFogTexCoords( float *st ) {
|
||||
int i;
|
||||
float *v;
|
||||
float s, t;
|
||||
float eyeT;
|
||||
qboolean eyeOutside;
|
||||
fog_t *fog;
|
||||
vec3_t local;
|
||||
vec4_t fogDistanceVector, fogDepthVector;
|
||||
|
||||
fog = tr.world->fogs + tess.fogNum;
|
||||
|
||||
// all fogging distance is based on world Z units
|
||||
VectorSubtract( backEnd.ori.origin, backEnd.viewParms.ori.origin, local );
|
||||
fogDistanceVector[0] = -backEnd.ori.modelMatrix[2];
|
||||
fogDistanceVector[1] = -backEnd.ori.modelMatrix[6];
|
||||
fogDistanceVector[2] = -backEnd.ori.modelMatrix[10];
|
||||
fogDistanceVector[3] = DotProduct( local, backEnd.viewParms.ori.axis[0] );
|
||||
|
||||
// scale the fog vectors based on the fog's thickness
|
||||
fogDistanceVector[0] *= fog->tcScale;
|
||||
fogDistanceVector[1] *= fog->tcScale;
|
||||
fogDistanceVector[2] *= fog->tcScale;
|
||||
fogDistanceVector[3] *= fog->tcScale;
|
||||
|
||||
// rotate the gradient vector for this orientation
|
||||
if ( fog->hasSurface ) {
|
||||
fogDepthVector[0] = fog->surface[0] * backEnd.ori.axis[0][0] +
|
||||
fog->surface[1] * backEnd.ori.axis[0][1] + fog->surface[2] * backEnd.ori.axis[0][2];
|
||||
fogDepthVector[1] = fog->surface[0] * backEnd.ori.axis[1][0] +
|
||||
fog->surface[1] * backEnd.ori.axis[1][1] + fog->surface[2] * backEnd.ori.axis[1][2];
|
||||
fogDepthVector[2] = fog->surface[0] * backEnd.ori.axis[2][0] +
|
||||
fog->surface[1] * backEnd.ori.axis[2][1] + fog->surface[2] * backEnd.ori.axis[2][2];
|
||||
fogDepthVector[3] = -fog->surface[3] + DotProduct( backEnd.ori.origin, fog->surface );
|
||||
|
||||
eyeT = DotProduct( backEnd.ori.viewOrigin, fogDepthVector ) + fogDepthVector[3];
|
||||
} else {
|
||||
eyeT = 1; // non-surface fog always has eye inside
|
||||
}
|
||||
|
||||
// see if the viewpoint is outside
|
||||
// this is needed for clipping distance even for constant fog
|
||||
|
||||
if ( eyeT < 0 ) {
|
||||
eyeOutside = qtrue;
|
||||
} else {
|
||||
eyeOutside = qfalse;
|
||||
}
|
||||
|
||||
fogDistanceVector[3] += 1.0/512;
|
||||
|
||||
// calculate density for each point
|
||||
for (i = 0, v = tess.xyz[0] ; i < tess.numVertexes ; i++, v += 4) {
|
||||
// calculate the length in fog
|
||||
s = DotProduct( v, fogDistanceVector ) + fogDistanceVector[3];
|
||||
t = DotProduct( v, fogDepthVector ) + fogDepthVector[3];
|
||||
|
||||
// partially clipped fogs use the T axis
|
||||
if ( eyeOutside ) {
|
||||
if ( t < 1.0 ) {
|
||||
t = 1.0/32; // point is outside, so no fogging
|
||||
} else {
|
||||
t = 1.0/32 + 30.0/32 * t / ( t - eyeT ); // cut the distance at the fog plane
|
||||
}
|
||||
} else {
|
||||
if ( t < 0 ) {
|
||||
t = 1.0/32; // point is outside, so no fogging
|
||||
} else {
|
||||
t = 31.0/32;
|
||||
}
|
||||
}
|
||||
|
||||
st[0] = s;
|
||||
st[1] = t;
|
||||
st += 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** RB_CalcEnvironmentTexCoords
|
||||
*/
|
||||
@@ -1099,7 +1010,36 @@ void RB_CalcSpecularAlpha(unsigned char* alphas, float alphaMax, vec3_t lightOri
|
||||
|
||||
void RB_CalcLightGridColor(unsigned char* colors)
|
||||
{
|
||||
// FIXME/ unimplemented
|
||||
int i;
|
||||
|
||||
if (!backEnd.currentEntity) {
|
||||
for (i = 0; i < tess.numVertexes; i++) {
|
||||
colors[i * 4] = backEnd.currentStaticModel->iGridLighting;
|
||||
colors[i * 4 + 1] = backEnd.currentStaticModel->iGridLighting;
|
||||
colors[i * 4 + 2] = backEnd.currentStaticModel->iGridLighting;
|
||||
colors[i * 4 + 3] = backEnd.currentStaticModel->iGridLighting;
|
||||
}
|
||||
}
|
||||
else if (backEnd.currentEntity != &tr.worldEntity) {
|
||||
for (i = 0; i < tess.numVertexes; i++) {
|
||||
colors[i * 4] = backEnd.currentEntity->iGridLighting;
|
||||
colors[i * 4 + 1] = backEnd.currentEntity->iGridLighting;
|
||||
colors[i * 4 + 2] = backEnd.currentEntity->iGridLighting;
|
||||
colors[i * 4 + 3] = backEnd.currentEntity->iGridLighting;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Com_Printf(
|
||||
"##### shader '%s' incorrectly uses rgbGen lightingGrid or lightingSpherical; was rgbGen vertex intended?\n",
|
||||
tess.shader->name);
|
||||
|
||||
for (i = 0; i < tess.numVertexes; i++) {
|
||||
colors[i * 4] = 0xFF;
|
||||
colors[i * 4 + 1] = 0xFF;
|
||||
colors[i * 4 + 2] = 0xFF;
|
||||
colors[i * 4 + 3] = 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RB_CalcAlphaFromDotView(unsigned char* colors, float alphaMin, float alphaMax)
|
||||
|
||||
+231
-102
@@ -625,7 +625,7 @@ static void ParseTexMod( char *_text, shaderStage_t *stage, int cntBundle )
|
||||
}
|
||||
else
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "WARNING: unknown tcMod '%s' in shader '%s'\n", token, shader.name );
|
||||
ri.Printf(PRINT_WARNING, "WARNING: unknown tcMod '%s' in shader '%s'\n", token, shader.name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -635,9 +635,9 @@ static void ParseTexMod( char *_text, shaderStage_t *stage, int cntBundle )
|
||||
ParseStage
|
||||
===================
|
||||
*/
|
||||
static qboolean ParseStage( shaderStage_t *stage, char **text )
|
||||
static qboolean ParseStage(shaderStage_t* stage, char** text)
|
||||
{
|
||||
char *token;
|
||||
char* token;
|
||||
int depthMaskBits = GLS_DEPTHMASK_TRUE, blendSrcBits = 0, blendDstBits = 0, atestBits = 0, depthFuncBits = 0;
|
||||
qboolean depthMaskExplicit = qfalse;
|
||||
int cntBundle = 0;
|
||||
@@ -649,33 +649,33 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
|
||||
stage->noPicMip = shader_noPicMip;
|
||||
stage->force32bit = shader_force32bit;
|
||||
|
||||
while ( 1 )
|
||||
while (1)
|
||||
{
|
||||
token = COM_ParseExt( text, qtrue );
|
||||
if ( !token[0] )
|
||||
token = COM_ParseExt(text, qtrue);
|
||||
if (!token[0])
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "WARNING: no matching '}' found\n" );
|
||||
ri.Printf(PRINT_WARNING, "WARNING: no matching '}' found\n");
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if ( token[0] == '}' )
|
||||
if (token[0] == '}')
|
||||
{
|
||||
break;
|
||||
}
|
||||
// no picmip adjustment
|
||||
else if ( !Q_stricmp( token, "nomipmaps" ) )
|
||||
else if (!Q_stricmp(token, "nomipmaps"))
|
||||
{
|
||||
stage->noMipMaps = qtrue;
|
||||
continue;
|
||||
}
|
||||
// no picmip adjustment
|
||||
else if ( !Q_stricmp( token, "nopicmip" ) )
|
||||
else if (!Q_stricmp(token, "nopicmip"))
|
||||
{
|
||||
stage->noPicMip = qtrue;
|
||||
continue;
|
||||
}
|
||||
// no picmip adjustment
|
||||
else if ( !Q_stricmp( token, "nofog" ) )
|
||||
else if (!Q_stricmp(token, "nofog"))
|
||||
{
|
||||
fogBits = GLS_FOG;
|
||||
continue;
|
||||
@@ -683,36 +683,37 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
|
||||
//
|
||||
// map <name>
|
||||
//
|
||||
else if ( !Q_stricmp( token, "map" ) )
|
||||
else if (!Q_stricmp(token, "map"))
|
||||
{
|
||||
token = COM_ParseExt( text, qfalse );
|
||||
if ( !token[0] )
|
||||
token = COM_ParseExt(text, qfalse);
|
||||
if (!token[0])
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "WARNING: missing parameter for 'map' keyword in shader '%s'\n", shader.name );
|
||||
ri.Printf(PRINT_WARNING, "WARNING: missing parameter for 'map' keyword in shader '%s'\n", shader.name);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( token, "$whiteimage" ) )
|
||||
if (!Q_stricmp(token, "$whiteimage"))
|
||||
{
|
||||
stage->bundle[cntBundle].image[0] = tr.whiteImage;
|
||||
continue;
|
||||
}
|
||||
else if ( !Q_stricmp( token, "$lightmap" ) )
|
||||
else if (!Q_stricmp(token, "$lightmap"))
|
||||
{
|
||||
stage->bundle[cntBundle].isLightmap = qtrue;
|
||||
if ( shader.lightmapIndex < 0 ) {
|
||||
if (shader.lightmapIndex < 0) {
|
||||
stage->bundle[cntBundle].image[0] = tr.whiteImage;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
stage->bundle[cntBundle].image[0] = tr.lightmaps[shader.lightmapIndex];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
stage->bundle[cntBundle].image[0] = R_FindImageFile( token, !stage->noMipMaps, !stage->noPicMip, qfalse, GL_REPEAT, GL_REPEAT );
|
||||
if ( !stage->bundle[cntBundle].image[0] )
|
||||
stage->bundle[cntBundle].image[0] = R_FindImageFile(token, !stage->noMipMaps, !stage->noPicMip, qfalse, GL_REPEAT, GL_REPEAT);
|
||||
if (!stage->bundle[cntBundle].image[0])
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "WARNING: R_FindImageFile could not find '%s' in shader '%s'\n", token, shader.name );
|
||||
ri.Printf(PRINT_WARNING, "WARNING: R_FindImageFile could not find '%s' in shader '%s'\n", token, shader.name);
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
@@ -720,19 +721,58 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
|
||||
//
|
||||
// clampmap <name>
|
||||
//
|
||||
else if ( !Q_stricmp( token, "clampmap" ) )
|
||||
else if (!Q_stricmpn(token, "clampmap", 8))
|
||||
{
|
||||
token = COM_ParseExt( text, qfalse );
|
||||
if ( !token[0] )
|
||||
int clampx, clampy;
|
||||
|
||||
if (!token[8]) {
|
||||
if (!r_forceClampToEdge->value) {
|
||||
clampx = GL_CLAMP;
|
||||
clampy = GL_CLAMP;
|
||||
}
|
||||
else {
|
||||
clampx = GL_CLAMP_TO_EDGE;
|
||||
clampy = GL_CLAMP_TO_EDGE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (token[8] == 'x')
|
||||
{
|
||||
if (!r_forceClampToEdge->value) {
|
||||
clampx = GL_CLAMP;
|
||||
}
|
||||
else {
|
||||
clampx = GL_CLAMP_TO_EDGE;
|
||||
}
|
||||
clampy = GL_CLAMP;
|
||||
}
|
||||
else if (token[8] == 'y')
|
||||
{
|
||||
clampx = GL_CLAMP;
|
||||
if (!r_forceClampToEdge->value) {
|
||||
clampy = GL_CLAMP;
|
||||
}
|
||||
else {
|
||||
clampy = GL_CLAMP_TO_EDGE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ri.Printf(PRINT_WARNING, "WARNING: Converting unknown clampmap type to clampmap\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
token = COM_ParseExt(text, qfalse);
|
||||
if (!token[0])
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "WARNING: missing parameter for 'clampmap' keyword in shader '%s'\n", shader.name );
|
||||
ri.Printf(PRINT_WARNING, "WARNING: missing parameter for 'clampmap' keyword in shader '%s'\n", shader.name);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
stage->bundle[cntBundle].image[0] = R_FindImageFile(token, !stage->noMipMaps, !stage->noPicMip, qfalse, r_forceClampToEdge->value ? GL_CLAMP_TO_EDGE : GL_CLAMP, r_forceClampToEdge->value ? GL_CLAMP_TO_EDGE : GL_CLAMP);
|
||||
if ( !stage->bundle[cntBundle].image[0] )
|
||||
stage->bundle[cntBundle].image[0] = R_FindImageFile(token, !stage->noMipMaps, !stage->noPicMip, qfalse, clampx, clampy);
|
||||
if (!stage->bundle[cntBundle].image[0])
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "WARNING: R_FindImageFile could not find '%s' in shader '%s'\n", token, shader.name );
|
||||
ri.Printf(PRINT_WARNING, "WARNING: R_FindImageFile could not find '%s' in shader '%s'\n", token, shader.name);
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
@@ -871,7 +911,61 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
|
||||
ParseWaveForm( text, &stage->rgbWave );
|
||||
stage->rgbGen = CGEN_WAVEFORM;
|
||||
}
|
||||
else if ( !Q_stricmp( token, "const" ) )
|
||||
else if (!Q_stricmp(token, "colorwave"))
|
||||
{
|
||||
vec3_t v;
|
||||
|
||||
ParseVector(text, 3, v);
|
||||
stage->colorConst[0] = v[0] * 255.0;
|
||||
stage->colorConst[1] = v[1] * 255.0;
|
||||
stage->colorConst[2] = v[2] * 255.0;
|
||||
stage->rgbGen = CGEN_MULTIPLY_BY_WAVEFORM;
|
||||
shader.flags |= 2;
|
||||
}
|
||||
else if (!Q_stricmp(token, "identity"))
|
||||
{
|
||||
stage->rgbGen = CGEN_IDENTITY;
|
||||
}
|
||||
else if (!Q_stricmp(token, "identityLighting"))
|
||||
{
|
||||
stage->rgbGen = CGEN_IDENTITY_LIGHTING;
|
||||
}
|
||||
else if (!Q_stricmp(token, "global"))
|
||||
{
|
||||
stage->rgbGen = CGEN_GLOBAL_COLOR;
|
||||
}
|
||||
else if (!Q_stricmp(token, "entity") || !Q_stricmp(token, "fromentity"))
|
||||
{
|
||||
stage->rgbGen = CGEN_ENTITY;
|
||||
}
|
||||
else if (!Q_stricmp(token, "oneMinusEntity"))
|
||||
{
|
||||
stage->rgbGen = CGEN_ONE_MINUS_ENTITY;
|
||||
}
|
||||
else if (!Q_stricmp(token, "vertex") || !Q_stricmp(token, "fromclient"))
|
||||
{
|
||||
stage->rgbGen = CGEN_VERTEX;
|
||||
if (stage->alphaGen == 0) {
|
||||
stage->alphaGen = AGEN_VERTEX;
|
||||
}
|
||||
}
|
||||
else if (!Q_stricmp(token, "exactVertex"))
|
||||
{
|
||||
stage->rgbGen = CGEN_EXACT_VERTEX;
|
||||
}
|
||||
else if (!Q_stricmp(token, "lightingGrid"))
|
||||
{
|
||||
stage->rgbGen = CGEN_LIGHTING_GRID;
|
||||
}
|
||||
else if (!Q_stricmp(token, "lightingSpherical"))
|
||||
{
|
||||
stage->rgbGen = CGEN_LIGHTING_SPHERICAL;
|
||||
}
|
||||
else if (!Q_stricmp(token, "oneMinusVertex"))
|
||||
{
|
||||
stage->rgbGen = CGEN_ONE_MINUS_VERTEX;
|
||||
}
|
||||
else if ( !Q_stricmp( token, "const" ) || !Q_stricmp(token, "constant"))
|
||||
{
|
||||
vec3_t color;
|
||||
|
||||
@@ -882,44 +976,91 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
|
||||
|
||||
stage->rgbGen = CGEN_CONSTANT;
|
||||
}
|
||||
else if ( !Q_stricmp( token, "identity" ) )
|
||||
else if (!Q_stricmp(token, "static"))
|
||||
{
|
||||
stage->rgbGen = CGEN_IDENTITY;
|
||||
}
|
||||
else if ( !Q_stricmp( token, "identityLighting" ) )
|
||||
{
|
||||
stage->rgbGen = CGEN_IDENTITY_LIGHTING;
|
||||
}
|
||||
else if ( !Q_stricmp( token, "entity" ) )
|
||||
{
|
||||
stage->rgbGen = CGEN_ENTITY;
|
||||
}
|
||||
else if ( !Q_stricmp( token, "oneMinusEntity" ) )
|
||||
{
|
||||
stage->rgbGen = CGEN_ONE_MINUS_ENTITY;
|
||||
}
|
||||
else if ( !Q_stricmp( token, "vertex" ) )
|
||||
{
|
||||
stage->rgbGen = CGEN_VERTEX;
|
||||
if ( stage->alphaGen == 0 ) {
|
||||
stage->rgbGen = CGEN_STATIC;
|
||||
if (stage->alphaGen == AGEN_IDENTITY) {
|
||||
stage->alphaGen = AGEN_VERTEX;
|
||||
}
|
||||
}
|
||||
else if ( !Q_stricmp( token, "exactVertex" ) )
|
||||
else if (!Q_stricmp(token, "sCoord") || !Q_stricmp(token, "tCoord"))
|
||||
{
|
||||
stage->rgbGen = CGEN_EXACT_VERTEX;
|
||||
if (!Q_stricmp(token, "sCoord")) {
|
||||
stage->rgbGen = CGEN_SCOORD;
|
||||
}
|
||||
else {
|
||||
stage->rgbGen = CGEN_TCOORD;
|
||||
}
|
||||
|
||||
stage->alphaMin = 0.0;
|
||||
stage->alphaMax = 1.0;
|
||||
stage->alphaConstMin = 0;
|
||||
stage->alphaConst = -1;
|
||||
|
||||
token = COM_ParseExt(text, qfalse);
|
||||
if (token[0] == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
stage->alphaMin = atof(token);
|
||||
|
||||
token = COM_ParseExt(text, qfalse);
|
||||
if (token[0] == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
stage->alphaMax = atof(token);
|
||||
|
||||
token = COM_ParseExt(text, qfalse);
|
||||
if (token[0] == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
stage->alphaConstMin = atof(token) * 255.0;
|
||||
|
||||
token = COM_ParseExt(text, qfalse);
|
||||
if (token[0] == 0) {
|
||||
ri.Printf(PRINT_WARNING, "WARNING: missing rgbGen sCoord or tCoord parm 'max' in shader '%s'\n", shader.name);
|
||||
continue;
|
||||
}
|
||||
|
||||
stage->alphaConst = atof(token) * 255.0;
|
||||
}
|
||||
else if ( !Q_stricmp( token, "lightingGrid" ) )
|
||||
else if (!Q_stricmp(token, "dot"))
|
||||
{
|
||||
stage->rgbGen = CGEN_LIGHTING_GRID;
|
||||
}
|
||||
else if ( !Q_stricmp( token, "lightingSpherical" ) )
|
||||
stage->rgbGen = CGEN_DOT;
|
||||
stage->alphaMin = 0.0;
|
||||
stage->alphaMax = 1.0;
|
||||
|
||||
token = COM_ParseExt(text, qfalse);
|
||||
if (token[0] == 0) {
|
||||
continue;
|
||||
}
|
||||
stage->alphaMin = atof(token);
|
||||
|
||||
token = COM_ParseExt(text, qfalse);
|
||||
if (token[0] == 0) {
|
||||
continue;
|
||||
}
|
||||
stage->alphaMax = atof(token);
|
||||
}
|
||||
else if (!Q_stricmp(token, "oneminusdot"))
|
||||
{
|
||||
stage->rgbGen = CGEN_LIGHTING_SPHERICAL;
|
||||
}
|
||||
else if ( !Q_stricmp( token, "oneMinusVertex" ) )
|
||||
{
|
||||
stage->rgbGen = CGEN_ONE_MINUS_VERTEX;
|
||||
stage->rgbGen = CGEN_ONE_MINUS_DOT;
|
||||
stage->alphaMin = 0.0;
|
||||
stage->alphaMax = 1.0;
|
||||
|
||||
token = COM_ParseExt(text, qfalse);
|
||||
if (token[0] == 0) {
|
||||
continue;
|
||||
}
|
||||
stage->alphaMin = atof(token);
|
||||
|
||||
token = COM_ParseExt(text, qfalse);
|
||||
if (token[0] == 0) {
|
||||
continue;
|
||||
}
|
||||
stage->alphaMax = atof(token);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1953,6 +2094,14 @@ static qboolean ParseShader( char **text )
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (!(shader.flags & 2)) {
|
||||
shader.flags &= ~1;
|
||||
}
|
||||
|
||||
if ((shader.contentFlags & CONTENTS_FENCE) != 0 && shader.cullType == CT_TWO_SIDED) {
|
||||
shader.cullType = CT_FRONT_SIDED;
|
||||
}
|
||||
|
||||
shader.explicitlyDefined = qtrue;
|
||||
|
||||
return qtrue;
|
||||
@@ -2009,7 +2158,7 @@ static void ComputeStageIteratorFunc( void )
|
||||
{
|
||||
if ( !shader.numDeforms )
|
||||
{
|
||||
shader.optimalStageIteratorFunc = RB_StageIteratorVertexLitTexture;
|
||||
shader.optimalStageIteratorFunc = RB_StageIteratorVertexLitTextureUnfogged;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
@@ -2035,7 +2184,7 @@ static void ComputeStageIteratorFunc( void )
|
||||
{
|
||||
if (unfoggedStages[0].multitextureEnv )
|
||||
{
|
||||
shader.optimalStageIteratorFunc = RB_StageIteratorLightmappedMultitexture;
|
||||
shader.optimalStageIteratorFunc = RB_StageIteratorLightmappedMultitextureUnfogged;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
@@ -2530,16 +2679,16 @@ static shader_t *FinishShader( void ) {
|
||||
//
|
||||
// default texture coordinate generation
|
||||
//
|
||||
for (bundle = 2; bundle > 0; bundle--) {
|
||||
if (pStage->bundle[bundle - 1].isLightmap) {
|
||||
if (pStage->bundle[bundle - 1].tcGen == TCGEN_BAD) {
|
||||
pStage->bundle[bundle - 1].tcGen = TCGEN_LIGHTMAP;
|
||||
for (bundle = 0; bundle < 2; bundle++) {
|
||||
if (pStage->bundle[bundle].isLightmap) {
|
||||
if (pStage->bundle[bundle].tcGen == TCGEN_BAD) {
|
||||
pStage->bundle[bundle].tcGen = TCGEN_LIGHTMAP;
|
||||
}
|
||||
hasLightmapStage = qtrue;
|
||||
}
|
||||
else {
|
||||
if (pStage->bundle[bundle - 1].tcGen == TCGEN_BAD) {
|
||||
pStage->bundle[bundle - 1].tcGen = TCGEN_TEXTURE;
|
||||
if (pStage->bundle[bundle].tcGen == TCGEN_BAD) {
|
||||
pStage->bundle[bundle].tcGen = TCGEN_TEXTURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2552,31 +2701,6 @@ static shader_t *FinishShader( void ) {
|
||||
pStage->bundle[0] = pStage->bundle[1];
|
||||
pStage->bundle[1] = tmpBundle;
|
||||
}
|
||||
|
||||
//
|
||||
// determine sort order and fog color adjustment
|
||||
//
|
||||
if ( ( pStage->stateBits & ( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ) ) &&
|
||||
( unfoggedStages[0].stateBits & ( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ) ) ) {
|
||||
int blendSrcBits = pStage->stateBits & GLS_SRCBLEND_BITS;
|
||||
int blendDstBits = pStage->stateBits & GLS_DSTBLEND_BITS;
|
||||
|
||||
// don't screw with sort order if this is a portal or environment
|
||||
if ( !shader.sort ) {
|
||||
// see through item, like a grill or grate
|
||||
if ( pStage->stateBits & GLS_DEPTHMASK_TRUE ) {
|
||||
shader.sort = SS_SEE_THROUGH;
|
||||
} else {
|
||||
shader.sort = SS_BLEND0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// there are times when you will need to manually apply a sort to
|
||||
// opaque alpha tested shaders that have later blend passes
|
||||
if ( !shader.sort ) {
|
||||
shader.sort = SS_OPAQUE;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -2645,7 +2769,7 @@ static shader_t *FinishShader( void ) {
|
||||
}
|
||||
|
||||
// fogonly shaders don't have any normal passes
|
||||
if (shader.sort == SS_BAD) {
|
||||
if (!shader.sort) {
|
||||
shader.sort = SS_OPAQUE;
|
||||
}
|
||||
|
||||
@@ -2735,17 +2859,22 @@ shader_t* R_FindShader(const char* name, int lightmapIndex, qboolean mipRawImage
|
||||
// with that same strippedName a new default shader is created.
|
||||
if (!Q_stricmp(currentShader->name, strippedName))
|
||||
{
|
||||
if (currentShader->shader && (currentShader->shader->lightmapIndex == lightmapIndex || currentShader->shader->defaultShader))
|
||||
{
|
||||
// match found
|
||||
return currentShader->shader;
|
||||
}
|
||||
// shader text found, but it has no shared assigned
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!currentShader) {
|
||||
if (currentShader)
|
||||
{
|
||||
for (sh = currentShader->shader; sh; sh = sh->next)
|
||||
{
|
||||
if (sh->lightmapIndex == lightmapIndex || sh == tr.defaultShader) {
|
||||
return sh;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// create a new shader text
|
||||
currentShader = AddShaderTextToHash(strippedName, hash);
|
||||
}
|
||||
@@ -3016,9 +3145,9 @@ void R_ShaderList_f (void) {
|
||||
ri.Printf( PRINT_ALL, "gen " );
|
||||
} else if ( shader->optimalStageIteratorFunc == RB_StageIteratorSky ) {
|
||||
ri.Printf( PRINT_ALL, "sky " );
|
||||
} else if ( shader->optimalStageIteratorFunc == RB_StageIteratorLightmappedMultitexture ) {
|
||||
} else if ( shader->optimalStageIteratorFunc == RB_StageIteratorLightmappedMultitextureUnfogged ) {
|
||||
ri.Printf( PRINT_ALL, "lmmt" );
|
||||
} else if ( shader->optimalStageIteratorFunc == RB_StageIteratorVertexLitTexture ) {
|
||||
} else if ( shader->optimalStageIteratorFunc == RB_StageIteratorVertexLitTextureUnfogged ) {
|
||||
ri.Printf( PRINT_ALL, "vlt " );
|
||||
} else {
|
||||
ri.Printf( PRINT_ALL, " " );
|
||||
|
||||
@@ -24,13 +24,40 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "tr_local.h"
|
||||
|
||||
vec3_t spheredef[6];
|
||||
suninfo_t s_sun;
|
||||
static vec3_t ambientlight;
|
||||
static qboolean bEntityOverbright;
|
||||
static int iEntityLightingMax;
|
||||
static int light_reference_count = 0;
|
||||
|
||||
int compare_light_intensities(const void* p1, const void* p2)
|
||||
{
|
||||
return ((const reallightinfo_t*)p2)->fIntensity - ((const reallightinfo_t*)p1)->fIntensity;
|
||||
}
|
||||
|
||||
static void RB_OptimizeLights()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static void RB_Light_CubeMap(const color4ub_t colors)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void RB_Light_Real(const color4ub_t colors)
|
||||
void RB_Light_Real(unsigned char* colors)
|
||||
{
|
||||
int i, j;
|
||||
float* normal;
|
||||
float* xyz;
|
||||
unsigned char* color;
|
||||
vec3_t v;
|
||||
vec3_t colorout;
|
||||
float fDot;
|
||||
reallightinfo_t* pLight;
|
||||
|
||||
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
@@ -42,16 +69,90 @@ static void RB_Sphere_Light_Sun()
|
||||
static qboolean RB_Sphere_CalculateSphereOrigin()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
static bool RB_Sphere_SetupGlobals()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
int i;
|
||||
|
||||
if (backEnd.refdef.rdflags & RDF_NOWORLDMODEL) {
|
||||
if (!(backEnd.refdef.rdflags & RDF_FULLBRIGHT)) {
|
||||
backEnd.currentSphere->TessFunction = &RB_Light_Fullbright;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!(backEnd.refdef.rdflags & RDF_FULLBRIGHT)) {
|
||||
if (!RB_Sphere_CalculateSphereOrigin()) {
|
||||
backEnd.currentSphere->TessFunction = &RB_CalcLightGridColor;
|
||||
|
||||
if (!backEnd.currentEntity->bLightGridCalculated) {
|
||||
RB_SetupEntityGridLighting();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (backEnd.refdef.vieworg[0] == 0 && backEnd.refdef.vieworg[1] == 0 && backEnd.refdef.vieworg[2] == 0) {
|
||||
backEnd.currentSphere->TessFunction = &RB_Light_Fullbright;
|
||||
return false;
|
||||
}
|
||||
|
||||
VectorCopy(backEnd.refdef.vieworg, backEnd.currentSphere->worldOrigin);
|
||||
VectorClear(backEnd.currentSphere->origin);
|
||||
backEnd.currentSphere->radius = 2.0;
|
||||
}
|
||||
|
||||
light_reference_count++;
|
||||
for (i = 0; i < 8; i++) {
|
||||
backEnd.currentSphere->leaves[i] = 0;
|
||||
}
|
||||
|
||||
R_SphereInLeafs(backEnd.currentSphere->worldOrigin, backEnd.currentSphere->radius, backEnd.currentSphere->leaves, 8);
|
||||
|
||||
backEnd.currentSphere->TessFunction = &RB_Light_Real;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool RB_Sphere_ResetPointColors()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
vec3_t light_offset, amb;
|
||||
|
||||
R_GetLightingGridValue(backEnd.currentSphere->worldOrigin, light_offset);
|
||||
light_offset[0] = ambientlight[0] + light_offset[0] * 0.18;
|
||||
light_offset[1] = ambientlight[1] + light_offset[1] * 0.18;
|
||||
light_offset[2] = ambientlight[2] + light_offset[2] * 0.18;
|
||||
if (tr.refdef.rdflags & RDF_FULLBRIGHT)
|
||||
{
|
||||
float fMin = tr.identityLight * 20.0;
|
||||
|
||||
if (fMin <= light_offset[0] || fMin <= light_offset[1] || fMin <= light_offset[2]) {
|
||||
light_offset[0] += fMin;
|
||||
light_offset[1] += fMin;
|
||||
light_offset[2] += fMin;
|
||||
}
|
||||
}
|
||||
|
||||
backEnd.currentSphere->ambient.level[0] = r_entlight_scale->value * tr.overbrightMult * light_offset[0];
|
||||
if (backEnd.currentSphere->ambient.level[0] >= 255.0) {
|
||||
backEnd.currentSphere->ambient.level[0] = -1;
|
||||
}
|
||||
|
||||
backEnd.currentSphere->ambient.level[1] = r_entlight_scale->value * tr.overbrightMult * light_offset[0];
|
||||
if (backEnd.currentSphere->ambient.level[1] >= 255.0) {
|
||||
backEnd.currentSphere->ambient.level[1] = -1;
|
||||
}
|
||||
|
||||
backEnd.currentSphere->ambient.level[2] = r_entlight_scale->value * tr.overbrightMult * light_offset[0];
|
||||
if (backEnd.currentSphere->ambient.level[2] >= 255.0) {
|
||||
backEnd.currentSphere->ambient.level[2] = -1;
|
||||
}
|
||||
|
||||
backEnd.currentSphere->ambient.level[3] = -1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void RB_Sphere_DrawDebugLine(const spherel_t* thislight, float falloff, const vec3_t origin)
|
||||
@@ -81,7 +182,19 @@ void RB_Sphere_BuildDLights()
|
||||
|
||||
void RB_Sphere_SetupEntity()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
if (r_light_nolight->integer)
|
||||
{
|
||||
backEnd.currentSphere->TessFunction = &RB_Light_Fullbright;
|
||||
}
|
||||
else if (RB_Sphere_SetupGlobals() && RB_Sphere_ResetPointColors())
|
||||
{
|
||||
backEnd.currentSphere->numRealLights = 0;
|
||||
RB_Sphere_Light_Sun();
|
||||
RB_Sphere_BuildStaticLights();
|
||||
RB_Sphere_BuildDLights();
|
||||
backEnd.pc.c_characterlights += backEnd.currentSphere->numRealLights;
|
||||
RB_OptimizeLights();
|
||||
}
|
||||
}
|
||||
|
||||
void RB_Grid_SetupEntity()
|
||||
@@ -94,14 +207,100 @@ void RB_Grid_SetupStaticModel()
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void RB_Light_Fullbright(const color4ub_t colors)
|
||||
void RB_Light_Fullbright(unsigned char* colors)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
memset((void*)colors, 0xFF, tess.numVertexes);
|
||||
}
|
||||
|
||||
void R_Sphere_InitLights()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
const char* ents;
|
||||
const char* ret;
|
||||
qboolean bFlareDirSet;
|
||||
|
||||
ents = ri.CM_EntityString();
|
||||
bFlareDirSet = qfalse;
|
||||
s_sun.szFlareName[0] = 0;
|
||||
s_sun.exists = qfalse;
|
||||
|
||||
for (int i = 0; i < 128; i++) {
|
||||
backEnd.spheres[i].TessFunction = &RB_Light_Real;
|
||||
}
|
||||
|
||||
VectorClear(ambientlight);
|
||||
backEnd.spareSphere.TessFunction = &RB_Light_Real;
|
||||
backEnd.currentSphere = &backEnd.spareSphere;
|
||||
bEntityOverbright = qfalse;
|
||||
iEntityLightingMax = tr.identityLightByte;
|
||||
s_sun.color[0] = s_sun.color[1] = s_sun.color[2] = tr.overbrightMult * 70;
|
||||
|
||||
while (ents)
|
||||
{
|
||||
ret = COM_Parse((char**)&ents);
|
||||
if (*ret == '{' || *ret == '}') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(ret, "suncolor") || !strcmp(ret, "sunlight"))
|
||||
{
|
||||
sscanf(COM_Parse((char**)&ents), "%f %f %f", &s_sun.color[0], &s_sun.color[1], &s_sun.color[2]);
|
||||
s_sun.color[0] *= tr.overbrightMult;
|
||||
s_sun.color[1] *= tr.overbrightMult;
|
||||
s_sun.color[2] *= tr.overbrightMult;
|
||||
s_sun.exists = qtrue;
|
||||
}
|
||||
else if (!strcmp(ret, "sundirection"))
|
||||
{
|
||||
vec3_t dir;
|
||||
|
||||
sscanf(COM_Parse((char**)&ents), "%f %f %f", &dir[0], &dir[1], &dir[2]);
|
||||
AngleVectorsLeft(dir, s_sun.direction, 0, 0);
|
||||
|
||||
s_sun.exists = qtrue;
|
||||
if (!bFlareDirSet)
|
||||
{
|
||||
s_sun.flaredirection[0] = s_sun.direction[0];
|
||||
s_sun.flaredirection[1] = s_sun.direction[1];
|
||||
s_sun.flaredirection[2] = s_sun.direction[2];
|
||||
}
|
||||
}
|
||||
else if (!strcmp(ret, "sunflaredirection"))
|
||||
{
|
||||
vec3_t dir;
|
||||
|
||||
sscanf(COM_Parse((char**)&ents), "%f %f %f", &dir[0], &dir[1], &dir[2]);
|
||||
AngleVectorsLeft(dir, s_sun.flaredirection, 0, 0);
|
||||
bFlareDirSet = qtrue;
|
||||
}
|
||||
else if (!strcmp(ret, "sunflarename"))
|
||||
{
|
||||
strcpy(s_sun.szFlareName, COM_Parse((char**)&ents));
|
||||
}
|
||||
else if (!strcmp(ret, "ambientlight"))
|
||||
{
|
||||
sscanf(COM_Parse((char**)&ents), "%f %f %f", &ambientlight[0], &ambientlight[1], &ambientlight[2]);
|
||||
}
|
||||
else if (!strcmp(ret, "overbright"))
|
||||
{
|
||||
ret = COM_Parse((char**)&ents);
|
||||
if (strcmp(ret, "world") || strcmp(ret, "none"))
|
||||
{
|
||||
bEntityOverbright = qtrue;
|
||||
iEntityLightingMax = 0xFF;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
COM_Parse((char**)&ents);
|
||||
}
|
||||
}
|
||||
|
||||
if (s_sun.exists)
|
||||
{
|
||||
if (!s_sun.szFlareName[0]) {
|
||||
strcpy(s_sun.szFlareName, "sun");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int R_GatherLightSources(const vec3_t vPos, vec3_t* pvLightPos, vec3_t* pvLightIntensity, int iMaxLights)
|
||||
|
||||
@@ -60,7 +60,7 @@ void R_InitStaticModels(void) {
|
||||
{
|
||||
float t;
|
||||
|
||||
t = 255.0 / (float)max(r, max(g, b));
|
||||
t = 255.0 / (float)Q_max(r, Q_max(g, b));
|
||||
|
||||
r = (int)((float)r * t);
|
||||
g = (int)((float)g * t);
|
||||
@@ -114,7 +114,7 @@ void R_InitStaticModels(void) {
|
||||
surf->hShader[k] = sh->index;
|
||||
}
|
||||
else {
|
||||
surf->hShader[k] = NULL;
|
||||
surf->hShader[k] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+33
-11
@@ -343,6 +343,7 @@ RB_SurfaceFace
|
||||
*/
|
||||
void RB_SurfaceFace( srfSurfaceFace_t *surf ) {
|
||||
int i;
|
||||
qboolean needsNormal;
|
||||
unsigned *indices, *tessIndexes;
|
||||
float *v;
|
||||
float *normal;
|
||||
@@ -366,27 +367,48 @@ void RB_SurfaceFace( srfSurfaceFace_t *surf ) {
|
||||
|
||||
tess.numIndexes += surf->numIndices;
|
||||
|
||||
numPoints = surf->numPoints;
|
||||
|
||||
needsNormal = qfalse;
|
||||
if (tess.shader->needsNormal || tess.shader->needsLSpherical || tr.refdef.num_dlights) {
|
||||
needsNormal = qtrue;
|
||||
}
|
||||
|
||||
v = surf->points[0];
|
||||
|
||||
ndx = tess.numVertexes;
|
||||
|
||||
numPoints = surf->numPoints;
|
||||
|
||||
if ( tess.shader->needsNormal || tess.shader->needsLSpherical || tr.refdef.num_dlights ) {
|
||||
if (needsNormal) {
|
||||
normal = surf->plane.normal;
|
||||
for ( i = 0, ndx = tess.numVertexes; i < numPoints; i++, ndx++ ) {
|
||||
VectorCopy( normal, tess.normal[ndx] );
|
||||
}
|
||||
}
|
||||
|
||||
for ( i = 0, v = surf->points[0], ndx = tess.numVertexes; i < numPoints; i++, v += VERTEXSIZE, ndx++ ) {
|
||||
VectorCopy( v, tess.xyz[ndx]);
|
||||
tess.texCoords[ndx][0][0] = v[3];
|
||||
tess.texCoords[ndx][0][1] = v[4];
|
||||
tess.texCoords[ndx][1][0] = v[5];
|
||||
tess.texCoords[ndx][1][1] = v[6];
|
||||
* ( unsigned int * ) &tess.vertexColors[ndx] = * ( unsigned int * ) &v[7];
|
||||
tess.vertexDlightBits[ndx] = dlightBits;
|
||||
if (tess.dlightMap)
|
||||
{
|
||||
|
||||
for (i = 0, v = surf->points[0], ndx = tess.numVertexes; i < numPoints; i++, v += VERTEXSIZE, ndx++) {
|
||||
VectorCopy(v, tess.xyz[ndx]);
|
||||
tess.texCoords[ndx][0][0] = v[3];
|
||||
tess.texCoords[ndx][0][1] = v[4];
|
||||
tess.texCoords[ndx][1][0] = v[5] + surf->lightmapOffset[0];
|
||||
tess.texCoords[ndx][1][1] = v[6] + surf->lightmapOffset[1];
|
||||
*(unsigned int*)&tess.vertexColors[ndx] = *(unsigned int*)&v[7];
|
||||
tess.vertexDlightBits[ndx] = dlightBits;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0, v = surf->points[0], ndx = tess.numVertexes; i < numPoints; i++, v += VERTEXSIZE, ndx++) {
|
||||
VectorCopy(v, tess.xyz[ndx]);
|
||||
tess.texCoords[ndx][0][0] = v[3];
|
||||
tess.texCoords[ndx][0][1] = v[4];
|
||||
tess.texCoords[ndx][1][0] = v[5];
|
||||
tess.texCoords[ndx][1][1] = v[6];
|
||||
*(unsigned int*)&tess.vertexColors[ndx] = *(unsigned int*)&v[7];
|
||||
tess.vertexDlightBits[ndx] = dlightBits;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ static void R_ValidateHeightmapForVertex(terraTri_t* pTri)
|
||||
}
|
||||
}
|
||||
|
||||
static int R_AllocateVert(cTerraPatchUnpacked_t* patch)
|
||||
static terraInt R_AllocateVert(cTerraPatchUnpacked_t* patch)
|
||||
{
|
||||
terraInt iVert = g_vert.iFreeHead;
|
||||
|
||||
@@ -227,12 +227,13 @@ static void R_ReleaseTri(cTerraPatchUnpacked_t* patch, terraInt iTri)
|
||||
|
||||
static int R_ConstChecksForTri(terraTri_t* pTri)
|
||||
{
|
||||
varnodeUnpacked_t vn = *pTri->varnode;
|
||||
varnodeUnpacked_t vn;
|
||||
|
||||
if (pTri->lod == MAX_TERRAIN_LOD) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
vn = *pTri->varnode;
|
||||
vn.s.flags &= 0xF0u;
|
||||
|
||||
if (vn.fVariance == 0.0 && !(pTri->varnode->s.flags & 8)) {
|
||||
@@ -340,7 +341,7 @@ void R_SplitTri(terraInt iSplit, terraInt iNewPt, terraInt iLeft, terraInt iRigh
|
||||
|
||||
int iNextLod = pSplit->lod + 1;
|
||||
int index = pSplit->index;
|
||||
varnodeUnpacked_t* varnode = pSplit->varnode + index;
|
||||
varnodeUnpacked_t* varnode = &pSplit->varnode[index];
|
||||
|
||||
if (pLeft)
|
||||
{
|
||||
@@ -747,8 +748,8 @@ static void R_PreTessellateTerrain()
|
||||
const float t11 = patch->texCoord[1][1][1] - tMin;
|
||||
|
||||
const float lmapSize = (float)(patch->drawinfo.lmapSize - 1) / TERRAIN_LIGHTMAP_SIZE;
|
||||
const float ls = patch->s * lmapSize;
|
||||
const float lt = patch->t * lmapSize;
|
||||
const float ls = patch->s + lmapSize;
|
||||
const float lt = patch->t + lmapSize;
|
||||
|
||||
terraInt iTri0 = R_AllocateTri(patch, qfalse);
|
||||
terraInt iTri1 = R_AllocateTri(patch, qfalse);
|
||||
|
||||
@@ -539,7 +539,10 @@ static void R_RecursiveWorldNode( mnode_t *node, int planeBits, int dlightBits )
|
||||
|
||||
}
|
||||
|
||||
|
||||
int R_SphereInLeafs(vec_t* p, float r, mnode_t** nodes, int nMaxNodes) {
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
===============
|
||||
R_PointInLeaf
|
||||
|
||||
@@ -216,7 +216,11 @@ extern uidef_t uid;
|
||||
extern uiexport_t uie;
|
||||
extern uiimport_t uii;
|
||||
|
||||
|
||||
void UI_Init(void);
|
||||
void UI_Shutdown(void);
|
||||
void UI_InitExports();
|
||||
qboolean CL_FinishedIntro(void);
|
||||
void UI_StartStageKeyEvent(void);
|
||||
void UI_GetMouseState( int *mouseX, int *mouseY, int *flags );
|
||||
int UI_GetCvarInt( const char *name, int def );
|
||||
float UI_GetCvarFloat( const char *name, float def );
|
||||
@@ -226,8 +230,5 @@ void UI_SetCvarInt( const char *cvar, int value );
|
||||
void UI_SetCvarFloat( const char *cvar, float value );
|
||||
void UI_ListFiles( const char *filespec );
|
||||
const char *UI_ConfigString( int index );
|
||||
void UI_Init( void );
|
||||
void UI_Shutdown( void );
|
||||
void UI_InitExports();
|
||||
|
||||
#endif
|
||||
+80
-9
@@ -24,12 +24,48 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
CLASS_DECLARATION( UIWidget, UIList, NULL )
|
||||
{
|
||||
{ &W_LeftMouseDown, &UIList::Pressed },
|
||||
{ &W_LeftMouseUp, &UIList::Released },
|
||||
{ &EV_Layout_AddListItem, &UIList::LayoutAddListItem },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
UIList::UIList()
|
||||
{
|
||||
// FIXME: stub
|
||||
m_arrow_width = 15.0;
|
||||
m_arrow_width = 0.0;
|
||||
m_currentItem = 0;
|
||||
m_next_arrow_region = 0;
|
||||
m_prev_arrow_region = 0;
|
||||
m_prev_arrow_depressed = 0;
|
||||
m_next_arrow_depressed = 0;
|
||||
|
||||
AllowActivate(true);
|
||||
|
||||
m_prev_arrow = uWinMan.RegisterShader("gfx/2d/arrow_left.tga");
|
||||
if (!m_prev_arrow) {
|
||||
uii.Sys_Printf("UIList::Ulist : Could not register shader gfx/2d/arrow_left.tga");
|
||||
}
|
||||
|
||||
|
||||
|
||||
m_next_arrow = uWinMan.RegisterShader("gfx/2d/arrow_right.tga");
|
||||
if (!m_next_arrow) {
|
||||
uii.Sys_Printf("UIList::Ulist : Could not register shader gfx/2d/arrow_right.tga");
|
||||
}
|
||||
}
|
||||
|
||||
UIList::~UIList()
|
||||
{
|
||||
for (int i = m_itemlist.NumObjects(); i > 0; i--)
|
||||
{
|
||||
UIListItem* item = m_itemlist.ObjectAt(i);
|
||||
m_itemlist.RemoveObjectAt(i);
|
||||
delete item;
|
||||
}
|
||||
|
||||
if (m_prev_arrow_region) delete m_prev_arrow_region;
|
||||
if (m_next_arrow_region) delete m_next_arrow_region;
|
||||
}
|
||||
|
||||
void UIList::Draw
|
||||
@@ -48,8 +84,26 @@ qboolean UIList::KeyEvent
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
return qfalse;
|
||||
switch (key)
|
||||
{
|
||||
case K_RIGHTARROW:
|
||||
ScrollNext();
|
||||
UpdateData();
|
||||
if (m_commandhandler) {
|
||||
m_commandhandler(m_itemlist.ObjectAt(m_currentItem)->itemname.c_str(), NULL);
|
||||
}
|
||||
return qtrue;
|
||||
case K_LEFTARROW:
|
||||
ScrollPrev();
|
||||
UpdateData();
|
||||
if (m_commandhandler) {
|
||||
m_commandhandler(m_itemlist.ObjectAt(m_currentItem)->itemname.c_str(), NULL);
|
||||
}
|
||||
return qtrue;
|
||||
default:
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void UIList::CharEvent
|
||||
@@ -58,7 +112,6 @@ void UIList::CharEvent
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UIList::Pressed
|
||||
@@ -85,7 +138,10 @@ void UIList::ScrollNext
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
m_currentItem++;
|
||||
if (m_currentItem > m_itemlist.NumObjects()) {
|
||||
m_currentItem = m_itemlist.NumObjects();
|
||||
}
|
||||
}
|
||||
|
||||
void UIList::ScrollPrev
|
||||
@@ -94,7 +150,10 @@ void UIList::ScrollPrev
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
m_currentItem--;
|
||||
if (m_currentItem < 1) {
|
||||
m_currentItem = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void UIList::FrameInitialized
|
||||
@@ -103,7 +162,8 @@ void UIList::FrameInitialized
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
m_prev_arrow_region = new UIRect2D(m_clippedframe.pos.x, m_clippedframe.pos.y, m_arrow_width, m_frame.size.height);
|
||||
m_next_arrow_region = new UIRect2D(m_clippedframe.size.width - m_arrow_width + m_clippedframe.pos.x, m_clippedframe.pos.y, m_arrow_width, m_frame.size.height);
|
||||
}
|
||||
|
||||
void UIList::LayoutAddListItem
|
||||
@@ -155,6 +215,17 @@ qboolean UIListIndex::KeyEvent
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
return qfalse;
|
||||
switch (key)
|
||||
{
|
||||
case K_RIGHTARROW:
|
||||
ScrollNext();
|
||||
UpdateData();
|
||||
return qtrue;
|
||||
case K_LEFTARROW:
|
||||
ScrollPrev();
|
||||
UpdateData();
|
||||
return qtrue;
|
||||
default:
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
@@ -59,6 +59,7 @@ protected:
|
||||
void AddItem( str item, str alias );
|
||||
public:
|
||||
UIList();
|
||||
~UIList();
|
||||
|
||||
void UpdateUIElement( void );
|
||||
void UpdateData( void );
|
||||
|
||||
+192
-29
@@ -29,7 +29,10 @@ CLASS_DECLARATION( UIWidget, UIListBase, NULL )
|
||||
|
||||
UIListBase::UIListBase()
|
||||
{
|
||||
// FIXME: stub
|
||||
m_currentItem = 0;
|
||||
m_vertscroll = 0;
|
||||
m_bUseVertScroll = 1;
|
||||
AllowActivate(true);
|
||||
}
|
||||
|
||||
void UIListBase::TrySelectItem
|
||||
@@ -58,7 +61,13 @@ void UIListBase::FrameInitialized
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
if (m_vertscroll) {
|
||||
delete m_vertscroll;
|
||||
}
|
||||
|
||||
m_vertscroll = new UIVertScroll();
|
||||
m_vertscroll->InitFrame(this, m_frame.size.width - 16.0, 0.0, 16.0, m_frame.size.height, -1);
|
||||
m_vertscroll->setTopItem(0);
|
||||
}
|
||||
|
||||
int UIListBase::getCurrentItem
|
||||
@@ -67,8 +76,7 @@ int UIListBase::getCurrentItem
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
return 0;
|
||||
return m_currentItem;
|
||||
}
|
||||
|
||||
int UIListBase::getNumItems
|
||||
@@ -77,8 +85,7 @@ int UIListBase::getNumItems
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void UIListBase::DeleteAllItems
|
||||
@@ -87,7 +94,6 @@ void UIListBase::DeleteAllItems
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UIListBase::DeleteItem
|
||||
@@ -96,7 +102,6 @@ void UIListBase::DeleteItem
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
UIVertScroll *UIListBase::GetScrollBar
|
||||
@@ -105,8 +110,7 @@ UIVertScroll *UIListBase::GetScrollBar
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
return NULL;
|
||||
return m_vertscroll;
|
||||
}
|
||||
|
||||
void UIListBase::SetUseScrollBar
|
||||
@@ -115,12 +119,28 @@ void UIListBase::SetUseScrollBar
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
m_bUseVertScroll = bUse;
|
||||
|
||||
if (bUse)
|
||||
{
|
||||
if (!m_vertscroll) {
|
||||
m_vertscroll = new UIVertScroll();
|
||||
}
|
||||
|
||||
m_vertscroll->InitFrame(this, m_frame.size.width - 16.0, 0.0, 16.0, m_frame.size.height, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_vertscroll) {
|
||||
delete m_vertscroll;
|
||||
m_vertscroll = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListItem::ListItem()
|
||||
{
|
||||
// FIXME: stub
|
||||
index = -1;
|
||||
}
|
||||
|
||||
ListItem::ListItem
|
||||
@@ -131,17 +151,71 @@ ListItem::ListItem
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
this->string = string;
|
||||
this->index = index;
|
||||
this->command = command;
|
||||
}
|
||||
|
||||
Event EV_UIListBase_ItemSelected
|
||||
(
|
||||
"listbase_item_selected",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"index",
|
||||
"Signaled when an item is selected"
|
||||
);
|
||||
|
||||
Event EV_UIListBase_ItemDoubleClicked
|
||||
(
|
||||
"listbase_item_doubleclicked",
|
||||
EV_DEFAULT,
|
||||
"i",
|
||||
"index",
|
||||
"Signaled when an item is double clicked"
|
||||
);
|
||||
|
||||
Event EV_Layout_AddListItem
|
||||
(
|
||||
"additem",
|
||||
EV_DEFAULT,
|
||||
"sS",
|
||||
"itemname command",
|
||||
"Add an item to the list"
|
||||
);
|
||||
|
||||
Event EV_Layout_AddConfigstringListItem
|
||||
(
|
||||
"addconfigstringitem",
|
||||
EV_DEFAULT,
|
||||
"iS",
|
||||
"index command",
|
||||
"Add an item to the list that uses a configstring"
|
||||
);
|
||||
|
||||
Event EV_UIListBox_DeleteAllItems
|
||||
(
|
||||
"deleteallitems",
|
||||
EV_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
"Delete all the items from the widget"
|
||||
);
|
||||
|
||||
CLASS_DECLARATION( UIListBase, UIListBox, NULL )
|
||||
{
|
||||
{ &W_LeftMouseDown, &UIListBox::MousePressed },
|
||||
{ &W_LeftMouseUp, &UIListBox::MouseReleased },
|
||||
{ &EV_Layout_AddListItem, &UIListBox::LayoutAddListItem },
|
||||
{ &EV_Layout_AddConfigstringListItem, &UIListBox::LayoutAddConfigstringListItem },
|
||||
{ &EV_UIListBox_DeleteAllItems, &UIListBox::DeleteAllItems },
|
||||
{ &EV_Layout_Font, &UIListBox::SetListFont },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
UIListBox::UIListBox()
|
||||
{
|
||||
// FIXME: stub
|
||||
m_clickState.point.x = 0.0;
|
||||
m_clickState.point.y = 0.0;
|
||||
}
|
||||
|
||||
void UIListBox::Draw
|
||||
@@ -168,7 +242,6 @@ void UIListBox::MouseReleased
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UIListBox::DeleteAllItems
|
||||
@@ -177,7 +250,14 @@ void UIListBox::DeleteAllItems
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
m_itemlist.ClearObjectList();
|
||||
m_currentItem = 0;
|
||||
|
||||
if (m_vertscroll)
|
||||
{
|
||||
m_vertscroll->setNumItems(0);
|
||||
m_vertscroll->setTopItem(0);
|
||||
}
|
||||
}
|
||||
|
||||
void UIListBox::SetListFont
|
||||
@@ -186,7 +266,13 @@ void UIListBox::SetListFont
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
LayoutFont(ev);
|
||||
|
||||
if (m_vertscroll) {
|
||||
m_vertscroll->setPageHeight(m_frame.size.height / m_font->getHeight(m_bVirtual));
|
||||
}
|
||||
|
||||
FrameInitialized();
|
||||
}
|
||||
|
||||
void UIListBox::TrySelectItem
|
||||
@@ -195,7 +281,16 @@ void UIListBox::TrySelectItem
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
UIListBase::TrySelectItem(which);
|
||||
|
||||
if (!getNumItems()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_cvarname.length())
|
||||
{
|
||||
uii.Cvar_Set(m_cvarname.c_str(), m_itemlist.ObjectAt(m_currentItem)->string.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void UIListBox::AddItem
|
||||
@@ -205,7 +300,27 @@ void UIListBox::AddItem
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
ListItem* li;
|
||||
|
||||
li = new ListItem();
|
||||
if (!li) {
|
||||
uii.Sys_Error(ERR_DROP, "Couldn't create list item\n");
|
||||
}
|
||||
|
||||
li->string = item;
|
||||
if (command) {
|
||||
li->command = command;
|
||||
}
|
||||
|
||||
m_itemlist.AddObject(li);
|
||||
|
||||
if (!m_currentItem) {
|
||||
m_currentItem = 1;
|
||||
}
|
||||
|
||||
if (m_vertscroll) {
|
||||
m_vertscroll->setNumItems(m_itemlist.NumObjects());
|
||||
}
|
||||
}
|
||||
|
||||
void UIListBox::AddItem
|
||||
@@ -215,7 +330,27 @@ void UIListBox::AddItem
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
ListItem* li;
|
||||
|
||||
li = new ListItem();
|
||||
if (!li) {
|
||||
uii.Sys_Error(ERR_DROP, "Couldn't create list item\n");
|
||||
}
|
||||
|
||||
li->index = index;
|
||||
if (command) {
|
||||
li->command = command;
|
||||
}
|
||||
|
||||
m_itemlist.AddObject(li);
|
||||
|
||||
if (!m_currentItem) {
|
||||
m_currentItem = 1;
|
||||
}
|
||||
|
||||
if (m_vertscroll) {
|
||||
m_vertscroll->setNumItems(m_itemlist.NumObjects());
|
||||
}
|
||||
}
|
||||
|
||||
void UIListBox::FrameInitialized
|
||||
@@ -224,7 +359,12 @@ void UIListBox::FrameInitialized
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
UIListBase::FrameInitialized();
|
||||
|
||||
if (m_vertscroll) {
|
||||
m_vertscroll->setPageHeight(m_frame.size.height / m_font->getHeight(m_bVirtual));
|
||||
m_vertscroll->setNumItems(m_itemlist.NumObjects());
|
||||
}
|
||||
}
|
||||
|
||||
void UIListBox::LayoutAddListItem
|
||||
@@ -233,7 +373,12 @@ void UIListBox::LayoutAddListItem
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
if (ev->NumArgs() != 2) {
|
||||
AddItem(ev->GetString(1), NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
AddItem(ev->GetString(1), ev->GetString(2).c_str());
|
||||
}
|
||||
|
||||
void UIListBox::LayoutAddConfigstringListItem
|
||||
@@ -242,7 +387,12 @@ void UIListBox::LayoutAddConfigstringListItem
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
if (ev->NumArgs() != 2) {
|
||||
AddItem(ev->GetInteger(1), NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
AddItem(ev->GetInteger(1), ev->GetString(2).c_str());
|
||||
}
|
||||
|
||||
str UIListBox::getItemText
|
||||
@@ -251,8 +401,7 @@ str UIListBox::getItemText
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
return "";
|
||||
return m_itemlist.ObjectAt(which)->string;
|
||||
}
|
||||
|
||||
int UIListBox::getNumItems
|
||||
@@ -261,8 +410,7 @@ int UIListBox::getNumItems
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
return 0;
|
||||
return m_itemlist.NumObjects();
|
||||
}
|
||||
|
||||
void UIListBox::DeleteAllItems
|
||||
@@ -271,7 +419,14 @@ void UIListBox::DeleteAllItems
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
m_itemlist.ClearObjectList();
|
||||
m_currentItem = 0;
|
||||
|
||||
if (m_vertscroll)
|
||||
{
|
||||
m_vertscroll->setNumItems(0);
|
||||
m_vertscroll->setTopItem(0);
|
||||
}
|
||||
}
|
||||
|
||||
void UIListBox::DeleteItem
|
||||
@@ -280,5 +435,13 @@ void UIListBox::DeleteItem
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
m_itemlist.RemoveObjectAt(which);
|
||||
|
||||
if (m_vertscroll) {
|
||||
m_vertscroll->setNumItems(m_itemlist.NumObjects());
|
||||
}
|
||||
|
||||
if (m_currentItem > getNumItems()) {
|
||||
TrySelectItem(getNumItems());
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#ifndef __UILISTBOX_H__
|
||||
#define __UILISTBOX_H__
|
||||
|
||||
extern Event EV_Layout_AddListItem;
|
||||
|
||||
class UIListBase : public UIWidget {
|
||||
protected:
|
||||
int m_currentItem;
|
||||
|
||||
+482
-84
@@ -21,66 +21,43 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "ui_local.h"
|
||||
#include "localization.h"
|
||||
|
||||
griditemtype_t UIListCtrlItem::getListItemType
|
||||
(
|
||||
int which
|
||||
) const
|
||||
static UISize2D s_columnpadding;
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
return TYPE_STRING;
|
||||
}
|
||||
|
||||
str UIListCtrlItem::getListItemString
|
||||
(
|
||||
int which
|
||||
) const
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
return "";
|
||||
}
|
||||
|
||||
int UIListCtrlItem::getListItemValue
|
||||
(
|
||||
int which
|
||||
) const
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
void UIListCtrlItem::DrawListItem
|
||||
(
|
||||
int,
|
||||
UIRect2D const &,
|
||||
bool, UIFont *
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
qboolean UIListCtrlItem::IsHeaderEntry
|
||||
(
|
||||
void
|
||||
) const
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
return qfalse;
|
||||
}
|
||||
bool UIListCtrl::s_qsortreverse;
|
||||
int UIListCtrl::s_qsortcolumn;
|
||||
class UIListCtrl* UIListCtrl::s_qsortobject;
|
||||
|
||||
CLASS_DECLARATION( UIListBase, UIListCtrl, NULL )
|
||||
{
|
||||
{ &W_SizeChanged, &UIListCtrl::OnSizeChanged },
|
||||
{ &W_LeftMouseDown, &UIListCtrl::MousePressed },
|
||||
{ &W_LeftMouseUp, &UIListCtrl::MouseReleased },
|
||||
{ &W_LeftMouseDragged, &UIListCtrl::MouseDragged },
|
||||
{ &W_MouseEntered, &UIListCtrl::MouseEntered },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
UIListCtrl::UIListCtrl()
|
||||
{
|
||||
// FIXME: stub
|
||||
m_clickState.point.x = m_clickState.point.y = 0;
|
||||
m_sizestate.column = 0;
|
||||
m_iLastSortColumn = 0;
|
||||
m_bDrawHeader = qtrue;
|
||||
m_headerfont = NULL;
|
||||
|
||||
Connect(this, W_SizeChanged, W_SizeChanged);
|
||||
m_background_color = UColor(0.02f, 0.07f, 0.005f, 1.0f);
|
||||
m_foreground_color = UHudColor;
|
||||
}
|
||||
|
||||
UIListCtrl::~UIListCtrl()
|
||||
{
|
||||
if (m_headerfont) {
|
||||
delete m_headerfont;
|
||||
m_headerfont = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int UIListCtrl::StringCompareFunction
|
||||
@@ -91,8 +68,34 @@ int UIListCtrl::StringCompareFunction
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
return 0;
|
||||
if (i1->getListItemType(columnname) != TYPE_STRING || i2->getListItemType(columnname) != TYPE_STRING) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* s1 = i1->getListItemString(columnname);
|
||||
const char* s2 = i2->getListItemString(columnname);
|
||||
|
||||
if (*s1 == '.')
|
||||
{
|
||||
if (*s2 != '.') {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (*s2 == '.') {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (*s1 == '[')
|
||||
{
|
||||
if (*s2 != '[') {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (*s2 == '[') {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return Q_stricmp(s1, s2);
|
||||
}
|
||||
|
||||
int UIListCtrl::StringNumberCompareFunction
|
||||
@@ -103,8 +106,18 @@ int UIListCtrl::StringNumberCompareFunction
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
return 0;
|
||||
int val1, val2;
|
||||
|
||||
val1 = i1->getListItemValue(columnname);
|
||||
val2 = i2->getListItemValue(columnname);
|
||||
|
||||
if (val1 > val2) {
|
||||
return 1;
|
||||
} else if (val1 < val2) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int UIListCtrl::QsortCompare
|
||||
@@ -114,8 +127,8 @@ int UIListCtrl::QsortCompare
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
return 0;
|
||||
int val = s_qsortobject->m_comparefunction((const UIListCtrlItem*)e1, (const UIListCtrlItem*)e2, s_qsortcolumn);
|
||||
return s_qsortreverse ? -val : val;
|
||||
}
|
||||
|
||||
void UIListCtrl::Draw
|
||||
@@ -124,7 +137,11 @@ void UIListCtrl::Draw
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
if (m_bDrawHeader) {
|
||||
DrawColumns();
|
||||
}
|
||||
|
||||
DrawContent();
|
||||
}
|
||||
|
||||
int UIListCtrl::getHeaderHeight
|
||||
@@ -133,8 +150,19 @@ int UIListCtrl::getHeaderHeight
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
return 0;
|
||||
if (!m_bDrawHeader) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (m_headerfont) {
|
||||
return (int)(m_headerfont->getHeight(m_bVirtual) + (s_columnpadding.height + s_columnpadding.height) * m_vVirtualScale[1]);
|
||||
}
|
||||
|
||||
if (m_font) {
|
||||
return (int)(m_font->getHeight(m_bVirtual) + (s_columnpadding.height + s_columnpadding.height) * m_vVirtualScale[1]);
|
||||
}
|
||||
|
||||
return (int)((s_columnpadding.height + s_columnpadding.height) * m_vVirtualScale[1]);
|
||||
}
|
||||
|
||||
void UIListCtrl::MousePressed
|
||||
@@ -143,7 +171,73 @@ void UIListCtrl::MousePressed
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
UIPoint2D p;
|
||||
|
||||
p = MouseEventToClientPoint(ev);
|
||||
|
||||
if (m_clicksound.length()) {
|
||||
uii.Snd_PlaySound(m_clicksound.c_str());
|
||||
}
|
||||
|
||||
if (getHeaderHeight() > p.y)
|
||||
{
|
||||
int closesep = 0;
|
||||
int atleft = 0;
|
||||
int closeatleft = 0;
|
||||
int insep = 0;
|
||||
|
||||
for (int i = 1; i <= m_columnlist.NumObjects(); i++) {
|
||||
const columndef_t& column = m_columnlist.ObjectAt(i);
|
||||
atleft += column.width;
|
||||
|
||||
if (abs(atleft - p.x) > 2)
|
||||
{
|
||||
if (atleft - column.width < p.x && atleft > p.x) {
|
||||
insep = i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
closesep = i;
|
||||
closeatleft = atleft;
|
||||
}
|
||||
}
|
||||
|
||||
if (closesep)
|
||||
{
|
||||
m_sizestate.column = closesep;
|
||||
m_sizestate.min = closeatleft - m_columnlist.ObjectAt(closesep).width;
|
||||
uWinMan.setFirstResponder(this);
|
||||
} else {
|
||||
SortByColumn(m_columnlist.ObjectAt(insep).name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_vertscroll) {
|
||||
TrySelectItem((m_vertscroll->getTopItem() + 1) + (p.y - getHeaderHeight()) / m_font->getHeight(m_bVirtual));
|
||||
} else {
|
||||
TrySelectItem(1.0 + (p.y - getHeaderHeight()) / m_font->getHeight(m_bVirtual));
|
||||
}
|
||||
|
||||
if (m_clickState.time + 500 > uid.time
|
||||
&& m_currentItem == m_clickState.selected
|
||||
&& fabs(m_clickState.point.x - p.x) <= 2.0
|
||||
&& fabs(m_clickState.point.y - p.y) <= 2.0)
|
||||
{
|
||||
Event newev;
|
||||
newev.AddInteger(m_currentItem);
|
||||
SendSignal(newev);
|
||||
m_clickState.time = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_clickState.time = uid.time;
|
||||
m_clickState.selected = m_currentItem;
|
||||
m_clickState.point.x = p.x;
|
||||
m_clickState.point.y = p.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UIListCtrl::MouseDragged
|
||||
@@ -152,7 +246,23 @@ void UIListCtrl::MouseDragged
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
UIPoint2D p;
|
||||
int newwidth;
|
||||
|
||||
p = MouseEventToClientPoint(ev);
|
||||
if (m_sizestate.column)
|
||||
{
|
||||
columndef_t& column = m_columnlist.ObjectAt(m_sizestate.column);
|
||||
|
||||
newwidth = p.x - m_sizestate.min;
|
||||
if (newwidth > 600) {
|
||||
newwidth = 600;
|
||||
} else if (newwidth < 0) {
|
||||
newwidth = 0;
|
||||
}
|
||||
|
||||
column.width = newwidth;
|
||||
}
|
||||
}
|
||||
|
||||
void UIListCtrl::MouseReleased
|
||||
@@ -161,7 +271,11 @@ void UIListCtrl::MouseReleased
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
m_sizestate.column = 0;
|
||||
|
||||
if (uWinMan.getFirstResponder() == this) {
|
||||
uWinMan.setFirstResponder(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void UIListCtrl::MouseEntered
|
||||
@@ -170,7 +284,7 @@ void UIListCtrl::MouseEntered
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
uWinMan.ActivateControl(this);
|
||||
}
|
||||
|
||||
void UIListCtrl::OnSizeChanged
|
||||
@@ -179,7 +293,13 @@ void UIListCtrl::OnSizeChanged
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
if (!m_vertscroll) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_vertscroll->InitFrame(this, m_frame.size.width - 16.0, 0.0, 16.0, m_frame.size.height, -1);
|
||||
m_vertscroll->setPageHeight((m_frame.size.height - getHeaderHeight()) / m_font->getHeight(m_bVirtual));
|
||||
m_vertscroll->setNumItems(m_itemlist.NumObjects());
|
||||
}
|
||||
|
||||
void UIListCtrl::DrawColumns
|
||||
@@ -188,7 +308,57 @@ void UIListCtrl::DrawColumns
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
int atleft;
|
||||
int i;
|
||||
int height;
|
||||
UIFont* pFont;
|
||||
UColor columnColor, textColor;
|
||||
|
||||
atleft = 0;
|
||||
columnColor = UColor(0.07f, 0.06f, 0.005f, 1.0f);
|
||||
textColor = UHudColor;
|
||||
|
||||
pFont = m_headerfont;
|
||||
if (!pFont) pFont = m_font;
|
||||
|
||||
height = (s_columnpadding.height + s_columnpadding.height) * m_vVirtualScale[1] + pFont->getHeight(m_bVirtual);
|
||||
pFont->setColor(textColor);
|
||||
|
||||
for (i = 1; i <= m_columnlist.NumObjects(); i++)
|
||||
{
|
||||
const columndef_t& column = m_columnlist.ObjectAt(i);
|
||||
|
||||
DrawBoxWithSolidBorder(
|
||||
UIRect2D(atleft, 0, column.width + m_vVirtualScale[1], height),
|
||||
columnColor,
|
||||
textColor,
|
||||
1,
|
||||
3,
|
||||
m_local_alpha
|
||||
);
|
||||
|
||||
pFont->Print(
|
||||
atleft / m_vVirtualScale[0] + s_columnpadding.width,
|
||||
s_columnpadding.height,
|
||||
Sys_LV_CL_ConvertString(column.title.c_str()),
|
||||
-1,
|
||||
m_bVirtual
|
||||
);
|
||||
|
||||
atleft += column.width;
|
||||
}
|
||||
|
||||
if (m_frame.size.width > atleft)
|
||||
{
|
||||
DrawBoxWithSolidBorder(
|
||||
UIRect2D(atleft, 0, m_frame.size.width - atleft + 1.0, height),
|
||||
columnColor,
|
||||
textColor,
|
||||
1,
|
||||
3,
|
||||
m_local_alpha
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void UIListCtrl::DrawContent
|
||||
@@ -197,7 +367,110 @@ void UIListCtrl::DrawContent
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
int item;
|
||||
int height, headerheight, iItemHeight;
|
||||
UIFont* pFont;
|
||||
int top;
|
||||
UColor selColor, selText;
|
||||
UColor backColor, textColor;
|
||||
|
||||
height = m_font->getHeight(m_bVirtual);
|
||||
selColor = UColor(0.21f, 0.18f, 0.015f, 1.0f);
|
||||
selText = UColor(0.9f, 0.8f, 0.6f, 1.0f);
|
||||
backColor = m_background_color;
|
||||
textColor = m_foreground_color;
|
||||
|
||||
if (m_headerfont) {
|
||||
headerheight = m_headerfont->getHeight(m_bVirtual);
|
||||
} else {
|
||||
headerheight = 0;
|
||||
}
|
||||
|
||||
selColor.a = m_local_alpha;
|
||||
selText.a = m_local_alpha;
|
||||
backColor.a = m_local_alpha;
|
||||
textColor.a = m_local_alpha;
|
||||
top = getHeaderHeight();
|
||||
if (m_vertscroll) {
|
||||
item = m_vertscroll->getTopItem() + 1;
|
||||
} else {
|
||||
item = 1;
|
||||
}
|
||||
|
||||
for (; item <= m_itemlist.NumObjects(); item++)
|
||||
{
|
||||
UIListCtrlItem* theitem;
|
||||
int col;
|
||||
int atleft;
|
||||
UColor* itemBg;
|
||||
UColor* itemText;
|
||||
|
||||
theitem = m_itemlist.ObjectAt(item);
|
||||
atleft = 0;
|
||||
|
||||
if (item == m_currentItem)
|
||||
{
|
||||
itemBg = &selColor;
|
||||
itemText = &selText;
|
||||
}
|
||||
else
|
||||
{
|
||||
itemBg = &backColor;
|
||||
itemText = &textColor;
|
||||
}
|
||||
|
||||
if (theitem->IsHeaderEntry() && m_headerfont) {
|
||||
pFont = m_headerfont;
|
||||
iItemHeight = headerheight;
|
||||
} else {
|
||||
pFont = m_font;
|
||||
iItemHeight = height;
|
||||
}
|
||||
|
||||
pFont->setColor(*itemText);
|
||||
for (col = 1; col <= m_columnlist.NumObjects(); col++)
|
||||
{
|
||||
columndef_t& column = m_columnlist.ObjectAt(col);
|
||||
UIRect2D drawRect(atleft, top, column.width, iItemHeight);
|
||||
griditemtype_t itemtype = theitem->getListItemType(column.name);
|
||||
|
||||
switch (itemtype)
|
||||
{
|
||||
case TYPE_STRING:
|
||||
DrawBox(drawRect, *itemBg, m_local_alpha);
|
||||
pFont->Print(
|
||||
drawRect.pos.x / m_vVirtualScale[0] + 1.0,
|
||||
drawRect.pos.y / m_vVirtualScale[1],
|
||||
Sys_LV_CL_ConvertString(theitem->getListItemString(column.name)),
|
||||
-1,
|
||||
m_bVirtual
|
||||
);
|
||||
break;
|
||||
case TYPE_OWNERDRAW:
|
||||
theitem->DrawListItem(column.name, drawRect, item == m_currentItem, pFont);
|
||||
break;
|
||||
}
|
||||
|
||||
atleft += column.width;
|
||||
}
|
||||
|
||||
if (m_frame.size.width > atleft)
|
||||
{
|
||||
DrawBox(
|
||||
atleft,
|
||||
top,
|
||||
m_frame.size.width - atleft,
|
||||
height,
|
||||
*itemBg,
|
||||
m_local_alpha
|
||||
);
|
||||
}
|
||||
|
||||
top += iItemHeight;
|
||||
if (iItemHeight + top > m_frame.size.height) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UIListCtrl::FrameInitialized
|
||||
@@ -206,7 +479,8 @@ void UIListCtrl::FrameInitialized
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
UIListBase::FrameInitialized();
|
||||
OnSizeChanged(NULL);
|
||||
}
|
||||
|
||||
void UIListCtrl::SetDrawHeader
|
||||
@@ -215,7 +489,7 @@ void UIListCtrl::SetDrawHeader
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
m_bDrawHeader = bDrawHeader;
|
||||
}
|
||||
|
||||
void UIListCtrl::AddItem
|
||||
@@ -224,7 +498,10 @@ void UIListCtrl::AddItem
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
m_itemlist.AddObject(item);
|
||||
if (m_vertscroll) {
|
||||
m_vertscroll->setNumItems(m_itemlist.NumObjects());
|
||||
}
|
||||
}
|
||||
|
||||
void UIListCtrl::InsertItem
|
||||
@@ -233,7 +510,26 @@ void UIListCtrl::InsertItem
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
if (where > 0 && where <= m_itemlist.NumObjects())
|
||||
{
|
||||
int i;
|
||||
|
||||
m_itemlist.AddObject(NULL);
|
||||
|
||||
for (i = m_itemlist.NumObjects(); i > where; i++) {
|
||||
m_itemlist.SetObjectAt(i, m_itemlist.ObjectAt(i - 1));
|
||||
}
|
||||
|
||||
m_itemlist.SetObjectAt(where, item);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_itemlist.AddObject(item);
|
||||
}
|
||||
|
||||
if (m_vertscroll) {
|
||||
m_vertscroll->setNumItems(m_itemlist.NumObjects());
|
||||
}
|
||||
}
|
||||
|
||||
int UIListCtrl::FindItem
|
||||
@@ -242,8 +538,7 @@ int UIListCtrl::FindItem
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
return 0;
|
||||
return m_itemlist.IndexOfObject(item);
|
||||
}
|
||||
|
||||
UIListCtrlItem *UIListCtrl::GetItem
|
||||
@@ -252,8 +547,7 @@ UIListCtrlItem *UIListCtrl::GetItem
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
return NULL;
|
||||
return m_itemlist.ObjectAt(item);
|
||||
}
|
||||
|
||||
void UIListCtrl::AddColumn
|
||||
@@ -266,7 +560,15 @@ void UIListCtrl::AddColumn
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
columndef_t column;
|
||||
|
||||
column.title = title;
|
||||
column.name = name;
|
||||
column.width = width;
|
||||
column.numeric = numeric;
|
||||
column.reverse_sort = reverse_sort;
|
||||
|
||||
m_columnlist.AddObject(column);
|
||||
}
|
||||
|
||||
void UIListCtrl::RemoveAllColumns
|
||||
@@ -275,7 +577,7 @@ void UIListCtrl::RemoveAllColumns
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
m_columnlist.ClearObjectList();
|
||||
}
|
||||
|
||||
int UIListCtrl::getNumItems
|
||||
@@ -284,8 +586,7 @@ int UIListCtrl::getNumItems
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
return 0;
|
||||
return m_itemlist.NumObjects();
|
||||
}
|
||||
|
||||
void UIListCtrl::DeleteAllItems
|
||||
@@ -294,7 +595,14 @@ void UIListCtrl::DeleteAllItems
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
m_itemlist.ClearObjectList();
|
||||
m_currentItem = 0;
|
||||
|
||||
if (m_vertscroll)
|
||||
{
|
||||
m_vertscroll->setNumItems(0);
|
||||
m_vertscroll->setTopItem(0);
|
||||
}
|
||||
}
|
||||
|
||||
void UIListCtrl::DeleteItem
|
||||
@@ -303,7 +611,15 @@ void UIListCtrl::DeleteItem
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
m_itemlist.RemoveObjectAt(which);
|
||||
|
||||
if (m_vertscroll) {
|
||||
m_vertscroll->setNumItems(m_itemlist.NumObjects());
|
||||
}
|
||||
|
||||
if (m_currentItem > getNumItems()) {
|
||||
TrySelectItem(getNumItems());
|
||||
}
|
||||
}
|
||||
|
||||
void UIListCtrl::SortByColumn
|
||||
@@ -312,7 +628,81 @@ void UIListCtrl::SortByColumn
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
int i;
|
||||
bool exists;
|
||||
bool numeric;
|
||||
bool reverse;
|
||||
UIListCtrlItem* selected;
|
||||
bool selvisible;
|
||||
|
||||
exists = 0;
|
||||
numeric = 0;
|
||||
reverse = 0;
|
||||
selected = NULL;
|
||||
selvisible = 0;
|
||||
|
||||
for (i = 1; i <= m_columnlist.NumObjects(); i++) {
|
||||
columndef_t& def = m_columnlist.ObjectAt(i);
|
||||
|
||||
if (def.name == i) {
|
||||
numeric = def.numeric;
|
||||
reverse = def.reverse_sort;
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (exists)
|
||||
{
|
||||
m_iLastSortColumn = column;
|
||||
s_qsortcolumn = column;
|
||||
s_qsortobject = this;
|
||||
s_qsortreverse = reverse;
|
||||
|
||||
if (m_currentItem)
|
||||
{
|
||||
selected = m_itemlist.ObjectAt(m_currentItem);
|
||||
if (m_vertscroll)
|
||||
{
|
||||
selvisible = false;
|
||||
if (m_currentItem >= m_vertscroll->getTopItem() + 1) {
|
||||
selvisible = m_currentItem <= m_vertscroll->getPageHeight() + m_vertscroll->getTopItem();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
selvisible = false;
|
||||
// FIXME: selvisible when there is no vertical scroll?
|
||||
//
|
||||
//if (m_currentItem > 0) {
|
||||
// selvisible = m_currentItem <= m_vertscroll->m_pageheight + m_vertscroll->getTopItem();
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
if (numeric) {
|
||||
m_comparefunction = &UIListCtrl::StringNumberCompareFunction;
|
||||
} else {
|
||||
m_comparefunction = &UIListCtrl::StringCompareFunction;
|
||||
}
|
||||
|
||||
if (m_itemlist.NumObjects()) {
|
||||
m_itemlist.Sort(&UIListCtrl::QsortCompare);
|
||||
}
|
||||
|
||||
if (selected)
|
||||
{
|
||||
if (selvisible) {
|
||||
TrySelectItem(FindItem(selected));
|
||||
} else {
|
||||
m_currentItem = FindItem(selected);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_iLastSortColumn = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void UIListCtrl::SortByLastSortColumn
|
||||
@@ -321,7 +711,7 @@ void UIListCtrl::SortByLastSortColumn
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
SortByColumn(m_iLastSortColumn);
|
||||
}
|
||||
|
||||
void UIListCtrl::setCompareFunction
|
||||
@@ -330,7 +720,7 @@ void UIListCtrl::setCompareFunction
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
m_comparefunction = func;
|
||||
}
|
||||
|
||||
void UIListCtrl::setHeaderFont
|
||||
@@ -339,5 +729,13 @@ void UIListCtrl::setHeaderFont
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
if (m_headerfont) {
|
||||
delete m_headerfont;
|
||||
}
|
||||
|
||||
if (name) {
|
||||
m_headerfont = new UIFont(name);
|
||||
} else {
|
||||
m_headerfont = NULL;
|
||||
}
|
||||
}
|
||||
@@ -27,11 +27,11 @@ typedef enum { TYPE_STRING, TYPE_OWNERDRAW } griditemtype_t;
|
||||
|
||||
class UIListCtrlItem {
|
||||
public:
|
||||
virtual griditemtype_t getListItemType( int which ) const;
|
||||
virtual str getListItemString( int which ) const;
|
||||
virtual int getListItemValue( int which ) const;
|
||||
virtual void DrawListItem( int iColumn, const UIRect2D &drawRect, bool bSelected, UIFont *pFont );
|
||||
virtual qboolean IsHeaderEntry( void ) const;
|
||||
virtual griditemtype_t getListItemType( int which ) const = 0;
|
||||
virtual str getListItemString( int which ) const = 0;
|
||||
virtual int getListItemValue( int which ) const = 0;
|
||||
virtual void DrawListItem( int iColumn, const UIRect2D &drawRect, bool bSelected, UIFont *pFont ) = 0;
|
||||
virtual qboolean IsHeaderEntry( void ) const = 0;
|
||||
};
|
||||
|
||||
typedef struct m_clickState_s {
|
||||
@@ -54,6 +54,7 @@ protected:
|
||||
static bool s_qsortreverse;
|
||||
static int s_qsortcolumn;
|
||||
static class UIListCtrl *s_qsortobject;
|
||||
|
||||
int m_iLastSortColumn;
|
||||
class UIFont *m_headerfont;
|
||||
Container<UIListCtrlItem *> m_itemlist;
|
||||
@@ -66,7 +67,7 @@ protected:
|
||||
} m_sizestate;
|
||||
m_clickState_s m_clickState;
|
||||
|
||||
int( *m_comparefunction ) (/* unknown */ );
|
||||
int (*m_comparefunction) (const UIListCtrlItem* i1, const UIListCtrlItem* i2, int columnname);
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( UIListCtrl );
|
||||
@@ -86,6 +87,7 @@ protected:
|
||||
void DrawContent( void );
|
||||
public:
|
||||
UIListCtrl();
|
||||
~UIListCtrl();
|
||||
|
||||
void FrameInitialized( void );
|
||||
void SetDrawHeader( qboolean bDrawHeader );
|
||||
|
||||
@@ -600,7 +600,14 @@ void MenuManager::RealignMenus
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
int i;
|
||||
int num;
|
||||
|
||||
num = m_menulist.NumObjects();
|
||||
for (i = 1; i <= num; i++)
|
||||
{
|
||||
m_menulist.ObjectAt(i)->RealignWidgets();
|
||||
}
|
||||
}
|
||||
|
||||
void MenuManager::AddMenu
|
||||
|
||||
@@ -1601,7 +1601,7 @@ void UIWidget::TextAlignment
|
||||
)
|
||||
|
||||
{
|
||||
for( int i = 1; i < ev->NumArgs(); i++ )
|
||||
for( int i = 1; i <= ev->NumArgs(); i++ )
|
||||
{
|
||||
str align = ev->GetString( 1 );
|
||||
|
||||
|
||||
@@ -81,6 +81,14 @@ static int tty_eof;
|
||||
|
||||
static struct termios tty_tc;
|
||||
|
||||
#define MAX_EDIT_LINE 256
|
||||
typedef struct {
|
||||
int cursor;
|
||||
int scroll;
|
||||
int widthInChars;
|
||||
char buffer[MAX_EDIT_LINE];
|
||||
} field_t;
|
||||
|
||||
static field_t tty_con;
|
||||
|
||||
// history
|
||||
@@ -459,6 +467,163 @@ void floating_point_exception_handler(int whatever)
|
||||
signal(SIGFPE, floating_point_exception_handler);
|
||||
}
|
||||
|
||||
/*
|
||||
===========================================
|
||||
command line completion
|
||||
===========================================
|
||||
*/
|
||||
|
||||
/*
|
||||
==================
|
||||
Field_Clear
|
||||
==================
|
||||
*/
|
||||
void Field_Clear(field_t* edit) {
|
||||
memset(edit->buffer, 0, MAX_EDIT_LINE);
|
||||
edit->cursor = 0;
|
||||
edit->scroll = 0;
|
||||
}
|
||||
|
||||
static const char* completionString;
|
||||
static char shortestMatch[MAX_TOKEN_CHARS];
|
||||
static int matchCount;
|
||||
// field we are working on, passed to Field_CompleteCommand (&g_consoleCommand for instance)
|
||||
static field_t* completionField;
|
||||
|
||||
/*
|
||||
===============
|
||||
FindMatches
|
||||
|
||||
===============
|
||||
*/
|
||||
static void FindMatches(const char* s) {
|
||||
int i;
|
||||
|
||||
if (Q_stricmpn(s, completionString, strlen(completionString))) {
|
||||
return;
|
||||
}
|
||||
matchCount++;
|
||||
if (matchCount == 1) {
|
||||
Q_strncpyz(shortestMatch, s, sizeof(shortestMatch));
|
||||
return;
|
||||
}
|
||||
|
||||
// cut shortestMatch to the amount common with s
|
||||
for (i = 0; s[i]; i++) {
|
||||
if (tolower(shortestMatch[i]) != tolower(s[i])) {
|
||||
shortestMatch[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
PrintMatches
|
||||
|
||||
===============
|
||||
*/
|
||||
static void PrintMatches(const char* s) {
|
||||
if (!Q_stricmpn(s, shortestMatch, strlen(shortestMatch))) {
|
||||
Com_Printf(" %s\n", s);
|
||||
}
|
||||
}
|
||||
|
||||
static void keyConcatArgs(void) {
|
||||
int i;
|
||||
char* arg;
|
||||
|
||||
for (i = 1; i < Cmd_Argc(); i++) {
|
||||
Q_strcat(completionField->buffer, sizeof(completionField->buffer), " ");
|
||||
arg = Cmd_Argv(i);
|
||||
while (*arg) {
|
||||
if (*arg == ' ') {
|
||||
Q_strcat(completionField->buffer, sizeof(completionField->buffer), "\"");
|
||||
break;
|
||||
}
|
||||
arg++;
|
||||
}
|
||||
Q_strcat(completionField->buffer, sizeof(completionField->buffer), Cmd_Argv(i));
|
||||
if (*arg == ' ') {
|
||||
Q_strcat(completionField->buffer, sizeof(completionField->buffer), "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ConcatRemaining(const char* src, const char* start) {
|
||||
char* str;
|
||||
|
||||
str = strstr(src, start);
|
||||
if (!str) {
|
||||
keyConcatArgs();
|
||||
return;
|
||||
}
|
||||
|
||||
str += strlen(start);
|
||||
Q_strcat(completionField->buffer, sizeof(completionField->buffer), str);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Field_CompleteCommand
|
||||
|
||||
perform Tab expansion
|
||||
NOTE TTimo this was originally client code only
|
||||
moved to common code when writing tty console for *nix dedicated server
|
||||
===============
|
||||
*/
|
||||
void Field_CompleteCommand(field_t* field) {
|
||||
field_t temp;
|
||||
|
||||
completionField = field;
|
||||
|
||||
// only look at the first token for completion purposes
|
||||
Cmd_TokenizeString(completionField->buffer);
|
||||
|
||||
completionString = Cmd_Argv(0);
|
||||
if (completionString[0] == '\\' || completionString[0] == '/') {
|
||||
completionString++;
|
||||
}
|
||||
matchCount = 0;
|
||||
shortestMatch[0] = 0;
|
||||
|
||||
if (strlen(completionString) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Cmd_CommandCompletion(FindMatches);
|
||||
Cvar_CommandCompletion(FindMatches);
|
||||
|
||||
if (matchCount == 0) {
|
||||
return; // no matches
|
||||
}
|
||||
|
||||
Com_Memcpy(&temp, completionField, sizeof(field_t));
|
||||
|
||||
if (matchCount == 1) {
|
||||
Com_sprintf(completionField->buffer, sizeof(completionField->buffer), "\\%s", shortestMatch);
|
||||
if (Cmd_Argc() == 1) {
|
||||
Q_strcat(completionField->buffer, sizeof(completionField->buffer), " ");
|
||||
}
|
||||
else {
|
||||
ConcatRemaining(temp.buffer, completionString);
|
||||
}
|
||||
completionField->cursor = strlen(completionField->buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
// multiple matches, complete to shortest
|
||||
Com_sprintf(completionField->buffer, sizeof(completionField->buffer), "\\%s", shortestMatch);
|
||||
completionField->cursor = strlen(completionField->buffer);
|
||||
ConcatRemaining(temp.buffer, completionString);
|
||||
|
||||
Com_Printf("]%s\n", completionField->buffer);
|
||||
|
||||
// run through again, printing matches
|
||||
Cmd_CommandCompletion(PrintMatches);
|
||||
Cvar_CommandCompletion(PrintMatches);
|
||||
}
|
||||
|
||||
|
||||
// initialize the console input (tty mode if wanted and possible)
|
||||
void Sys_ConsoleInputInit()
|
||||
{
|
||||
|
||||
+13
-1
@@ -1201,7 +1201,19 @@ Sys_PumpMessageLoop
|
||||
*/
|
||||
void Sys_PumpMessageLoop(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
MSG msg;
|
||||
|
||||
while (PeekMessageA(&msg, 0, 0, 0, 0))
|
||||
{
|
||||
if (!GetMessageA(&msg, 0, 0, 0)) {
|
||||
Com_Quit_f();
|
||||
}
|
||||
|
||||
g_wv.sysMsgTime = msg.time;
|
||||
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageA(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 996 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 881 KiB |
Reference in new issue
Block a user