From 87f3c9c5b75c8b78d96e462e0028e960883a62e4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 2 Jan 2010 11:38:27 +0000 Subject: [PATCH] - 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) --- docs/rh-log.txt | 14 ++++++ src/g_shared/shared_hud.cpp | 9 +++- src/m_options.cpp | 2 +- src/p_floor.cpp | 12 ++++- src/textures/multipatchtexture.cpp | 9 +++- src/textures/texture.cpp | 2 +- src/textures/textures.h | 1 + src/thingdef/thingdef_parse.cpp | 52 +++++++++++++-------- src/v_font.cpp | 6 +-- src/v_video.cpp | 74 ++++++++++++++++-------------- 10 files changed, 117 insertions(+), 64 deletions(-) diff --git a/docs/rh-log.txt b/docs/rh-log.txt index bf9dcdb6e..b727cb295 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -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 diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index a1905aff9..b2efa1d13 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -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; } } diff --git a/src/m_options.cpp b/src/m_options.cpp index 219170e36..83b2a038d 100644 --- a/src/m_options.cpp +++ b/src/m_options.cpp @@ -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) { diff --git a/src/p_floor.cpp b/src/p_floor.cpp index 984a0f064..fd06ff0c1 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -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); diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index 34956dff7..faaa5db6c 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -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 parts; + bMultiPatch = true; sc.SetCMode(true); sc.MustGetString(); uppercopy(Name, sc.String); diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 88acefb47..97f393cb2 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -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(); diff --git a/src/textures/textures.h b/src/textures/textures.h index 1bd9282a9..0146b7355 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -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; diff --git a/src/thingdef/thingdef_parse.cpp b/src/thingdef/thingdef_parse.cpp index 4aea677aa..85930b09c 100644 --- a/src/thingdef/thingdef_parse.cpp +++ b/src/thingdef/thingdef_parse.cpp @@ -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; } diff --git a/src/v_font.cpp b/src/v_font.cpp index e36bd1cac..ead32a8c5 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -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; } diff --git a/src/v_video.cpp b/src/v_video.cpp index e9be86208..f6e0eb546 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -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; }