mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-12 08:11:10 +02:00
Added Quake 1 map loading support, adjusted lighting.
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerCommandArguments>+set r_fullscreen 0 +set r_mode 1</LocalDebuggerCommandArguments>
|
||||
<LocalDebuggerWorkingDirectory>D:\projects\Doom3</LocalDebuggerWorkingDirectory>
|
||||
<LocalDebuggerCommandArgumentsHistory>+set r_fullscreen 0 +set r_mode 6|+set r_fullscreen 1 +set r_mode 6|+set r_fullscreen 1 +set r_mode 1|+set r_fullscreen 0 +set r_mode 1|</LocalDebuggerCommandArgumentsHistory>
|
||||
<LocalDebuggerCommandArgumentsHistory>+set r_fullscreen 0 +set r_mode 6|+set r_fullscreen 1 +set r_mode 6|+set r_fullscreen 1 +set r_mode 1|+set r_fullscreen 0 +set r_mode 1 +set fs_game q1base|+set r_fullscreen 0 +set r_mode 1|</LocalDebuggerCommandArgumentsHistory>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Q4 Debug|x64'">
|
||||
<LocalDebuggerCommand>D:\projects\Doom3\Quake4.exe</LocalDebuggerCommand>
|
||||
|
||||
@@ -112,6 +112,544 @@ static void ComputeAxisBase(const idVec3& normal, idVec3& texS, idVec3& texT) {
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
Quake 1 .map compatibility helpers
|
||||
|
||||
Quake 1 and Valve 220 maps use the same outer entity/brush braces as the
|
||||
legacy Quake 3 parser, but their texture projection data must be interpreted
|
||||
as Quake axial vectors instead of the existing Quake 3 fallback texture matrix.
|
||||
The detector below enables this mode only for files that advertise Quake 1 or
|
||||
Valve 220 metadata, so the original Quake 3 fallback path remains unchanged.
|
||||
=================
|
||||
*/
|
||||
static bool g_parseQuake1Map = false;
|
||||
|
||||
typedef struct quake1MapTextureSizeCacheEntry_s {
|
||||
idStr name;
|
||||
int width;
|
||||
int height;
|
||||
} quake1MapTextureSizeCacheEntry_t;
|
||||
|
||||
static idList<quake1MapTextureSizeCacheEntry_t> g_quake1MapTextureSizeCache;
|
||||
|
||||
/*
|
||||
=================
|
||||
Quake1MapTokenToFloat
|
||||
=================
|
||||
*/
|
||||
static bool Quake1MapTokenToFloat(const idToken& token, float& value) {
|
||||
char* end;
|
||||
const char* str;
|
||||
|
||||
str = token.c_str();
|
||||
if (!str || !str[0]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
value = (float)strtod(str, &end);
|
||||
return end != str && *end == '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Quake1MapReadFloatToken
|
||||
|
||||
idLexer may emit a negative number as either one token, "-1", or as a
|
||||
punctuation sign followed by a number, "-" "1". Quake .map texture scales
|
||||
commonly use negative values, so parse both forms from a token list.
|
||||
=================
|
||||
*/
|
||||
static bool Quake1MapReadFloatToken(const idList<idToken>& tokens, int& index, float& value) {
|
||||
float parsed;
|
||||
float sign;
|
||||
|
||||
if (index >= tokens.Num()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sign = 1.0f;
|
||||
if (tokens[index] == "-" || tokens[index] == "+") {
|
||||
if (tokens[index] == "-") {
|
||||
sign = -1.0f;
|
||||
}
|
||||
index++;
|
||||
if (index >= tokens.Num()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Quake1MapTokenToFloat(tokens[index], parsed)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
value = sign * parsed;
|
||||
index++;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Quake1MapTokensAreFloatSuffix
|
||||
=================
|
||||
*/
|
||||
static bool Quake1MapTokensAreFloatSuffix(const idList<idToken>& tokens, int first, int minimumFloats) {
|
||||
int index, count;
|
||||
float value;
|
||||
|
||||
index = first;
|
||||
count = 0;
|
||||
while (index < tokens.Num()) {
|
||||
if (!Quake1MapReadFloatToken(tokens, index, value)) {
|
||||
return false;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
return count >= minimumFloats;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
JoinQuake1MapTextureName
|
||||
|
||||
Quake texture names may begin with punctuation, for example +0WALL or *WATER.
|
||||
Collecting the whole texture-name token run avoids treating those prefixes as
|
||||
separate syntax.
|
||||
=================
|
||||
*/
|
||||
static void JoinQuake1MapTextureName(const idList<idToken>& tokens, int first, int count, idStr& material) {
|
||||
int i;
|
||||
|
||||
material.Clear();
|
||||
for (i = 0; i < count; i++) {
|
||||
material += tokens[first + i].c_str();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
FindQuake1MapStandardTextureParms
|
||||
|
||||
Classic Quake faces end with:
|
||||
textureName offsetX offsetY rotation scaleX scaleY [optional numeric flags]
|
||||
Return the first token of that numeric suffix.
|
||||
=================
|
||||
*/
|
||||
static int FindQuake1MapStandardTextureParms(const idList<idToken>& tokens) {
|
||||
int i;
|
||||
|
||||
for (i = 1; i < tokens.Num(); i++) {
|
||||
if (Quake1MapTokensAreFloatSuffix(tokens, i, 5)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
ParseQuake1MapValve220Vector
|
||||
=================
|
||||
*/
|
||||
static bool ParseQuake1MapValve220Vector(const idList<idToken>& tokens, int& index, idVec3& axis, float& offset) {
|
||||
float v[4];
|
||||
int i;
|
||||
|
||||
if (index >= tokens.Num() || tokens[index] != "[") {
|
||||
return false;
|
||||
}
|
||||
index++;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (!Quake1MapReadFloatToken(tokens, index, v[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (index >= tokens.Num() || tokens[index] != "]") {
|
||||
return false;
|
||||
}
|
||||
index++;
|
||||
|
||||
axis[0] = v[0];
|
||||
axis[1] = v[1];
|
||||
axis[2] = v[2];
|
||||
offset = v[3];
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Quake1MapTextureAxisFromPlane
|
||||
|
||||
This is the historical dominant-axis basis used by Quake-family map compilers
|
||||
for the classic texture tuple.
|
||||
=================
|
||||
*/
|
||||
static void Quake1MapTextureAxisFromPlane(const idVec3& normal, idVec3& texS, idVec3& texT) {
|
||||
static const float baseAxis[18][3] = {
|
||||
{ 0, 0, 1 }, { 1, 0, 0 }, { 0, -1, 0 },
|
||||
{ 0, 0, -1 }, { 1, 0, 0 }, { 0, -1, 0 },
|
||||
{ 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, -1 },
|
||||
{ -1, 0, 0 }, { 0, 1, 0 }, { 0, 0, -1 },
|
||||
{ 0, 1, 0 }, { 1, 0, 0 }, { 0, 0, -1 },
|
||||
{ 0, -1, 0 }, { 1, 0, 0 }, { 0, 0, -1 }
|
||||
};
|
||||
int i, bestAxis;
|
||||
float best, dot;
|
||||
|
||||
best = 0.0f;
|
||||
bestAxis = 0;
|
||||
for (i = 0; i < 6; i++) {
|
||||
dot = normal[0] * baseAxis[i * 3][0] + normal[1] * baseAxis[i * 3][1] + normal[2] * baseAxis[i * 3][2];
|
||||
if (dot > best) {
|
||||
best = dot;
|
||||
bestAxis = i;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
texS[i] = baseAxis[bestAxis * 3 + 1][i];
|
||||
texT[i] = baseAxis[bestAxis * 3 + 2][i];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
RotateQuake1MapTextureAxes
|
||||
=================
|
||||
*/
|
||||
static void RotateQuake1MapTextureAxes(idVec3 axes[2], float rotate) {
|
||||
int i, sv, tv;
|
||||
float angle, sinv, cosv, ns, nt;
|
||||
|
||||
angle = rotate * (3.14159265358979323846f / 180.0f);
|
||||
|
||||
if (rotate == 0.0f) {
|
||||
sinv = 0.0f;
|
||||
cosv = 1.0f;
|
||||
}
|
||||
else if (rotate == 90.0f) {
|
||||
sinv = 1.0f;
|
||||
cosv = 0.0f;
|
||||
}
|
||||
else if (rotate == 180.0f) {
|
||||
sinv = 0.0f;
|
||||
cosv = -1.0f;
|
||||
}
|
||||
else if (rotate == 270.0f) {
|
||||
sinv = -1.0f;
|
||||
cosv = 0.0f;
|
||||
}
|
||||
else {
|
||||
#ifdef QUAKE4
|
||||
sinv = idMath::Sin(angle);
|
||||
cosv = idMath::Cos(angle);
|
||||
#else
|
||||
sinv = sin(angle);
|
||||
cosv = cos(angle);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (axes[0][0]) {
|
||||
sv = 0;
|
||||
}
|
||||
else if (axes[0][1]) {
|
||||
sv = 1;
|
||||
}
|
||||
else {
|
||||
sv = 2;
|
||||
}
|
||||
|
||||
if (axes[1][0]) {
|
||||
tv = 0;
|
||||
}
|
||||
else if (axes[1][1]) {
|
||||
tv = 1;
|
||||
}
|
||||
else {
|
||||
tv = 2;
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
ns = cosv * axes[i][sv] - sinv * axes[i][tv];
|
||||
nt = sinv * axes[i][sv] + cosv * axes[i][tv];
|
||||
axes[i][sv] = ns;
|
||||
axes[i][tv] = nt;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
ClearQuake1MapTextureSizeCache
|
||||
=================
|
||||
*/
|
||||
static void ClearQuake1MapTextureSizeCache() {
|
||||
g_quake1MapTextureSizeCache.Clear();
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
GetQuake1MapTextureDimensions
|
||||
|
||||
Quake texture shifts and scales are stored in texture pixels. Convert them
|
||||
to Doom 3 brushDef UV space by normalizing S by the real texture width and T
|
||||
by the real texture height. renderSystem->LoadImage accepts names without an
|
||||
extension and resolves the actual image file. Missing textures fall back to
|
||||
32x32, preserving the old hardcoded behavior for unresolved assets.
|
||||
=================
|
||||
*/
|
||||
static bool GetQuake1MapTextureDimensions(const idStr& materialName, int& width, int& height) {
|
||||
int i;
|
||||
byte* pic;
|
||||
ID_TIME_T timestamp;
|
||||
quake1MapTextureSizeCacheEntry_t entry;
|
||||
|
||||
for (i = 0; i < g_quake1MapTextureSizeCache.Num(); i++) {
|
||||
if (!g_quake1MapTextureSizeCache[i].name.Icmp(materialName)) {
|
||||
width = g_quake1MapTextureSizeCache[i].width;
|
||||
height = g_quake1MapTextureSizeCache[i].height;
|
||||
return width > 0 && height > 0;
|
||||
}
|
||||
}
|
||||
|
||||
width = 0;
|
||||
height = 0;
|
||||
pic = NULL;
|
||||
timestamp = 0;
|
||||
|
||||
if (renderSystem) {
|
||||
renderSystem->LoadImage(materialName.c_str(), &pic, &width, &height, ×tamp, false);
|
||||
}
|
||||
|
||||
if (pic) {
|
||||
Mem_Free(pic);
|
||||
}
|
||||
|
||||
if (width <= 0 || height <= 0) {
|
||||
width = 32;
|
||||
height = 32;
|
||||
}
|
||||
|
||||
entry.name = materialName;
|
||||
entry.width = width;
|
||||
entry.height = height;
|
||||
g_quake1MapTextureSizeCache.Append(entry);
|
||||
|
||||
return width > 0 && height > 0;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
GetQuake1MapTextureUnitScales
|
||||
=================
|
||||
*/
|
||||
static void GetQuake1MapTextureUnitScales(const idStr& materialName, float& sUnitScale, float& tUnitScale) {
|
||||
int textureWidth, textureHeight;
|
||||
|
||||
GetQuake1MapTextureDimensions(materialName, textureWidth, textureHeight);
|
||||
sUnitScale = 1.0f / (float)textureWidth;
|
||||
tUnitScale = 1.0f / (float)textureHeight;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
BuildQuake1MapTextureMatrix
|
||||
|
||||
Convert Quake world-space texture vectors into the brushDef texture matrix
|
||||
basis used by idMapBrushSide::GetTextureVectors. Any component along the
|
||||
plane normal is folded into the constant offset because all points on the face
|
||||
share the same normal distance.
|
||||
=================
|
||||
*/
|
||||
static void BuildQuake1MapTextureMatrix(const idPlane& plane, const idVec3& origin, const idVec3& sVecIn, float sOffsetIn, const idVec3& tVecIn, float tOffsetIn, idVec3 texMat[2]) {
|
||||
idVec3 normal, texX, texY, sVec, tVec;
|
||||
float sNormal, tNormal, planeDistance;
|
||||
int i;
|
||||
|
||||
normal = plane.Normal();
|
||||
ComputeAxisBase(normal, texX, texY);
|
||||
|
||||
sNormal = sVecIn * normal;
|
||||
tNormal = tVecIn * normal;
|
||||
for (i = 0; i < 3; i++) {
|
||||
sVec[i] = sVecIn[i] - normal[i] * sNormal;
|
||||
tVec[i] = tVecIn[i] - normal[i] * tNormal;
|
||||
}
|
||||
|
||||
planeDistance = -plane[3] + (origin * normal);
|
||||
|
||||
texMat[0][0] = sVec * texX;
|
||||
texMat[0][1] = sVec * texY;
|
||||
texMat[0][2] = sOffsetIn + sNormal * planeDistance;
|
||||
texMat[1][0] = tVec * texX;
|
||||
texMat[1][1] = tVec * texY;
|
||||
texMat[1][2] = tOffsetIn + tNormal * planeDistance;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SetQuake1MapMaterial
|
||||
=================
|
||||
*/
|
||||
static void SetQuake1MapMaterial(idStr& out, const idStr& material) {
|
||||
// Keep the old id map convention for legacy texture names.
|
||||
out = "textures/";
|
||||
out += material;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
ParseQuake1MapTextureInfo
|
||||
|
||||
Supports both classic Quake 1 faces:
|
||||
TEXTURE offsetX offsetY rotation scaleX scaleY
|
||||
and Valve 220 faces:
|
||||
TEXTURE [ ux uy uz offsetX ] [ vx vy vz offsetY ] rotation scaleX scaleY
|
||||
=================
|
||||
*/
|
||||
static bool ParseQuake1MapTextureInfo(const idList<idToken>& tokens, const idPlane& plane, const idVec3& origin, idStr& materialOut, idVec3 texMat[2]) {
|
||||
idStr material;
|
||||
int i, j, index, parmIndex;
|
||||
float rotate, scale[2], shift[2], sUnitScale, tUnitScale;
|
||||
idVec3 axes[2];
|
||||
|
||||
if (tokens.Num() < 6) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < tokens.Num(); i++) {
|
||||
if (tokens[i] == "[") {
|
||||
JoinQuake1MapTextureName(tokens, 0, i, material);
|
||||
if (material.Length() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
index = i;
|
||||
if (!ParseQuake1MapValve220Vector(tokens, index, axes[0], shift[0]) ||
|
||||
!ParseQuake1MapValve220Vector(tokens, index, axes[1], shift[1]) ||
|
||||
!Quake1MapReadFloatToken(tokens, index, rotate) ||
|
||||
!Quake1MapReadFloatToken(tokens, index, scale[0]) ||
|
||||
!Quake1MapReadFloatToken(tokens, index, scale[1])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (scale[0] == 0.0f) {
|
||||
scale[0] = 1.0f;
|
||||
}
|
||||
if (scale[1] == 0.0f) {
|
||||
scale[1] = 1.0f;
|
||||
}
|
||||
|
||||
SetQuake1MapMaterial(materialOut, material);
|
||||
GetQuake1MapTextureUnitScales(materialOut, sUnitScale, tUnitScale);
|
||||
|
||||
// Valve 220 stores the texture axes directly. The rotation token is an
|
||||
// editor compatibility field and should not be applied again here.
|
||||
for (j = 0; j < 3; j++) {
|
||||
axes[0][j] *= sUnitScale / scale[0];
|
||||
axes[1][j] *= tUnitScale / scale[1];
|
||||
}
|
||||
shift[0] *= sUnitScale;
|
||||
shift[1] *= tUnitScale;
|
||||
|
||||
BuildQuake1MapTextureMatrix(plane, origin, axes[0], shift[0], axes[1], shift[1], texMat);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
parmIndex = FindQuake1MapStandardTextureParms(tokens);
|
||||
if (parmIndex <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JoinQuake1MapTextureName(tokens, 0, parmIndex, material);
|
||||
index = parmIndex;
|
||||
if (material.Length() == 0 ||
|
||||
!Quake1MapReadFloatToken(tokens, index, shift[0]) ||
|
||||
!Quake1MapReadFloatToken(tokens, index, shift[1]) ||
|
||||
!Quake1MapReadFloatToken(tokens, index, rotate) ||
|
||||
!Quake1MapReadFloatToken(tokens, index, scale[0]) ||
|
||||
!Quake1MapReadFloatToken(tokens, index, scale[1])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (scale[0] == 0.0f) {
|
||||
scale[0] = 1.0f;
|
||||
}
|
||||
if (scale[1] == 0.0f) {
|
||||
scale[1] = 1.0f;
|
||||
}
|
||||
|
||||
SetQuake1MapMaterial(materialOut, material);
|
||||
GetQuake1MapTextureUnitScales(materialOut, sUnitScale, tUnitScale);
|
||||
|
||||
Quake1MapTextureAxisFromPlane(plane.Normal(), axes[0], axes[1]);
|
||||
RotateQuake1MapTextureAxes(axes, rotate);
|
||||
for (i = 0; i < 3; i++) {
|
||||
axes[0][i] *= sUnitScale / scale[0];
|
||||
axes[1][i] *= tUnitScale / scale[1];
|
||||
}
|
||||
shift[0] *= sUnitScale;
|
||||
shift[1] *= tUnitScale;
|
||||
|
||||
BuildQuake1MapTextureMatrix(plane, origin, axes[0], shift[0], axes[1], shift[1], texMat);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
DetectQuake1MapFile
|
||||
|
||||
This deliberately avoids classifying every old brace-only map as Quake 1,
|
||||
because that would change existing Quake 3 fallback behavior. Instead it
|
||||
requires common Quake 1/Valve220 signals: a wad key, mapversion 220, TrenchBroom
|
||||
texture metadata, or Valve 220 bracketed face axes.
|
||||
=================
|
||||
*/
|
||||
static bool DetectQuake1MapFile(const idStr& fullName, bool osPath) {
|
||||
#ifdef QUAKE4
|
||||
idAutoPtr<Lexer> lexer(LexerFactory::MakeLexer(LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES));
|
||||
Lexer& detectSrc(*lexer);
|
||||
#else
|
||||
idLexer detectSrc(LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES);
|
||||
#endif
|
||||
idToken token;
|
||||
idToken value;
|
||||
|
||||
detectSrc.LoadFile(fullName, osPath);
|
||||
if (!detectSrc.IsLoaded()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// idTech map files advertise their format with a top-level Version token;
|
||||
// Quake 1 maps do not.
|
||||
if (detectSrc.CheckTokenString("Version")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (detectSrc.ReadToken(&token)) {
|
||||
if (token == "[") {
|
||||
return true;
|
||||
}
|
||||
if (!token.Icmp("wad") || !token.Icmp("_tb_textures")) {
|
||||
return true;
|
||||
}
|
||||
if (!token.Icmp("mapversion")) {
|
||||
if (detectSrc.ReadTokenOnLine(&value) && atoi(value.c_str()) == 220) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#ifdef QUAKE4
|
||||
/*
|
||||
===============
|
||||
@@ -507,6 +1045,63 @@ idMapBrush* idMapBrush::ParseQ3(Lexer & src, const idVec3 & origin) {
|
||||
#else
|
||||
idMapBrush* idMapBrush::ParseQ3(idLexer & src, const idVec3 & origin) {
|
||||
#endif
|
||||
if (g_parseQuake1Map) {
|
||||
int i;
|
||||
idVec3 planepts[3];
|
||||
idToken token;
|
||||
idList<idToken> textureTokens;
|
||||
idList<idMapBrushSide*> sides;
|
||||
idMapBrushSide* side;
|
||||
idDict epairs;
|
||||
|
||||
do {
|
||||
if (src.CheckTokenString("}")) {
|
||||
break;
|
||||
}
|
||||
|
||||
side = new idMapBrushSide();
|
||||
sides.Append(side);
|
||||
|
||||
// read the three point plane definition
|
||||
if (!src.Parse1DMatrix(3, planepts[0].ToFloatPtr()) ||
|
||||
!src.Parse1DMatrix(3, planepts[1].ToFloatPtr()) ||
|
||||
!src.Parse1DMatrix(3, planepts[2].ToFloatPtr())) {
|
||||
src.Error("idMapBrush::ParseQ3: unable to read Quake 1 brush side plane definition");
|
||||
sides.DeleteContents(true);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
planepts[0] -= origin;
|
||||
planepts[1] -= origin;
|
||||
planepts[2] -= origin;
|
||||
|
||||
side->plane.FromPoints(planepts[0], planepts[1], planepts[2]);
|
||||
side->origin = origin;
|
||||
|
||||
// Read the rest of the face line. Quake texture names may begin with
|
||||
// punctuation, so keep the whole line and identify the numeric suffix.
|
||||
textureTokens.Clear();
|
||||
while (src.ReadTokenOnLine(&token)) {
|
||||
textureTokens.Append(token);
|
||||
}
|
||||
|
||||
if (!ParseQuake1MapTextureInfo(textureTokens, side->plane, origin, side->material, side->texMat)) {
|
||||
src.Error("idMapBrush::ParseQ3: unable to read Quake 1 brush side texture info");
|
||||
sides.DeleteContents(true);
|
||||
return NULL;
|
||||
}
|
||||
} while (1);
|
||||
|
||||
idMapBrush* brush = new idMapBrush();
|
||||
for (i = 0; i < sides.Num(); i++) {
|
||||
brush->AddSide(sides[i]);
|
||||
}
|
||||
|
||||
brush->epairs = epairs;
|
||||
|
||||
return brush;
|
||||
}
|
||||
|
||||
int i, shift[2], rotate;
|
||||
float scale[2];
|
||||
idVec3 planepts[3];
|
||||
@@ -925,6 +1520,8 @@ bool idMapFile::Parse(const char* filename, bool ignoreRegion, bool osPath) {
|
||||
name.StripFileExtension();
|
||||
fullName = name;
|
||||
hasPrimitiveData = false;
|
||||
g_parseQuake1Map = false;
|
||||
ClearQuake1MapTextureSizeCache();
|
||||
#ifdef QUAKE4
|
||||
mHasExportEntities = false;
|
||||
mHasFuncGroups = false;
|
||||
@@ -953,6 +1550,7 @@ bool idMapFile::Parse(const char* filename, bool ignoreRegion, bool osPath) {
|
||||
version = OLD_MAP_VERSION;
|
||||
fileTime = src.GetFileTime();
|
||||
entities.DeleteContents(true);
|
||||
g_parseQuake1Map = DetectQuake1MapFile(fullName, osPath);
|
||||
|
||||
if (src.CheckTokenString("Version")) {
|
||||
src.ReadTokenOnLine(&token);
|
||||
@@ -1050,6 +1648,8 @@ bool idMapFile::Parse(const char* filename, bool ignoreRegion, bool osPath) {
|
||||
#endif
|
||||
|
||||
hasPrimitiveData = true;
|
||||
g_parseQuake1Map = false;
|
||||
ClearQuake1MapTextureSizeCache();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1382,6 +1982,8 @@ bool idMapFile::ParseExport(const char* filename, bool osPath)
|
||||
|
||||
numMerged = numNotMerged = numAdded = numRemoved = 0;
|
||||
mHasExportEntities = false;
|
||||
g_parseQuake1Map = false;
|
||||
ClearQuake1MapTextureSizeCache();
|
||||
|
||||
fullName = filename;
|
||||
fullName.StripFileExtension();
|
||||
|
||||
@@ -176,7 +176,7 @@ void RB_DXDrawInteractions(void)
|
||||
const float r = srcLight.shaderParms[SHADERPARM_RED];
|
||||
const float g = srcLight.shaderParms[SHADERPARM_GREEN];
|
||||
const float b = srcLight.shaderParms[SHADERPARM_BLUE];
|
||||
const float intensity = 4.0f;
|
||||
const float intensity = 6.0f;
|
||||
|
||||
glRaytracingLight_t light = {};
|
||||
bool supported = true;
|
||||
|
||||
Reference in New Issue
Block a user