- 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:
Christoph Oelckers 2010-01-02 11:38:27 +00:00
parent 54283ee231
commit 87f3c9c5b7
10 changed files with 117 additions and 64 deletions

View file

@ -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

View file

@ -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;
}
}

View file

@ -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)
{

View file

@ -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);

View file

@ -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);

View file

@ -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();

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}