mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-02-17 09:31:43 +00:00
- fixed: The floor waggle code used FloatBobOffsets as sine table but this
only has 64 entries and is not precise enough. It now uses finesine instead. - fixed: When compositing a multipatch texture any patch that is a multpatch texture itself and contains rotations may not be composited directly into the destination buffer. This must be done with an intermediate buffer. - Fixed: Drawing a slider in the options menu did not scale the x-coordinate. - Fixed: If the alt HUD had to draw negative numbers the minus sign was misplaced due to incorrect texture coordinate calculations. - changed option menu scaling for widescreen modes so that it doesn't scale down so quickly. - made some error messages in DECORATE that don't affect the parsing non-fatal so that the parser can continue to find more problems. SVN r2076 (trunk)
This commit is contained in:
parent
54283ee231
commit
87f3c9c5b7
10 changed files with 117 additions and 64 deletions
|
@ -1,3 +1,17 @@
|
|||
January 2, 2010 (Changes by Graf Zahl)
|
||||
- fixed: The floor waggle code used FloatBobOffsets as sine table but this
|
||||
only has 64 entries and is not precise enough. It now uses finesine instead.
|
||||
- fixed: When compositing a multipatch texture any patch that is a multpatch
|
||||
texture itself and contains rotations may not be composited directly into
|
||||
the destination buffer. This must be done with an intermediate buffer.
|
||||
- Fixed: Drawing a slider in the options menu did not scale the x-coordinate.
|
||||
- Fixed: If the alt HUD had to draw negative numbers the minus sign was misplaced
|
||||
due to incorrect texture coordinate calculations.
|
||||
- changed option menu scaling for widescreen modes so that it doesn't scale down
|
||||
so quickly.
|
||||
- made some error messages in DECORATE that don't affect the parsing non-fatal
|
||||
so that the parser can continue to find more problems.
|
||||
|
||||
January 1, 2010 (Changes by Graf Zahl)
|
||||
- added initial support for a GAMEINFO lump in PWADs. When the game is started
|
||||
all files loaded with '-file' are scanned for this lump. This lump is read
|
||||
|
|
|
@ -158,15 +158,20 @@ static void DrawImageToBox(FTexture * tex, int x, int y, int w, int h, int trans
|
|||
|
||||
static void DrawHudText(FFont *font, int color, char * text, int x, int y, int trans=0xc000)
|
||||
{
|
||||
int zerowidth = font->GetCharWidth('0');
|
||||
int zerowidth;
|
||||
FTexture *tex_zero = font->GetChar('0', &zerowidth);
|
||||
|
||||
x+=zerowidth/2;
|
||||
for(int i=0;text[i];i++)
|
||||
{
|
||||
int width;
|
||||
FTexture *texc = font->GetChar(text[i], &width);
|
||||
int offset = texc->TopOffset - tex_zero->TopOffset + tex_zero->GetHeight();
|
||||
screen->DrawChar(font, color, x, y, text[i],
|
||||
DTA_KeepRatio, true,
|
||||
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, trans,
|
||||
DTA_CenterBottomOffset, 1, TAG_DONE);
|
||||
DTA_LeftOffset, width/2, DTA_TopOffset, offset,
|
||||
/*DTA_CenterBottomOffset, 1,*/ TAG_DONE);
|
||||
x+=zerowidth;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1565,7 +1565,7 @@ static void M_DrawSlider (int x, int y, double min, double max, double cur,int f
|
|||
cur = clamp(cur, min, max) - min;
|
||||
|
||||
M_DrawConText(CR_WHITE, x, y, "\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12");
|
||||
M_DrawConText(CR_ORANGE, x + 5 + (int)((cur * 78) / range), y, "\x13");
|
||||
M_DrawConText(CR_ORANGE, x + int((5 + ((cur * 78) / range)) * CleanXfac_1), y, "\x13");
|
||||
|
||||
if (fracdigits >= 0)
|
||||
{
|
||||
|
|
|
@ -1268,9 +1268,17 @@ void DWaggleBase::DoWaggle (bool ceiling)
|
|||
break;
|
||||
}
|
||||
m_Accumulator += m_AccDelta;
|
||||
|
||||
|
||||
#if 1
|
||||
fixed_t mag = finesine[(m_Accumulator>>9)&8191]*8;
|
||||
#else
|
||||
// Hexen used a 64 entry(!) sine table here which is not nearly precise enough for smooth movement
|
||||
fixed_t mag = FloatBobOffsets[(m_Accumulator>>FRACBITS)&63];
|
||||
#endif
|
||||
|
||||
dist = plane->d;
|
||||
plane->d = m_OriginalDist + plane->PointToDist (0, 0,
|
||||
FixedMul (FloatBobOffsets[(m_Accumulator>>FRACBITS)&63], m_Scale));
|
||||
plane->d = m_OriginalDist + plane->PointToDist (0, 0, FixedMul (mag, m_Scale));
|
||||
m_Sector->ChangePlaneTexZ(pos, plane->HeightDiff (dist));
|
||||
dist = plane->HeightDiff (dist);
|
||||
|
||||
|
|
|
@ -218,6 +218,7 @@ FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchl
|
|||
int i;
|
||||
|
||||
mtexture.d = (const maptexture_t *)texdef;
|
||||
bMultiPatch = true;
|
||||
|
||||
if (strife)
|
||||
{
|
||||
|
@ -561,7 +562,10 @@ int FMultiPatchTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rota
|
|||
{
|
||||
int ret = -1;
|
||||
|
||||
if (!Parts[i].Texture->bComplex || inf == NULL)
|
||||
// rotated multipatch parts cannot be composited directly
|
||||
bool rotatedmulti = Parts[i].Rotate != 0 && Parts[i].Texture->bMultiPatch;
|
||||
|
||||
if ((!Parts[i].Texture->bComplex || inf == NULL) && !rotatedmulti)
|
||||
{
|
||||
memset (&info, 0, sizeof (info));
|
||||
info.alpha = Parts[i].Alpha;
|
||||
|
@ -612,7 +616,7 @@ int FMultiPatchTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rota
|
|||
{
|
||||
Parts[i].Texture->CopyTrueColorPixels(&bmp1, 0, 0);
|
||||
bmp->CopyPixelDataRGB(x+Parts[i].OriginX, y+Parts[i].OriginY, bmp1.GetPixels(),
|
||||
bmp1.GetWidth(), bmp1.GetHeight(), 4, bmp1.GetPitch()*4, Parts[i].Rotate, CF_BGRA, inf);
|
||||
bmp1.GetWidth(), bmp1.GetHeight(), 4, bmp1.GetPitch(), Parts[i].Rotate, CF_BGRA, inf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1179,6 +1183,7 @@ FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, int usetype)
|
|||
{
|
||||
TArray<TexPart> parts;
|
||||
|
||||
bMultiPatch = true;
|
||||
sc.SetCMode(true);
|
||||
sc.MustGetString();
|
||||
uppercopy(Name, sc.String);
|
||||
|
|
|
@ -143,7 +143,7 @@ FTexture::FTexture (const char *name, int lumpnum)
|
|||
: LeftOffset(0), TopOffset(0),
|
||||
WidthBits(0), HeightBits(0), xScale(FRACUNIT), yScale(FRACUNIT), SourceLump(lumpnum),
|
||||
UseType(TEX_Any), bNoDecals(false), bNoRemap0(false), bWorldPanning(false),
|
||||
bMasked(true), bAlphaTexture(false), bHasCanvas(false), bWarped(0), bComplex(false),
|
||||
bMasked(true), bAlphaTexture(false), bHasCanvas(false), bWarped(0), bComplex(false), bMultiPatch(false),
|
||||
Rotations(0xFFFF), SkyOffset(0), Width(0), Height(0), WidthMask(0), Native(NULL)
|
||||
{
|
||||
id.SetInvalid();
|
||||
|
|
|
@ -119,6 +119,7 @@ public:
|
|||
BYTE bComplex:1; // Will be used to mark extended MultipatchTextures that have to be
|
||||
// fully composited before subjected to any kinf of postprocessing instead of
|
||||
// doing it per patch.
|
||||
BYTE bMultiPatch:1; // This is a multipatch texture (we really could use real type info for textures...)
|
||||
|
||||
WORD Rotations;
|
||||
SWORD SkyOffset;
|
||||
|
|
|
@ -149,7 +149,8 @@ FxExpression *ParseParameter(FScanner &sc, PClass *cls, char type, bool constant
|
|||
x = ParseExpression (sc, cls);
|
||||
if (constant && !x->isConstant())
|
||||
{
|
||||
sc.ScriptError("Default parameter must be constant.");
|
||||
sc.ScriptMessage("Default parameter must be constant.");
|
||||
FScriptPosition::ErrorCounter++;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -196,13 +197,15 @@ static void ParseConstant (FScanner &sc, PSymbolTable * symt, PClass *cls)
|
|||
if (symt->AddSymbol (sym) == NULL)
|
||||
{
|
||||
delete sym;
|
||||
sc.ScriptError ("'%s' is already defined in '%s'.",
|
||||
sc.ScriptMessage ("'%s' is already defined in '%s'.",
|
||||
symname.GetChars(), cls? cls->TypeName.GetChars() : "Global");
|
||||
FScriptPosition::ErrorCounter++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.ScriptError("Numeric type required for constant");
|
||||
sc.ScriptMessage("Numeric type required for constant");
|
||||
FScriptPosition::ErrorCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,8 +238,9 @@ static void ParseEnum (FScanner &sc, PSymbolTable *symt, PClass *cls)
|
|||
if (symt->AddSymbol (sym) == NULL)
|
||||
{
|
||||
delete sym;
|
||||
sc.ScriptError ("'%s' is already defined in '%s'.",
|
||||
sc.ScriptMessage ("'%s' is already defined in '%s'.",
|
||||
symname.GetChars(), cls? cls->TypeName.GetChars() : "Global");
|
||||
FScriptPosition::ErrorCounter++;
|
||||
}
|
||||
// This allows a comma after the last value but doesn't enforce it.
|
||||
if (sc.CheckToken('}')) break;
|
||||
|
@ -260,7 +264,8 @@ static void ParseNativeVariable (FScanner &sc, PSymbolTable * symt, PClass *cls)
|
|||
|
||||
if (sc.LumpNum == -1 || Wads.GetLumpFile(sc.LumpNum) > 0)
|
||||
{
|
||||
sc.ScriptError ("variables can only be imported by internal class and actor definitions!");
|
||||
sc.ScriptMessage ("variables can only be imported by internal class and actor definitions!");
|
||||
FScriptPosition::ErrorCounter++;
|
||||
}
|
||||
|
||||
// Read the type and make sure it's int or float.
|
||||
|
@ -324,8 +329,9 @@ static void ParseNativeVariable (FScanner &sc, PSymbolTable * symt, PClass *cls)
|
|||
if (symt->AddSymbol (sym) == NULL)
|
||||
{
|
||||
delete sym;
|
||||
sc.ScriptError ("'%s' is already defined in '%s'.",
|
||||
sc.ScriptMessage ("'%s' is already defined in '%s'.",
|
||||
symname.GetChars(), cls? cls->TypeName.GetChars() : "Global");
|
||||
FScriptPosition::ErrorCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -349,21 +355,20 @@ static void ParseUserVariable (FScanner &sc, PSymbolTable *symt, PClass *cls)
|
|||
|
||||
// Read the type and make sure it's int.
|
||||
sc.MustGetAnyToken();
|
||||
if (sc.TokenType == TK_Int)
|
||||
if (sc.TokenType != TK_Int)
|
||||
{
|
||||
valuetype = VAL_Int;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.ScriptError("User variables must be of type int");
|
||||
sc.ScriptMessage("User variables must be of type int");
|
||||
FScriptPosition::ErrorCounter++;
|
||||
}
|
||||
valuetype = VAL_Int;
|
||||
|
||||
sc.MustGetToken(TK_Identifier);
|
||||
// For now, restrict user variables to those that begin with "user_" to guarantee
|
||||
// no clashes with internal member variable names.
|
||||
if (sc.StringLen < 6 || strnicmp("user_", sc.String, 5) != 0)
|
||||
{
|
||||
sc.ScriptError("User variable names must begin with \"user_\"");
|
||||
sc.ScriptMessage("User variable names must begin with \"user_\"");
|
||||
FScriptPosition::ErrorCounter++;
|
||||
}
|
||||
|
||||
FName symname = sc.String;
|
||||
|
@ -375,7 +380,9 @@ static void ParseUserVariable (FScanner &sc, PSymbolTable *symt, PClass *cls)
|
|||
sc.MustGetToken(']');
|
||||
if (maxelems <= 0)
|
||||
{
|
||||
sc.ScriptError("Array size must be positive");
|
||||
sc.ScriptMessage("Array size must be positive");
|
||||
FScriptPosition::ErrorCounter++;
|
||||
maxelems = 1;
|
||||
}
|
||||
valuetype.MakeArray(maxelems);
|
||||
}
|
||||
|
@ -388,8 +395,9 @@ static void ParseUserVariable (FScanner &sc, PSymbolTable *symt, PClass *cls)
|
|||
if (symt->AddSymbol(sym) == NULL)
|
||||
{
|
||||
delete sym;
|
||||
sc.ScriptError ("'%s' is already defined in '%s'.",
|
||||
sc.ScriptMessage ("'%s' is already defined in '%s'.",
|
||||
symname.GetChars(), cls ? cls->TypeName.GetChars() : "Global");
|
||||
FScriptPosition::ErrorCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -445,12 +453,13 @@ void HandleActorFlag(FScanner &sc, Baggage &bag, const char *part1, const char *
|
|||
{
|
||||
if (part2 == NULL)
|
||||
{
|
||||
sc.ScriptError("\"%s\" is an unknown flag\n", part1);
|
||||
sc.ScriptMessage("\"%s\" is an unknown flag\n", part1);
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.ScriptError("\"%s.%s\" is an unknown flag\n", part1, part2);
|
||||
sc.ScriptMessage("\"%s.%s\" is an unknown flag\n", part1, part2);
|
||||
}
|
||||
FScriptPosition::ErrorCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -583,13 +592,18 @@ static FState *CheckState(FScanner &sc, PClass *type)
|
|||
|
||||
if (v!=0 && state==NULL)
|
||||
{
|
||||
sc.ScriptError("Attempt to get invalid state from actor %s\n", type->ParentClass->TypeName.GetChars());
|
||||
sc.ScriptMessage("Attempt to get invalid state from actor %s\n", type->ParentClass->TypeName.GetChars());
|
||||
FScriptPosition::ErrorCounter++;
|
||||
return NULL;
|
||||
}
|
||||
state+=v;
|
||||
return state;
|
||||
}
|
||||
else sc.ScriptError("Invalid state assignment");
|
||||
else
|
||||
{
|
||||
sc.ScriptMessage("Invalid state assignment");
|
||||
FScriptPosition::ErrorCounter++;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -736,19 +736,19 @@ FTexture *FFont::GetChar (int code, int *const width) const
|
|||
code > LastChar ||
|
||||
Chars[code - FirstChar].Pic == NULL)
|
||||
{
|
||||
*width = SpaceWidth;
|
||||
if (width != NULL) *width = SpaceWidth;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*width = SpaceWidth;
|
||||
if (width != NULL) *width = SpaceWidth;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
code -= FirstChar;
|
||||
*width = Chars[code].Pic->GetScaledWidth();
|
||||
if (width != NULL) *width = Chars[code].Pic->GetScaledWidth();
|
||||
return Chars[code].Pic;
|
||||
}
|
||||
|
||||
|
|
|
@ -1336,6 +1336,10 @@ CCMD(clean)
|
|||
bool V_DoModeSetup (int width, int height, int bits)
|
||||
{
|
||||
DFrameBuffer *buff = I_SetMode (width, height, screen);
|
||||
int ratio;
|
||||
int cwidth;
|
||||
int cheight;
|
||||
int cx1, cy1, cx2, cy2;
|
||||
|
||||
if (buff == NULL)
|
||||
{
|
||||
|
@ -1350,39 +1354,32 @@ bool V_DoModeSetup (int width, int height, int bits)
|
|||
// if D3DFB is being used for the display.
|
||||
FFont::StaticPreloadFonts();
|
||||
|
||||
ratio = CheckRatio (width, height);
|
||||
if (ratio & 4)
|
||||
{
|
||||
int ratio;
|
||||
int cwidth;
|
||||
int cheight;
|
||||
int cx1, cy1, cx2, cy2;
|
||||
|
||||
ratio = CheckRatio (width, height);
|
||||
if (ratio & 4)
|
||||
{
|
||||
cwidth = width;
|
||||
cheight = height * BaseRatioSizes[ratio][3] / 48;
|
||||
}
|
||||
else
|
||||
{
|
||||
cwidth = width * BaseRatioSizes[ratio][3] / 48;
|
||||
cheight = height;
|
||||
}
|
||||
// Use whichever pair of cwidth/cheight or width/height that produces less difference
|
||||
// between CleanXfac and CleanYfac.
|
||||
cx1 = MAX(cwidth / 320, 1);
|
||||
cy1 = MAX(cheight / 200, 1);
|
||||
cx2 = MAX(width / 320, 1);
|
||||
cy2 = MAX(height / 200, 1);
|
||||
if (abs(cx1 - cy1) <= abs(cx2 - cy2))
|
||||
{ // e.g. 640x360 looks better with this.
|
||||
CleanXfac = cx1;
|
||||
CleanYfac = cy1;
|
||||
}
|
||||
else
|
||||
{ // e.g. 720x480 looks better with this.
|
||||
CleanXfac = cx2;
|
||||
CleanYfac = cy2;
|
||||
}
|
||||
cwidth = width;
|
||||
cheight = height * BaseRatioSizes[ratio][3] / 48;
|
||||
}
|
||||
else
|
||||
{
|
||||
cwidth = width * BaseRatioSizes[ratio][3] / 48;
|
||||
cheight = height;
|
||||
}
|
||||
// Use whichever pair of cwidth/cheight or width/height that produces less difference
|
||||
// between CleanXfac and CleanYfac.
|
||||
cx1 = MAX(cwidth / 320, 1);
|
||||
cy1 = MAX(cheight / 200, 1);
|
||||
cx2 = MAX(width / 320, 1);
|
||||
cy2 = MAX(height / 200, 1);
|
||||
if (abs(cx1 - cy1) <= abs(cx2 - cy2))
|
||||
{ // e.g. 640x360 looks better with this.
|
||||
CleanXfac = cx1;
|
||||
CleanYfac = cy1;
|
||||
}
|
||||
else
|
||||
{ // e.g. 720x480 looks better with this.
|
||||
CleanXfac = cx2;
|
||||
CleanYfac = cy2;
|
||||
}
|
||||
|
||||
if (CleanXfac > 1 && CleanYfac > 1 && CleanXfac != CleanYfac)
|
||||
|
@ -1400,8 +1397,17 @@ bool V_DoModeSetup (int width, int height, int bits)
|
|||
|
||||
if (width < 800 || width >= 960)
|
||||
{
|
||||
CleanXfac_1 = MAX(CleanXfac - 1, 1);
|
||||
CleanYfac_1 = MAX(CleanYfac - 1, 1);
|
||||
if (cx1 < cx2)
|
||||
{
|
||||
// Special case in which we don't need to scale down.
|
||||
CleanXfac_1 =
|
||||
CleanYfac_1 = cx1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CleanXfac_1 = MAX(CleanXfac - 1, 1);
|
||||
CleanYfac_1 = MAX(CleanYfac - 1, 1);
|
||||
}
|
||||
CleanWidth_1 = width / CleanXfac_1;
|
||||
CleanHeight_1 = height / CleanYfac_1;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue