From 5f36b86013018c5a7b76b069952c0ef94d87d3f9 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 4 Jan 2018 17:58:11 +0100 Subject: [PATCH 01/29] - Add dynamic spot lights --- src/g_shared/a_dynlight.cpp | 7 ++- src/g_shared/a_dynlight.h | 9 ++-- src/g_shared/a_dynlightdata.cpp | 59 +++++++++++++++++++++- src/gl/dynlights/gl_dynlight1.cpp | 29 ++++++++++- src/scripting/thingdef_data.cpp | 1 + wadsrc/static/shaders/glsl/main.fp | 34 ++++++++++--- wadsrc/static/zscript/shared/dynlights.txt | 8 ++- 7 files changed, 134 insertions(+), 13 deletions(-) diff --git a/src/g_shared/a_dynlight.cpp b/src/g_shared/a_dynlight.cpp index 0cad5e9ba7..1858a9a929 100644 --- a/src/g_shared/a_dynlight.cpp +++ b/src/g_shared/a_dynlight.cpp @@ -114,6 +114,9 @@ DEFINE_CLASS_PROPERTY(type, S, DynamicLight) //========================================================================== IMPLEMENT_CLASS(ADynamicLight, false, false) +DEFINE_FIELD(ADynamicLight, SpotInnerAngle) +DEFINE_FIELD(ADynamicLight, SpotOuterAngle) + static FRandom randLight; //========================================================================== @@ -134,7 +137,9 @@ void ADynamicLight::Serialize(FSerializer &arc) arc("lightflags", lightflags, def->lightflags) ("lighttype", lighttype, def->lighttype) ("tickcount", m_tickCount, def->m_tickCount) - ("currentradius", m_currentRadius, def->m_currentRadius); + ("currentradius", m_currentRadius, def->m_currentRadius) + ("spotinnerangle", SpotInnerAngle, def->SpotInnerAngle) + ("spotouterangle", SpotOuterAngle, def->SpotOuterAngle); if (lighttype == PulseLight) arc("lastupdate", m_lastUpdate, def->m_lastUpdate) diff --git a/src/g_shared/a_dynlight.h b/src/g_shared/a_dynlight.h index 5446ba8cf9..b659507d12 100644 --- a/src/g_shared/a_dynlight.h +++ b/src/g_shared/a_dynlight.h @@ -28,7 +28,8 @@ enum LightFlag LF_DONTLIGHTSELF = 4, LF_ATTENUATE = 8, LF_NOSHADOWMAP = 16, - LF_DONTLIGHTACTORS = 32 + LF_DONTLIGHTACTORS = 32, + LF_SPOT = 64 }; typedef TFlags LightFlags; @@ -42,7 +43,7 @@ enum ELightType FlickerLight, RandomFlickerLight, SectorLight, - SpotLight, + DummyLight, ColorPulseLight, ColorFlickerLight, RandomColorFlickerLight @@ -100,6 +101,7 @@ public: bool IsActive() const { return !(flags2&MF2_DORMANT); } bool IsSubtractive() { return !!(lightflags & LF_SUBTRACTIVE); } bool IsAdditive() { return !!(lightflags & LF_ADDITIVE); } + bool IsSpot() { return !!(lightflags & LF_SPOT); } FState *targetState; FLightNode * touching_sides; FLightNode * touching_subsectors; @@ -127,6 +129,7 @@ public: bool shadowmapped; int bufferindex; LightFlags lightflags; - + DAngle SpotInnerAngle = 10.0; + DAngle SpotOuterAngle = 25.0; }; diff --git a/src/g_shared/a_dynlightdata.cpp b/src/g_shared/a_dynlightdata.cpp index fcdbcd3d10..817e7a80b2 100644 --- a/src/g_shared/a_dynlightdata.cpp +++ b/src/g_shared/a_dynlightdata.cpp @@ -128,6 +128,9 @@ public: void SetAttenuate(bool on) { m_attenuate = on; } void SetHalo(bool halo) { m_halo = halo; } void SetDontLightActors(bool on) { m_dontlightactors = on; } + void SetSpot(bool spot) { m_spot = spot; } + void SetSpotInnerAngle(double angle) { m_spotInnerAngle = angle; } + void SetSpotOuterAngle(double angle) { m_spotOuterAngle = angle; } void OrderIntensities() { @@ -151,6 +154,9 @@ protected: bool m_dontlightself = false; bool m_dontlightactors = false; bool m_swapped = false; + bool m_spot = false; + double m_spotInnerAngle = 10.0; + double m_spotOuterAngle = 25.0; }; TDeletingArray LightDefaults; @@ -183,6 +189,10 @@ void FLightDefaults::ApplyProperties(ADynamicLight * light) const if (m_additive) light->lightflags |= LF_ADDITIVE; if (m_dontlightself) light->lightflags |= LF_DONTLIGHTSELF; if (m_dontlightactors) light->lightflags |= LF_DONTLIGHTACTORS; + if (m_spot) + light->lightflags |= LF_SPOT; + light->SpotInnerAngle = m_spotInnerAngle; + light->SpotOuterAngle = m_spotOuterAngle; light->m_tickCount = 0; if (m_type == PulseLight) { @@ -233,7 +243,8 @@ static const char *LightTags[]= "dontlightself", "attenuate", "dontlightactors", - NULL + "spot", + nullptr }; @@ -255,6 +266,7 @@ enum { LIGHTTAG_DONTLIGHTSELF, LIGHTTAG_ATTENUATE, LIGHTTAG_DONTLIGHTACTORS, + LIGHTTAG_SPOT }; @@ -395,6 +407,15 @@ static void ParsePointLight(FScanner &sc) case LIGHTTAG_DONTLIGHTACTORS: defaults->SetDontLightActors(ParseInt(sc) != 0); break; + case LIGHTTAG_SPOT: + { + float innerAngle = ParseFloat(sc); + float outerAngle = ParseFloat(sc); + defaults->SetSpot(true); + defaults->SetSpotInnerAngle(innerAngle); + defaults->SetSpotOuterAngle(outerAngle); + } + break; default: sc.ScriptError("Unknown tag: %s\n", sc.String); } @@ -480,6 +501,15 @@ static void ParsePulseLight(FScanner &sc) case LIGHTTAG_DONTLIGHTACTORS: defaults->SetDontLightActors(ParseInt(sc) != 0); break; + case LIGHTTAG_SPOT: + { + float innerAngle = ParseFloat(sc); + float outerAngle = ParseFloat(sc); + defaults->SetSpot(true); + defaults->SetSpotInnerAngle(innerAngle); + defaults->SetSpotOuterAngle(outerAngle); + } + break; default: sc.ScriptError("Unknown tag: %s\n", sc.String); } @@ -567,6 +597,15 @@ void ParseFlickerLight(FScanner &sc) case LIGHTTAG_DONTLIGHTACTORS: defaults->SetDontLightActors(ParseInt(sc) != 0); break; + case LIGHTTAG_SPOT: + { + float innerAngle = ParseFloat(sc); + float outerAngle = ParseFloat(sc); + defaults->SetSpot(true); + defaults->SetSpotInnerAngle(innerAngle); + defaults->SetSpotOuterAngle(outerAngle); + } + break; default: sc.ScriptError("Unknown tag: %s\n", sc.String); } @@ -653,6 +692,15 @@ void ParseFlickerLight2(FScanner &sc) case LIGHTTAG_DONTLIGHTACTORS: defaults->SetDontLightActors(ParseInt(sc) != 0); break; + case LIGHTTAG_SPOT: + { + float innerAngle = ParseFloat(sc); + float outerAngle = ParseFloat(sc); + defaults->SetSpot(true); + defaults->SetSpotInnerAngle(innerAngle); + defaults->SetSpotOuterAngle(outerAngle); + } + break; default: sc.ScriptError("Unknown tag: %s\n", sc.String); } @@ -736,6 +784,15 @@ static void ParseSectorLight(FScanner &sc) case LIGHTTAG_DONTLIGHTACTORS: defaults->SetDontLightActors(ParseInt(sc) != 0); break; + case LIGHTTAG_SPOT: + { + float innerAngle = ParseFloat(sc); + float outerAngle = ParseFloat(sc); + defaults->SetSpot(true); + defaults->SetSpotInnerAngle(innerAngle); + defaults->SetSpotOuterAngle(outerAngle); + } + break; default: sc.ScriptError("Unknown tag: %s\n", sc.String); } diff --git a/src/gl/dynlights/gl_dynlight1.cpp b/src/gl/dynlights/gl_dynlight1.cpp index e42f89ac4b..a9efdd8807 100644 --- a/src/gl/dynlights/gl_dynlight1.cpp +++ b/src/gl/dynlights/gl_dynlight1.cpp @@ -128,7 +128,26 @@ void gl_AddLightToList(int group, ADynamicLight * light, FDynLightData &ldata) if (attenuate) shadowIndex = -shadowIndex; - float *data = &ldata.arrays[i][ldata.arrays[i].Reserve(8)]; + float lightType = 0.0f; + float spotInnerAngle = 0.0f; + float spotOuterAngle = 0.0f; + float spotDirX = 0.0f; + float spotDirY = 0.0f; + float spotDirZ = 0.0f; + if (light->IsSpot()) + { + lightType = 1.0f; + spotInnerAngle = light->SpotInnerAngle.Cos(); + spotOuterAngle = light->SpotOuterAngle.Cos(); + + DAngle negPitch = -light->Angles.Pitch; + float xyLen = negPitch.Cos(); + spotDirX = light->Angles.Yaw.Cos() * xyLen; + spotDirY = light->Angles.Yaw.Sin() * xyLen; + spotDirZ = negPitch.Sin(); + } + + float *data = &ldata.arrays[i][ldata.arrays[i].Reserve(16)]; data[0] = pos.X; data[1] = pos.Z; data[2] = pos.Y; @@ -137,5 +156,13 @@ void gl_AddLightToList(int group, ADynamicLight * light, FDynLightData &ldata) data[5] = g; data[6] = b; data[7] = shadowIndex; + data[8] = spotDirX; + data[9] = spotDirY; + data[10] = spotDirZ; + data[11] = lightType; + data[12] = spotInnerAngle; + data[13] = spotOuterAngle; + data[14] = 0.0f; // unused + data[15] = 0.0f; // unused } diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index c746c536d7..09e28ba556 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -494,6 +494,7 @@ static FFlagDef DynLightFlagDefs[] = DEFINE_FLAG(LF, ATTENUATE, ADynamicLight, lightflags), DEFINE_FLAG(LF, NOSHADOWMAP, ADynamicLight, lightflags), DEFINE_FLAG(LF, DONTLIGHTACTORS, ADynamicLight, lightflags), + DEFINE_FLAG(LF, SPOT, ADynamicLight, lightflags), }; static FFlagDef PowerSpeedFlagDefs[] = diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 83cabbd0d3..25a2c14d2a 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -278,6 +278,13 @@ float pointLightAttenuation(vec4 lightpos, float lightcolorA) } } +float spotLightAttenuation(vec4 lightpos, vec3 spotdir, float lightCosInnerAngle, float lightCosOuterAngle) +{ + vec3 lightDirection = normalize(lightpos.xyz - pixelpos.xyz); + float cosDir = dot(lightDirection, spotdir); + return smoothstep(lightCosOuterAngle, lightCosInnerAngle, cosDir); +} + //=========================================================================== // // Calculate light @@ -348,23 +355,33 @@ vec4 getLightColor(float fogdist, float fogfactor) // // modulated lights // - for(int i=lightRange.x; i Date: Thu, 4 Jan 2018 19:09:12 +0100 Subject: [PATCH 02/29] - Fix wrong spot direction --- src/gl/dynlights/gl_dynlight1.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gl/dynlights/gl_dynlight1.cpp b/src/gl/dynlights/gl_dynlight1.cpp index a9efdd8807..c412907405 100644 --- a/src/gl/dynlights/gl_dynlight1.cpp +++ b/src/gl/dynlights/gl_dynlight1.cpp @@ -142,9 +142,9 @@ void gl_AddLightToList(int group, ADynamicLight * light, FDynLightData &ldata) DAngle negPitch = -light->Angles.Pitch; float xyLen = negPitch.Cos(); - spotDirX = light->Angles.Yaw.Cos() * xyLen; - spotDirY = light->Angles.Yaw.Sin() * xyLen; - spotDirZ = negPitch.Sin(); + spotDirX = -light->Angles.Yaw.Cos() * xyLen; + spotDirY = -light->Angles.Yaw.Sin() * xyLen; + spotDirZ = -negPitch.Sin(); } float *data = &ldata.arrays[i][ldata.arrays[i].Reserve(16)]; From bae36205404bdc5c348ef9f68a31c66faa45385a Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 4 Jan 2018 19:27:03 +0100 Subject: [PATCH 03/29] - Added spot light support to gl_SetDynSpriteLight --- src/gl/dynlights/gl_dynlight1.cpp | 8 ++++---- src/gl/scene/gl_spritelight.cpp | 24 ++++++++++++++++++++++-- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/gl/dynlights/gl_dynlight1.cpp b/src/gl/dynlights/gl_dynlight1.cpp index c412907405..42f1c27cfb 100644 --- a/src/gl/dynlights/gl_dynlight1.cpp +++ b/src/gl/dynlights/gl_dynlight1.cpp @@ -141,10 +141,10 @@ void gl_AddLightToList(int group, ADynamicLight * light, FDynLightData &ldata) spotOuterAngle = light->SpotOuterAngle.Cos(); DAngle negPitch = -light->Angles.Pitch; - float xyLen = negPitch.Cos(); - spotDirX = -light->Angles.Yaw.Cos() * xyLen; - spotDirY = -light->Angles.Yaw.Sin() * xyLen; - spotDirZ = -negPitch.Sin(); + double xzLen = negPitch.Cos(); + spotDirX = -light->Angles.Yaw.Cos() * xzLen; + spotDirY = -negPitch.Sin(); + spotDirZ = -light->Angles.Yaw.Sin() * xzLen; } float *data = &ldata.arrays[i][ldata.arrays[i].Reserve(16)]; diff --git a/src/gl/scene/gl_spritelight.cpp b/src/gl/scene/gl_spritelight.cpp index 2d2e65b760..bde9f1450c 100644 --- a/src/gl/scene/gl_spritelight.cpp +++ b/src/gl/scene/gl_spritelight.cpp @@ -49,6 +49,13 @@ FDynLightData modellightdata; int modellightindex = -1; +template +T smoothstep(const T edge0, const T edge1, const T x) +{ + auto t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0); + return t * t * (3.0 - 2.0 * t); +} + //========================================================================== // // Sets a single light value from all dynamic lights affecting the specified location @@ -70,6 +77,7 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t * if (light->visibletoplayer && !(light->flags2&MF2_DORMANT) && (!(light->lightflags&LF_DONTLIGHTSELF) || light->target != self) && !(light->lightflags&LF_DONTLIGHTACTORS)) { float dist; + FVector3 L; // This is a performance critical section of code where we cannot afford to let the compiler decide whether to inline the function or not. // This will do the calculations explicitly rather than calling one of AActor's utility functions. @@ -80,14 +88,15 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t * if (fromgroup == togroup || fromgroup == 0 || togroup == 0) goto direct; DVector2 offset = Displacements.getOffset(fromgroup, togroup); - dist = FVector3(x - light->X() - offset.X, y - light->Y() - offset.Y, z - light->Z()).LengthSquared(); + L = FVector3(x - light->X() - offset.X, y - light->Y() - offset.Y, z - light->Z()); } else { direct: - dist = FVector3(x - light->X(), y - light->Y(), z - light->Z()).LengthSquared(); + L = FVector3(x - light->X(), y - light->Y(), z - light->Z()); } + dist = L.LengthSquared(); radius = light->GetRadius(); if (dist < radius * radius) @@ -96,6 +105,17 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t * frac = 1.0f - (dist / radius); + if (light->IsSpot()) + { + DAngle negPitch = -light->Angles.Pitch; + double xzLen = negPitch.Cos(); + double spotDirX = -light->Angles.Yaw.Cos() * xzLen; + double spotDirY = -negPitch.Sin(); + double spotDirZ = -light->Angles.Yaw.Sin() * xzLen; + double cosDir = L.X * spotDirX + L.Y * spotDirY + L.Z * spotDirZ; + frac *= (float)smoothstep(light->SpotOuterAngle.Cos(), light->SpotInnerAngle.Cos(), cosDir); + } + if (frac > 0 && GLRenderer->mShadowMap.ShadowTest(light, { x, y, z })) { lr = light->GetRed() / 255.0f; From 79440d70141eb504990acf5e8023108e070ed66e Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 4 Jan 2018 19:42:52 +0100 Subject: [PATCH 04/29] - Fix sprite spot light calculation --- src/gl/scene/gl_spritelight.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/gl/scene/gl_spritelight.cpp b/src/gl/scene/gl_spritelight.cpp index bde9f1450c..ac7e6971e5 100644 --- a/src/gl/scene/gl_spritelight.cpp +++ b/src/gl/scene/gl_spritelight.cpp @@ -107,11 +107,12 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t * if (light->IsSpot()) { + L *= -1.0f / dist; DAngle negPitch = -light->Angles.Pitch; - double xzLen = negPitch.Cos(); - double spotDirX = -light->Angles.Yaw.Cos() * xzLen; - double spotDirY = -negPitch.Sin(); - double spotDirZ = -light->Angles.Yaw.Sin() * xzLen; + double xyLen = negPitch.Cos(); + double spotDirX = -light->Angles.Yaw.Cos() * xyLen; + double spotDirY = -light->Angles.Yaw.Sin() * xyLen; + double spotDirZ = -negPitch.Sin(); double cosDir = L.X * spotDirX + L.Y * spotDirY + L.Z * spotDirZ; frac *= (float)smoothstep(light->SpotOuterAngle.Cos(), light->SpotInnerAngle.Cos(), cosDir); } From 7f7c720883e6841ced9c5e66cdae5e6b531872ad Mon Sep 17 00:00:00 2001 From: Jonathan Russell Date: Thu, 4 Jan 2018 22:41:57 +0000 Subject: [PATCH 05/29] - added UDMF properties for spotlights (args have all been used up for dynlights) --- src/doomdata.h | 2 ++ src/p_mobj.cpp | 11 ++++++ wadsrc/static/mapinfo/common.txt | 5 +++ wadsrc/static/zscript/shared/dynlights.txt | 40 ++++++++++++++++++++++ 4 files changed, 58 insertions(+) diff --git a/src/doomdata.h b/src/doomdata.h index 5f681fa76e..d11a45ce7d 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -371,6 +371,8 @@ struct FMapThing int16_t roll; uint32_t RenderStyle; int FloatbobPhase; + double SpotInnerAngle; + double SpotOuterAngle; }; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index d5c5e93ea6..78b41facc4 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -108,6 +108,7 @@ #include "a_morph.h" #include "events.h" #include "actorinlines.h" +#include "a_dynlight.h" // MACROS ------------------------------------------------------------------ @@ -6001,6 +6002,8 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) } } + + // spawn it double sz; @@ -6087,6 +6090,14 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) mobj->fillcolor = (mthing->fillcolor & 0xffffff) | (ColorMatcher.Pick((mthing->fillcolor & 0xff0000) >> 16, (mthing->fillcolor & 0xff00) >> 8, (mthing->fillcolor & 0xff)) << 24); + if (i->IsDescendantOf(RUNTIME_CLASS(ADynamicLight))) + { + if (mthing->SpotInnerAngle != 0) + ((ADynamicLight*)mobj)->SpotInnerAngle = mthing->SpotInnerAngle; + if (mthing->SpotOuterAngle != 0) + ((ADynamicLight*)mobj)->SpotOuterAngle = mthing->SpotOuterAngle; + } + mobj->CallBeginPlay (); if (!(mobj->ObjectFlags & OF_EuthanizeMe)) { diff --git a/wadsrc/static/mapinfo/common.txt b/wadsrc/static/mapinfo/common.txt index 5782f8808a..d183675c0c 100644 --- a/wadsrc/static/mapinfo/common.txt +++ b/wadsrc/static/mapinfo/common.txt @@ -109,6 +109,11 @@ DoomEdNums 9832 = PointLightFlickerAttenuated 9833 = SectorPointLightAttenuated 9834 = PointLightFlickerRandomAttenuated + 9840 = SpotLight + 9841 = SpotLightPulse + 9842 = SpotLightFlicker + 9843 = SectorSpotLight + 9844 = SpotLightFlickerRandom 9982 = SecActEyesAboveC 9983 = SecActEyesBelowC 9988 = CustomSprite diff --git a/wadsrc/static/zscript/shared/dynlights.txt b/wadsrc/static/zscript/shared/dynlights.txt index 8cdd3b2670..362389b8a7 100644 --- a/wadsrc/static/zscript/shared/dynlights.txt +++ b/wadsrc/static/zscript/shared/dynlights.txt @@ -205,6 +205,46 @@ class PointLightFlickerRandomAttenuated :PointLightFlickerRandom } } +class SpotLight : DynamicLight +{ + Default + { + DynamicLight.Type "Point"; + +DYNAMICLIGHT.SPOT + } +} + +class SpotLightPulse : SpotLight +{ + Default + { + DynamicLight.Type "Pulse"; + } +} + +class SpotLightFlicker : SpotLight +{ + Default + { + DynamicLight.Type "Flicker"; + } +} + +class SectorSpotLight : SpotLight +{ + Default + { + DynamicLight.Type "Sector"; + } +} + +class SpotLightFlickerRandom : SpotLight +{ + Default + { + DynamicLight.Type "RandomFlicker"; + } +} class VavoomLight : DynamicLight { From 254501d3e8ee3ec77ff24d68a1bc364f3da71aaa Mon Sep 17 00:00:00 2001 From: Jonathan Russell Date: Thu, 4 Jan 2018 23:09:48 +0000 Subject: [PATCH 06/29] - fixing last commit, which didn't seem to work correctly --- src/namedef.h | 2 + src/p_udmf.cpp | 8 ++ wadsrc/static/mapinfo/common.txt | 21 ++++ wadsrc/static/zscript/shared/dynlights.txt | 126 +++++++++++++++++++++ 4 files changed, 157 insertions(+) diff --git a/src/namedef.h b/src/namedef.h index 054c53e492..f94d008588 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -502,6 +502,8 @@ xx(Roll) xx(Scale) xx(ScaleX) xx(ScaleY) +xx(SpotInnerAngle) +xx(SpotOuterAngle) xx(Floatbobphase) xx(Floatbobstrength) xx(Target) diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 24257dbcd0..4df2d08eba 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -799,6 +799,14 @@ public: th->Scale.X = th->Scale.Y = CheckFloat(key); break; + case NAME_SpotInnerAngle: + th->SpotInnerAngle = CheckFloat(key); + break; + + case NAME_SpotOuterAngle: + th->SpotOuterAngle = CheckFloat(key); + break; + default: CHECK_N(Zd | Zdt) if (0 == strnicmp("user_", key.GetChars(), 5)) diff --git a/wadsrc/static/mapinfo/common.txt b/wadsrc/static/mapinfo/common.txt index d183675c0c..500e9b3c76 100644 --- a/wadsrc/static/mapinfo/common.txt +++ b/wadsrc/static/mapinfo/common.txt @@ -114,6 +114,27 @@ DoomEdNums 9842 = SpotLightFlicker 9843 = SectorSpotLight 9844 = SpotLightFlickerRandom +<<<<<<< Updated upstream +======= +<<<<<<< HEAD + 9850 = SpotLightAdditive + 9851 = SpotLightPulseAdditive + 9852 = SpotLightFlickerAdditive + 9853 = SectorSpotLightAdditive + 9854 = SpotLightFlickerRandomSubtractive + 9860 = SpotLightSubtractive + 9861 = SpotLightPulseSubtractive + 9862 = SpotLightFlickerSubtractive + 9863 = SectorSpotLightSubtractive + 9864 = SpotLightFlickerRandomSubtractive + 9870 = SpotLightAttenuated + 9871 = SpotLightPulseAttenuated + 9872 = SpotLightFlickerAttenuated + 9873 = SectorSpotLightAttenuated + 9874 = SpotLightFlickerRandomAttenuated +======= +>>>>>>> 7f7c720883e6841ced9c5e66cdae5e6b531872ad +>>>>>>> Stashed changes 9982 = SecActEyesAboveC 9983 = SecActEyesBelowC 9988 = CustomSprite diff --git a/wadsrc/static/zscript/shared/dynlights.txt b/wadsrc/static/zscript/shared/dynlights.txt index 362389b8a7..59584bb235 100644 --- a/wadsrc/static/zscript/shared/dynlights.txt +++ b/wadsrc/static/zscript/shared/dynlights.txt @@ -245,6 +245,132 @@ class SpotLightFlickerRandom : SpotLight DynamicLight.Type "RandomFlicker"; } } +<<<<<<< Updated upstream +======= +<<<<<<< HEAD + +class SpotLightAdditive : SpotLight +{ + Default + { + +DYNAMICLIGHT.ADDITIVE + } +} + +class SpotLightPulseAdditive : SpotLightPulse +{ + Default + { + +DYNAMICLIGHT.ADDITIVE + } +} + +class SpotLightFlickerAdditive : SpotLightFlicker +{ + Default + { + +DYNAMICLIGHT.ADDITIVE + } +} + +class SectorSpotLightAdditive : SectorSpotLight +{ + Default + { + +DYNAMICLIGHT.ADDITIVE + } +} + +class SpotLightFlickerRandomAdditive : SpotLightFlickerRandom +{ + Default + { + +DYNAMICLIGHT.ADDITIVE + } +} + +class SpotLightSubtractive : SpotLight +{ + Default + { + +DYNAMICLIGHT.SUBTRACTIVE + } +} + +class SpotLightPulseSubtractive : SpotLightPulse +{ + Default + { + +DYNAMICLIGHT.SUBTRACTIVE + } +} + +class SpotLightFlickerSubtractive : SpotLightFlicker +{ + Default + { + +DYNAMICLIGHT.SUBTRACTIVE + } +} + +class SectorSpotLightSubtractive : SectorSpotLight +{ + Default + { + +DYNAMICLIGHT.SUBTRACTIVE + } +} + +class SpotLightFlickerRandomSubtractive : SpotLightFlickerRandom +{ + Default + { + +DYNAMICLIGHT.SUBTRACTIVE + } +} + +class SpotLightAttenuated : SpotLight +{ + Default + { + +DYNAMICLIGHT.ATTENUATE + } +} + +class SpotLightPulseAttenuated : SpotLightPulse +{ + Default + { + +DYNAMICLIGHT.ATTENUATE + } +} + +class SpotLightFlickerAttenuated : SpotLightFlicker +{ + Default + { + +DYNAMICLIGHT.ATTENUATE + } +} + +class SectorSpotLightAttenuated : SectorSpotLight +{ + Default + { + +DYNAMICLIGHT.ATTENUATE + } +} + +class SpotLightFlickerRandomAttenuated : SpotLightFlickerRandom +{ + Default + { + +DYNAMICLIGHT.ATTENUATE + } +} +======= +>>>>>>> 7f7c720883e6841ced9c5e66cdae5e6b531872ad +>>>>>>> Stashed changes class VavoomLight : DynamicLight { From acf83c2a74445d697a46fa463f605f624fe7f3dc Mon Sep 17 00:00:00 2001 From: Jonathan Russell Date: Thu, 4 Jan 2018 23:13:14 +0000 Subject: [PATCH 07/29] - fixing the last commit... --- wadsrc/static/mapinfo/common.txt | 6 ------ wadsrc/static/zscript/shared/dynlights.txt | 6 ------ 2 files changed, 12 deletions(-) diff --git a/wadsrc/static/mapinfo/common.txt b/wadsrc/static/mapinfo/common.txt index 500e9b3c76..1c1559b061 100644 --- a/wadsrc/static/mapinfo/common.txt +++ b/wadsrc/static/mapinfo/common.txt @@ -114,9 +114,6 @@ DoomEdNums 9842 = SpotLightFlicker 9843 = SectorSpotLight 9844 = SpotLightFlickerRandom -<<<<<<< Updated upstream -======= -<<<<<<< HEAD 9850 = SpotLightAdditive 9851 = SpotLightPulseAdditive 9852 = SpotLightFlickerAdditive @@ -132,9 +129,6 @@ DoomEdNums 9872 = SpotLightFlickerAttenuated 9873 = SectorSpotLightAttenuated 9874 = SpotLightFlickerRandomAttenuated -======= ->>>>>>> 7f7c720883e6841ced9c5e66cdae5e6b531872ad ->>>>>>> Stashed changes 9982 = SecActEyesAboveC 9983 = SecActEyesBelowC 9988 = CustomSprite diff --git a/wadsrc/static/zscript/shared/dynlights.txt b/wadsrc/static/zscript/shared/dynlights.txt index 59584bb235..c2c005bd88 100644 --- a/wadsrc/static/zscript/shared/dynlights.txt +++ b/wadsrc/static/zscript/shared/dynlights.txt @@ -245,9 +245,6 @@ class SpotLightFlickerRandom : SpotLight DynamicLight.Type "RandomFlicker"; } } -<<<<<<< Updated upstream -======= -<<<<<<< HEAD class SpotLightAdditive : SpotLight { @@ -368,9 +365,6 @@ class SpotLightFlickerRandomAttenuated : SpotLightFlickerRandom +DYNAMICLIGHT.ATTENUATE } } -======= ->>>>>>> 7f7c720883e6841ced9c5e66cdae5e6b531872ad ->>>>>>> Stashed changes class VavoomLight : DynamicLight { From e754fe04efc8720d46f5fb266899219bb7f24c1f Mon Sep 17 00:00:00 2001 From: Jonathan Russell Date: Thu, 4 Jan 2018 23:22:45 +0000 Subject: [PATCH 08/29] - removed the 0 check on the UDMF property, so 0 can be a valid aperture --- src/p_mobj.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 78b41facc4..fc41dd3b07 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -6092,10 +6092,8 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) if (i->IsDescendantOf(RUNTIME_CLASS(ADynamicLight))) { - if (mthing->SpotInnerAngle != 0) - ((ADynamicLight*)mobj)->SpotInnerAngle = mthing->SpotInnerAngle; - if (mthing->SpotOuterAngle != 0) - ((ADynamicLight*)mobj)->SpotOuterAngle = mthing->SpotOuterAngle; + ((ADynamicLight*)mobj)->SpotInnerAngle = mthing->SpotInnerAngle; + ((ADynamicLight*)mobj)->SpotOuterAngle = mthing->SpotOuterAngle; } mobj->CallBeginPlay (); From 67e3106254e987f5acb9534e725d4f5c3eaa82b2 Mon Sep 17 00:00:00 2001 From: Jonathan Russell Date: Thu, 4 Jan 2018 23:31:10 +0000 Subject: [PATCH 09/29] - add the default spotlight apertures in FMapThing --- src/doomdata.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doomdata.h b/src/doomdata.h index d11a45ce7d..e01bab0306 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -371,8 +371,8 @@ struct FMapThing int16_t roll; uint32_t RenderStyle; int FloatbobPhase; - double SpotInnerAngle; - double SpotOuterAngle; + double SpotInnerAngle = 10; + double SpotOuterAngle = 25; }; From d5d393aaf2891814d3db209d0e3dda4d47b6d209 Mon Sep 17 00:00:00 2001 From: Major Cooke Date: Tue, 9 Jan 2018 09:12:17 -0600 Subject: [PATCH 10/29] - Added GetRadiusDamage. Returns the raw calculated explosion damage falloff by distance only. - Split off both explosion damage calculations into P_Get(Old)RadiusDamage functions for ease of maintenance. --- src/p_map.cpp | 254 +++++++++++++++++++++----------- wadsrc/static/zscript/actor.txt | 1 + 2 files changed, 173 insertions(+), 82 deletions(-) diff --git a/src/p_map.cpp b/src/p_map.cpp index 7cab335c09..304cfd8cf9 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -5695,6 +5695,168 @@ CUSTOM_CVAR(Float, splashfactor, 1.f, CVAR_SERVERINFO) selfthrustscale = 1.f / self; } +//========================================================================== +// +// P_GetRadiusDamage +// +// Part of P_RadiusAttack, separated so the GetRadiusAttack function can +// exist without needing to maintain more than one function. +// +// Used by anything without OLDRADIUSDMG flag +//========================================================================== + +static double P_GetRadiusDamage(bool fromaction, AActor *bombspot, AActor *thing, int bombdamage, int bombdistance, int fulldamagedistance, bool thingbombsource) +{ + // [RH] New code. The bounding box only covers the + // height of the thing and not the height of the map. + double points; + double len; + double dx, dy; + double boxradius; + + double bombdistancefloat = 1. / (double)(bombdistance - fulldamagedistance); + double bombdamagefloat = (double)bombdamage; + + DVector2 vec = bombspot->Vec2To(thing); + dx = fabs(vec.X); + dy = fabs(vec.Y); + boxradius = thing->radius; + + // The damage pattern is square, not circular. + len = double(dx > dy ? dx : dy); + + if (bombspot->Z() < thing->Z() || bombspot->Z() >= thing->Top()) + { + double dz; + + if (bombspot->Z() > thing->Z()) + { + dz = double(bombspot->Z() - thing->Top()); + } + else + { + dz = double(thing->Z() - bombspot->Z()); + } + if (len <= boxradius) + { + len = dz; + } + else + { + len -= boxradius; + len = g_sqrt(len*len + dz*dz); + } + } + else + { + len -= boxradius; + if (len < 0.f) + len = 0.f; + } + len = clamp(len - (double)fulldamagedistance, 0, len); + points = bombdamagefloat * (1. - len * bombdistancefloat); + + // Calculate the splash and radius damage factor if called by P_RadiusAttack. + // Otherwise, just get the raw damage. This allows modders to manipulate it + // however they want. + if (!fromaction) + { + if (thingbombsource) //thing is bomb source + { + points = points * splashfactor; + } + points *= thing->RadiusDamageFactor; + } + + return points; +} + +//========================================================================== +// +// P_GetOldRadiusDamage +// +// Part of P_RadiusAttack, separated so the GetRadiusAttack function can +// exist without needing to maintain more than one function. +// +// Used by barrels (OLDRADIUSDMG flag). Returns calculated damage +// based on XY distance. +//========================================================================== + +static int P_GetOldRadiusDamage(bool fromaction, AActor *bombspot, AActor *thing, int bombdamage, int bombdistance, int fulldamagedistance) +{ + const int ret = fromaction ? 0 : -1; // -1 is specifically for P_RadiusAttack; continue onto another actor. + double dx, dy, dist; + + DVector2 vec = bombspot->Vec2To(thing); + dx = fabs(vec.X); + dy = fabs(vec.Y); + + dist = dx>dy ? dx : dy; + dist -= thing->radius; + + if (dist < 0) + dist = 0; + + if (dist >= bombdistance) + return ret; // out of range + + // When called from the action function, ignore the sight check. + if (fromaction || P_CheckSight(thing, bombspot, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY)) + { + dist = clamp(dist - fulldamagedistance, 0, dist); + int damage = Scale(bombdamage, bombdistance - int(dist), bombdistance); + + if (!fromaction) + { + double factor = splashfactor * thing->RadiusDamageFactor; + damage = int(damage * factor); + } + + return damage; + } + + return ret; // Not in sight. +} + +//========================================================================== +// +// GetRadiusDamage +// +// Returns the falloff damage from an A_Explode attack without doing any +// damage and not taking into account any damage reduction. +//========================================================================== + +DEFINE_ACTION_FUNCTION(AActor, GetRadiusDamage) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_OBJECT(thing, AActor); + PARAM_INT(damage); + PARAM_INT(distance); + PARAM_INT_DEF(fulldmgdistance); + PARAM_BOOL_DEF(oldradiusdmg); + + if (!thing) + { + ACTION_RETURN_INT(0); + } + else if (thing == self) + { // No point in calculating falloff in this case since it is the bomb spot. + ACTION_RETURN_INT(damage); + } + + fulldmgdistance = clamp(fulldmgdistance, 0, distance - 1); + + // Mirroring A_Explode's behavior. + if (distance <= 0) + distance = damage; + + const int newdam = oldradiusdmg + ? P_GetOldRadiusDamage(true, self, thing, damage, distance, fulldmgdistance) + : int(P_GetRadiusDamage(true, self, thing, damage, distance, fulldmgdistance, false)); + + ACTION_RETURN_INT(newdam); +} + //========================================================================== // // P_RadiusAttack @@ -5709,9 +5871,6 @@ int P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bom return 0; fulldamagedistance = clamp(fulldamagedistance, 0, bombdistance - 1); - double bombdistancefloat = 1. / (double)(bombdistance - fulldamagedistance); - double bombdamagefloat = (double)bombdamage; - FPortalGroupArray grouplist(FPortalGroupArray::PGA_Full3d); FMultiBlockThingsIterator it(grouplist, bombspot->X(), bombspot->Y(), bombspot->Z() - bombdistance, bombspot->Height + bombdistance*2, bombdistance, false, bombspot->Sector); FMultiBlockThingsIterator::CheckResult cres; @@ -5757,57 +5916,7 @@ int P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bom // which can make them near impossible to hit with the new code. if ((flags & RADF_NODAMAGE) || !((bombspot->flags5 | thing->flags5) & MF5_OLDRADIUSDMG)) { - // [RH] New code. The bounding box only covers the - // height of the thing and not the height of the map. - double points; - double len; - double dx, dy; - double boxradius; - - DVector2 vec = bombspot->Vec2To(thing); - dx = fabs(vec.X); - dy = fabs(vec.Y); - boxradius = thing->radius; - - // The damage pattern is square, not circular. - len = double(dx > dy ? dx : dy); - - if (bombspot->Z() < thing->Z() || bombspot->Z() >= thing->Top()) - { - double dz; - - if (bombspot->Z() > thing->Z()) - { - dz = double(bombspot->Z() - thing->Top()); - } - else - { - dz = double(thing->Z() - bombspot->Z()); - } - if (len <= boxradius) - { - len = dz; - } - else - { - len -= boxradius; - len = g_sqrt(len*len + dz*dz); - } - } - else - { - len -= boxradius; - if (len < 0.f) - len = 0.f; - } - len = clamp(len - (double)fulldamagedistance, 0, len); - points = bombdamagefloat * (1. - len * bombdistancefloat); - if (thing == bombsource) - { - points = points * splashfactor; - } - points *= thing->RadiusDamageFactor; - + double points = P_GetRadiusDamage(false, bombspot, thing, bombdamage, bombdistance, fulldamagedistance, bombsource == thing); double check = int(points) * bombdamage; // points and bombdamage should be the same sign (the double cast of 'points' is needed to prevent overflows and incorrect values slipping through.) if ((check > 0 || (check == 0 && bombspot->flags7 & MF7_FORCEZERORADIUSDMG)) && P_CheckSight(thing, bombspot, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY)) @@ -5865,36 +5974,17 @@ int P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bom else { // [RH] Old code just for barrels - double dx, dy, dist; + int damage = P_GetOldRadiusDamage(false, bombspot, thing, bombdamage, bombdistance, fulldamagedistance); - DVector2 vec = bombspot->Vec2To(thing); - dx = fabs(vec.X); - dy = fabs(vec.Y); - - dist = dx>dy ? dx : dy; - dist -= thing->radius; - - if (dist < 0) - dist = 0; - - if (dist >= bombdistance) - continue; // out of range - - if (P_CheckSight(thing, bombspot, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY)) + if (damage < 0) + continue; // Sight check failed. + else if (damage > 0 || (bombspot->flags7 & MF7_FORCEZERORADIUSDMG)) { // OK to damage; target is in direct path - dist = clamp(dist - fulldamagedistance, 0, dist); - int damage = Scale(bombdamage, bombdistance - int(dist), bombdistance); - - double factor = splashfactor * thing->RadiusDamageFactor; - damage = int(damage * factor); - if (damage > 0 || (bombspot->flags7 & MF7_FORCEZERORADIUSDMG)) - { - //[MC] Don't count actors saved by buddha if already at 1 health. - int prehealth = thing->health; - int newdam = P_DamageMobj(thing, bombspot, bombsource, damage, bombmod); - P_TraceBleed(newdam > 0 ? newdam : damage, thing, bombspot); - if (thing->health < prehealth) count++; - } + //[MC] Don't count actors saved by buddha if already at 1 health. + int prehealth = thing->health; + int newdam = P_DamageMobj(thing, bombspot, bombsource, damage, bombmod); + P_TraceBleed(newdam > 0 ? newdam : damage, thing, bombspot); + if (thing->health < prehealth) count++; } } } diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 1cdbecc0e1..4d61435a66 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -1061,6 +1061,7 @@ class Actor : Thinker native native void A_RadiusThrust(int force = 128, int distance = -1, int flags = RTF_AFFECTSOURCE, int fullthrustdistance = 0); native void A_RadiusDamageSelf(int damage = 128, double distance = 128, int flags = 0, class flashtype = null); native int A_Explode(int damage = -1, int distance = -1, int flags = XF_HURTSOURCE, bool alert = false, int fulldamagedistance = 0, int nails = 0, int naildamage = 10, class pufftype = "BulletPuff", name damagetype = "none"); + native int GetRadiusDamage(Actor thing, int damage, int distance, int fulldmgdistance = 0, bool oldradiusdmg = false); native void A_Stop(); native void A_Respawn(int flags = 1); native void A_RestoreSpecialPosition(); From a01ca4c3a128699dec8511c3c8096f600e247c1a Mon Sep 17 00:00:00 2001 From: Marisa Kirisame Date: Sun, 7 Jan 2018 00:42:37 +0100 Subject: [PATCH 11/29] Exported S_IsActorPlayingSomething and S_GetMSLength to ZScript. Added missing vm.h include, moved A_IsPlayingSound to p_actionfunctions.cpp. - make A_IsPlayingSound ui only --- src/p_actionfunctions.cpp | 8 ++++++++ src/s_advsound.cpp | 7 +++++++ wadsrc/static/zscript/actor.txt | 1 + wadsrc/static/zscript/base.txt | 1 + 4 files changed, 17 insertions(+) diff --git a/src/p_actionfunctions.cpp b/src/p_actionfunctions.cpp index 1abe2c9390..c6a6b20f4d 100644 --- a/src/p_actionfunctions.cpp +++ b/src/p_actionfunctions.cpp @@ -988,6 +988,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_SoundVolume) return 0; } +DEFINE_ACTION_FUNCTION(AActor, A_IsPlayingSound) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_INT(channel); + PARAM_SOUND(sound); + ACTION_RETURN_BOOL(S_IsActorPlayingSomething(self,channel,sound)); +} + //========================================================================== // // These come from a time when DECORATE constants did not exist yet and diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index 5aa52981d0..85db21c4b1 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -53,6 +53,7 @@ #include "serializer.h" #include "v_text.h" #include "g_levellocals.h" +#include "vm.h" // MACROS ------------------------------------------------------------------ @@ -491,6 +492,12 @@ unsigned int S_GetMSLength(FSoundID sound) else return 0; } +DEFINE_ACTION_FUNCTION(DObject,S_GetLength) +{ + PARAM_PROLOGUE; + PARAM_SOUND(sound_id); + ACTION_RETURN_FLOAT(S_GetMSLength(sound_id)/1000.0); +} //========================================================================== // diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 4d61435a66..1dde579379 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -1010,6 +1010,7 @@ class Actor : Thinker native native void A_StopSound(int slot = CHAN_VOICE); // Bad default but that's what is originally was... deprecated("2.3") native void A_PlaySoundEx(sound whattoplay, name slot, bool looping = false, int attenuation = 0); deprecated("2.3") native void A_StopSoundEx(name slot); + native ui bool A_IsPlayingSound(int channel = 0, sound sound_id = ""); native void A_SeekerMissile(int threshold, int turnmax, int flags = 0, int chance = 50, int distance = 10); native action state A_Jump(int chance, statelabel label, ...); native Actor A_SpawnProjectile(class missiletype, double spawnheight = 32, double spawnofs_xy = 0, double angle = 0, int flags = 0, double pitch = 0, int ptr = AAPTR_TARGET); diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index fe776fcbc1..804bc7c499 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -354,6 +354,7 @@ class Object native native static void S_PauseSound (bool notmusic, bool notsfx); native static void S_ResumeSound (bool notsfx); native static bool S_ChangeMusic(String music_name, int order = 0, bool looping = true, bool force = false); + native static float S_GetLength(Sound sound_id); native static uint BAM(double angle); native static void SetMusicVolume(float vol); native static uint MSTime(); From 6df936e0a0195e425998bb9605777eb9a052eb41 Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Sat, 20 Jan 2018 12:52:44 -0500 Subject: [PATCH 12/29] - remove A_IsPlayingSound --- src/p_actionfunctions.cpp | 7 ------- wadsrc/static/zscript/actor.txt | 1 - 2 files changed, 8 deletions(-) diff --git a/src/p_actionfunctions.cpp b/src/p_actionfunctions.cpp index c6a6b20f4d..1a3333bdd5 100644 --- a/src/p_actionfunctions.cpp +++ b/src/p_actionfunctions.cpp @@ -988,13 +988,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_SoundVolume) return 0; } -DEFINE_ACTION_FUNCTION(AActor, A_IsPlayingSound) -{ - PARAM_SELF_PROLOGUE(AActor); - PARAM_INT(channel); - PARAM_SOUND(sound); - ACTION_RETURN_BOOL(S_IsActorPlayingSomething(self,channel,sound)); -} //========================================================================== // diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 1dde579379..4d61435a66 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -1010,7 +1010,6 @@ class Actor : Thinker native native void A_StopSound(int slot = CHAN_VOICE); // Bad default but that's what is originally was... deprecated("2.3") native void A_PlaySoundEx(sound whattoplay, name slot, bool looping = false, int attenuation = 0); deprecated("2.3") native void A_StopSoundEx(name slot); - native ui bool A_IsPlayingSound(int channel = 0, sound sound_id = ""); native void A_SeekerMissile(int threshold, int turnmax, int flags = 0, int chance = 50, int distance = 10); native action state A_Jump(int chance, statelabel label, ...); native Actor A_SpawnProjectile(class missiletype, double spawnheight = 32, double spawnofs_xy = 0, double angle = 0, int flags = 0, double pitch = 0, int ptr = AAPTR_TARGET); From 708d24aba748f5e1e138b739c631161982c09a4d Mon Sep 17 00:00:00 2001 From: Jonathan Russell Date: Sat, 20 Jan 2018 20:02:36 +0000 Subject: [PATCH 13/29] - added Screen.getViewWindow function --- src/v_draw.cpp | 9 +++++++++ wadsrc/static/zscript/base.txt | 1 + 2 files changed, 10 insertions(+) diff --git a/src/v_draw.cpp b/src/v_draw.cpp index fc592949c2..32f908d034 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -230,6 +230,15 @@ DEFINE_ACTION_FUNCTION(_Screen, GetClipRect) return MIN(numret, 4); } +DEFINE_ACTION_FUNCTION(_Screen, GetViewWindow) +{ + PARAM_PROLOGUE; + if (numret > 0) ret[0].SetInt(viewwindowx); + if (numret > 1) ret[1].SetInt(viewwindowy); + if (numret > 2) ret[2].SetInt(viewwidth); + if (numret > 3) ret[3].SetInt(viewheight); + return MIN(numret, 4); +} bool DCanvas::SetTextureParms(DrawParms *parms, FTexture *img, double xx, double yy) const { diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 804bc7c499..bf5edf6caa 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -175,6 +175,7 @@ struct Screen native native static void SetClipRect(int x, int y, int w, int h); native static void ClearClipRect(); native static int, int, int, int GetClipRect(); + native static int, int, int, int GetViewWindow(); // This is a leftover of the abandoned Inventory.DrawPowerup method. From 6aaf5df6175650e224b59f6f35c27d0730a7721e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 20 Jan 2018 22:41:28 +0100 Subject: [PATCH 14/29] - reworked spot lights to receive all relevant information through the args. As a bonus, arg0str can now be used for all dynamic lights to pass a color in textual form, including X11R6RGB-names. --- src/doomdata.h | 3 +-- src/namedef.h | 2 -- src/p_mobj.cpp | 20 ++++++++++++++++++-- src/p_udmf.cpp | 9 +-------- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/doomdata.h b/src/doomdata.h index 4e3acdce61..cfebe196d6 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -372,8 +372,7 @@ struct FMapThing uint32_t RenderStyle; int FloatbobPhase; int friendlyseeblocks; - double SpotInnerAngle = 10; - double SpotOuterAngle = 25; + FString arg0str; }; diff --git a/src/namedef.h b/src/namedef.h index fa345397f6..ace456a691 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -503,8 +503,6 @@ xx(Scale) xx(ScaleX) xx(ScaleY) xx(FriendlySeeBlocks) -xx(SpotInnerAngle) -xx(SpotOuterAngle) xx(Floatbobphase) xx(Floatbobstrength) xx(Target) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 09fdc3eac9..0f77f534d7 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -6094,10 +6094,26 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) mobj->fillcolor = (mthing->fillcolor & 0xffffff) | (ColorMatcher.Pick((mthing->fillcolor & 0xff0000) >> 16, (mthing->fillcolor & 0xff00) >> 8, (mthing->fillcolor & 0xff)) << 24); + // allow color strings for lights and reshuffle the args for spot lights if (i->IsDescendantOf(RUNTIME_CLASS(ADynamicLight))) { - ((ADynamicLight*)mobj)->SpotInnerAngle = mthing->SpotInnerAngle; - ((ADynamicLight*)mobj)->SpotOuterAngle = mthing->SpotOuterAngle; + auto light = static_cast(mobj); + if (mthing->arg0str.IsNotEmpty()) + { + PalEntry color = V_GetColor(nullptr, mthing->arg0str); + } + else if (light->lightflags & LF_SPOT) + { + light->args[0] = RPART(mthing->args[0]); + light->args[1] = GPART(mthing->args[0]); + light->args[2] = BPART(mthing->args[0]); + } + + if (light->lightflags & LF_SPOT) + { + light->SpotInnerAngle = double(mthing->args[1]); + light->SpotOuterAngle = double(mthing->args[2]); + } } mobj->CallBeginPlay (); diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 5b3d0e3542..53d2ece9bd 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -604,6 +604,7 @@ public: case NAME_Arg0Str: CHECK_N(Zd); arg0str = CheckString(key); + th->arg0str = arg0str; break; case NAME_Arg1Str: @@ -799,14 +800,6 @@ public: th->Scale.X = th->Scale.Y = CheckFloat(key); break; - case NAME_SpotInnerAngle: - th->SpotInnerAngle = CheckFloat(key); - break; - - case NAME_SpotOuterAngle: - th->SpotOuterAngle = CheckFloat(key); - break; - case NAME_FriendlySeeBlocks: CHECK_N(Zd | Zdt) th->friendlyseeblocks = CheckInt(key); From 8b3cc6a617acd3f2694d67ff67fc44358e7631bd Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Sun, 21 Jan 2018 01:02:00 -0500 Subject: [PATCH 15/29] - remove redundant vm.h include in events.cpp --- src/events.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/events.cpp b/src/events.cpp index cca0a93984..ec8b07af95 100755 --- a/src/events.cpp +++ b/src/events.cpp @@ -39,7 +39,6 @@ #include "actor.h" #include "c_dispatch.h" #include "d_net.h" -#include "vm.h" DStaticEventHandler* E_FirstEventHandler = nullptr; DStaticEventHandler* E_LastEventHandler = nullptr; From 56e2db38fd8e7ec09809ad6ef682f428d71ff6fe Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 21 Jan 2018 09:10:04 +0100 Subject: [PATCH 16/29] - Use FName instead of FString to store arg0str in FMapThing. This is because FMapThing gets memset to 0 and changing that would cause more work than it is worth to keep the string. The only thing it is used for is the color for dynamic lights and those do not need case sensitivity so a name will just do as well, but require less adjustments elsewhere. --- src/doomdata.h | 2 +- src/p_mobj.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doomdata.h b/src/doomdata.h index cfebe196d6..58bfea68af 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -372,7 +372,7 @@ struct FMapThing uint32_t RenderStyle; int FloatbobPhase; int friendlyseeblocks; - FString arg0str; + FNameNoInit arg0str; }; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 0f77f534d7..79f549dd38 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -6098,7 +6098,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) if (i->IsDescendantOf(RUNTIME_CLASS(ADynamicLight))) { auto light = static_cast(mobj); - if (mthing->arg0str.IsNotEmpty()) + if (mthing->arg0str != NAME_None) { PalEntry color = V_GetColor(nullptr, mthing->arg0str); } From ded0c7805dab170b14932273a0b8c399f2b43d7e Mon Sep 17 00:00:00 2001 From: Neil McPhail Date: Sun, 10 Dec 2017 16:27:36 +0000 Subject: [PATCH 17/29] Fix failure to write under ~/ in confinement When running in a confined environment (such as a snap) it may not be possible to write to directories such as ~/.config. By using the $HOME variable instead of the '~' shortcut, the confined environment can pass an alternative 'home' directory with write privelges. I have only changed this for posix/unix and haven't touched code for MacOS, as I don't know if that behaves differently --- src/d_main.cpp | 2 +- src/gameconfigfile.cpp | 4 ++-- src/posix/unix/i_specialpaths.cpp | 26 +++++++++++++------------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 92e10903f6..d3838e5d86 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2138,7 +2138,7 @@ static void AddAutoloadFiles(const char *autoname) D_AddDirectory (allwads, file); #ifdef __unix__ - file = NicePath("~/" GAME_DIR "/skins"); + file = NicePath("$HOME/" GAME_DIR "/skins"); D_AddDirectory (allwads, file); #endif diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index f6fc12dfa9..5053fd033d 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -125,7 +125,7 @@ FGameConfigFile::FGameConfigFile () SetValueForKey ("Path", "$HOME", true); SetValueForKey ("Path", "$PROGDIR", true); #else - SetValueForKey ("Path", "~/" GAME_DIR, true); + SetValueForKey ("Path", "$HOME/" GAME_DIR, true); // Arch Linux likes them in /usr/share/doom // Debian likes them in /usr/share/games/doom // I assume other distributions don't do anything radically different @@ -148,7 +148,7 @@ FGameConfigFile::FGameConfigFile () #elif !defined(__unix__) SetValueForKey ("Path", "$PROGDIR", true); #else - SetValueForKey ("Path", "~/" GAME_DIR, true); + SetValueForKey ("Path", "$HOME/" GAME_DIR, true); SetValueForKey ("Path", "/usr/local/share/doom", true); SetValueForKey ("Path", "/usr/local/share/games/doom", true); SetValueForKey ("Path", "/usr/share/doom", true); diff --git a/src/posix/unix/i_specialpaths.cpp b/src/posix/unix/i_specialpaths.cpp index 01320548df..60cc12fcf8 100644 --- a/src/posix/unix/i_specialpaths.cpp +++ b/src/posix/unix/i_specialpaths.cpp @@ -46,30 +46,30 @@ FString GetUserFile (const char *file) FString path; struct stat info; - path = NicePath("~/" GAME_DIR "/"); + path = NicePath("$HOME/" GAME_DIR "/"); if (stat (path, &info) == -1) { struct stat extrainfo; - // Sanity check for ~/.config - FString configPath = NicePath("~/.config/"); + // Sanity check for $HOME/.config + FString configPath = NicePath("$HOME/.config/"); if (stat (configPath, &extrainfo) == -1) { if (mkdir (configPath, S_IRUSR | S_IWUSR | S_IXUSR) == -1) { - I_FatalError ("Failed to create ~/.config directory:\n%s", strerror(errno)); + I_FatalError ("Failed to create $HOME/.config directory:\n%s", strerror(errno)); } } else if (!S_ISDIR(extrainfo.st_mode)) { - I_FatalError ("~/.config must be a directory"); + I_FatalError ("$HOME/.config must be a directory"); } // This can be removed after a release or two // Transfer the old zdoom directory to the new location bool moved = false; - FString oldpath = NicePath("~/." GAMENAMELOWERCASE "/"); + FString oldpath = NicePath("$HOME/." GAMENAMELOWERCASE "/"); if (stat (oldpath, &extrainfo) != -1) { if (rename(oldpath, path) == -1) @@ -110,7 +110,7 @@ FString M_GetAppDataPath(bool create) { // Don't use GAME_DIR and such so that ZDoom and its child ports can // share the node cache. - FString path = NicePath("~/.config/" GAMENAMELOWERCASE); + FString path = NicePath("$HOME/.config/" GAMENAMELOWERCASE); if (create) { CreatePath(path); @@ -130,7 +130,7 @@ FString M_GetCachePath(bool create) { // Don't use GAME_DIR and such so that ZDoom and its child ports can // share the node cache. - FString path = NicePath("~/.config/zdoom/cache"); + FString path = NicePath("$HOME/.config/zdoom/cache"); if (create) { CreatePath(path); @@ -163,7 +163,7 @@ FString M_GetCajunPath(const char *botfilename) { FString path; - // Check first in ~/.config/zdoom/botfilename. + // Check first in $HOME/.config/zdoom/botfilename. path = GetUserFile(botfilename); if (!FileExists(path)) { @@ -203,7 +203,7 @@ FString M_GetConfigPath(bool for_reading) FString M_GetScreenshotsPath() { - return NicePath("~/" GAME_DIR "/screenshots/"); + return NicePath("$HOME/" GAME_DIR "/screenshots/"); } //=========================================================================== @@ -216,7 +216,7 @@ FString M_GetScreenshotsPath() FString M_GetSavegamesPath() { - return NicePath("~/" GAME_DIR); + return NicePath("$HOME/" GAME_DIR); } //=========================================================================== @@ -229,5 +229,5 @@ FString M_GetSavegamesPath() FString M_GetDocumentsPath() { - return NicePath("~/" GAME_DIR); -} \ No newline at end of file + return NicePath("$HOME/" GAME_DIR); +} From 3f45f938d6bec9539c42f0b2eb7c0f2c918d4cda Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Mon, 8 Jan 2018 13:00:01 +0100 Subject: [PATCH 18/29] Update LZMA SDK to version 17.01 --- lzma/C/7z.h | 12 +- lzma/C/7zArcIn.c | 129 +++++++-------- lzma/C/7zBuf.c | 12 +- lzma/C/7zBuf.h | 10 +- lzma/C/7zCrc.c | 16 +- lzma/C/7zCrcOpt.c | 50 +++--- lzma/C/7zDec.c | 54 +++---- lzma/C/7zStream.c | 111 ++++++------- lzma/C/7zTypes.h | 230 ++++++++++++++++++++------- lzma/C/7zVersion.h | 22 ++- lzma/C/Bcj2.c | 5 +- lzma/C/Bra.c | 289 ++++++++++++++++++++++------------ lzma/C/Bra86.c | 4 +- lzma/C/BraIA64.c | 82 ++++------ lzma/C/Compiler.h | 3 +- lzma/C/CpuArch.c | 13 +- lzma/C/CpuArch.h | 175 ++++++++++++++++---- lzma/C/LzFind.c | 163 +++++++++++-------- lzma/C/LzFind.h | 12 +- lzma/C/LzFindMt.c | 67 +++++--- lzma/C/LzFindMt.h | 6 +- lzma/C/Lzma2Dec.c | 158 +++++++++---------- lzma/C/Lzma2Dec.h | 8 +- lzma/C/LzmaDec.c | 34 ++-- lzma/C/LzmaDec.h | 12 +- lzma/C/LzmaEnc.c | 194 +++++++++++++---------- lzma/C/LzmaEnc.h | 48 +++--- lzma/C/Ppmd.h | 6 +- lzma/C/Ppmd7.c | 38 ++--- lzma/C/Ppmd7.h | 28 ++-- lzma/C/Ppmd7Dec.c | 34 ++-- lzma/C/Threads.c | 14 +- lzma/C/Threads.h | 5 +- src/files.cpp | 4 +- src/resourcefiles/file_7z.cpp | 17 +- 35 files changed, 1239 insertions(+), 826 deletions(-) diff --git a/lzma/C/7z.h b/lzma/C/7z.h index 4768151948..6c7886e38b 100644 --- a/lzma/C/7z.h +++ b/lzma/C/7z.h @@ -1,5 +1,5 @@ /* 7z.h -- 7z interface -2015-11-18 : Igor Pavlov : Public domain */ +2017-04-03 : Igor Pavlov : Public domain */ #ifndef __7Z_H #define __7Z_H @@ -98,7 +98,7 @@ UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex); SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex, ILookInStream *stream, UInt64 startPos, Byte *outBuffer, size_t outSize, - ISzAlloc *allocMain); + ISzAllocPtr allocMain); typedef struct { @@ -131,7 +131,7 @@ typedef struct #define SzArEx_GetFileSize(p, i) ((p)->UnpackPositions[(i) + 1] - (p)->UnpackPositions[i]) void SzArEx_Init(CSzArEx *p); -void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc); +void SzArEx_Free(CSzArEx *p, ISzAllocPtr alloc); UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder); int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize); @@ -179,8 +179,8 @@ SRes SzArEx_Extract( size_t *outBufferSize, /* buffer size for output buffer */ size_t *offset, /* offset of stream for required file in *outBuffer */ size_t *outSizeProcessed, /* size of file in *outBuffer */ - ISzAlloc *allocMain, - ISzAlloc *allocTemp); + ISzAllocPtr allocMain, + ISzAllocPtr allocTemp); /* @@ -195,7 +195,7 @@ SZ_ERROR_FAIL */ SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, - ISzAlloc *allocMain, ISzAlloc *allocTemp); + ISzAllocPtr allocMain, ISzAllocPtr allocTemp); EXTERN_C_END diff --git a/lzma/C/7zArcIn.c b/lzma/C/7zArcIn.c index 06e35de0d4..e1b03d8792 100644 --- a/lzma/C/7zArcIn.c +++ b/lzma/C/7zArcIn.c @@ -1,5 +1,5 @@ /* 7zArcIn.c -- 7z Input functions -2015-11-18 : Igor Pavlov : Public domain */ +2017-04-03 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -11,7 +11,7 @@ #include "CpuArch.h" #define MY_ALLOC(T, p, size, alloc) { \ - if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == NULL) return SZ_ERROR_MEM; } + if ((p = (T *)ISzAlloc_Alloc(alloc, (size) * sizeof(T))) == NULL) return SZ_ERROR_MEM; } #define MY_ALLOC_ZE(T, p, size, alloc) { if ((size) == 0) p = NULL; else MY_ALLOC(T, p, size, alloc) } @@ -60,7 +60,7 @@ const Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; #define SzBitUi32s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; } -static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAlloc *alloc) +static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAllocPtr alloc) { if (num == 0) { @@ -75,18 +75,18 @@ static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAlloc *alloc) return SZ_OK; } -void SzBitUi32s_Free(CSzBitUi32s *p, ISzAlloc *alloc) +void SzBitUi32s_Free(CSzBitUi32s *p, ISzAllocPtr alloc) { - IAlloc_Free(alloc, p->Defs); p->Defs = NULL; - IAlloc_Free(alloc, p->Vals); p->Vals = NULL; + ISzAlloc_Free(alloc, p->Defs); p->Defs = NULL; + ISzAlloc_Free(alloc, p->Vals); p->Vals = NULL; } #define SzBitUi64s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; } -void SzBitUi64s_Free(CSzBitUi64s *p, ISzAlloc *alloc) +void SzBitUi64s_Free(CSzBitUi64s *p, ISzAllocPtr alloc) { - IAlloc_Free(alloc, p->Defs); p->Defs = NULL; - IAlloc_Free(alloc, p->Vals); p->Vals = NULL; + ISzAlloc_Free(alloc, p->Defs); p->Defs = NULL; + ISzAlloc_Free(alloc, p->Vals); p->Vals = NULL; } @@ -107,18 +107,18 @@ static void SzAr_Init(CSzAr *p) p->CodersData = NULL; } -static void SzAr_Free(CSzAr *p, ISzAlloc *alloc) +static void SzAr_Free(CSzAr *p, ISzAllocPtr alloc) { - IAlloc_Free(alloc, p->PackPositions); + ISzAlloc_Free(alloc, p->PackPositions); SzBitUi32s_Free(&p->FolderCRCs, alloc); - IAlloc_Free(alloc, p->FoCodersOffsets); - IAlloc_Free(alloc, p->FoStartPackStreamIndex); - IAlloc_Free(alloc, p->FoToCoderUnpackSizes); - IAlloc_Free(alloc, p->FoToMainUnpackSizeIndex); - IAlloc_Free(alloc, p->CoderUnpackSizes); + ISzAlloc_Free(alloc, p->FoCodersOffsets); + ISzAlloc_Free(alloc, p->FoStartPackStreamIndex); + ISzAlloc_Free(alloc, p->FoToCoderUnpackSizes); + ISzAlloc_Free(alloc, p->FoToMainUnpackSizeIndex); + ISzAlloc_Free(alloc, p->CoderUnpackSizes); - IAlloc_Free(alloc, p->CodersData); + ISzAlloc_Free(alloc, p->CodersData); SzAr_Init(p); } @@ -147,16 +147,16 @@ void SzArEx_Init(CSzArEx *p) SzBitUi64s_Init(&p->CTime); } -void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc) +void SzArEx_Free(CSzArEx *p, ISzAllocPtr alloc) { - IAlloc_Free(alloc, p->UnpackPositions); - IAlloc_Free(alloc, p->IsDirs); + ISzAlloc_Free(alloc, p->UnpackPositions); + ISzAlloc_Free(alloc, p->IsDirs); - IAlloc_Free(alloc, p->FolderToFile); - IAlloc_Free(alloc, p->FileToFolder); + ISzAlloc_Free(alloc, p->FolderToFile); + ISzAlloc_Free(alloc, p->FileToFolder); - IAlloc_Free(alloc, p->FileNameOffsets); - IAlloc_Free(alloc, p->FileNames); + ISzAlloc_Free(alloc, p->FileNameOffsets); + ISzAlloc_Free(alloc, p->FileNames); SzBitUi32s_Free(&p->CRCs, alloc); SzBitUi32s_Free(&p->Attribs, alloc); @@ -305,7 +305,7 @@ static UInt32 CountDefinedBits(const Byte *bits, UInt32 numItems) return sum; } -static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAlloc *alloc) +static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAllocPtr alloc) { Byte allAreDefined; Byte *v2; @@ -328,12 +328,12 @@ static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, I { unsigned numBits = (unsigned)numItems & 7; if (numBits != 0) - v2[numBytes - 1] = (Byte)((((UInt32)1 << numBits) - 1) << (8 - numBits)); + v2[(size_t)numBytes - 1] = (Byte)((((UInt32)1 << numBits) - 1) << (8 - numBits)); } return SZ_OK; } -static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *crcs, ISzAlloc *alloc) +static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc) { UInt32 i; CSzData sd; @@ -354,7 +354,7 @@ static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *c return SZ_OK; } -static SRes ReadBitUi32s(CSzData *sd, UInt32 numItems, CSzBitUi32s *crcs, ISzAlloc *alloc) +static SRes ReadBitUi32s(CSzData *sd, UInt32 numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc) { SzBitUi32s_Free(crcs, alloc); RINOK(ReadBitVector(sd, numItems, &crcs->Defs, alloc)); @@ -380,7 +380,7 @@ static SRes SkipBitUi32s(CSzData *sd, UInt32 numItems) return SZ_OK; } -static SRes ReadPackInfo(CSzAr *p, CSzData *sd, ISzAlloc *alloc) +static SRes ReadPackInfo(CSzAr *p, CSzData *sd, ISzAllocPtr alloc) { RINOK(SzReadNumber32(sd, &p->NumPackStreams)); @@ -635,7 +635,7 @@ static SRes ReadUnpackInfo(CSzAr *p, CSzData *sd2, UInt32 numFoldersMax, const CBuf *tempBufs, UInt32 numTempBufs, - ISzAlloc *alloc) + ISzAllocPtr alloc) { CSzData sd; @@ -788,13 +788,9 @@ static SRes ReadUnpackInfo(CSzAr *p, numCodersOutStreams += numCoders; if (numCodersOutStreams < numCoders) return SZ_ERROR_UNSUPPORTED; - - packStreamIndex += numPackStreams; - if (packStreamIndex < numPackStreams) - return SZ_ERROR_UNSUPPORTED; - - if (packStreamIndex > p->NumPackStreams) + if (numPackStreams > p->NumPackStreams - packStreamIndex) return SZ_ERROR_ARCHIVE; + packStreamIndex += numPackStreams; } } @@ -938,7 +934,7 @@ static SRes SzReadStreamsInfo(CSzAr *p, UInt32 numFoldersMax, const CBuf *tempBufs, UInt32 numTempBufs, UInt64 *dataOffset, CSubStreamInfo *ssi, - ISzAlloc *alloc) + ISzAllocPtr alloc) { UInt64 type; @@ -980,7 +976,7 @@ static SRes SzReadAndDecodePackedStreams( UInt32 numFoldersMax, UInt64 baseOffset, CSzAr *p, - ISzAlloc *allocTemp) + ISzAllocPtr allocTemp) { UInt64 dataStartPos; UInt32 fo; @@ -1047,7 +1043,7 @@ static SRes SzReadFileNames(const Byte *data, size_t size, UInt32 numFiles, size static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num, CSzData *sd2, const CBuf *tempBufs, UInt32 numTempBufs, - ISzAlloc *alloc) + ISzAllocPtr alloc) { CSzData sd; UInt32 i; @@ -1100,17 +1096,15 @@ static SRes SzReadHeader2( CSzData *sd, ILookInStream *inStream, CBuf *tempBufs, UInt32 *numTempBufs, - ISzAlloc *allocMain, - ISzAlloc *allocTemp + ISzAllocPtr allocMain, + ISzAllocPtr allocTemp ) { - UInt64 type; - UInt32 numFiles = 0; - UInt32 numEmptyStreams = 0; CSubStreamInfo ssi; - const Byte *emptyStreams = NULL; - const Byte *emptyFiles = NULL; +{ + UInt64 type; + SzData_Clear(&ssi.sdSizes); SzData_Clear(&ssi.sdCRCs); SzData_Clear(&ssi.sdNumSubStreams); @@ -1124,9 +1118,9 @@ static SRes SzReadHeader2( { for (;;) { - UInt64 type; - RINOK(ReadID(sd, &type)); - if (type == k7zIdEnd) + UInt64 type2; + RINOK(ReadID(sd, &type2)); + if (type2 == k7zIdEnd) break; RINOK(SkipData(sd)); } @@ -1164,6 +1158,13 @@ static SRes SzReadHeader2( if (type != k7zIdFilesInfo) return SZ_ERROR_ARCHIVE; +} + +{ + UInt32 numFiles = 0; + UInt32 numEmptyStreams = 0; + const Byte *emptyStreams = NULL; + const Byte *emptyFiles = NULL; RINOK(SzReadNumber32(sd, &numFiles)); p->NumFiles = numFiles; @@ -1462,7 +1463,7 @@ static SRes SzReadHeader2( if (ssi.sdNumSubStreams.Data && ssi.sdNumSubStreams.Size != 0) return SZ_ERROR_ARCHIVE; } - +} return SZ_OK; } @@ -1471,8 +1472,8 @@ static SRes SzReadHeader( CSzArEx *p, CSzData *sd, ILookInStream *inStream, - ISzAlloc *allocMain, - ISzAlloc *allocTemp) + ISzAllocPtr allocMain, + ISzAllocPtr allocTemp) { UInt32 i; UInt32 numTempBufs = 0; @@ -1500,8 +1501,8 @@ static SRes SzReadHeader( static SRes SzArEx_Open2( CSzArEx *p, ILookInStream *inStream, - ISzAlloc *allocMain, - ISzAlloc *allocTemp) + ISzAllocPtr allocMain, + ISzAllocPtr allocTemp) { Byte header[k7zStartHeaderSize]; Int64 startArcPos; @@ -1512,7 +1513,7 @@ static SRes SzArEx_Open2( SRes res; startArcPos = 0; - RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR)); + RINOK(ILookInStream_Seek(inStream, &startArcPos, SZ_SEEK_CUR)); RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE)); @@ -1541,7 +1542,7 @@ static SRes SzArEx_Open2( { Int64 pos = 0; - RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END)); + RINOK(ILookInStream_Seek(inStream, &pos, SZ_SEEK_END)); if ((UInt64)pos < startArcPos + nextHeaderOffset || (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset || (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize) @@ -1622,7 +1623,7 @@ static SRes SzArEx_Open2( SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, - ISzAlloc *allocMain, ISzAlloc *allocTemp) + ISzAllocPtr allocMain, ISzAllocPtr allocTemp) { SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp); if (res != SZ_OK) @@ -1640,8 +1641,8 @@ SRes SzArEx_Extract( size_t *outBufferSize, size_t *offset, size_t *outSizeProcessed, - ISzAlloc *allocMain, - ISzAlloc *allocTemp) + ISzAllocPtr allocMain, + ISzAllocPtr allocTemp) { UInt32 folderIndex = p->FileToFolder[fileIndex]; SRes res = SZ_OK; @@ -1651,7 +1652,7 @@ SRes SzArEx_Extract( if (folderIndex == (UInt32)-1) { - IAlloc_Free(allocMain, *tempBuf); + ISzAlloc_Free(allocMain, *tempBuf); *blockIndex = folderIndex; *tempBuf = NULL; *outBufferSize = 0; @@ -1663,7 +1664,7 @@ SRes SzArEx_Extract( UInt64 unpackSizeSpec = SzAr_GetFolderUnpackSize(&p->db, folderIndex); /* UInt64 unpackSizeSpec = - p->UnpackPositions[p->FolderToFile[folderIndex + 1]] - + p->UnpackPositions[p->FolderToFile[(size_t)folderIndex + 1]] - p->UnpackPositions[p->FolderToFile[folderIndex]]; */ size_t unpackSize = (size_t)unpackSizeSpec; @@ -1671,7 +1672,7 @@ SRes SzArEx_Extract( if (unpackSize != unpackSizeSpec) return SZ_ERROR_MEM; *blockIndex = folderIndex; - IAlloc_Free(allocMain, *tempBuf); + ISzAlloc_Free(allocMain, *tempBuf); *tempBuf = NULL; if (res == SZ_OK) @@ -1679,7 +1680,7 @@ SRes SzArEx_Extract( *outBufferSize = unpackSize; if (unpackSize != 0) { - *tempBuf = (Byte *)IAlloc_Alloc(allocMain, unpackSize); + *tempBuf = (Byte *)ISzAlloc_Alloc(allocMain, unpackSize); if (*tempBuf == NULL) res = SZ_ERROR_MEM; } @@ -1696,7 +1697,7 @@ SRes SzArEx_Extract( { UInt64 unpackPos = p->UnpackPositions[fileIndex]; *offset = (size_t)(unpackPos - p->UnpackPositions[p->FolderToFile[folderIndex]]); - *outSizeProcessed = (size_t)(p->UnpackPositions[fileIndex + 1] - unpackPos); + *outSizeProcessed = (size_t)(p->UnpackPositions[(size_t)fileIndex + 1] - unpackPos); if (*offset + *outSizeProcessed > *outBufferSize) return SZ_ERROR_FAIL; if (SzBitWithVals_Check(&p->CRCs, fileIndex)) diff --git a/lzma/C/7zBuf.c b/lzma/C/7zBuf.c index 089a5c4f21..8865c32a81 100644 --- a/lzma/C/7zBuf.c +++ b/lzma/C/7zBuf.c @@ -1,5 +1,5 @@ /* 7zBuf.c -- Byte Buffer -2013-01-21 : Igor Pavlov : Public domain */ +2017-04-03 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -11,7 +11,7 @@ void Buf_Init(CBuf *p) p->size = 0; } -int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc) +int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc) { p->size = 0; if (size == 0) @@ -19,8 +19,8 @@ int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc) p->data = 0; return 1; } - p->data = (Byte *)alloc->Alloc(alloc, size); - if (p->data != 0) + p->data = (Byte *)ISzAlloc_Alloc(alloc, size); + if (p->data) { p->size = size; return 1; @@ -28,9 +28,9 @@ int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc) return 0; } -void Buf_Free(CBuf *p, ISzAlloc *alloc) +void Buf_Free(CBuf *p, ISzAllocPtr alloc) { - alloc->Free(alloc, p->data); + ISzAlloc_Free(alloc, p->data); p->data = 0; p->size = 0; } diff --git a/lzma/C/7zBuf.h b/lzma/C/7zBuf.h index 65f1d7a716..81d1b5b646 100644 --- a/lzma/C/7zBuf.h +++ b/lzma/C/7zBuf.h @@ -1,5 +1,5 @@ /* 7zBuf.h -- Byte Buffer -2013-01-18 : Igor Pavlov : Public domain */ +2017-04-03 : Igor Pavlov : Public domain */ #ifndef __7Z_BUF_H #define __7Z_BUF_H @@ -15,8 +15,8 @@ typedef struct } CBuf; void Buf_Init(CBuf *p); -int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc); -void Buf_Free(CBuf *p, ISzAlloc *alloc); +int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc); +void Buf_Free(CBuf *p, ISzAllocPtr alloc); typedef struct { @@ -27,8 +27,8 @@ typedef struct void DynBuf_Construct(CDynBuf *p); void DynBuf_SeekToBeg(CDynBuf *p); -int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc); -void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc); +int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAllocPtr alloc); +void DynBuf_Free(CDynBuf *p, ISzAllocPtr alloc); EXTERN_C_END diff --git a/lzma/C/7zCrc.c b/lzma/C/7zCrc.c index dc6d6abdc0..b4d84f0233 100644 --- a/lzma/C/7zCrc.c +++ b/lzma/C/7zCrc.c @@ -1,5 +1,5 @@ /* 7zCrc.c -- CRC32 init -2015-03-10 : Igor Pavlov : Public domain */ +2017-06-06 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -61,12 +61,12 @@ void MY_FAST_CALL CrcGenerateTable() UInt32 r = i; unsigned j; for (j = 0; j < 8; j++) - r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); + r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1))); g_CrcTable[i] = r; } - for (; i < 256 * CRC_NUM_TABLES; i++) + for (i = 256; i < 256 * CRC_NUM_TABLES; i++) { - UInt32 r = g_CrcTable[i - 256]; + UInt32 r = g_CrcTable[(size_t)i - 256]; g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8); } @@ -86,8 +86,8 @@ void MY_FAST_CALL CrcGenerateTable() #ifdef MY_CPU_X86_OR_AMD64 if (!CPU_Is_InOrder()) - g_CrcUpdate = CrcUpdateT8; #endif + g_CrcUpdate = CrcUpdateT8; #endif #else @@ -101,7 +101,7 @@ void MY_FAST_CALL CrcGenerateTable() g_CrcUpdate = CrcUpdateT4; #if CRC_NUM_TABLES >= 8 g_CrcUpdateT8 = CrcUpdateT8; - // g_CrcUpdate = CrcUpdateT8; + g_CrcUpdate = CrcUpdateT8; #endif } else if (p[0] != 1 || p[1] != 2) @@ -111,14 +111,14 @@ void MY_FAST_CALL CrcGenerateTable() { for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--) { - UInt32 x = g_CrcTable[i - 256]; + UInt32 x = g_CrcTable[(size_t)i - 256]; g_CrcTable[i] = CRC_UINT32_SWAP(x); } g_CrcUpdateT4 = CrcUpdateT1_BeT4; g_CrcUpdate = CrcUpdateT1_BeT4; #if CRC_NUM_TABLES >= 8 g_CrcUpdateT8 = CrcUpdateT1_BeT8; - // g_CrcUpdate = CrcUpdateT1_BeT8; + g_CrcUpdate = CrcUpdateT1_BeT8; #endif } } diff --git a/lzma/C/7zCrcOpt.c b/lzma/C/7zCrcOpt.c index d1e1cd7bae..73beba298d 100644 --- a/lzma/C/7zCrcOpt.c +++ b/lzma/C/7zCrcOpt.c @@ -1,5 +1,5 @@ /* 7zCrcOpt.c -- CRC32 calculation -2015-03-01 : Igor Pavlov : Public domain */ +2017-04-03 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -18,10 +18,10 @@ UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const U { v ^= *(const UInt32 *)p; v = - table[0x300 + ((v ) & 0xFF)] - ^ table[0x200 + ((v >> 8) & 0xFF)] - ^ table[0x100 + ((v >> 16) & 0xFF)] - ^ table[0x000 + ((v >> 24))]; + (table + 0x300)[((v ) & 0xFF)] + ^ (table + 0x200)[((v >> 8) & 0xFF)] + ^ (table + 0x100)[((v >> 16) & 0xFF)] + ^ (table + 0x000)[((v >> 24))]; } for (; size > 0; size--, p++) v = CRC_UPDATE_BYTE_2(v, *p); @@ -38,16 +38,16 @@ UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const U UInt32 d; v ^= *(const UInt32 *)p; v = - table[0x700 + ((v ) & 0xFF)] - ^ table[0x600 + ((v >> 8) & 0xFF)] - ^ table[0x500 + ((v >> 16) & 0xFF)] - ^ table[0x400 + ((v >> 24))]; + (table + 0x700)[((v ) & 0xFF)] + ^ (table + 0x600)[((v >> 8) & 0xFF)] + ^ (table + 0x500)[((v >> 16) & 0xFF)] + ^ (table + 0x400)[((v >> 24))]; d = *((const UInt32 *)p + 1); v ^= - table[0x300 + ((d ) & 0xFF)] - ^ table[0x200 + ((d >> 8) & 0xFF)] - ^ table[0x100 + ((d >> 16) & 0xFF)] - ^ table[0x000 + ((d >> 24))]; + (table + 0x300)[((d ) & 0xFF)] + ^ (table + 0x200)[((d >> 8) & 0xFF)] + ^ (table + 0x100)[((d >> 16) & 0xFF)] + ^ (table + 0x000)[((d >> 24))]; } for (; size > 0; size--, p++) v = CRC_UPDATE_BYTE_2(v, *p); @@ -74,10 +74,10 @@ UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, co { v ^= *(const UInt32 *)p; v = - table[0x000 + ((v ) & 0xFF)] - ^ table[0x100 + ((v >> 8) & 0xFF)] - ^ table[0x200 + ((v >> 16) & 0xFF)] - ^ table[0x300 + ((v >> 24))]; + (table + 0x000)[((v ) & 0xFF)] + ^ (table + 0x100)[((v >> 8) & 0xFF)] + ^ (table + 0x200)[((v >> 16) & 0xFF)] + ^ (table + 0x300)[((v >> 24))]; } for (; size > 0; size--, p++) v = CRC_UPDATE_BYTE_2_BE(v, *p); @@ -96,16 +96,16 @@ UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, co UInt32 d; v ^= *(const UInt32 *)p; v = - table[0x400 + ((v ) & 0xFF)] - ^ table[0x500 + ((v >> 8) & 0xFF)] - ^ table[0x600 + ((v >> 16) & 0xFF)] - ^ table[0x700 + ((v >> 24))]; + (table + 0x400)[((v ) & 0xFF)] + ^ (table + 0x500)[((v >> 8) & 0xFF)] + ^ (table + 0x600)[((v >> 16) & 0xFF)] + ^ (table + 0x700)[((v >> 24))]; d = *((const UInt32 *)p + 1); v ^= - table[0x000 + ((d ) & 0xFF)] - ^ table[0x100 + ((d >> 8) & 0xFF)] - ^ table[0x200 + ((d >> 16) & 0xFF)] - ^ table[0x300 + ((d >> 24))]; + (table + 0x000)[((d ) & 0xFF)] + ^ (table + 0x100)[((d >> 8) & 0xFF)] + ^ (table + 0x200)[((d >> 16) & 0xFF)] + ^ (table + 0x300)[((d >> 24))]; } for (; size > 0; size--, p++) v = CRC_UPDATE_BYTE_2_BE(v, *p); diff --git a/lzma/C/7zDec.c b/lzma/C/7zDec.c index c45d6bf8d4..1ae87dfafe 100644 --- a/lzma/C/7zDec.c +++ b/lzma/C/7zDec.c @@ -1,5 +1,5 @@ /* 7zDec.c -- Decoding from 7z folder -2015-11-18 : Igor Pavlov : Public domain */ +2017-04-03 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -39,28 +39,28 @@ typedef struct { - IByteIn p; + IByteIn vt; const Byte *cur; const Byte *end; const Byte *begin; UInt64 processed; Bool extra; SRes res; - ILookInStream *inStream; + const ILookInStream *inStream; } CByteInToLook; -static Byte ReadByte(void *pp) +static Byte ReadByte(const IByteIn *pp) { - CByteInToLook *p = (CByteInToLook *)pp; + CByteInToLook *p = CONTAINER_FROM_VTBL(pp, CByteInToLook, vt); if (p->cur != p->end) return *p->cur++; if (p->res == SZ_OK) { size_t size = p->cur - p->begin; p->processed += size; - p->res = p->inStream->Skip(p->inStream, size); + p->res = ILookInStream_Skip(p->inStream, size); size = (1 << 25); - p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size); + p->res = ILookInStream_Look(p->inStream, (const void **)&p->begin, &size); p->cur = p->begin; p->end = p->begin + size; if (size != 0) @@ -70,14 +70,14 @@ static Byte ReadByte(void *pp) return 0; } -static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream, - Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) +static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, const ILookInStream *inStream, + Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain) { CPpmd7 ppmd; CByteInToLook s; SRes res = SZ_OK; - s.p.Read = ReadByte; + s.vt.Read = ReadByte; s.inStream = inStream; s.begin = s.end = s.cur = NULL; s.extra = False; @@ -103,7 +103,7 @@ static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, I { CPpmd7z_RangeDec rc; Ppmd7z_RangeDec_CreateVTable(&rc); - rc.Stream = &s.p; + rc.Stream = &s.vt; if (!Ppmd7z_RangeDec_Init(&rc)) res = SZ_ERROR_DATA; else if (s.extra) @@ -113,7 +113,7 @@ static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, I SizeT i; for (i = 0; i < outSize; i++) { - int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p); + int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.vt); if (s.extra || sym < 0) break; outBuffer[i] = (Byte)sym; @@ -132,7 +132,7 @@ static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, I static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream, - Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) + Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain) { CLzmaDec state; SRes res = SZ_OK; @@ -149,7 +149,7 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I size_t lookahead = (1 << 18); if (lookahead > inSize) lookahead = (size_t)inSize; - res = inStream->Look(inStream, &inBuf, &lookahead); + res = ILookInStream_Look(inStream, &inBuf, &lookahead); if (res != SZ_OK) break; @@ -178,7 +178,7 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I break; } - res = inStream->Skip((void *)inStream, inProcessed); + res = ILookInStream_Skip(inStream, inProcessed); if (res != SZ_OK) break; } @@ -192,7 +192,7 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I #ifndef _7Z_NO_METHOD_LZMA2 static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream, - Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) + Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain) { CLzma2Dec state; SRes res = SZ_OK; @@ -211,7 +211,7 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, size_t lookahead = (1 << 18); if (lookahead > inSize) lookahead = (size_t)inSize; - res = inStream->Look(inStream, &inBuf, &lookahead); + res = ILookInStream_Look(inStream, &inBuf, &lookahead); if (res != SZ_OK) break; @@ -237,7 +237,7 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, break; } - res = inStream->Skip((void *)inStream, inProcessed); + res = ILookInStream_Skip(inStream, inProcessed); if (res != SZ_OK) break; } @@ -258,13 +258,13 @@ static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer size_t curSize = (1 << 18); if (curSize > inSize) curSize = (size_t)inSize; - RINOK(inStream->Look(inStream, &inBuf, &curSize)); + RINOK(ILookInStream_Look(inStream, &inBuf, &curSize)); if (curSize == 0) return SZ_ERROR_INPUT_EOF; memcpy(outBuffer, inBuf, curSize); outBuffer += curSize; inSize -= curSize; - RINOK(inStream->Skip((void *)inStream, curSize)); + RINOK(ILookInStream_Skip(inStream, curSize)); } return SZ_OK; } @@ -372,7 +372,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *unpackSizes, const UInt64 *packPositions, ILookInStream *inStream, UInt64 startPos, - Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain, + Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain, Byte *tempBuf[]) { UInt32 ci; @@ -404,7 +404,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, outSizeCur = (SizeT)unpackSize; if (outSizeCur != unpackSize) return SZ_ERROR_MEM; - temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur); + temp = (Byte *)ISzAlloc_Alloc(allocMain, outSizeCur); if (!temp && outSizeCur != 0) return SZ_ERROR_MEM; outBufCur = tempBuf[1 - ci] = temp; @@ -421,7 +421,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, return SZ_ERROR_UNSUPPORTED; } offset = packPositions[si]; - inSize = packPositions[si + 1] - offset; + inSize = packPositions[(size_t)si + 1] - offset; RINOK(LookInStream_SeekTo(inStream, startPos + offset)); if (coder->MethodID == k_Copy) @@ -460,7 +460,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, tempSizes[2] = (SizeT)s3Size; if (tempSizes[2] != s3Size) return SZ_ERROR_MEM; - tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]); + tempBuf[2] = (Byte *)ISzAlloc_Alloc(allocMain, tempSizes[2]); if (!tempBuf[2] && tempSizes[2] != 0) return SZ_ERROR_MEM; @@ -549,7 +549,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex, ILookInStream *inStream, UInt64 startPos, Byte *outBuffer, size_t outSize, - ISzAlloc *allocMain) + ISzAllocPtr allocMain) { SRes res; CSzFolder folder; @@ -557,7 +557,7 @@ SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex, const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex]; sd.Data = data; - sd.Size = p->FoCodersOffsets[folderIndex + 1] - p->FoCodersOffsets[folderIndex]; + sd.Size = p->FoCodersOffsets[(size_t)folderIndex + 1] - p->FoCodersOffsets[folderIndex]; res = SzGetNextFolderItem(&folder, &sd); @@ -579,7 +579,7 @@ SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex, outBuffer, (SizeT)outSize, allocMain, tempBuf); for (i = 0; i < 3; i++) - IAlloc_Free(allocMain, tempBuf[i]); + ISzAlloc_Free(allocMain, tempBuf[i]); if (res == SZ_OK) if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex)) diff --git a/lzma/C/7zStream.c b/lzma/C/7zStream.c index 88f9c42b1d..6b5aa1621d 100644 --- a/lzma/C/7zStream.c +++ b/lzma/C/7zStream.c @@ -1,5 +1,5 @@ /* 7zStream.c -- 7z Stream functions -2013-11-12 : Igor Pavlov : Public domain */ +2017-04-03 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -7,12 +7,12 @@ #include "7zTypes.h" -SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType) +SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType) { while (size != 0) { size_t processed = size; - RINOK(stream->Read(stream, buf, &processed)); + RINOK(ISeqInStream_Read(stream, buf, &processed)); if (processed == 0) return errorType; buf = (void *)((Byte *)buf + processed); @@ -21,40 +21,42 @@ SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorT return SZ_OK; } -SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size) +SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size) { return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); } -SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf) +SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf) { size_t processed = 1; - RINOK(stream->Read(stream, buf, &processed)); + RINOK(ISeqInStream_Read(stream, buf, &processed)); return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF; } -SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset) + + +SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset) { Int64 t = offset; - return stream->Seek(stream, &t, SZ_SEEK_SET); + return ILookInStream_Seek(stream, &t, SZ_SEEK_SET); } -SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size) +SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size) { const void *lookBuf; if (*size == 0) return SZ_OK; - RINOK(stream->Look(stream, &lookBuf, size)); + RINOK(ILookInStream_Look(stream, &lookBuf, size)); memcpy(buf, lookBuf, *size); - return stream->Skip(stream, *size); + return ILookInStream_Skip(stream, *size); } -SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType) +SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType) { while (size != 0) { size_t processed = size; - RINOK(stream->Read(stream, buf, &processed)); + RINOK(ILookInStream_Read(stream, buf, &processed)); if (processed == 0) return errorType; buf = (void *)((Byte *)buf + processed); @@ -63,61 +65,67 @@ SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes erro return SZ_OK; } -SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size) +SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size) { return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); } -static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size) + + +#define GET_LookToRead2 CLookToRead2 *p = CONTAINER_FROM_VTBL(pp, CLookToRead2, vt); + +static SRes LookToRead2_Look_Lookahead(const ILookInStream *pp, const void **buf, size_t *size) { SRes res = SZ_OK; - CLookToRead *p = (CLookToRead *)pp; + GET_LookToRead2 size_t size2 = p->size - p->pos; - if (size2 == 0 && *size > 0) + if (size2 == 0 && *size != 0) { p->pos = 0; - size2 = LookToRead_BUF_SIZE; - res = p->realStream->Read(p->realStream, p->buf, &size2); + p->size = 0; + size2 = p->bufSize; + res = ISeekInStream_Read(p->realStream, p->buf, &size2); p->size = size2; } - if (size2 < *size) + if (*size > size2) *size = size2; *buf = p->buf + p->pos; return res; } -static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size) +static SRes LookToRead2_Look_Exact(const ILookInStream *pp, const void **buf, size_t *size) { SRes res = SZ_OK; - CLookToRead *p = (CLookToRead *)pp; + GET_LookToRead2 size_t size2 = p->size - p->pos; - if (size2 == 0 && *size > 0) + if (size2 == 0 && *size != 0) { p->pos = 0; - if (*size > LookToRead_BUF_SIZE) - *size = LookToRead_BUF_SIZE; - res = p->realStream->Read(p->realStream, p->buf, size); + p->size = 0; + if (*size > p->bufSize) + *size = p->bufSize; + res = ISeekInStream_Read(p->realStream, p->buf, size); size2 = p->size = *size; } - if (size2 < *size) + if (*size > size2) *size = size2; *buf = p->buf + p->pos; return res; } -static SRes LookToRead_Skip(void *pp, size_t offset) +static SRes LookToRead2_Skip(const ILookInStream *pp, size_t offset) { - CLookToRead *p = (CLookToRead *)pp; + GET_LookToRead2 p->pos += offset; return SZ_OK; } -static SRes LookToRead_Read(void *pp, void *buf, size_t *size) +static SRes LookToRead2_Read(const ILookInStream *pp, void *buf, size_t *size) { - CLookToRead *p = (CLookToRead *)pp; + GET_LookToRead2 size_t rem = p->size - p->pos; if (rem == 0) - return p->realStream->Read(p->realStream, buf, size); + return ISeekInStream_Read(p->realStream, buf, size); if (rem > *size) rem = *size; memcpy(buf, p->buf + p->pos, rem); @@ -126,46 +134,43 @@ static SRes LookToRead_Read(void *pp, void *buf, size_t *size) return SZ_OK; } -static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin) +static SRes LookToRead2_Seek(const ILookInStream *pp, Int64 *pos, ESzSeek origin) { - CLookToRead *p = (CLookToRead *)pp; + GET_LookToRead2 p->pos = p->size = 0; - return p->realStream->Seek(p->realStream, pos, origin); + return ISeekInStream_Seek(p->realStream, pos, origin); } -void LookToRead_CreateVTable(CLookToRead *p, int lookahead) +void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead) { - p->s.Look = lookahead ? - LookToRead_Look_Lookahead : - LookToRead_Look_Exact; - p->s.Skip = LookToRead_Skip; - p->s.Read = LookToRead_Read; - p->s.Seek = LookToRead_Seek; + p->vt.Look = lookahead ? + LookToRead2_Look_Lookahead : + LookToRead2_Look_Exact; + p->vt.Skip = LookToRead2_Skip; + p->vt.Read = LookToRead2_Read; + p->vt.Seek = LookToRead2_Seek; } -void LookToRead_Init(CLookToRead *p) -{ - p->pos = p->size = 0; -} -static SRes SecToLook_Read(void *pp, void *buf, size_t *size) + +static SRes SecToLook_Read(const ISeqInStream *pp, void *buf, size_t *size) { - CSecToLook *p = (CSecToLook *)pp; + CSecToLook *p = CONTAINER_FROM_VTBL(pp, CSecToLook, vt); return LookInStream_LookRead(p->realStream, buf, size); } void SecToLook_CreateVTable(CSecToLook *p) { - p->s.Read = SecToLook_Read; + p->vt.Read = SecToLook_Read; } -static SRes SecToRead_Read(void *pp, void *buf, size_t *size) +static SRes SecToRead_Read(const ISeqInStream *pp, void *buf, size_t *size) { - CSecToRead *p = (CSecToRead *)pp; - return p->realStream->Read(p->realStream, buf, size); + CSecToRead *p = CONTAINER_FROM_VTBL(pp, CSecToRead, vt); + return ILookInStream_Read(p->realStream, buf, size); } void SecToRead_CreateVTable(CSecToRead *p) { - p->s.Read = SecToRead_Read; + p->vt.Read = SecToRead_Read; } diff --git a/lzma/C/7zTypes.h b/lzma/C/7zTypes.h index adde88e757..29244b23ee 100644 --- a/lzma/C/7zTypes.h +++ b/lzma/C/7zTypes.h @@ -1,11 +1,11 @@ /* 7zTypes.h -- Basic types -2013-11-12 : Igor Pavlov : Public domain */ +2017-07-17 : Igor Pavlov : Public domain */ #ifndef __7Z_TYPES_H #define __7Z_TYPES_H #ifdef _WIN32 -#include +/* #include */ #endif #include @@ -42,13 +42,23 @@ EXTERN_C_BEGIN typedef int SRes; + #ifdef _WIN32 -typedef DWORD WRes; -/* typedef unsigned WRes; */ + +/* typedef DWORD WRes; */ +typedef unsigned WRes; +#define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x) + #else + typedef int WRes; +#define MY__FACILITY_WIN32 7 +#define MY__FACILITY__WRes MY__FACILITY_WIN32 +#define MY_SRes_HRESULT_FROM_WRes(x) ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (MY__FACILITY__WRes << 16) | 0x80000000))) + #endif + #ifndef RINOK #define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } #endif @@ -112,48 +122,72 @@ typedef int Bool; #define MY_NO_INLINE #endif +#define MY_FORCE_INLINE __forceinline + #define MY_CDECL __cdecl #define MY_FAST_CALL __fastcall #else #define MY_NO_INLINE +#define MY_FORCE_INLINE #define MY_CDECL #define MY_FAST_CALL +/* inline keyword : for C++ / C99 */ + +/* GCC, clang: */ +/* +#if defined (__GNUC__) && (__GNUC__ >= 4) +#define MY_FORCE_INLINE __attribute__((always_inline)) +#define MY_NO_INLINE __attribute__((noinline)) +#endif +*/ + #endif /* The following interfaces use first parameter as pointer to structure */ -typedef struct +typedef struct IByteIn IByteIn; +struct IByteIn { - Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */ -} IByteIn; + Byte (*Read)(const IByteIn *p); /* reads one byte, returns 0 in case of EOF or error */ +}; +#define IByteIn_Read(p) (p)->Read(p) -typedef struct -{ - void (*Write)(void *p, Byte b); -} IByteOut; -typedef struct +typedef struct IByteOut IByteOut; +struct IByteOut { - SRes (*Read)(void *p, void *buf, size_t *size); + void (*Write)(const IByteOut *p, Byte b); +}; +#define IByteOut_Write(p, b) (p)->Write(p, b) + + +typedef struct ISeqInStream ISeqInStream; +struct ISeqInStream +{ + SRes (*Read)(const ISeqInStream *p, void *buf, size_t *size); /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. (output(*size) < input(*size)) is allowed */ -} ISeqInStream; +}; +#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size) /* it can return SZ_ERROR_INPUT_EOF */ -SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); -SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); -SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); +SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size); +SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType); +SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf); -typedef struct + +typedef struct ISeqOutStream ISeqOutStream; +struct ISeqOutStream { - size_t (*Write)(void *p, const void *buf, size_t size); + size_t (*Write)(const ISeqOutStream *p, const void *buf, size_t size); /* Returns: result - the number of actually written bytes. (result < size) means error */ -} ISeqOutStream; +}; +#define ISeqOutStream_Write(p, buf, size) (p)->Write(p, buf, size) typedef enum { @@ -162,78 +196,162 @@ typedef enum SZ_SEEK_END = 2 } ESzSeek; -typedef struct -{ - SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ - SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); -} ISeekInStream; -typedef struct +typedef struct ISeekInStream ISeekInStream; +struct ISeekInStream { - SRes (*Look)(void *p, const void **buf, size_t *size); + SRes (*Read)(const ISeekInStream *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ + SRes (*Seek)(const ISeekInStream *p, Int64 *pos, ESzSeek origin); +}; +#define ISeekInStream_Read(p, buf, size) (p)->Read(p, buf, size) +#define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin) + + +typedef struct ILookInStream ILookInStream; +struct ILookInStream +{ + SRes (*Look)(const ILookInStream *p, const void **buf, size_t *size); /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. (output(*size) > input(*size)) is not allowed (output(*size) < input(*size)) is allowed */ - SRes (*Skip)(void *p, size_t offset); + SRes (*Skip)(const ILookInStream *p, size_t offset); /* offset must be <= output(*size) of Look */ - SRes (*Read)(void *p, void *buf, size_t *size); + SRes (*Read)(const ILookInStream *p, void *buf, size_t *size); /* reads directly (without buffer). It's same as ISeqInStream::Read */ - SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); -} ILookInStream; + SRes (*Seek)(const ILookInStream *p, Int64 *pos, ESzSeek origin); +}; -SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); -SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); +#define ILookInStream_Look(p, buf, size) (p)->Look(p, buf, size) +#define ILookInStream_Skip(p, offset) (p)->Skip(p, offset) +#define ILookInStream_Read(p, buf, size) (p)->Read(p, buf, size) +#define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin) + + +SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size); +SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset); /* reads via ILookInStream::Read */ -SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); -SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); +SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType); +SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size); + -#define LookToRead_BUF_SIZE (1 << 14) typedef struct { - ILookInStream s; - ISeekInStream *realStream; + ILookInStream vt; + const ISeekInStream *realStream; + size_t pos; - size_t size; - Byte buf[LookToRead_BUF_SIZE]; -} CLookToRead; + size_t size; /* it's data size */ + + /* the following variables must be set outside */ + Byte *buf; + size_t bufSize; +} CLookToRead2; + +void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead); + +#define LookToRead2_Init(p) { (p)->pos = (p)->size = 0; } -void LookToRead_CreateVTable(CLookToRead *p, int lookahead); -void LookToRead_Init(CLookToRead *p); typedef struct { - ISeqInStream s; - ILookInStream *realStream; + ISeqInStream vt; + const ILookInStream *realStream; } CSecToLook; void SecToLook_CreateVTable(CSecToLook *p); + + typedef struct { - ISeqInStream s; - ILookInStream *realStream; + ISeqInStream vt; + const ILookInStream *realStream; } CSecToRead; void SecToRead_CreateVTable(CSecToRead *p); -typedef struct + +typedef struct ICompressProgress ICompressProgress; + +struct ICompressProgress { - SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); + SRes (*Progress)(const ICompressProgress *p, UInt64 inSize, UInt64 outSize); /* Returns: result. (result != SZ_OK) means break. Value (UInt64)(Int64)-1 for size means unknown value. */ -} ICompressProgress; +}; +#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize) -typedef struct + + +typedef struct ISzAlloc ISzAlloc; +typedef const ISzAlloc * ISzAllocPtr; + +struct ISzAlloc { - void *(*Alloc)(void *p, size_t size); - void (*Free)(void *p, void *address); /* address can be 0 */ -} ISzAlloc; + void *(*Alloc)(ISzAllocPtr p, size_t size); + void (*Free)(ISzAllocPtr p, void *address); /* address can be 0 */ +}; + +#define ISzAlloc_Alloc(p, size) (p)->Alloc(p, size) +#define ISzAlloc_Free(p, a) (p)->Free(p, a) + +/* deprecated */ +#define IAlloc_Alloc(p, size) ISzAlloc_Alloc(p, size) +#define IAlloc_Free(p, a) ISzAlloc_Free(p, a) + + + + + +#ifndef MY_offsetof + #ifdef offsetof + #define MY_offsetof(type, m) offsetof(type, m) + /* + #define MY_offsetof(type, m) FIELD_OFFSET(type, m) + */ + #else + #define MY_offsetof(type, m) ((size_t)&(((type *)0)->m)) + #endif +#endif + + + +#ifndef MY_container_of + +/* +#define MY_container_of(ptr, type, m) container_of(ptr, type, m) +#define MY_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m) +#define MY_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m))) +#define MY_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m)))) +*/ + +/* + GCC shows warning: "perhaps the 'offsetof' macro was used incorrectly" + GCC 3.4.4 : classes with constructor + GCC 4.8.1 : classes with non-public variable members" +*/ + +#define MY_container_of(ptr, type, m) ((type *)((char *)(1 ? (ptr) : &((type *)0)->m) - MY_offsetof(type, m))) + + +#endif + +#define CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(ptr)) + +/* +#define CONTAINER_FROM_VTBL(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) +*/ +#define CONTAINER_FROM_VTBL(ptr, type, m) MY_container_of(ptr, type, m) + +#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) +/* +#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL(ptr, type, m) +*/ + -#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) -#define IAlloc_Free(p, a) (p)->Free((p), a) #ifdef _WIN32 diff --git a/lzma/C/7zVersion.h b/lzma/C/7zVersion.h index c4f5c8e940..a0f5627915 100644 --- a/lzma/C/7zVersion.h +++ b/lzma/C/7zVersion.h @@ -1,14 +1,21 @@ -#define MY_VER_MAJOR 15 -#define MY_VER_MINOR 14 +#define MY_VER_MAJOR 17 +#define MY_VER_MINOR 01 #define MY_VER_BUILD 0 -#define MY_VERSION_NUMBERS "15.14" -#define MY_VERSION "15.14" -#define MY_DATE "2015-12-31" +#define MY_VERSION_NUMBERS "17.01 beta" +#define MY_VERSION MY_VERSION_NUMBERS + +#ifdef MY_CPU_NAME + #define MY_VERSION_CPU MY_VERSION " (" MY_CPU_NAME ")" +#else + #define MY_VERSION_CPU MY_VERSION +#endif + +#define MY_DATE "2017-08-28" #undef MY_COPYRIGHT #undef MY_VERSION_COPYRIGHT_DATE #define MY_AUTHOR_NAME "Igor Pavlov" #define MY_COPYRIGHT_PD "Igor Pavlov : Public domain" -#define MY_COPYRIGHT_CR "Copyright (c) 1999-2015 Igor Pavlov" +#define MY_COPYRIGHT_CR "Copyright (c) 1999-2017 Igor Pavlov" #ifdef USE_COPYRIGHT_CR #define MY_COPYRIGHT MY_COPYRIGHT_CR @@ -16,4 +23,5 @@ #define MY_COPYRIGHT MY_COPYRIGHT_PD #endif -#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " : " MY_COPYRIGHT " : " MY_DATE +#define MY_COPYRIGHT_DATE MY_COPYRIGHT " : " MY_DATE +#define MY_VERSION_COPYRIGHT_DATE MY_VERSION_CPU " : " MY_COPYRIGHT " : " MY_DATE diff --git a/lzma/C/Bcj2.c b/lzma/C/Bcj2.c index 3c88e44fc1..0efff4e5d4 100644 --- a/lzma/C/Bcj2.c +++ b/lzma/C/Bcj2.c @@ -1,5 +1,5 @@ /* Bcj2.c -- BCJ2 Decoder (Converter for x86 code) -2015-08-01 : Igor Pavlov : Public domain */ +2017-04-03 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -61,7 +61,8 @@ SRes Bcj2Dec_Decode(CBcj2Dec *p) Byte *dest = p->dest; if (dest == p->destLim) return SZ_OK; - *dest = p->temp[p->state++ - BCJ2_DEC_STATE_ORIG_0]; + *dest = p->temp[(size_t)p->state - BCJ2_DEC_STATE_ORIG_0]; + p->state++; p->dest = dest + 1; } } diff --git a/lzma/C/Bra.c b/lzma/C/Bra.c index cdb9456920..aed17e330d 100644 --- a/lzma/C/Bra.c +++ b/lzma/C/Bra.c @@ -1,135 +1,230 @@ /* Bra.c -- Converters for RISC code -2010-04-16 : Igor Pavlov : Public domain */ +2017-04-04 : Igor Pavlov : Public domain */ #include "Precomp.h" +#include "CpuArch.h" #include "Bra.h" SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) { - SizeT i; - if (size < 4) - return 0; - size -= 4; - ip += 8; - for (i = 0; i <= size; i += 4) + Byte *p; + const Byte *lim; + size &= ~(size_t)3; + ip += 4; + p = data; + lim = data + size; + + if (encoding) + + for (;;) { - if (data[i + 3] == 0xEB) + for (;;) { - UInt32 dest; - UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]); - src <<= 2; - if (encoding) - dest = ip + (UInt32)i + src; - else - dest = src - (ip + (UInt32)i); - dest >>= 2; - data[i + 2] = (Byte)(dest >> 16); - data[i + 1] = (Byte)(dest >> 8); - data[i + 0] = (Byte)dest; + if (p >= lim) + return p - data; + p += 4; + if (p[-1] == 0xEB) + break; + } + { + UInt32 v = GetUi32(p - 4); + v <<= 2; + v += ip + (UInt32)(p - data); + v >>= 2; + v &= 0x00FFFFFF; + v |= 0xEB000000; + SetUi32(p - 4, v); + } + } + + for (;;) + { + for (;;) + { + if (p >= lim) + return p - data; + p += 4; + if (p[-1] == 0xEB) + break; + } + { + UInt32 v = GetUi32(p - 4); + v <<= 2; + v -= ip + (UInt32)(p - data); + v >>= 2; + v &= 0x00FFFFFF; + v |= 0xEB000000; + SetUi32(p - 4, v); } } - return i; } + SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) { - SizeT i; - if (size < 4) - return 0; - size -= 4; - ip += 4; - for (i = 0; i <= size; i += 2) + Byte *p; + const Byte *lim; + size &= ~(size_t)1; + p = data; + lim = data + size - 4; + + if (encoding) + + for (;;) { - if ((data[i + 1] & 0xF8) == 0xF0 && - (data[i + 3] & 0xF8) == 0xF8) + UInt32 b1; + for (;;) { - UInt32 dest; - UInt32 src = - (((UInt32)data[i + 1] & 0x7) << 19) | - ((UInt32)data[i + 0] << 11) | - (((UInt32)data[i + 3] & 0x7) << 8) | - (data[i + 2]); - - src <<= 1; - if (encoding) - dest = ip + (UInt32)i + src; - else - dest = src - (ip + (UInt32)i); - dest >>= 1; - - data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7)); - data[i + 0] = (Byte)(dest >> 11); - data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7)); - data[i + 2] = (Byte)dest; - i += 2; + UInt32 b3; + if (p > lim) + return p - data; + b1 = p[1]; + b3 = p[3]; + p += 2; + b1 ^= 8; + if ((b3 & b1) >= 0xF8) + break; + } + { + UInt32 v = + ((UInt32)b1 << 19) + + (((UInt32)p[1] & 0x7) << 8) + + (((UInt32)p[-2] << 11)) + + (p[0]); + + p += 2; + { + UInt32 cur = (ip + (UInt32)(p - data)) >> 1; + v += cur; + } + + p[-4] = (Byte)(v >> 11); + p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7)); + p[-2] = (Byte)v; + p[-1] = (Byte)(0xF8 | (v >> 8)); + } + } + + for (;;) + { + UInt32 b1; + for (;;) + { + UInt32 b3; + if (p > lim) + return p - data; + b1 = p[1]; + b3 = p[3]; + p += 2; + b1 ^= 8; + if ((b3 & b1) >= 0xF8) + break; + } + { + UInt32 v = + ((UInt32)b1 << 19) + + (((UInt32)p[1] & 0x7) << 8) + + (((UInt32)p[-2] << 11)) + + (p[0]); + + p += 2; + { + UInt32 cur = (ip + (UInt32)(p - data)) >> 1; + v -= cur; + } + + /* + SetUi16(p - 4, (UInt16)(((v >> 11) & 0x7FF) | 0xF000)); + SetUi16(p - 2, (UInt16)(v | 0xF800)); + */ + + p[-4] = (Byte)(v >> 11); + p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7)); + p[-2] = (Byte)v; + p[-1] = (Byte)(0xF8 | (v >> 8)); } } - return i; } + SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) { - SizeT i; - if (size < 4) - return 0; - size -= 4; - for (i = 0; i <= size; i += 4) + Byte *p; + const Byte *lim; + size &= ~(size_t)3; + ip -= 4; + p = data; + lim = data + size; + + for (;;) { - if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1) + for (;;) { - UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) | - ((UInt32)data[i + 1] << 16) | - ((UInt32)data[i + 2] << 8) | - ((UInt32)data[i + 3] & (~3)); - - UInt32 dest; + if (p >= lim) + return p - data; + p += 4; + /* if ((v & 0xFC000003) == 0x48000001) */ + if ((p[-4] & 0xFC) == 0x48 && (p[-1] & 3) == 1) + break; + } + { + UInt32 v = GetBe32(p - 4); if (encoding) - dest = ip + (UInt32)i + src; + v += ip + (UInt32)(p - data); else - dest = src - (ip + (UInt32)i); - data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3)); - data[i + 1] = (Byte)(dest >> 16); - data[i + 2] = (Byte)(dest >> 8); - data[i + 3] &= 0x3; - data[i + 3] |= dest; + v -= ip + (UInt32)(p - data); + v &= 0x03FFFFFF; + v |= 0x48000000; + SetBe32(p - 4, v); } } - return i; } + SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) { - UInt32 i; - if (size < 4) - return 0; - size -= 4; - for (i = 0; i <= size; i += 4) - { - if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) || - (data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)) - { - UInt32 src = - ((UInt32)data[i + 0] << 24) | - ((UInt32)data[i + 1] << 16) | - ((UInt32)data[i + 2] << 8) | - ((UInt32)data[i + 3]); - UInt32 dest; - - src <<= 2; - if (encoding) - dest = ip + i + src; - else - dest = src - (ip + i); - dest >>= 2; - - dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000; + Byte *p; + const Byte *lim; + size &= ~(size_t)3; + ip -= 4; + p = data; + lim = data + size; - data[i + 0] = (Byte)(dest >> 24); - data[i + 1] = (Byte)(dest >> 16); - data[i + 2] = (Byte)(dest >> 8); - data[i + 3] = (Byte)dest; + for (;;) + { + for (;;) + { + if (p >= lim) + return p - data; + /* + v = GetBe32(p); + p += 4; + m = v + ((UInt32)5 << 29); + m ^= (UInt32)7 << 29; + m += (UInt32)1 << 22; + if ((m & ((UInt32)0x1FF << 23)) == 0) + break; + */ + p += 4; + if ((p[-4] == 0x40 && (p[-3] & 0xC0) == 0) || + (p[-4] == 0x7F && (p[-3] >= 0xC0))) + break; + } + { + UInt32 v = GetBe32(p - 4); + v <<= 2; + if (encoding) + v += ip + (UInt32)(p - data); + else + v -= ip + (UInt32)(p - data); + + v &= 0x01FFFFFF; + v -= (UInt32)1 << 24; + v ^= 0xFF000000; + v >>= 2; + v |= 0x40000000; + SetBe32(p - 4, v); } } - return i; } diff --git a/lzma/C/Bra86.c b/lzma/C/Bra86.c index 6db15e7ecd..93ed4d762b 100644 --- a/lzma/C/Bra86.c +++ b/lzma/C/Bra86.c @@ -1,5 +1,5 @@ /* Bra86.c -- Converter for x86 code (BCJ) -2013-11-12 : Igor Pavlov : Public domain */ +2017-04-03 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -37,7 +37,7 @@ SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding else { mask >>= (unsigned)d; - if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(mask >> 1) + 1]))) + if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(size_t)(mask >> 1) + 1]))) { mask = (mask >> 1) | 4; pos++; diff --git a/lzma/C/BraIA64.c b/lzma/C/BraIA64.c index fa60356b28..d1dbc62c55 100644 --- a/lzma/C/BraIA64.c +++ b/lzma/C/BraIA64.c @@ -1,69 +1,53 @@ /* BraIA64.c -- Converter for IA-64 code -2013-11-12 : Igor Pavlov : Public domain */ +2017-01-26 : Igor Pavlov : Public domain */ #include "Precomp.h" +#include "CpuArch.h" #include "Bra.h" -static const Byte kBranchTable[32] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 4, 4, 6, 6, 0, 0, 7, 7, - 4, 4, 0, 0, 4, 4, 0, 0 -}; - SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) { SizeT i; if (size < 16) return 0; size -= 16; - for (i = 0; i <= size; i += 16) + i = 0; + do { - UInt32 instrTemplate = data[i] & 0x1F; - UInt32 mask = kBranchTable[instrTemplate]; - UInt32 bitPos = 5; - int slot; - for (slot = 0; slot < 3; slot++, bitPos += 41) + unsigned m = ((UInt32)0x334B0000 >> (data[i] & 0x1E)) & 3; + if (m) { - UInt32 bytePos, bitRes; - UInt64 instruction, instNorm; - int j; - if (((mask >> slot) & 1) == 0) - continue; - bytePos = (bitPos >> 3); - bitRes = bitPos & 0x7; - instruction = 0; - for (j = 0; j < 6; j++) - instruction += (UInt64)data[i + j + bytePos] << (8 * j); - - instNorm = instruction >> bitRes; - if (((instNorm >> 37) & 0xF) == 0x5 && ((instNorm >> 9) & 0x7) == 0) + m++; + do { - UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF); - UInt32 dest; - src |= ((UInt32)(instNorm >> 36) & 1) << 20; - - src <<= 4; - - if (encoding) - dest = ip + (UInt32)i + src; - else - dest = src - (ip + (UInt32)i); - - dest >>= 4; - - instNorm &= ~((UInt64)(0x8FFFFF) << 13); - instNorm |= ((UInt64)(dest & 0xFFFFF) << 13); - instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20)); - - instruction &= (1 << bitRes) - 1; - instruction |= (instNorm << bitRes); - for (j = 0; j < 6; j++) - data[i + j + bytePos] = (Byte)(instruction >> (8 * j)); + Byte *p = data + (i + (size_t)m * 5 - 8); + if (((p[3] >> m) & 15) == 5 + && (((p[-1] | ((UInt32)p[0] << 8)) >> m) & 0x70) == 0) + { + unsigned raw = GetUi32(p); + unsigned v = raw >> m; + v = (v & 0xFFFFF) | ((v & (1 << 23)) >> 3); + + v <<= 4; + if (encoding) + v += ip + (UInt32)i; + else + v -= ip + (UInt32)i; + v >>= 4; + + v &= 0x1FFFFF; + v += 0x700000; + v &= 0x8FFFFF; + raw &= ~((UInt32)0x8FFFFF << m); + raw |= (v << m); + SetUi32(p, raw); + } } + while (++m <= 4); } + i += 16; } + while (i <= size); return i; } diff --git a/lzma/C/Compiler.h b/lzma/C/Compiler.h index 5bba7ee561..0cc409d8a8 100644 --- a/lzma/C/Compiler.h +++ b/lzma/C/Compiler.h @@ -1,5 +1,5 @@ /* Compiler.h -2015-08-02 : Igor Pavlov : Public domain */ +2017-04-03 : Igor Pavlov : Public domain */ #ifndef __7Z_COMPILER_H #define __7Z_COMPILER_H @@ -21,6 +21,7 @@ #pragma warning(disable : 4514) // unreferenced inline function has been removed #pragma warning(disable : 4702) // unreachable code #pragma warning(disable : 4710) // not inlined + #pragma warning(disable : 4714) // function marked as __forceinline not inlined #pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information #endif diff --git a/lzma/C/CpuArch.c b/lzma/C/CpuArch.c index 36fc5bb497..554ffa4fc7 100644 --- a/lzma/C/CpuArch.c +++ b/lzma/C/CpuArch.c @@ -1,5 +1,5 @@ /* CpuArch.c -- CPU specific code -2015-03-25: Igor Pavlov : Public domain */ +2016-02-25: Igor Pavlov : Public domain */ #include "Precomp.h" @@ -45,7 +45,8 @@ static UInt32 CheckFlag(UInt32 flag) "push %%EDX\n\t" "popf\n\t" "andl %%EAX, %0\n\t": - "=c" (flag) : "c" (flag)); + "=c" (flag) : "c" (flag) : + "%eax", "%edx"); #endif return flag; } @@ -79,7 +80,13 @@ void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d) #else __asm__ __volatile__ ( - #if defined(MY_CPU_X86) && defined(__PIC__) + #if defined(MY_CPU_AMD64) && defined(__PIC__) + "mov %%rbx, %%rdi;" + "cpuid;" + "xchg %%rbx, %%rdi;" + : "=a" (*a) , + "=D" (*b) , + #elif defined(MY_CPU_X86) && defined(__PIC__) "mov %%ebx, %%edi;" "cpuid;" "xchgl %%ebx, %%edi;" diff --git a/lzma/C/CpuArch.h b/lzma/C/CpuArch.h index f6a28ba7e6..51dd607b08 100644 --- a/lzma/C/CpuArch.h +++ b/lzma/C/CpuArch.h @@ -1,5 +1,5 @@ /* CpuArch.h -- CPU specific code -2015-12-01: Igor Pavlov : Public domain */ +2017-06-30 : Igor Pavlov : Public domain */ #ifndef __CPU_ARCH_H #define __CPU_ARCH_H @@ -16,48 +16,122 @@ If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of pl MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses. */ -#if defined(_M_X64) \ - || defined(_M_AMD64) \ - || defined(__x86_64__) \ - || defined(__AMD64__) \ - || defined(__amd64__) +#if defined(_M_X64) \ + || defined(_M_AMD64) \ + || defined(__x86_64__) \ + || defined(__AMD64__) \ + || defined(__amd64__) #define MY_CPU_AMD64 -#endif - -#if defined(MY_CPU_AMD64) \ - || defined(_M_IA64) \ - || defined(__AARCH64EL__) \ - || defined(__AARCH64EB__) + #ifdef __ILP32__ + #define MY_CPU_NAME "x32" + #else + #define MY_CPU_NAME "x64" + #endif #define MY_CPU_64BIT #endif -#if defined(_M_IX86) || defined(__i386__) -#define MY_CPU_X86 + +#if defined(_M_IX86) \ + || defined(__i386__) + #define MY_CPU_X86 + #define MY_CPU_NAME "x86" + #define MY_CPU_32BIT #endif + +#if defined(_M_ARM64) \ + || defined(__AARCH64EL__) \ + || defined(__AARCH64EB__) \ + || defined(__aarch64__) + #define MY_CPU_ARM64 + #define MY_CPU_NAME "arm64" + #define MY_CPU_64BIT +#endif + + +#if defined(_M_ARM) \ + || defined(_M_ARM_NT) \ + || defined(_M_ARMT) \ + || defined(__arm__) \ + || defined(__thumb__) \ + || defined(__ARMEL__) \ + || defined(__ARMEB__) \ + || defined(__THUMBEL__) \ + || defined(__THUMBEB__) + #define MY_CPU_ARM + #define MY_CPU_NAME "arm" + #define MY_CPU_32BIT +#endif + + +#if defined(_M_IA64) \ + || defined(__ia64__) + #define MY_CPU_IA64 + #define MY_CPU_NAME "ia64" + #define MY_CPU_64BIT +#endif + + +#if defined(__mips64) \ + || defined(__mips64__) \ + || (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3)) + #define MY_CPU_NAME "mips64" + #define MY_CPU_64BIT +#elif defined(__mips__) + #define MY_CPU_NAME "mips" + /* #define MY_CPU_32BIT */ +#endif + + +#if defined(__ppc64__) \ + || defined(__powerpc64__) + #ifdef __ILP32__ + #define MY_CPU_NAME "ppc64-32" + #else + #define MY_CPU_NAME "ppc64" + #endif + #define MY_CPU_64BIT +#elif defined(__ppc__) \ + || defined(__powerpc__) + #define MY_CPU_NAME "ppc" + #define MY_CPU_32BIT +#endif + + +#if defined(__sparc64__) + #define MY_CPU_NAME "sparc64" + #define MY_CPU_64BIT +#elif defined(__sparc__) + #define MY_CPU_NAME "sparc" + /* #define MY_CPU_32BIT */ +#endif + + #if defined(MY_CPU_X86) || defined(MY_CPU_AMD64) #define MY_CPU_X86_OR_AMD64 #endif -#if defined(MY_CPU_X86) \ - || defined(_M_ARM) \ - || defined(__ARMEL__) \ - || defined(__THUMBEL__) \ - || defined(__ARMEB__) \ - || defined(__THUMBEB__) - #define MY_CPU_32BIT + +#ifdef _WIN32 + + #ifdef MY_CPU_ARM + #define MY_CPU_ARM_LE + #endif + + #ifdef MY_CPU_ARM64 + #define MY_CPU_ARM64_LE + #endif + + #ifdef _M_IA64 + #define MY_CPU_IA64_LE + #endif + #endif -#if defined(_WIN32) && defined(_M_ARM) -#define MY_CPU_ARM_LE -#endif - -#if defined(_WIN32) && defined(_M_IA64) -#define MY_CPU_IA64_LE -#endif #if defined(MY_CPU_X86_OR_AMD64) \ || defined(MY_CPU_ARM_LE) \ + || defined(MY_CPU_ARM64_LE) \ || defined(MY_CPU_IA64_LE) \ || defined(__LITTLE_ENDIAN__) \ || defined(__ARMEL__) \ @@ -66,6 +140,7 @@ MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned mem || defined(__MIPSEL__) \ || defined(__MIPSEL) \ || defined(_MIPSEL) \ + || defined(__BFIN__) \ || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) #define MY_CPU_LE #endif @@ -85,14 +160,37 @@ MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned mem #define MY_CPU_BE #endif + #if defined(MY_CPU_LE) && defined(MY_CPU_BE) -Stop_Compiling_Bad_Endian + #error Stop_Compiling_Bad_Endian #endif +#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT) + #error Stop_Compiling_Bad_32_64_BIT +#endif + + +#ifndef MY_CPU_NAME + #ifdef MY_CPU_LE + #define MY_CPU_NAME "LE" + #elif MY_CPU_BE + #define MY_CPU_NAME "BE" + #else + /* + #define MY_CPU_NAME "" + */ + #endif +#endif + + + + + #ifdef MY_CPU_LE #if defined(MY_CPU_X86_OR_AMD64) \ - /* || defined(__AARCH64EL__) */ + || defined(MY_CPU_ARM64) \ + || defined(__ARM_FEATURE_UNALIGNED) #define MY_CPU_LE_UNALIGN #endif #endif @@ -138,6 +236,11 @@ Stop_Compiling_Bad_Endian #endif +#ifdef __has_builtin + #define MY__has_builtin(x) __has_builtin(x) +#else + #define MY__has_builtin(x) 0 +#endif #if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300) @@ -145,15 +248,21 @@ Stop_Compiling_Bad_Endian #include +#pragma intrinsic(_byteswap_ushort) #pragma intrinsic(_byteswap_ulong) #pragma intrinsic(_byteswap_uint64) + +/* #define GetBe16(p) _byteswap_ushort(*(const UInt16 *)(const Byte *)(p)) */ #define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p)) #define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p)) #define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v) -#elif defined(MY_CPU_LE_UNALIGN) && defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) +#elif defined(MY_CPU_LE_UNALIGN) && ( \ + (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \ + || (defined(__clang__) && MY__has_builtin(__builtin_bswap16)) ) +/* #define GetBe16(p) __builtin_bswap16(*(const UInt16 *)(const Byte *)(p)) */ #define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p)) #define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p)) @@ -178,10 +287,14 @@ Stop_Compiling_Bad_Endian #endif +#ifndef GetBe16 + #define GetBe16(p) ( (UInt16) ( \ ((UInt16)((const Byte *)(p))[0] << 8) | \ ((const Byte *)(p))[1] )) +#endif + #ifdef MY_CPU_X86_OR_AMD64 diff --git a/lzma/C/LzFind.c b/lzma/C/LzFind.c index 2d05fa3953..18ef49dca7 100644 --- a/lzma/C/LzFind.c +++ b/lzma/C/LzFind.c @@ -1,5 +1,5 @@ /* LzFind.c -- Match finder for LZ algorithms -2015-10-15 : Igor Pavlov : Public domain */ +2017-06-10 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -16,18 +16,18 @@ #define kStartMaxLen 3 -static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) +static void LzInWindow_Free(CMatchFinder *p, ISzAllocPtr alloc) { if (!p->directInput) { - alloc->Free(alloc, p->bufferBase); + ISzAlloc_Free(alloc, p->bufferBase); p->bufferBase = NULL; } } /* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */ -static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) +static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAllocPtr alloc) { UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; if (p->directInput) @@ -39,7 +39,7 @@ static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *a { LzInWindow_Free(p, alloc); p->blockSize = blockSize; - p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize); + p->bufferBase = (Byte *)ISzAlloc_Alloc(alloc, (size_t)blockSize); } return (p->bufferBase != NULL); } @@ -81,7 +81,7 @@ static void MatchFinder_ReadBlock(CMatchFinder *p) if (size == 0) return; - p->result = p->stream->Read(p->stream, dest, &size); + p->result = ISeqInStream_Read(p->stream, dest, &size); if (p->result != SZ_OK) return; if (size == 0) @@ -142,6 +142,7 @@ void MatchFinder_Construct(CMatchFinder *p) p->bufferBase = NULL; p->directInput = 0; p->hash = NULL; + p->expectedDataSize = (UInt64)(Int64)-1; MatchFinder_SetDefaultSettings(p); for (i = 0; i < 256; i++) @@ -149,34 +150,34 @@ void MatchFinder_Construct(CMatchFinder *p) UInt32 r = i; unsigned j; for (j = 0; j < 8; j++) - r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); + r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1))); p->crc[i] = r; } } -static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) +static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAllocPtr alloc) { - alloc->Free(alloc, p->hash); + ISzAlloc_Free(alloc, p->hash); p->hash = NULL; } -void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) +void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc) { MatchFinder_FreeThisClassMemory(p, alloc); LzInWindow_Free(p, alloc); } -static CLzRef* AllocRefs(size_t num, ISzAlloc *alloc) +static CLzRef* AllocRefs(size_t num, ISzAllocPtr alloc) { size_t sizeInBytes = (size_t)num * sizeof(CLzRef); if (sizeInBytes / sizeof(CLzRef) != num) return NULL; - return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); + return (CLzRef *)ISzAlloc_Alloc(alloc, sizeInBytes); } int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, - ISzAlloc *alloc) + ISzAllocPtr alloc) { UInt32 sizeReserv; @@ -208,7 +209,11 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, hs = (1 << 16) - 1; else { - hs = historySize - 1; + hs = historySize; + if (hs > p->expectedDataSize) + hs = (UInt32)p->expectedDataSize; + if (hs != 0) + hs--; hs |= (hs >> 1); hs |= (hs >> 2); hs |= (hs >> 4); @@ -292,17 +297,33 @@ static void MatchFinder_SetLimits(CMatchFinder *p) p->posLimit = p->pos + limit; } -void MatchFinder_Init_2(CMatchFinder *p, int readData) + +void MatchFinder_Init_LowHash(CMatchFinder *p) +{ + size_t i; + CLzRef *items = p->hash; + size_t numItems = p->fixedHashSize; + for (i = 0; i < numItems; i++) + items[i] = kEmptyHashValue; +} + + +void MatchFinder_Init_HighHash(CMatchFinder *p) +{ + size_t i; + CLzRef *items = p->hash + p->fixedHashSize; + size_t numItems = (size_t)p->hashMask + 1; + for (i = 0; i < numItems; i++) + items[i] = kEmptyHashValue; +} + + +void MatchFinder_Init_3(CMatchFinder *p, int readData) { - UInt32 i; - UInt32 *hash = p->hash; - UInt32 num = p->hashSizeSum; - for (i = 0; i < num; i++) - hash[i] = kEmptyHashValue; - p->cyclicBufferPos = 0; p->buffer = p->bufferBase; - p->pos = p->streamPos = p->cyclicBufferSize; + p->pos = + p->streamPos = p->cyclicBufferSize; p->result = SZ_OK; p->streamEndWasReached = 0; @@ -312,10 +333,14 @@ void MatchFinder_Init_2(CMatchFinder *p, int readData) MatchFinder_SetLimits(p); } + void MatchFinder_Init(CMatchFinder *p) { - MatchFinder_Init_2(p, True); + MatchFinder_Init_HighHash(p); + MatchFinder_Init_LowHash(p); + MatchFinder_Init_3(p, True); } + static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) { @@ -558,10 +583,10 @@ static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) d2 = pos - hash[h2]; - curMatch = hash[kFix3HashSize + hv]; + curMatch = (hash + kFix3HashSize)[hv]; hash[h2] = pos; - hash[kFix3HashSize + hv] = pos; + (hash + kFix3HashSize)[hv] = pos; maxLen = 2; offset = 0; @@ -594,13 +619,13 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) pos = p->pos; d2 = pos - hash[ h2]; - d3 = pos - hash[kFix3HashSize + h3]; + d3 = pos - (hash + kFix3HashSize)[h3]; - curMatch = hash[kFix4HashSize + hv]; + curMatch = (hash + kFix4HashSize)[hv]; hash[ h2] = pos; - hash[kFix3HashSize + h3] = pos; - hash[kFix4HashSize + hv] = pos; + (hash + kFix3HashSize)[h3] = pos; + (hash + kFix4HashSize)[hv] = pos; maxLen = 0; offset = 0; @@ -615,7 +640,7 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur) { maxLen = 3; - distances[offset + 1] = d3 - 1; + distances[(size_t)offset + 1] = d3 - 1; offset += 2; d2 = d3; } @@ -623,7 +648,7 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) if (offset != 0) { UPDATE_maxLen - distances[offset - 2] = maxLen; + distances[(size_t)offset - 2] = maxLen; if (maxLen == lenLimit) { SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); @@ -650,15 +675,15 @@ static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) pos = p->pos; d2 = pos - hash[ h2]; - d3 = pos - hash[kFix3HashSize + h3]; - d4 = pos - hash[kFix4HashSize + h4]; + d3 = pos - (hash + kFix3HashSize)[h3]; + d4 = pos - (hash + kFix4HashSize)[h4]; - curMatch = hash[kFix5HashSize + hv]; + curMatch = (hash + kFix5HashSize)[hv]; hash[ h2] = pos; - hash[kFix3HashSize + h3] = pos; - hash[kFix4HashSize + h4] = pos; - hash[kFix5HashSize + hv] = pos; + (hash + kFix3HashSize)[h3] = pos; + (hash + kFix4HashSize)[h4] = pos; + (hash + kFix5HashSize)[hv] = pos; maxLen = 0; offset = 0; @@ -691,7 +716,7 @@ static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) && *(cur - d4 + 3) == *(cur + 3)) { maxLen = 4; - distances[offset + 1] = d4 - 1; + distances[(size_t)offset + 1] = d4 - 1; offset += 2; d2 = d4; } @@ -699,7 +724,7 @@ static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) if (offset != 0) { UPDATE_maxLen - distances[offset - 2] = maxLen; + distances[(size_t)offset - 2] = maxLen; if (maxLen == lenLimit) { SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); @@ -726,13 +751,13 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) pos = p->pos; d2 = pos - hash[ h2]; - d3 = pos - hash[kFix3HashSize + h3]; + d3 = pos - (hash + kFix3HashSize)[h3]; - curMatch = hash[kFix4HashSize + hv]; + curMatch = (hash + kFix4HashSize)[hv]; hash[ h2] = pos; - hash[kFix3HashSize + h3] = pos; - hash[kFix4HashSize + hv] = pos; + (hash + kFix3HashSize)[h3] = pos; + (hash + kFix4HashSize)[hv] = pos; maxLen = 0; offset = 0; @@ -747,7 +772,7 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur) { maxLen = 3; - distances[offset + 1] = d3 - 1; + distances[(size_t)offset + 1] = d3 - 1; offset += 2; d2 = d3; } @@ -755,7 +780,7 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) if (offset != 0) { UPDATE_maxLen - distances[offset - 2] = maxLen; + distances[(size_t)offset - 2] = maxLen; if (maxLen == lenLimit) { p->son[p->cyclicBufferPos] = curMatch; @@ -784,15 +809,15 @@ static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) pos = p->pos; d2 = pos - hash[ h2]; - d3 = pos - hash[kFix3HashSize + h3]; - d4 = pos - hash[kFix4HashSize + h4]; + d3 = pos - (hash + kFix3HashSize)[h3]; + d4 = pos - (hash + kFix4HashSize)[h4]; - curMatch = hash[kFix5HashSize + hv]; + curMatch = (hash + kFix5HashSize)[hv]; hash[ h2] = pos; - hash[kFix3HashSize + h3] = pos; - hash[kFix4HashSize + h4] = pos; - hash[kFix5HashSize + hv] = pos; + (hash + kFix3HashSize)[h3] = pos; + (hash + kFix4HashSize)[h4] = pos; + (hash + kFix5HashSize)[hv] = pos; maxLen = 0; offset = 0; @@ -825,7 +850,7 @@ static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) && *(cur - d4 + 3) == *(cur + 3)) { maxLen = 4; - distances[offset + 1] = d4 - 1; + distances[(size_t)offset + 1] = d4 - 1; offset += 2; d2 = d4; } @@ -833,7 +858,7 @@ static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) if (offset != 0) { UPDATE_maxLen - distances[offset - 2] = maxLen; + distances[(size_t)offset - 2] = maxLen; if (maxLen == lenLimit) { p->son[p->cyclicBufferPos] = curMatch; @@ -897,9 +922,9 @@ static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) SKIP_HEADER(3) HASH3_CALC; hash = p->hash; - curMatch = hash[kFix3HashSize + hv]; + curMatch = (hash + kFix3HashSize)[hv]; hash[h2] = - hash[kFix3HashSize + hv] = p->pos; + (hash + kFix3HashSize)[hv] = p->pos; SKIP_FOOTER } while (--num != 0); @@ -914,10 +939,10 @@ static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) SKIP_HEADER(4) HASH4_CALC; hash = p->hash; - curMatch = hash[kFix4HashSize + hv]; + curMatch = (hash + kFix4HashSize)[hv]; hash[ h2] = - hash[kFix3HashSize + h3] = - hash[kFix4HashSize + hv] = p->pos; + (hash + kFix3HashSize)[h3] = + (hash + kFix4HashSize)[hv] = p->pos; SKIP_FOOTER } while (--num != 0); @@ -933,11 +958,11 @@ static void Bt5_MatchFinder_Skip(CMatchFinder *p, UInt32 num) SKIP_HEADER(5) HASH5_CALC; hash = p->hash; - curMatch = hash[kFix5HashSize + hv]; + curMatch = (hash + kFix5HashSize)[hv]; hash[ h2] = - hash[kFix3HashSize + h3] = - hash[kFix4HashSize + h4] = - hash[kFix5HashSize + hv] = p->pos; + (hash + kFix3HashSize)[h3] = + (hash + kFix4HashSize)[h4] = + (hash + kFix5HashSize)[hv] = p->pos; SKIP_FOOTER } while (--num != 0); @@ -953,10 +978,10 @@ static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) SKIP_HEADER(4) HASH4_CALC; hash = p->hash; - curMatch = hash[kFix4HashSize + hv]; + curMatch = (hash + kFix4HashSize)[hv]; hash[ h2] = - hash[kFix3HashSize + h3] = - hash[kFix4HashSize + hv] = p->pos; + (hash + kFix3HashSize)[h3] = + (hash + kFix4HashSize)[hv] = p->pos; p->son[p->cyclicBufferPos] = curMatch; MOVE_POS } @@ -973,11 +998,11 @@ static void Hc5_MatchFinder_Skip(CMatchFinder *p, UInt32 num) SKIP_HEADER(5) HASH5_CALC; hash = p->hash; - curMatch = p->hash[kFix5HashSize + hv]; + curMatch = hash + kFix5HashSize)[hv]; hash[ h2] = - hash[kFix3HashSize + h3] = - hash[kFix4HashSize + h4] = - hash[kFix5HashSize + hv] = p->pos; + (hash + kFix3HashSize)[h3] = + (hash + kFix4HashSize)[h4] = + (hash + kFix5HashSize)[hv] = p->pos; p->son[p->cyclicBufferPos] = curMatch; MOVE_POS } diff --git a/lzma/C/LzFind.h b/lzma/C/LzFind.h index d119944f44..42c13be157 100644 --- a/lzma/C/LzFind.h +++ b/lzma/C/LzFind.h @@ -1,5 +1,5 @@ /* LzFind.h -- Match finder for LZ algorithms -2015-10-15 : Igor Pavlov : Public domain */ +2017-06-10 : Igor Pavlov : Public domain */ #ifndef __LZ_FIND_H #define __LZ_FIND_H @@ -47,6 +47,8 @@ typedef struct _CMatchFinder SRes result; UInt32 crc[256]; size_t numRefs; + + UInt64 expectedDataSize; } CMatchFinder; #define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) @@ -71,8 +73,8 @@ void MatchFinder_Construct(CMatchFinder *p); */ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, - ISzAlloc *alloc); -void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); + ISzAllocPtr alloc); +void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc); void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems); void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); @@ -103,7 +105,9 @@ typedef struct _IMatchFinder void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); -void MatchFinder_Init_2(CMatchFinder *p, int readData); +void MatchFinder_Init_LowHash(CMatchFinder *p); +void MatchFinder_Init_HighHash(CMatchFinder *p); +void MatchFinder_Init_3(CMatchFinder *p, int readData); void MatchFinder_Init(CMatchFinder *p); UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); diff --git a/lzma/C/LzFindMt.c b/lzma/C/LzFindMt.c index a4ffa5ef9c..65c9ffd73b 100644 --- a/lzma/C/LzFindMt.c +++ b/lzma/C/LzFindMt.c @@ -1,5 +1,5 @@ /* LzFindMt.c -- multithreaded Match finder for LZ algorithms -2015-10-15 : Igor Pavlov : Public domain */ +2017-06-10 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -33,6 +33,8 @@ static void MtSync_GetNextBlock(CMtSync *p) Event_Set(&p->canStart); Event_Wait(&p->wasStarted); + + // if (mt) MatchFinder_Init_LowHash(mt->MatchFinder); } else { @@ -155,6 +157,9 @@ static void HashThreadFunc(CMatchFinderMt *mt) UInt32 numProcessedBlocks = 0; Event_Wait(&p->canStart); Event_Set(&p->wasStarted); + + MatchFinder_Init_HighHash(mt->MatchFinder); + for (;;) { if (p->exit) @@ -205,7 +210,7 @@ static void HashThreadFunc(CMatchFinderMt *mt) if (num > kMtHashBlockSize - 2) num = kMtHashBlockSize - 2; mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num, mf->crc); - heads[0] += num; + heads[0] = 2 + num; } mf->pos += num; mf->buffer += num; @@ -443,13 +448,13 @@ void MatchFinderMt_Construct(CMatchFinderMt *p) MtSync_Construct(&p->btSync); } -static void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc) +static void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAllocPtr alloc) { - alloc->Free(alloc, p->hashBuf); + ISzAlloc_Free(alloc, p->hashBuf); p->hashBuf = NULL; } -void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc) +void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAllocPtr alloc) { MtSync_Destruct(&p->hashSync); MtSync_Destruct(&p->btSync); @@ -472,7 +477,7 @@ static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE BtThreadFunc2(void *p) } SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore, - UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc) + UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc) { CMatchFinder *mf = p->MatchFinder; p->historySize = historySize; @@ -480,7 +485,7 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB return SZ_ERROR_PARAM; if (!p->hashBuf) { - p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32)); + p->hashBuf = (UInt32 *)ISzAlloc_Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32)); if (!p->hashBuf) return SZ_ERROR_MEM; p->btBuf = p->hashBuf + kHashBufferSize; @@ -496,14 +501,18 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB } /* Call it after ReleaseStream / SetStream */ -void MatchFinderMt_Init(CMatchFinderMt *p) +static void MatchFinderMt_Init(CMatchFinderMt *p) { CMatchFinder *mf = p->MatchFinder; - p->btBufPos = p->btBufPosLimit = 0; - p->hashBufPos = p->hashBufPosLimit = 0; + + p->btBufPos = + p->btBufPosLimit = 0; + p->hashBufPos = + p->hashBufPosLimit = 0; /* Init without data reading. We don't want to read data in this thread */ - MatchFinder_Init_2(mf, False); + MatchFinder_Init_3(mf, False); + MatchFinder_Init_LowHash(mf); p->pointerToCurPos = Inline_MatchFinder_GetPointerToCurrentPos(mf); p->btNumAvailBytes = 0; @@ -591,10 +600,10 @@ static UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *dista MT_HASH3_CALC curMatch2 = hash[ h2]; - curMatch3 = hash[kFix3HashSize + h3]; + curMatch3 = (hash + kFix3HashSize)[h3]; hash[ h2] = lzPos; - hash[kFix3HashSize + h3] = lzPos; + (hash + kFix3HashSize)[h3] = lzPos; if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0]) { @@ -627,12 +636,12 @@ static UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distan MT_HASH4_CALC curMatch2 = hash[ h2]; - curMatch3 = hash[kFix3HashSize + h3]; - curMatch4 = hash[kFix4HashSize + h4]; + curMatch3 = (hash + kFix3HashSize)[h3]; + curMatch4 = (hash + kFix4HashSize)[h4]; hash[ h2] = lzPos; - hash[kFix3HashSize + h3] = lzPos; - hash[kFix4HashSize + h4] = lzPos; + (hash + kFix3HashSize)[h3] = lzPos; + (hash + kFix4HashSize)[h4] = lzPos; if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0]) { @@ -684,8 +693,12 @@ static UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances) UInt32 i; for (i = 0; i < len; i += 2) { - *distances++ = *btBuf++; - *distances++ = *btBuf++; + UInt32 v0 = btBuf[0]; + UInt32 v1 = btBuf[1]; + btBuf += 2; + distances[0] = v0; + distances[1] = v1; + distances += 2; } } INCREASE_LZ_POS @@ -712,8 +725,12 @@ static UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances) distances2 = p->MixMatchesFunc(p, p->lzPos - btBuf[1], distances); do { - *distances2++ = *btBuf++; - *distances2++ = *btBuf++; + UInt32 v0 = btBuf[0]; + UInt32 v1 = btBuf[1]; + btBuf += 2; + distances2[0] = v0; + distances2[1] = v1; + distances2 += 2; } while ((len -= 2) != 0); len = (UInt32)(distances2 - (distances)); @@ -746,7 +763,7 @@ static void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num) SKIP_HEADER_MT(3) UInt32 h2, h3; MT_HASH3_CALC - hash[kFix3HashSize + h3] = + (hash + kFix3HashSize)[h3] = hash[ h2] = p->lzPos; SKIP_FOOTER_MT @@ -758,8 +775,8 @@ static void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num) SKIP_HEADER_MT(4) UInt32 h2, h3, h4; MT_HASH4_CALC - hash[kFix4HashSize + h4] = - hash[kFix3HashSize + h3] = + (hash + kFix4HashSize)[h4] = + (hash + kFix3HashSize)[h3] = hash[ h2] = p->lzPos; SKIP_FOOTER_MT @@ -777,7 +794,7 @@ void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable) { case 2: p->GetHeadsFunc = GetHeads2; - p->MixMatchesFunc = (Mf_Mix_Matches)0; + p->MixMatchesFunc = (Mf_Mix_Matches)NULL; vTable->Skip = (Mf_Skip_Func)MatchFinderMt0_Skip; vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt2_GetMatches; break; diff --git a/lzma/C/LzFindMt.h b/lzma/C/LzFindMt.h index 89b91fefd6..a6645f53cd 100644 --- a/lzma/C/LzFindMt.h +++ b/lzma/C/LzFindMt.h @@ -1,5 +1,5 @@ /* LzFindMt.h -- multithreaded Match finder for LZ algorithms -2015-05-03 : Igor Pavlov : Public domain */ +2017-04-03 : Igor Pavlov : Public domain */ #ifndef __LZ_FIND_MT_H #define __LZ_FIND_MT_H @@ -90,9 +90,9 @@ typedef struct _CMatchFinderMt } CMatchFinderMt; void MatchFinderMt_Construct(CMatchFinderMt *p); -void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc); +void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAllocPtr alloc); SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore, - UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc); + UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc); void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable); void MatchFinderMt_ReleaseStream(CMatchFinderMt *p); diff --git a/lzma/C/Lzma2Dec.c b/lzma/C/Lzma2Dec.c index b84f88a481..63853c6dfe 100644 --- a/lzma/C/Lzma2Dec.c +++ b/lzma/C/Lzma2Dec.c @@ -1,5 +1,5 @@ /* Lzma2Dec.c -- LZMA2 Decoder -2015-11-09 : Igor Pavlov : Public domain */ +2017-04-03 : Igor Pavlov : Public domain */ /* #define SHOW_DEBUG_INFO */ @@ -74,14 +74,14 @@ static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props) return SZ_OK; } -SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc) +SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc) { Byte props[LZMA_PROPS_SIZE]; RINOK(Lzma2Dec_GetOldProps(prop, props)); return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc); } -SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc) +SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc) { Byte props[LZMA_PROPS_SIZE]; RINOK(Lzma2Dec_GetOldProps(prop, props)); @@ -105,16 +105,16 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b) p->control = b; PRF(printf("\n %4X ", (unsigned)p->decoder.dicPos)); PRF(printf(" %2X", (unsigned)b)); - if (p->control == 0) + if (b == 0) return LZMA2_STATE_FINISHED; if (LZMA2_IS_UNCOMPRESSED_STATE(p)) { - if ((p->control & 0x7F) > 2) + if (b > 2) return LZMA2_STATE_ERROR; p->unpackSize = 0; } else - p->unpackSize = (UInt32)(p->control & 0x1F) << 16; + p->unpackSize = (UInt32)(b & 0x1F) << 16; return LZMA2_STATE_UNPACK0; case LZMA2_STATE_UNPACK0: @@ -169,6 +169,7 @@ static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT s void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState); + SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) { @@ -176,12 +177,17 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, *srcLen = 0; *status = LZMA_STATUS_NOT_SPECIFIED; - while (p->state != LZMA2_STATE_FINISHED) + while (p->state != LZMA2_STATE_ERROR) { - SizeT dicPos = p->decoder.dicPos; + SizeT dicPos; + + if (p->state == LZMA2_STATE_FINISHED) + { + *status = LZMA_STATUS_FINISHED_WITH_MARK; + return SZ_OK; + } - if (p->state == LZMA2_STATE_ERROR) - return SZ_ERROR_DATA; + dicPos = p->decoder.dicPos; if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY) { @@ -198,29 +204,25 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, } (*srcLen)++; p->state = Lzma2Dec_UpdateState(p, *src++); - if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED) - { - p->state = LZMA2_STATE_ERROR; - return SZ_ERROR_DATA; - } + break; continue; } { - SizeT destSizeCur = dicLimit - dicPos; - SizeT srcSizeCur = inSize - *srcLen; + SizeT inCur = inSize - *srcLen; + SizeT outCur = dicLimit - dicPos; ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY; - if (p->unpackSize <= destSizeCur) + if (outCur >= p->unpackSize) { - destSizeCur = (SizeT)p->unpackSize; + outCur = (SizeT)p->unpackSize; curFinishMode = LZMA_FINISH_END; } if (LZMA2_IS_UNCOMPRESSED_STATE(p)) { - if (*srcLen == inSize) + if (inCur == 0) { *status = LZMA_STATUS_NEEDS_MORE_INPUT; return SZ_OK; @@ -232,33 +234,25 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, if (initDic) p->needInitProp = p->needInitState = True; else if (p->needInitDic) - { - p->state = LZMA2_STATE_ERROR; - return SZ_ERROR_DATA; - } + break; p->needInitDic = False; LzmaDec_InitDicAndState(&p->decoder, initDic, False); } - if (srcSizeCur > destSizeCur) - srcSizeCur = destSizeCur; + if (inCur > outCur) + inCur = outCur; + if (inCur == 0) + break; - if (srcSizeCur == 0) - { - p->state = LZMA2_STATE_ERROR; - return SZ_ERROR_DATA; - } + LzmaDec_UpdateWithUncompressed(&p->decoder, src, inCur); - LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur); - - src += srcSizeCur; - *srcLen += srcSizeCur; - p->unpackSize -= (UInt32)srcSizeCur; + src += inCur; + *srcLen += inCur; + p->unpackSize -= (UInt32)inCur; p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT; } else { - SizeT outSizeProcessed; SRes res; if (p->state == LZMA2_STATE_DATA) @@ -267,96 +261,98 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, Bool initDic = (mode == 3); Bool initState = (mode != 0); if ((!initDic && p->needInitDic) || (!initState && p->needInitState)) - { - p->state = LZMA2_STATE_ERROR; - return SZ_ERROR_DATA; - } - + break; + LzmaDec_InitDicAndState(&p->decoder, initDic, initState); p->needInitDic = False; p->needInitState = False; p->state = LZMA2_STATE_DATA_CONT; } - if (srcSizeCur > p->packSize) - srcSizeCur = (SizeT)p->packSize; + if (inCur > p->packSize) + inCur = (SizeT)p->packSize; - res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status); + res = LzmaDec_DecodeToDic(&p->decoder, dicPos + outCur, src, &inCur, curFinishMode, status); - src += srcSizeCur; - *srcLen += srcSizeCur; - p->packSize -= (UInt32)srcSizeCur; + src += inCur; + *srcLen += inCur; + p->packSize -= (UInt32)inCur; + outCur = p->decoder.dicPos - dicPos; + p->unpackSize -= (UInt32)outCur; - outSizeProcessed = p->decoder.dicPos - dicPos; - p->unpackSize -= (UInt32)outSizeProcessed; - - RINOK(res); + if (res != 0) + break; + if (*status == LZMA_STATUS_NEEDS_MORE_INPUT) - return res; + { + if (p->packSize == 0) + break; + return SZ_OK; + } - if (srcSizeCur == 0 && outSizeProcessed == 0) + if (inCur == 0 && outCur == 0) { if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK || p->unpackSize != 0 || p->packSize != 0) - { - p->state = LZMA2_STATE_ERROR; - return SZ_ERROR_DATA; - } + break; p->state = LZMA2_STATE_CONTROL; } - if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) - *status = LZMA_STATUS_NOT_FINISHED; + *status = LZMA_STATUS_NOT_SPECIFIED; } } } - *status = LZMA_STATUS_FINISHED_WITH_MARK; - return SZ_OK; + *status = LZMA_STATUS_NOT_SPECIFIED; + p->state = LZMA2_STATE_ERROR; + return SZ_ERROR_DATA; } + SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) { SizeT outSize = *destLen, inSize = *srcLen; *srcLen = *destLen = 0; + for (;;) { - SizeT srcSizeCur = inSize, outSizeCur, dicPos; + SizeT inCur = inSize, outCur, dicPos; ELzmaFinishMode curFinishMode; SRes res; + if (p->decoder.dicPos == p->decoder.dicBufSize) p->decoder.dicPos = 0; dicPos = p->decoder.dicPos; - if (outSize > p->decoder.dicBufSize - dicPos) + curFinishMode = LZMA_FINISH_ANY; + outCur = p->decoder.dicBufSize - dicPos; + + if (outCur >= outSize) { - outSizeCur = p->decoder.dicBufSize; - curFinishMode = LZMA_FINISH_ANY; - } - else - { - outSizeCur = dicPos + outSize; + outCur = outSize; curFinishMode = finishMode; } - res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status); - src += srcSizeCur; - inSize -= srcSizeCur; - *srcLen += srcSizeCur; - outSizeCur = p->decoder.dicPos - dicPos; - memcpy(dest, p->decoder.dic + dicPos, outSizeCur); - dest += outSizeCur; - outSize -= outSizeCur; - *destLen += outSizeCur; + res = Lzma2Dec_DecodeToDic(p, dicPos + outCur, src, &inCur, curFinishMode, status); + + src += inCur; + inSize -= inCur; + *srcLen += inCur; + outCur = p->decoder.dicPos - dicPos; + memcpy(dest, p->decoder.dic + dicPos, outCur); + dest += outCur; + outSize -= outCur; + *destLen += outCur; if (res != 0) return res; - if (outSizeCur == 0 || outSize == 0) + if (outCur == 0 || outSize == 0) return SZ_OK; } } + SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, - Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc) + Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc) { CLzma2Dec p; SRes res; diff --git a/lzma/C/Lzma2Dec.h b/lzma/C/Lzma2Dec.h index e6a0f6ed6d..917af990dd 100644 --- a/lzma/C/Lzma2Dec.h +++ b/lzma/C/Lzma2Dec.h @@ -1,5 +1,5 @@ /* Lzma2Dec.h -- LZMA2 Decoder -2015-05-13 : Igor Pavlov : Public domain */ +2017-04-03 : Igor Pavlov : Public domain */ #ifndef __LZMA2_DEC_H #define __LZMA2_DEC_H @@ -26,8 +26,8 @@ typedef struct #define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc); #define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc); -SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc); -SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc); +SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc); +SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc); void Lzma2Dec_Init(CLzma2Dec *p); @@ -73,7 +73,7 @@ Returns: */ SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, - Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc); + Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc); EXTERN_C_END diff --git a/lzma/C/LzmaDec.c b/lzma/C/LzmaDec.c index 27efbaba90..e96fa975bd 100644 --- a/lzma/C/LzmaDec.c +++ b/lzma/C/LzmaDec.c @@ -1,5 +1,5 @@ /* LzmaDec.c -- LZMA Decoder -2015-06-23 : Igor Pavlov : Public domain */ +2017-04-03 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -294,14 +294,14 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte #ifdef _LZMA_SIZE_OPT { - unsigned limit, offset; + unsigned lim, offset; CLzmaProb *probLen = prob + LenChoice; IF_BIT_0(probLen) { UPDATE_0(probLen); probLen = prob + LenLow + (posState << kLenNumLowBits); offset = 0; - limit = (1 << kLenNumLowBits); + lim = (1 << kLenNumLowBits); } else { @@ -312,17 +312,17 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte UPDATE_0(probLen); probLen = prob + LenMid + (posState << kLenNumMidBits); offset = kLenNumLowSymbols; - limit = (1 << kLenNumMidBits); + lim = (1 << kLenNumMidBits); } else { UPDATE_1(probLen); probLen = prob + LenHigh; offset = kLenNumLowSymbols + kLenNumMidSymbols; - limit = (1 << kLenNumHighBits); + lim = (1 << kLenNumHighBits); } } - TREE_DECODE(probLen, limit, len); + TREE_DECODE(probLen, lim, len); len += offset; } #else @@ -975,19 +975,19 @@ SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *sr } } -void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) +void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc) { - alloc->Free(alloc, p->probs); + ISzAlloc_Free(alloc, p->probs); p->probs = NULL; } -static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) +static void LzmaDec_FreeDict(CLzmaDec *p, ISzAllocPtr alloc) { - alloc->Free(alloc, p->dic); + ISzAlloc_Free(alloc, p->dic); p->dic = NULL; } -void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) +void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc) { LzmaDec_FreeProbs(p, alloc); LzmaDec_FreeDict(p, alloc); @@ -1019,13 +1019,13 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) return SZ_OK; } -static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) +static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAllocPtr alloc) { UInt32 numProbs = LzmaProps_GetNumProbs(propNew); if (!p->probs || numProbs != p->numProbs) { LzmaDec_FreeProbs(p, alloc); - p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); + p->probs = (CLzmaProb *)ISzAlloc_Alloc(alloc, numProbs * sizeof(CLzmaProb)); p->numProbs = numProbs; if (!p->probs) return SZ_ERROR_MEM; @@ -1033,7 +1033,7 @@ static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAl return SZ_OK; } -SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) +SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc) { CLzmaProps propNew; RINOK(LzmaProps_Decode(&propNew, props, propsSize)); @@ -1042,7 +1042,7 @@ SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, I return SZ_OK; } -SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) +SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc) { CLzmaProps propNew; SizeT dicBufSize; @@ -1062,7 +1062,7 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll if (!p->dic || dicBufSize != p->dicBufSize) { LzmaDec_FreeDict(p, alloc); - p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); + p->dic = (Byte *)ISzAlloc_Alloc(alloc, dicBufSize); if (!p->dic) { LzmaDec_FreeProbs(p, alloc); @@ -1076,7 +1076,7 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, - ELzmaStatus *status, ISzAlloc *alloc) + ELzmaStatus *status, ISzAllocPtr alloc) { CLzmaDec p; SRes res; diff --git a/lzma/C/LzmaDec.h b/lzma/C/LzmaDec.h index cc44daef21..d6af922030 100644 --- a/lzma/C/LzmaDec.h +++ b/lzma/C/LzmaDec.h @@ -1,5 +1,5 @@ /* LzmaDec.h -- LZMA Decoder -2013-01-18 : Igor Pavlov : Public domain */ +2017-04-03 : Igor Pavlov : Public domain */ #ifndef __LZMA_DEC_H #define __LZMA_DEC_H @@ -129,11 +129,11 @@ LzmaDec_Allocate* can return: SZ_ERROR_UNSUPPORTED - Unsupported properties */ -SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); -void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); +SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc); +void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc); -SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); -void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); +SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAllocPtr alloc); +void LzmaDec_Free(CLzmaDec *state, ISzAllocPtr alloc); /* ---------- Dictionary Interface ---------- */ @@ -220,7 +220,7 @@ Returns: SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, - ELzmaStatus *status, ISzAlloc *alloc); + ELzmaStatus *status, ISzAllocPtr alloc); EXTERN_C_END diff --git a/lzma/C/LzmaEnc.c b/lzma/C/LzmaEnc.c index 9c164e6f04..9b7e691048 100644 --- a/lzma/C/LzmaEnc.c +++ b/lzma/C/LzmaEnc.c @@ -1,5 +1,5 @@ /* LzmaEnc.c -- LZMA Encoder -2015-11-08 : Igor Pavlov : Public domain */ +2017-06-22 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -23,8 +23,8 @@ static unsigned g_STAT_OFFSET = 0; #endif -#define kMaxHistorySize ((UInt32)3 << 29) -/* #define kMaxHistorySize ((UInt32)7 << 29) */ +#define kLzmaMaxHistorySize ((UInt32)3 << 29) +/* #define kLzmaMaxHistorySize ((UInt32)7 << 29) */ #define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1) @@ -62,14 +62,15 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p) if (level < 0) level = 5; p->level = level; - if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26))); + if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level <= 7 ? (1 << 25) : (1 << 26))); if (p->dictSize > p->reduceSize) { unsigned i; + UInt32 reduceSize = (UInt32)p->reduceSize; for (i = 11; i <= 30; i++) { - if ((UInt32)p->reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; } - if ((UInt32)p->reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; } + if (reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; } + if (reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; } } } @@ -108,7 +109,7 @@ UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) #define kDicLogSizeMaxCompress 32 -#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); } +#define BSR2_RET(pos, res) { unsigned long zz; _BitScanReverse(&zz, (pos)); res = (zz + zz) + ((pos >> (zz - 1)) & 1); } static UInt32 GetPosSlot1(UInt32 pos) { @@ -145,19 +146,19 @@ static void LzmaEnc_FastPosInit(Byte *g_FastPos) /* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */ /* -#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ +#define BSR2_RET(pos, res) { UInt32 zz = 6 + ((kNumLogBits - 1) & \ (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ - res = p->g_FastPos[pos >> i] + (i * 2); } + res = p->g_FastPos[pos >> zz] + (zz * 2); } */ /* -#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ +#define BSR2_RET(pos, res) { UInt32 zz = 6 + ((kNumLogBits - 1) & \ (0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \ - res = p->g_FastPos[pos >> i] + (i * 2); } + res = p->g_FastPos[pos >> zz] + (zz * 2); } */ -#define BSR2_RET(pos, res) { UInt32 i = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \ - res = p->g_FastPos[pos >> i] + (i * 2); } +#define BSR2_RET(pos, res) { UInt32 zz = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \ + res = p->g_FastPos[pos >> zz] + (zz * 2); } /* #define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ @@ -445,7 +446,7 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX || props.dictSize > ((UInt64)1 << kDicLogSizeMaxCompress) - || props.dictSize > kMaxHistorySize) + || props.dictSize > kLzmaMaxHistorySize) return SZ_ERROR_PARAM; p->dictSize = props.dictSize; @@ -492,6 +493,15 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) return SZ_OK; } + +void LzmaEnc_SetDataSize(CLzmaEncHandle pp, UInt64 expectedDataSiize) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + p->matchFinderBase.expectedDataSize = expectedDataSiize; +} + + + static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; @@ -512,11 +522,11 @@ static void RangeEnc_Construct(CRangeEnc *p) #define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize) #define RC_BUF_SIZE (1 << 16) -static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) +static int RangeEnc_Alloc(CRangeEnc *p, ISzAllocPtr alloc) { if (!p->bufBase) { - p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE); + p->bufBase = (Byte *)ISzAlloc_Alloc(alloc, RC_BUF_SIZE); if (!p->bufBase) return 0; p->bufLim = p->bufBase + RC_BUF_SIZE; @@ -524,9 +534,9 @@ static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) return 1; } -static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc) +static void RangeEnc_Free(CRangeEnc *p, ISzAllocPtr alloc) { - alloc->Free(alloc, p->bufBase); + ISzAlloc_Free(alloc, p->bufBase); p->bufBase = 0; } @@ -550,7 +560,7 @@ static void RangeEnc_FlushStream(CRangeEnc *p) if (p->res != SZ_OK) return; num = p->buf - p->bufBase; - if (num != p->outStream->Write(p->outStream, p->bufBase, num)) + if (num != ISeqOutStream_Write(p->outStream, p->bufBase, num)) p->res = SZ_ERROR_WRITE; p->processed += num; p->buf = p->bufBase; @@ -882,7 +892,7 @@ static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes) if (numPairs > 0) { - lenRes = p->matches[numPairs - 2]; + lenRes = p->matches[(size_t)numPairs - 2]; if (lenRes == p->numFastBytes) { UInt32 numAvail = p->numAvail; @@ -891,7 +901,7 @@ static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes) { const Byte *pbyCur = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; const Byte *pby = pbyCur + lenRes; - ptrdiff_t dif = (ptrdiff_t)-1 - p->matches[numPairs - 1]; + ptrdiff_t dif = (ptrdiff_t)-1 - p->matches[(size_t)numPairs - 1]; const Byte *pbyLim = pbyCur + numAvail; for (; pby != pbyLim && *pby == pby[dif]; pby++); lenRes = (UInt32)(pby - pbyCur); @@ -939,7 +949,7 @@ static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState) { - return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] + + return p->repLenEnc.prices[posState][(size_t)len - LZMA_MATCH_LEN_MIN] + GetPureRepPrice(p, repIndex, state, posState); } @@ -956,9 +966,9 @@ static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur) p->opt[posMem].posPrev = posMem - 1; if (p->opt[cur].prev2) { - p->opt[posMem - 1].prev1IsChar = False; - p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2; - p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2; + p->opt[(size_t)posMem - 1].prev1IsChar = False; + p->opt[(size_t)posMem - 1].posPrev = p->opt[cur].posPrev2; + p->opt[(size_t)posMem - 1].backPrev = p->opt[cur].backPrev2; } } { @@ -983,12 +993,17 @@ static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur) static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) { - UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur; - UInt32 matchPrice, repMatchPrice, normalMatchPrice; + UInt32 lenEnd, cur; UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS]; UInt32 *matches; + + { + + UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, len; + UInt32 matchPrice, repMatchPrice, normalMatchPrice; const Byte *data; Byte curByte, matchByte; + if (p->optimumEndIndex != p->optimumCurrentIndex) { const COptimal *opt = &p->opt[p->optimumCurrentIndex]; @@ -1046,7 +1061,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) matches = p->matches; if (mainLen >= p->numFastBytes) { - *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; + *backRes = matches[(size_t)numPairs - 1] + LZMA_NUM_REPS; MovePos(p, mainLen - 1); return mainLen; } @@ -1111,7 +1126,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState); do { - UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2]; + UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][(size_t)repLen - 2]; COptimal *opt = &p->opt[repLen]; if (curAndLenPrice < opt->price) { @@ -1135,9 +1150,9 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) for (; ; len++) { COptimal *opt; - UInt32 distance = matches[offs + 1]; + UInt32 distance = matches[(size_t)offs + 1]; - UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN]; + UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][(size_t)len - LZMA_MATCH_LEN_MIN]; UInt32 lenToPosState = GetLenToPosState(len); if (distance < kNumFullDistances) curAndLenPrice += p->distancesPrices[lenToPosState][distance]; @@ -1176,8 +1191,11 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) } #endif + } + for (;;) { + UInt32 numAvail; UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen; UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice; Bool nextIsChar; @@ -1248,7 +1266,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) UInt32 i; reps[0] = prevOpt->backs[pos]; for (i = 1; i <= pos; i++) - reps[i] = prevOpt->backs[i - 1]; + reps[i] = prevOpt->backs[(size_t)i - 1]; for (; i < LZMA_NUM_REPS; i++) reps[i] = prevOpt->backs[i]; } @@ -1257,7 +1275,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) UInt32 i; reps[0] = (pos - LZMA_NUM_REPS); for (i = 1; i < LZMA_NUM_REPS; i++) - reps[i] = prevOpt->backs[i - 1]; + reps[i] = prevOpt->backs[(size_t)i - 1]; } } curOpt->state = (CState)state; @@ -1284,7 +1302,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) LitEnc_GetPrice(probs, curByte, p->ProbPrices)); } - nextOpt = &p->opt[cur + 1]; + nextOpt = &p->opt[(size_t)cur + 1]; if (curAnd1Price < nextOpt->price) { @@ -1377,7 +1395,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState); do { - UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2]; + UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][(size_t)lenTest - 2]; COptimal *opt = &p->opt[cur + lenTest]; if (curAndLenPrice < opt->price) { @@ -1407,9 +1425,9 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) UInt32 state2 = kRepNextStates[state]; UInt32 posStateNext = (position + lenTest) & p->pbMask; UInt32 curAndLenCharPrice = - price + p->repLenEnc.prices[posState][lenTest - 2] + + price + p->repLenEnc.prices[posState][(size_t)lenTest - 2] + GET_PRICE_0(p->isMatch[state2][posStateNext]) + - LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), + LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[(size_t)lenTest - 1]), data[lenTest], data2[lenTest], p->ProbPrices); state2 = kLiteralNextStates[state2]; posStateNext = (position + lenTest + 1) & p->pbMask; @@ -1460,11 +1478,12 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) offs = 0; while (startLen > matches[offs]) offs += 2; - curBack = matches[offs + 1]; + curBack = matches[(size_t)offs + 1]; GetPosSlot2(curBack, posSlot); for (lenTest = /*2*/ startLen; ; lenTest++) { - UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN]; + UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][(size_t)lenTest - LZMA_MATCH_LEN_MIN]; + { UInt32 lenToPosState = GetLenToPosState(lenTest); COptimal *opt; if (curBack < kNumFullDistances) @@ -1480,6 +1499,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) opt->backPrev = curBack + LZMA_NUM_REPS; opt->prev1IsChar = False; } + } if (/*_maxMode && */lenTest == matches[offs]) { @@ -1498,7 +1518,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) UInt32 posStateNext = (position + lenTest) & p->pbMask; UInt32 curAndLenCharPrice = curAndLenPrice + GET_PRICE_0(p->isMatch[state2][posStateNext]) + - LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), + LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[(size_t)lenTest - 1]), data[lenTest], data2[lenTest], p->ProbPrices); state2 = kLiteralNextStates[state2]; posStateNext = (posStateNext + 1) & p->pbMask; @@ -1509,15 +1529,15 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) /* for (; lenTest2 >= 2; lenTest2--) */ { UInt32 offset = cur + lenTest + 1 + lenTest2; - UInt32 curAndLenPrice; + UInt32 curAndLenPrice2; COptimal *opt; while (lenEnd < offset) p->opt[++lenEnd].price = kInfinityPrice; - curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); + curAndLenPrice2 = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); opt = &p->opt[offset]; - if (curAndLenPrice < opt->price) + if (curAndLenPrice2 < opt->price) { - opt->price = curAndLenPrice; + opt->price = curAndLenPrice2; opt->posPrev = cur + lenTest + 1; opt->backPrev = 0; opt->prev1IsChar = True; @@ -1530,7 +1550,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) offs += 2; if (offs == numPairs) break; - curBack = matches[offs + 1]; + curBack = matches[(size_t)offs + 1]; if (curBack >= kNumFullDistances) GetPosSlot2(curBack, posSlot); } @@ -1587,7 +1607,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) matches = p->matches; if (mainLen >= p->numFastBytes) { - *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; + *backRes = matches[(size_t)numPairs - 1] + LZMA_NUM_REPS; MovePos(p, mainLen - 1); return mainLen; } @@ -1595,14 +1615,14 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) mainDist = 0; /* for GCC */ if (mainLen >= 2) { - mainDist = matches[numPairs - 1]; - while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1) + mainDist = matches[(size_t)numPairs - 1]; + while (numPairs > 2 && mainLen == matches[(size_t)numPairs - 4] + 1) { - if (!ChangePair(matches[numPairs - 3], mainDist)) + if (!ChangePair(matches[(size_t)numPairs - 3], mainDist)) break; numPairs -= 2; - mainLen = matches[numPairs - 2]; - mainDist = matches[numPairs - 1]; + mainLen = matches[(size_t)numPairs - 2]; + mainDist = matches[(size_t)numPairs - 1]; } if (mainLen == 2 && mainDist >= 0x80) mainLen = 1; @@ -1624,7 +1644,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) p->longestMatchLength = ReadMatchDistances(p, &p->numPairs); if (p->longestMatchLength >= 2) { - UInt32 newDistance = matches[p->numPairs - 1]; + UInt32 newDistance = matches[(size_t)p->numPairs - 1]; if ((p->longestMatchLength >= mainLen && newDistance < mainDist) || (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) || (p->longestMatchLength > mainLen + 1) || @@ -1718,7 +1738,6 @@ static void FillDistancesPrices(CLzmaEnc *p) { UInt32 *distancesPrices = p->distancesPrices[lenToPosState]; - UInt32 i; for (i = 0; i < kStartPosModelIndex; i++) distancesPrices[i] = posSlotPrices[i]; for (; i < kNumFullDistances; i++) @@ -1753,24 +1772,24 @@ void LzmaEnc_Construct(CLzmaEnc *p) p->saveState.litProbs = NULL; } -CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc) +CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc) { void *p; - p = alloc->Alloc(alloc, sizeof(CLzmaEnc)); + p = ISzAlloc_Alloc(alloc, sizeof(CLzmaEnc)); if (p) LzmaEnc_Construct((CLzmaEnc *)p); return p; } -void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) +void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAllocPtr alloc) { - alloc->Free(alloc, p->litProbs); - alloc->Free(alloc, p->saveState.litProbs); + ISzAlloc_Free(alloc, p->litProbs); + ISzAlloc_Free(alloc, p->saveState.litProbs); p->litProbs = NULL; p->saveState.litProbs = NULL; } -void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) +void LzmaEnc_Destruct(CLzmaEnc *p, ISzAllocPtr alloc, ISzAllocPtr allocBig) { #ifndef _7ZIP_ST MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); @@ -1781,10 +1800,10 @@ void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) RangeEnc_Free(&p->rc, alloc); } -void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig) +void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig) { LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig); - alloc->Free(alloc, p); + ISzAlloc_Free(alloc, p); } static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize) @@ -1951,7 +1970,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize #define kBigHashDicLimit ((UInt32)1 << 24) -static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) +static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig) { UInt32 beforeSize = kNumOpts; if (!RangeEnc_Alloc(&p->rc, alloc)) @@ -1966,8 +1985,8 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I if (!p->litProbs || !p->saveState.litProbs || p->lclp != lclp) { LzmaEnc_FreeLits(p, alloc); - p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb)); - p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb)); + p->litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb)); + p->saveState.litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb)); if (!p->litProbs || !p->saveState.litProbs) { LzmaEnc_FreeLits(p, alloc); @@ -1987,6 +2006,8 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I { RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)); p->matchFinderObj = &p->matchFinderMt; + p->matchFinderBase.bigHash = (Byte)( + (p->dictSize > kBigHashDicLimit && p->matchFinderBase.hashMask >= 0xFFFFFF) ? 1 : 0); MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); } else @@ -2075,7 +2096,7 @@ void LzmaEnc_InitPrices(CLzmaEnc *p) LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices); } -static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) +static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig) { UInt32 i; for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++) @@ -2093,7 +2114,7 @@ static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *a } static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, - ISzAlloc *alloc, ISzAlloc *allocBig) + ISzAllocPtr alloc, ISzAllocPtr allocBig) { CLzmaEnc *p = (CLzmaEnc *)pp; p->matchFinderBase.stream = inStream; @@ -2104,7 +2125,7 @@ static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInS SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, ISeqInStream *inStream, UInt32 keepWindowSize, - ISzAlloc *alloc, ISzAlloc *allocBig) + ISzAllocPtr alloc, ISzAllocPtr allocBig) { CLzmaEnc *p = (CLzmaEnc *)pp; p->matchFinderBase.stream = inStream; @@ -2120,12 +2141,13 @@ static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) } SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, - UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) + UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig) { CLzmaEnc *p = (CLzmaEnc *)pp; LzmaEnc_SetInputBuf(p, src, srcLen); p->needInit = 1; + LzmaEnc_SetDataSize(pp, srcLen); return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); } @@ -2143,15 +2165,15 @@ void LzmaEnc_Finish(CLzmaEncHandle pp) typedef struct { - ISeqOutStream funcTable; + ISeqOutStream vt; Byte *data; SizeT rem; Bool overflow; -} CSeqOutStreamBuf; +} CLzmaEnc_SeqOutStreamBuf; -static size_t MyWrite(void *pp, const void *data, size_t size) +static size_t SeqOutStreamBuf_Write(const ISeqOutStream *pp, const void *data, size_t size) { - CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp; + CLzmaEnc_SeqOutStreamBuf *p = CONTAINER_FROM_VTBL(pp, CLzmaEnc_SeqOutStreamBuf, vt); if (p->rem < size) { size = p->rem; @@ -2184,9 +2206,9 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, CLzmaEnc *p = (CLzmaEnc *)pp; UInt64 nowPos64; SRes res; - CSeqOutStreamBuf outStream; + CLzmaEnc_SeqOutStreamBuf outStream; - outStream.funcTable.Write = MyWrite; + outStream.vt.Write = SeqOutStreamBuf_Write; outStream.data = dest; outStream.rem = *destLen; outStream.overflow = False; @@ -2200,7 +2222,7 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, LzmaEnc_InitPrices(p); nowPos64 = p->nowPos64; RangeEnc_Init(&p->rc); - p->rc.outStream = &outStream.funcTable; + p->rc.outStream = &outStream.vt; res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize); @@ -2230,7 +2252,7 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) break; if (progress) { - res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); + res = ICompressProgress_Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); if (res != SZ_OK) { res = SZ_ERROR_PROGRESS; @@ -2242,7 +2264,7 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) LzmaEnc_Finish(p); /* - if (res == S_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase)) + if (res == SZ_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase)) res = SZ_ERROR_FAIL; } */ @@ -2252,7 +2274,7 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, - ISzAlloc *alloc, ISzAlloc *allocBig) + ISzAllocPtr alloc, ISzAllocPtr allocBig) { RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig)); return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); @@ -2287,21 +2309,27 @@ SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) } +unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle pp) +{ + return ((CLzmaEnc *)pp)->writeEndMark; +} + + SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, - int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) + int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig) { SRes res; CLzmaEnc *p = (CLzmaEnc *)pp; - CSeqOutStreamBuf outStream; + CLzmaEnc_SeqOutStreamBuf outStream; - outStream.funcTable.Write = MyWrite; + outStream.vt.Write = SeqOutStreamBuf_Write; outStream.data = dest; outStream.rem = *destLen; outStream.overflow = False; p->writeEndMark = writeEndMark; - p->rc.outStream = &outStream.funcTable; + p->rc.outStream = &outStream.vt; res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig); @@ -2321,7 +2349,7 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, - ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) + ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig) { CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); SRes res; diff --git a/lzma/C/LzmaEnc.h b/lzma/C/LzmaEnc.h index cffe220bbf..9194ee576d 100644 --- a/lzma/C/LzmaEnc.h +++ b/lzma/C/LzmaEnc.h @@ -1,5 +1,5 @@ /* LzmaEnc.h -- LZMA Encoder -2013-01-18 : Igor Pavlov : Public domain */ +2017-07-27 : Igor Pavlov : Public domain */ #ifndef __LZMA_ENC_H #define __LZMA_ENC_H @@ -12,12 +12,10 @@ EXTERN_C_BEGIN typedef struct _CLzmaEncProps { - int level; /* 0 <= level <= 9 */ + int level; /* 0 <= level <= 9 */ UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version - (1 << 12) <= dictSize <= (1 << 30) for 64-bit version - default = (1 << 24) */ - UInt64 reduceSize; /* estimated size of data that will be compressed. default = 0xFFFFFFFF. - Encoder uses this value to reduce dictionary size */ + (1 << 12) <= dictSize <= (3 << 29) for 64-bit version + default = (1 << 24) */ int lc; /* 0 <= lc <= 8, default = 3 */ int lp; /* 0 <= lp <= 4, default = 0 */ int pb; /* 0 <= pb <= 4, default = 2 */ @@ -25,9 +23,12 @@ typedef struct _CLzmaEncProps int fb; /* 5 <= fb <= 273, default = 32 */ int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ int numHashBytes; /* 2, 3 or 4, default = 4 */ - UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ + UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ int numThreads; /* 1 or 2, default = 2 */ + + UInt64 reduceSize; /* estimated size of data that will be compressed. default = (UInt64)(Int64)-1. + Encoder uses this value to reduce dictionary size */ } CLzmaEncProps; void LzmaEncProps_Init(CLzmaEncProps *p); @@ -37,41 +38,38 @@ UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); /* ---------- CLzmaEncHandle Interface ---------- */ -/* LzmaEnc_* functions can return the following exit codes: -Returns: +/* LzmaEnc* functions can return the following exit codes: +SRes: SZ_OK - OK SZ_ERROR_MEM - Memory allocation error SZ_ERROR_PARAM - Incorrect paramater in props - SZ_ERROR_WRITE - Write callback error. + SZ_ERROR_WRITE - ISeqOutStream write callback error + SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output SZ_ERROR_PROGRESS - some break from progress callback - SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) + SZ_ERROR_THREAD - error in multithreading functions (only for Mt version) */ typedef void * CLzmaEncHandle; -CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc); -void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); +CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc); +void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig); + SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); +void LzmaEnc_SetDataSize(CLzmaEncHandle p, UInt64 expectedDataSiize); SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); +unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p); + SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, - ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); + ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, - int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); + int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); + /* ---------- One Call Interface ---------- */ -/* LzmaEncode -Return code: - SZ_OK - OK - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_PARAM - Incorrect paramater - SZ_ERROR_OUTPUT_EOF - output buffer overflow - SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -*/ - SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, - ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); + ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); EXTERN_C_END diff --git a/lzma/C/Ppmd.h b/lzma/C/Ppmd.h index 4356dd1d87..a5c1e3ef25 100644 --- a/lzma/C/Ppmd.h +++ b/lzma/C/Ppmd.h @@ -1,5 +1,5 @@ /* Ppmd.h -- PPMD codec common code -2013-01-18 : Igor Pavlov : Public domain +2017-04-03 : Igor Pavlov : Public domain This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ #ifndef __PPMD_H @@ -77,8 +77,8 @@ typedef CPpmd_Byte_Ref; #define PPMD_SetAllBitsIn256Bytes(p) \ - { unsigned i; for (i = 0; i < 256 / sizeof(p[0]); i += 8) { \ - p[i+7] = p[i+6] = p[i+5] = p[i+4] = p[i+3] = p[i+2] = p[i+1] = p[i+0] = ~(size_t)0; }} + { size_t z; for (z = 0; z < 256 / sizeof(p[0]); z += 8) { \ + p[z+7] = p[z+6] = p[z+5] = p[z+4] = p[z+3] = p[z+2] = p[z+1] = p[z+0] = ~(size_t)0; }} EXTERN_C_END diff --git a/lzma/C/Ppmd7.c b/lzma/C/Ppmd7.c index abd7e63094..0951a7c74a 100644 --- a/lzma/C/Ppmd7.c +++ b/lzma/C/Ppmd7.c @@ -1,5 +1,5 @@ /* Ppmd7.c -- PPMdH codec -2015-09-28 : Igor Pavlov : Public domain +2017-04-03 : Igor Pavlov : Public domain This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ #include "Precomp.h" @@ -15,7 +15,7 @@ static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x #define UNIT_SIZE 12 #define U2B(nu) ((UInt32)(nu) * UNIT_SIZE) -#define U2I(nu) (p->Units2Indx[(nu) - 1]) +#define U2I(nu) (p->Units2Indx[(size_t)(nu) - 1]) #define I2U(indx) (p->Indx2Units[indx]) #ifdef PPMD_32BIT @@ -88,29 +88,31 @@ void Ppmd7_Construct(CPpmd7 *p) memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40); } -void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc) +void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc) { - alloc->Free(alloc, p->Base); + ISzAlloc_Free(alloc, p->Base); p->Size = 0; p->Base = 0; } -Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc) +Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc) { - if (p->Base == 0 || p->Size != size) + if (!p->Base || p->Size != size) { + size_t size2; Ppmd7_Free(p, alloc); + size2 = 0 + #ifndef PPMD_32BIT + + UNIT_SIZE + #endif + ; p->AlignOffset = #ifdef PPMD_32BIT (4 - size) & 3; #else 4 - (size & 3); #endif - if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size - #ifndef PPMD_32BIT - + UNIT_SIZE - #endif - )) == 0) + if ((p->Base = (Byte *)ISzAlloc_Alloc(alloc, p->AlignOffset + size + size2)) == 0) return False; p->Size = size; } @@ -276,12 +278,12 @@ static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU return oldPtr; } -#define SUCCESSOR(p) ((CPpmd_Void_Ref)(size_t)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16))) +#define SUCCESSOR(p) ((CPpmd_Void_Ref)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16))) static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v) { - (p)->SuccessorLow = (UInt16)((UInt32)((size_t)v) & 0xFFFF); - (p)->SuccessorHigh = (UInt16)(((UInt32)((size_t)v) >> 16) & 0xFFFF); + (p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF); + (p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF); } static void RestartModel(CPpmd7 *p) @@ -513,7 +515,7 @@ static void UpdateModel(CPpmd7 *p) /* Expand for one UNIT */ unsigned oldNU = ns1 >> 1; unsigned i = U2I(oldNU); - if (i != U2I(oldNU + 1)) + if (i != U2I((size_t)oldNU + 1)) { void *ptr = AllocUnits(p, i + 1); void *oldPtr; @@ -639,10 +641,10 @@ CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq) unsigned nonMasked = p->MinContext->NumStats - numMasked; if (p->MinContext->NumStats != 256) { - see = p->See[p->NS2Indx[nonMasked - 1]] + + see = p->See[(unsigned)p->NS2Indx[(size_t)nonMasked - 1]] + (nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) + - 2 * (p->MinContext->SummFreq < 11 * p->MinContext->NumStats) + - 4 * (numMasked > nonMasked) + + 2 * (unsigned)(p->MinContext->SummFreq < 11 * p->MinContext->NumStats) + + 4 * (unsigned)(numMasked > nonMasked) + p->HiBitsFlag; { unsigned r = (see->Summ >> see->Shift); diff --git a/lzma/C/Ppmd7.h b/lzma/C/Ppmd7.h index 96521c31f1..45002d95bc 100644 --- a/lzma/C/Ppmd7.h +++ b/lzma/C/Ppmd7.h @@ -1,5 +1,5 @@ /* Ppmd7.h -- PPMdH compression codec -2010-03-12 : Igor Pavlov : Public domain +2017-04-03 : Igor Pavlov : Public domain This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ /* This code supports virtual RangeDecoder and includes the implementation @@ -60,8 +60,8 @@ typedef struct } CPpmd7; void Ppmd7_Construct(CPpmd7 *p); -Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc); -void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc); +Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc); +void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc); void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder); #define Ppmd7_WasAllocated(p) ((p)->Base != NULL) @@ -86,10 +86,10 @@ void Ppmd7_Update2(CPpmd7 *p); void Ppmd7_UpdateBin(CPpmd7 *p); #define Ppmd7_GetBinSumm(p) \ - &p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \ - p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \ + &p->BinSumm[(size_t)(unsigned)Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \ + p->NS2BSIndx[(size_t)Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \ (p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \ - 2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \ + 2 * p->HB2Flag[(unsigned)Ppmd7Context_OneState(p->MinContext)->Symbol] + \ ((p->RunLength >> 26) & 0x20)] CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale); @@ -97,16 +97,18 @@ CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale); /* ---------- Decode ---------- */ -typedef struct +typedef struct IPpmd7_RangeDec IPpmd7_RangeDec; + +struct IPpmd7_RangeDec { - UInt32 (*GetThreshold)(void *p, UInt32 total); - void (*Decode)(void *p, UInt32 start, UInt32 size); - UInt32 (*DecodeBit)(void *p, UInt32 size0); -} IPpmd7_RangeDec; + UInt32 (*GetThreshold)(const IPpmd7_RangeDec *p, UInt32 total); + void (*Decode)(const IPpmd7_RangeDec *p, UInt32 start, UInt32 size); + UInt32 (*DecodeBit)(const IPpmd7_RangeDec *p, UInt32 size0); +}; typedef struct { - IPpmd7_RangeDec p; + IPpmd7_RangeDec vt; UInt32 Range; UInt32 Code; IByteIn *Stream; @@ -116,7 +118,7 @@ void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p); Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p); #define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0) -int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc); +int Ppmd7_DecodeSymbol(CPpmd7 *p, const IPpmd7_RangeDec *rc); /* ---------- Encode ---------- */ diff --git a/lzma/C/Ppmd7Dec.c b/lzma/C/Ppmd7Dec.c index 04b4b09e33..7953bb07c1 100644 --- a/lzma/C/Ppmd7Dec.c +++ b/lzma/C/Ppmd7Dec.c @@ -1,5 +1,5 @@ /* Ppmd7Dec.c -- PPMdH Decoder -2010-03-12 : Igor Pavlov : Public domain +2017-04-03 : Igor Pavlov : Public domain This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ #include "Precomp.h" @@ -13,44 +13,46 @@ Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p) unsigned i; p->Code = 0; p->Range = 0xFFFFFFFF; - if (p->Stream->Read((void *)p->Stream) != 0) + if (IByteIn_Read(p->Stream) != 0) return False; for (i = 0; i < 4; i++) - p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); + p->Code = (p->Code << 8) | IByteIn_Read(p->Stream); return (p->Code < 0xFFFFFFFF); } -static UInt32 Range_GetThreshold(void *pp, UInt32 total) +#define GET_Ppmd7z_RangeDec CPpmd7z_RangeDec *p = CONTAINER_FROM_VTBL(pp, CPpmd7z_RangeDec, vt); + +static UInt32 Range_GetThreshold(const IPpmd7_RangeDec *pp, UInt32 total) { - CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; - return (p->Code) / (p->Range /= total); + GET_Ppmd7z_RangeDec + return p->Code / (p->Range /= total); } static void Range_Normalize(CPpmd7z_RangeDec *p) { if (p->Range < kTopValue) { - p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); + p->Code = (p->Code << 8) | IByteIn_Read(p->Stream); p->Range <<= 8; if (p->Range < kTopValue) { - p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); + p->Code = (p->Code << 8) | IByteIn_Read(p->Stream); p->Range <<= 8; } } } -static void Range_Decode(void *pp, UInt32 start, UInt32 size) +static void Range_Decode(const IPpmd7_RangeDec *pp, UInt32 start, UInt32 size) { - CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; + GET_Ppmd7z_RangeDec p->Code -= start * p->Range; p->Range *= size; Range_Normalize(p); } -static UInt32 Range_DecodeBit(void *pp, UInt32 size0) +static UInt32 Range_DecodeBit(const IPpmd7_RangeDec *pp, UInt32 size0) { - CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; + GET_Ppmd7z_RangeDec UInt32 newBound = (p->Range >> 14) * size0; UInt32 symbol; if (p->Code < newBound) @@ -70,15 +72,15 @@ static UInt32 Range_DecodeBit(void *pp, UInt32 size0) void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p) { - p->p.GetThreshold = Range_GetThreshold; - p->p.Decode = Range_Decode; - p->p.DecodeBit = Range_DecodeBit; + p->vt.GetThreshold = Range_GetThreshold; + p->vt.Decode = Range_Decode; + p->vt.DecodeBit = Range_DecodeBit; } #define MASK(sym) ((signed char *)charMask)[sym] -int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc) +int Ppmd7_DecodeSymbol(CPpmd7 *p, const IPpmd7_RangeDec *rc) { size_t charMask[256 / sizeof(size_t)]; if (p->MinContext->NumStats != 1) diff --git a/lzma/C/Threads.c b/lzma/C/Threads.c index d3d0912da4..930ad271b4 100644 --- a/lzma/C/Threads.c +++ b/lzma/C/Threads.c @@ -1,5 +1,5 @@ /* Threads.c -- multithreading library -2014-09-21 : Igor Pavlov : Public domain */ +2017-06-26 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -12,18 +12,20 @@ static WRes GetError() { DWORD res = GetLastError(); - return (res) ? (WRes)(res) : 1; + return res ? (WRes)res : 1; } -WRes HandleToWRes(HANDLE h) { return (h != 0) ? 0 : GetError(); } -WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); } +static WRes HandleToWRes(HANDLE h) { return (h != NULL) ? 0 : GetError(); } +static WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); } WRes HandlePtr_Close(HANDLE *p) { if (*p != NULL) + { if (!CloseHandle(*p)) return GetError(); - *p = NULL; + *p = NULL; + } return 0; } @@ -49,7 +51,7 @@ WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param) return HandleToWRes(*p); } -WRes Event_Create(CEvent *p, BOOL manualReset, int signaled) +static WRes Event_Create(CEvent *p, BOOL manualReset, int signaled) { *p = CreateEvent(NULL, manualReset, (signaled ? TRUE : FALSE), NULL); return HandleToWRes(*p); diff --git a/lzma/C/Threads.h b/lzma/C/Threads.h index 9b3e1c556d..e53ace4356 100644 --- a/lzma/C/Threads.h +++ b/lzma/C/Threads.h @@ -1,5 +1,5 @@ /* Threads.h -- multithreading library -2013-11-12 : Igor Pavlov : Public domain */ +2017-06-18 : Igor Pavlov : Public domain */ #ifndef __7Z_THREADS_H #define __7Z_THREADS_H @@ -49,7 +49,8 @@ WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled); WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p); typedef HANDLE CSemaphore; -#define Semaphore_Construct(p) (*p) = NULL +#define Semaphore_Construct(p) *(p) = NULL +#define Semaphore_IsCreated(p) (*(p) != NULL) #define Semaphore_Close(p) HandlePtr_Close(p) #define Semaphore_Wait(p) Handle_WaitObject(*(p)) WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount); diff --git a/src/files.cpp b/src/files.cpp index 8ad4d63294..1b0e5db1fd 100644 --- a/src/files.cpp +++ b/src/files.cpp @@ -393,8 +393,8 @@ struct FileReaderLZMA::StreamPointer CLzmaDec Stream; }; -static void *SzAlloc(void *, size_t size) { return malloc(size); } -static void SzFree(void *, void *address) { free(address); } +static void *SzAlloc(ISzAllocPtr, size_t size) { return malloc(size); } +static void SzFree(ISzAllocPtr, void *address) { free(address); } ISzAlloc g_Alloc = { SzAlloc, SzFree }; FileReaderLZMA::FileReaderLZMA (FileReader &file, size_t uncompressed_size, bool zip) diff --git a/src/resourcefiles/file_7z.cpp b/src/resourcefiles/file_7z.cpp index d6bfa68f65..aa5018eb30 100644 --- a/src/resourcefiles/file_7z.cpp +++ b/src/resourcefiles/file_7z.cpp @@ -67,7 +67,7 @@ struct CZDFileInStream File = _file; } - static SRes Read(void *pp, void *buf, size_t *size) + static SRes Read(const ISeekInStream *pp, void *buf, size_t *size) { CZDFileInStream *p = (CZDFileInStream *)pp; long numread = p->File->Read(buf, (long)*size); @@ -80,7 +80,7 @@ struct CZDFileInStream return SZ_OK; } - static SRes Seek(void *pp, Int64 *pos, ESzSeek origin) + static SRes Seek(const ISeekInStream *pp, Int64 *pos, ESzSeek origin) { CZDFileInStream *p = (CZDFileInStream *)pp; int move_method; @@ -111,7 +111,8 @@ struct C7zArchive { CSzArEx DB; CZDFileInStream ArchiveStream; - CLookToRead LookStream; + CLookToRead2 LookStream; + Byte StreamBuffer[1<<14]; UInt32 BlockIndex; Byte *OutBuffer; size_t OutBufferSize; @@ -123,9 +124,11 @@ struct C7zArchive CrcGenerateTable(); } file->Seek(0, SEEK_SET); - LookToRead_CreateVTable(&LookStream, false); + LookToRead2_CreateVTable(&LookStream, false); LookStream.realStream = &ArchiveStream.s; - LookToRead_Init(&LookStream); + LookToRead2_Init(&LookStream); + LookStream.bufSize = sizeof(StreamBuffer); + LookStream.buf = StreamBuffer; SzArEx_Init(&DB); BlockIndex = 0xFFFFFFFF; OutBuffer = NULL; @@ -143,13 +146,13 @@ struct C7zArchive SRes Open() { - return SzArEx_Open(&DB, &LookStream.s, &g_Alloc, &g_Alloc); + return SzArEx_Open(&DB, &LookStream.vt, &g_Alloc, &g_Alloc); } SRes Extract(UInt32 file_index, char *buffer) { size_t offset, out_size_processed; - SRes res = SzArEx_Extract(&DB, &LookStream.s, file_index, + SRes res = SzArEx_Extract(&DB, &LookStream.vt, file_index, &BlockIndex, &OutBuffer, &OutBufferSize, &offset, &out_size_processed, &g_Alloc, &g_Alloc); From 69e8c9ec6edfb80b4a5fac9f5434227dd567ab32 Mon Sep 17 00:00:00 2001 From: Marisa Kirisame Date: Fri, 19 Jan 2018 00:29:49 +0100 Subject: [PATCH 19/29] A more "general purpose" line trace function. Far from a complete ZScript interface with Trace(), though. --- src/p_linetracedata.h | 25 +++++ src/p_local.h | 12 +++ src/p_map.cpp | 154 ++++++++++++++++++++++++++++ wadsrc/static/zscript/actor.txt | 27 +++++ wadsrc/static/zscript/constants.txt | 12 +++ 5 files changed, 230 insertions(+) create mode 100644 src/p_linetracedata.h diff --git a/src/p_linetracedata.h b/src/p_linetracedata.h new file mode 100644 index 0000000000..f6191b5d19 --- /dev/null +++ b/src/p_linetracedata.h @@ -0,0 +1,25 @@ +#ifndef P_LTRACEDATA_H +#define P_LTRACEDATA_H + +//============================================================================ +// +// Structure for passing detailed results of LineTrace to ZScript +// +//============================================================================ +struct FLineTraceData +{ + AActor *HitActor; + line_t *HitLine; + sector_t *HitSector; + F3DFloor *Hit3DFloor; + FTextureID HitTexture; + DVector3 HitLocation; + double Distance; + int NumPortals; + int LineSide; + int LinePart; + int SectorPlane; + ETraceResult HitType; +}; + +#endif diff --git a/src/p_local.h b/src/p_local.h index 2f12b6a5ba..d22d8a7ef8 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -336,6 +336,18 @@ enum // P_LineAttack flags AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL, double sz = 0.0, double offsetforward = 0.0, double offsetside = 0.0); AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, DAngle pitch, int damage, FName damageType, FName pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL, double sz = 0.0, double offsetforward = 0.0, double offsetside = 0.0); +enum // P_LineTrace flags +{ + TRF_ABSPOSITION = 1, + TRF_ABSOFFSET = 2, + TRF_THRUSPECIES = 4, + TRF_THRUACTORS = 8, + TRF_THRUBLOCK = 16, + TRF_THRUHITSCAN = 32, + TRF_NOSKY = 64, + TRF_ALLACTORS = 128, +}; + void P_TraceBleed(int damage, const DVector3 &pos, AActor *target, DAngle angle, DAngle pitch); void P_TraceBleed(int damage, AActor *target, DAngle angle, DAngle pitch); diff --git a/src/p_map.cpp b/src/p_map.cpp index 304cfd8cf9..8f04d24a56 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -79,6 +79,7 @@ #include "p_terrain.h" #include "p_trace.h" #include "p_checkposition.h" +#include "p_linetracedata.h" #include "r_utility.h" #include "p_blockmap.h" #include "p_3dmidtex.h" @@ -4814,6 +4815,159 @@ DEFINE_ACTION_FUNCTION(AActor, LineAttack) return numret; } +//========================================================================== +// +// P_LineTrace +// +//========================================================================== +struct LineTraceData +{ + AActor *Caller; + bool ThruSpecies; + bool ThruActors; + int NumPortals; +}; + +static ETraceStatus CheckLineTrace(FTraceResults &res, void *userdata) +{ + LineTraceData *TData = (LineTraceData *)userdata; + if ( res.HitType == TRACE_CrossingPortal ) + { + TData->NumPortals++; + return TRACE_Skip; + } + if ( res.HitType != TRACE_HitActor ) + { + return TRACE_Stop; + } + if ( (TData->ThruActors) || (TData->ThruSpecies && res.Actor->GetSpecies() == TData->Caller->GetSpecies()) ) + { + return TRACE_Skip; + } + return TRACE_Stop; +} + +bool P_LineTrace(AActor *t1, DAngle angle, double distance, + DAngle pitch, int flags, double sz, double offsetforward, + double offsetside, FLineTraceData *outdata) +{ + FTraceResults trace; + LineTraceData TData; + TData.Caller = t1; + TData.ThruSpecies = (flags & TRF_THRUSPECIES); + TData.ThruActors = (flags & TRF_THRUACTORS); + TData.NumPortals = 0; + DVector3 direction; + double pc = pitch.Cos(); + direction = { pc * angle.Cos(), pc * angle.Sin(), -pitch.Sin() }; + DVector3 startpos; + double startz = t1->Z() - t1->Floorclip; + startz += sz; + if ( flags & TRF_ABSPOSITION ) + { + startpos = DVector3(offsetforward, offsetside, sz); + } + else if ( flags & TRF_ABSOFFSET ) + { + startpos = t1->Vec2OffsetZ(offsetforward, offsetside, startz); + } + else if ( (offsetforward == 0.0) && (offsetside == 0.0) ) + { + startpos = t1->PosAtZ(startz); + } + else + { + const double s = angle.Sin(); + const double c = angle.Cos(); + startpos = t1->Vec2OffsetZ(offsetforward * c + offsetside * s, offsetforward * s - offsetside * c, startz); + } + + ActorFlags aflags = (flags & TRF_ALLACTORS) ? ActorFlags::FromInt(0xFFFFFFFF) : MF_SHOOTABLE; + int lflags = 0; + if ( !(lflags & TRF_THRUBLOCK) ) lflags |= ML_BLOCKEVERYTHING; + if ( !(lflags & TRF_THRUHITSCAN) ) lflags |= ML_BLOCKHITSCAN; + int tflags = TRACE_ReportPortals; + if ( flags & TRF_NOSKY ) tflags |= TRACE_NoSky; + + // Do trace + bool ret = Trace(startpos, t1->Sector, direction, distance, aflags, lflags, t1, trace, tflags, CheckLineTrace, &TData); + if ( outdata ) + { + memset(outdata,0,sizeof(*outdata)); + outdata->HitActor = trace.Actor; + outdata->HitLine = trace.Line; + outdata->HitSector = trace.Sector; + outdata->Hit3DFloor = trace.ffloor; + switch ( trace.HitType ) + { + case TRACE_HitFloor: + outdata->SectorPlane = 0; + outdata->HitTexture = trace.Sector->planes[0].Texture; + break; + case TRACE_HitCeiling: + outdata->SectorPlane = 1; + outdata->HitTexture = trace.Sector->planes[1].Texture; + break; + case TRACE_HitWall: + outdata->LineSide = trace.Side; + int txpart; + switch ( trace.Tier ) + { + case TIER_Middle: + outdata->LinePart = 1; + outdata->HitTexture = trace.Line->sidedef[trace.Side]->textures[1].texture; + break; + case TIER_Upper: + outdata->LinePart = 0; + outdata->HitTexture = trace.Line->sidedef[trace.Side]->textures[0].texture; + break; + case TIER_Lower: + outdata->LinePart = 2; + outdata->HitTexture = trace.Line->sidedef[trace.Side]->textures[2].texture; + break; + case TIER_FFloor: + txpart = (trace.ffloor->flags & FF_UPPERTEXTURE) ? 0 : (trace.ffloor->flags & FF_LOWERTEXTURE) ? 2 : 1; + outdata->HitTexture = trace.ffloor->master->sidedef[0]->textures[txpart].texture; + break; + } + default: + break; + } + outdata->HitLocation = trace.HitPos; + outdata->Distance = trace.Distance; + outdata->NumPortals = TData.NumPortals; + outdata->HitType = trace.HitType; + } + return ret; +} + +DEFINE_FIELD_X(FLineTraceData, FLineTraceData, HitActor); +DEFINE_FIELD_X(FLineTraceData, FLineTraceData, HitLine); +DEFINE_FIELD_X(FLineTraceData, FLineTraceData, HitSector); +DEFINE_FIELD_X(FLineTraceData, FLineTraceData, Hit3DFloor); +DEFINE_FIELD_X(FLineTraceData, FLineTraceData, HitTexture); +DEFINE_FIELD_X(FLineTraceData, FLineTraceData, HitLocation); +DEFINE_FIELD_X(FLineTraceData, FLineTraceData, Distance); +DEFINE_FIELD_X(FLineTraceData, FLineTraceData, NumPortals); +DEFINE_FIELD_X(FLineTraceData, FLineTraceData, LineSide); +DEFINE_FIELD_X(FLineTraceData, FLineTraceData, LinePart); +DEFINE_FIELD_X(FLineTraceData, FLineTraceData, SectorPlane); +DEFINE_FIELD_X(FLineTraceData, FLineTraceData, HitType); + +DEFINE_ACTION_FUNCTION(AActor, LineTrace) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_ANGLE(angle); + PARAM_FLOAT(distance); + PARAM_ANGLE(pitch); + PARAM_INT_DEF(flags); + PARAM_FLOAT_DEF(offsetz); + PARAM_FLOAT_DEF(offsetforward); + PARAM_FLOAT_DEF(offsetside); + PARAM_POINTER_DEF(data, FLineTraceData); + ACTION_RETURN_BOOL(P_LineTrace(self,angle,distance,pitch,flags,offsetz,offsetforward,offsetside,data)); +} + //========================================================================== // // P_LinePickActor diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 4d61435a66..dbea3fd47c 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -29,6 +29,32 @@ struct FCheckPosition native void ClearLastRipped(); } +struct FLineTraceData +{ + enum ETraceResult + { + TRACE_HitNone, + TRACE_HitFloor, + TRACE_HitCeiling, + TRACE_HitWall, + TRACE_HitActor, + TRACE_CrossingPortal + }; + + Actor HitActor; + Line HitLine; + Sector HitSector; + F3DFloor Hit3DFloor; + TextureID HitTexture; + Vector3 HitLocation; + double Distance; + int NumPortals; + int LineSide; + int LinePart; + int SectorPlane; + int HitType; +} + struct LinkContext { voidptr sector_list; // really msecnode but that's not exported yet. @@ -602,6 +628,7 @@ class Actor : Thinker native native void PoisonMobj (Actor inflictor, Actor source, int damage, int duration, int period, Name type); native double AimLineAttack(double angle, double distance, out FTranslatedLineTarget pLineTarget = null, double vrange = 0., int flags = 0, Actor target = null, Actor friender = null); native Actor, int LineAttack(double angle, double distance, double pitch, int damage, Name damageType, class pufftype, int flags = 0, out FTranslatedLineTarget victim = null, double offsetz = 0., double offsetforward = 0., double offsetside = 0.); + native bool LineTrace(double angle, double distance, double pitch, int flags = 0, double offsetz = 0., double offsetforward = 0., double offsetside = 0., out FLineTraceData data = null); native bool CheckSight(Actor target, int flags = 0); native bool IsVisible(Actor other, bool allaround, LookExParams params = null); native bool HitFriend(); diff --git a/wadsrc/static/zscript/constants.txt b/wadsrc/static/zscript/constants.txt index e6954b7896..47cf4accda 100644 --- a/wadsrc/static/zscript/constants.txt +++ b/wadsrc/static/zscript/constants.txt @@ -897,6 +897,18 @@ enum ELineAttackFlags LAF_ABSPOSITION = 1 << 7, } +enum ELineTraceFlags +{ + TRF_ABSPOSITION = 1, + TRF_ABSOFFSET = 2, + TRF_THRUSPECIES = 4, + TRF_THRUACTORS = 8, + TRF_THRUBLOCK = 16, + TRF_THRUHITSCAN = 32, + TRF_NOSKY = 64, + TRF_ALLACTORS = 128, +} + const DEFMELEERANGE = 64; const SAWRANGE = (64.+(1./65536.)); // use meleerange + 1 so the puff doesn't skip the flash (i.e. plays all states) const MISSILERANGE = (32*64); From 15e7d9daba8770915764e24f63ce26e62ae8bc74 Mon Sep 17 00:00:00 2001 From: Marisa Kirisame Date: Fri, 19 Jan 2018 00:41:53 +0100 Subject: [PATCH 20/29] Gave the user data struct for CheckLineTrace a more unique name to avoid confusion with FLineTraceData --- src/p_map.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_map.cpp b/src/p_map.cpp index 8f04d24a56..6c269e8101 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -4820,7 +4820,7 @@ DEFINE_ACTION_FUNCTION(AActor, LineAttack) // P_LineTrace // //========================================================================== -struct LineTraceData +struct CheckLineData { AActor *Caller; bool ThruSpecies; @@ -4830,7 +4830,7 @@ struct LineTraceData static ETraceStatus CheckLineTrace(FTraceResults &res, void *userdata) { - LineTraceData *TData = (LineTraceData *)userdata; + CheckLineData *TData = (CheckLineData *)userdata; if ( res.HitType == TRACE_CrossingPortal ) { TData->NumPortals++; @@ -4852,7 +4852,7 @@ bool P_LineTrace(AActor *t1, DAngle angle, double distance, double offsetside, FLineTraceData *outdata) { FTraceResults trace; - LineTraceData TData; + CheckLineData TData; TData.Caller = t1; TData.ThruSpecies = (flags & TRF_THRUSPECIES); TData.ThruActors = (flags & TRF_THRUACTORS); From a7ff62316d92e3bafc1f9c63c2d625e26bc2fdc8 Mon Sep 17 00:00:00 2001 From: ZZYZX Date: Sat, 20 Jan 2018 15:37:03 +0200 Subject: [PATCH 21/29] Exported Trace() interface to ZScript --- src/p_trace.cpp | 74 +++++++++++++++++++++++++++++++ src/p_trace.h | 10 +++++ wadsrc/static/zscript/base.txt | 81 ++++++++++++++++++++++++++++++++++ 3 files changed, 165 insertions(+) diff --git a/src/p_trace.cpp b/src/p_trace.cpp index 8522e891a5..8c991d1014 100644 --- a/src/p_trace.cpp +++ b/src/p_trace.cpp @@ -42,6 +42,7 @@ #include "p_spec.h" #include "g_levellocals.h" #include "p_terrain.h" +#include "vm.h" //========================================================================== // @@ -948,3 +949,76 @@ static bool EditTraceResult (uint32_t flags, FTraceResults &res) } return true; } + +//========================================================================== +// +// [ZZ] here go the methods for the ZScript interface +// +//========================================================================== +IMPLEMENT_CLASS(DTracer, false, false) +DEFINE_FIELD_X(Tracer, DTracer, Results) + +// define TraceResults fields +DEFINE_FIELD_NAMED_X(TraceResults, FTraceResults, Sector, Sec) +DEFINE_FIELD_X(TraceResults, FTraceResults, HitTexture) +DEFINE_FIELD_X(TraceResults, FTraceResults, HitPos) +DEFINE_FIELD_X(TraceResults, FTraceResults, HitVector) +DEFINE_FIELD_X(TraceResults, FTraceResults, SrcFromTarget) +DEFINE_FIELD_X(TraceResults, FTraceResults, SrcAngleFromTarget) +DEFINE_FIELD_X(TraceResults, FTraceResults, Distance) +DEFINE_FIELD_X(TraceResults, FTraceResults, Fraction) +DEFINE_FIELD_NAMED_X(TraceResults, FTraceResults, Actor, Thing) +DEFINE_FIELD_NAMED_X(TraceResults, FTraceResults, Line, Linedef) +DEFINE_FIELD_X(TraceResults, FTraceResults, Side) +DEFINE_FIELD_X(TraceResults, FTraceResults, Tier) +DEFINE_FIELD_X(TraceResults, FTraceResults, unlinked) +DEFINE_FIELD_X(TraceResults, FTraceResults, HitType) +DEFINE_FIELD_X(TraceResults, FTraceResults, CrossedWater) +DEFINE_FIELD_X(TraceResults, FTraceResults, CrossedWaterPos) +DEFINE_FIELD_X(TraceResults, FTraceResults, Crossed3DWater) +DEFINE_FIELD_X(TraceResults, FTraceResults, Crossed3DWaterPos) + +DEFINE_ACTION_FUNCTION(DTracer, Trace) +{ + PARAM_SELF_PROLOGUE(DTracer); + /*bool Trace(const DVector3 &start, sector_t *sector, const DVector3 &direction, double maxDist, + ActorFlags ActorMask, uint32_t WallMask, AActor *ignore, FTraceResults &res, uint32_t traceFlags = 0, + ETraceStatus(*callback)(FTraceResults &res, void *) = NULL, void *callbackdata = NULL);*/ + PARAM_FLOAT(start_x); + PARAM_FLOAT(start_y); + PARAM_FLOAT(start_z); + PARAM_POINTER(sector, sector_t); + PARAM_FLOAT(direction_x); + PARAM_FLOAT(direction_y); + PARAM_FLOAT(direction_z); + PARAM_FLOAT(maxDist); + // actor flags and wall flags are not supported due to how flags are implemented on the ZScript side. + // say thanks to oversimplifying the user API. + PARAM_INT(traceFlags); + + // Trace(vector3 start, Sector sector, vector3 direction, double maxDist, ETraceFlags traceFlags) + bool res = Trace(DVector3(start_x, start_y, start_z), sector, DVector3(direction_x, direction_y, direction_z), maxDist, + (ActorFlag)0xFFFFFFFF, 0xFFFFFFFF, nullptr, self->Results, traceFlags, &DTracer::TraceCallback, self); + ACTION_RETURN_BOOL(res); +} + +ETraceStatus DTracer::TraceCallback(FTraceResults& res, void* pthis) +{ + DTracer* self = (DTracer*)pthis; + // "res" here should refer to self->Results anyway. + return self->CallZScriptCallback(); +} + +ETraceStatus DTracer::CallZScriptCallback() +{ + IFVIRTUAL(DTracer, TraceCallback) + { + int status; + VMReturn results[1] = { &status }; + VMValue params[1] = { (DTracer*)this }; + VMCall(func, params, 1, results, 1); + return (ETraceStatus)status; + } + + return TRACE_Stop; +} \ No newline at end of file diff --git a/src/p_trace.h b/src/p_trace.h index 914eee2887..af4187f785 100644 --- a/src/p_trace.h +++ b/src/p_trace.h @@ -112,4 +112,14 @@ bool Trace(const DVector3 &start, sector_t *sector, const DVector3 &direction, d ActorFlags ActorMask, uint32_t WallMask, AActor *ignore, FTraceResults &res, uint32_t traceFlags = 0, ETraceStatus(*callback)(FTraceResults &res, void *) = NULL, void *callbackdata = NULL); +// [ZZ] this is the object that's used for ZScript +class DTracer : public DObject +{ + DECLARE_CLASS(DTracer, DObject) +public: + FTraceResults Results; + static ETraceStatus TraceCallback(FTraceResults& res, void* pthis); + ETraceStatus CallZScriptCallback(); +}; + #endif //__P_TRACE_H__ diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index bf5edf6caa..1b32b82d30 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -460,6 +460,87 @@ class BlockLinesIterator : Object native native bool Next(); } +enum ETraceStatus +{ + TRACE_Stop, // stop the trace, returning this hit + TRACE_Continue, // continue the trace, returning this hit if there are none further along + TRACE_Skip, // continue the trace; do not return this hit + TRACE_Abort // stop the trace, returning no hits +} + +enum ETraceFlags +{ + TRACE_NoSky = 1, // Hitting the sky returns TRACE_HitNone + TRACE_PCross = 2, // Trigger SPAC_PCROSS lines + TRACE_Impact = 4, // Trigger SPAC_IMPACT lines + TRACE_PortalRestrict = 8, // Cannot go through portals without a static link offset. + TRACE_ReportPortals = 16 // Report any portal crossing to the TraceCallback +} + + +enum ETraceResult +{ + TRACE_HitNone, + TRACE_HitFloor, + TRACE_HitCeiling, + TRACE_HitWall, + TRACE_HitActor, + TRACE_CrossingPortal +} + +enum ELineTier +{ + TIER_Middle, + TIER_Upper, + TIER_Lower, + TIER_FFloor +} + +struct TraceResults native +{ + native Sector Sec; // originally called "Sector". cannot be named like this in ZScript. + native TextureID HitTexture; + native vector3 HitPos; + native vector3 HitVector; + native vector3 SrcFromTarget; + native double SrcAngleFromTarget; + + native double Distance; + native double Fraction; + + native Actor Thing; // valid if hit an actor. // originally called "Actor". + + native Line Linedef; // valid if hit a line // originally called "Line". + native uint8 Side; + native uint8 Tier; // see Tracer.ELineTier + native bool unlinked; // passed through a portal without static offset. + + native ETraceResult HitType; + // F3DFloor *ffloor; + + native Sector CrossedWater; // For Boom-style, Transfer_Heights-based deep water + native vector3 CrossedWaterPos; // remember the position so that we can use it for spawning the splash + native Sector Crossed3DWater; // For 3D floor-based deep water + native vector3 Crossed3DWaterPos; +} + +class Tracer : Object native +{ + native @TraceResults Results; + native bool Trace(vector3 start, Sector sec, vector3 direction, double maxDist, ETraceFlags traceFlags); + + virtual ETraceStatus TraceCallback() + { + // Normally you would examine Results.HitType (for ETraceResult), and determine either: + // - stop tracing and return the entity that was found (return TRACE_Stop) + // - ignore some object, like noclip, e.g. only count solid walls and floors, and ignore actors (return TRACE_Skip) + // - find last object of some type (return TRACE_Continue) + // - stop tracing entirely and assume we found nothing (return TRACE_Abort) + // TRACE_Abort and TRACE_Continue are of limited use in scripting. + + return TRACE_Stop; // default callback returns first hit, whatever it is. + } +} struct DropItem native { From 74b937620e8e85a07662c3ff186f20605ea3bcbf Mon Sep 17 00:00:00 2001 From: ZZYZX Date: Sat, 20 Jan 2018 15:49:46 +0200 Subject: [PATCH 22/29] Added texture detection for walls and 3D floors; renamed some fields to more intuitive names --- src/p_trace.cpp | 30 +++++++++++++++++++++++++++--- wadsrc/static/zscript/base.txt | 6 +++--- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/p_trace.cpp b/src/p_trace.cpp index 8c991d1014..16a699a383 100644 --- a/src/p_trace.cpp +++ b/src/p_trace.cpp @@ -959,7 +959,7 @@ IMPLEMENT_CLASS(DTracer, false, false) DEFINE_FIELD_X(Tracer, DTracer, Results) // define TraceResults fields -DEFINE_FIELD_NAMED_X(TraceResults, FTraceResults, Sector, Sec) +DEFINE_FIELD_NAMED_X(TraceResults, FTraceResults, Sector, HitSector) DEFINE_FIELD_X(TraceResults, FTraceResults, HitTexture) DEFINE_FIELD_X(TraceResults, FTraceResults, HitPos) DEFINE_FIELD_X(TraceResults, FTraceResults, HitVector) @@ -967,8 +967,8 @@ DEFINE_FIELD_X(TraceResults, FTraceResults, SrcFromTarget) DEFINE_FIELD_X(TraceResults, FTraceResults, SrcAngleFromTarget) DEFINE_FIELD_X(TraceResults, FTraceResults, Distance) DEFINE_FIELD_X(TraceResults, FTraceResults, Fraction) -DEFINE_FIELD_NAMED_X(TraceResults, FTraceResults, Actor, Thing) -DEFINE_FIELD_NAMED_X(TraceResults, FTraceResults, Line, Linedef) +DEFINE_FIELD_NAMED_X(TraceResults, FTraceResults, Actor, HitActor) +DEFINE_FIELD_NAMED_X(TraceResults, FTraceResults, Line, HitLine) DEFINE_FIELD_X(TraceResults, FTraceResults, Side) DEFINE_FIELD_X(TraceResults, FTraceResults, Tier) DEFINE_FIELD_X(TraceResults, FTraceResults, unlinked) @@ -1006,6 +1006,30 @@ ETraceStatus DTracer::TraceCallback(FTraceResults& res, void* pthis) { DTracer* self = (DTracer*)pthis; // "res" here should refer to self->Results anyway. + + // patch results a bit. modders don't expect it to work like this most likely. + // code by MarisaKirisame + if (res.HitType == TRACE_HitWall) + { + int txpart; + switch (res.Tier) + { + case TIER_Middle: + res.HitTexture = res.Line->sidedef[res.Side]->textures[1].texture; + break; + case TIER_Upper: + res.HitTexture = res.Line->sidedef[res.Side]->textures[0].texture; + break; + case TIER_Lower: + res.HitTexture = res.Line->sidedef[res.Side]->textures[2].texture; + break; + case TIER_FFloor: + txpart = (res.ffloor->flags & FF_UPPERTEXTURE) ? 0 : (res.ffloor->flags & FF_LOWERTEXTURE) ? 2 : 1; + res.HitTexture = res.ffloor->master->sidedef[0]->textures[txpart].texture; + break; + } + } + return self->CallZScriptCallback(); } diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 1b32b82d30..9db86bcda6 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -498,7 +498,7 @@ enum ELineTier struct TraceResults native { - native Sector Sec; // originally called "Sector". cannot be named like this in ZScript. + native Sector HitSector; // originally called "Sector". cannot be named like this in ZScript. native TextureID HitTexture; native vector3 HitPos; native vector3 HitVector; @@ -508,9 +508,9 @@ struct TraceResults native native double Distance; native double Fraction; - native Actor Thing; // valid if hit an actor. // originally called "Actor". + native Actor HitActor; // valid if hit an actor. // originally called "Actor". - native Line Linedef; // valid if hit a line // originally called "Line". + native Line HitLine; // valid if hit a line // originally called "Line". native uint8 Side; native uint8 Tier; // see Tracer.ELineTier native bool unlinked; // passed through a portal without static offset. From ee1a8f71bbb19fc9eeb812fd4b986073aa57d983 Mon Sep 17 00:00:00 2001 From: ZZYZX Date: Sun, 21 Jan 2018 05:06:00 +0200 Subject: [PATCH 23/29] Disable TRACE_PCross and TRACE_Impact on ZScript side --- src/p_trace.cpp | 3 +++ wadsrc/static/zscript/base.txt | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/p_trace.cpp b/src/p_trace.cpp index 16a699a383..d00a5c4cc0 100644 --- a/src/p_trace.cpp +++ b/src/p_trace.cpp @@ -996,6 +996,9 @@ DEFINE_ACTION_FUNCTION(DTracer, Trace) // say thanks to oversimplifying the user API. PARAM_INT(traceFlags); + // these are internal hacks. + traceFlags &= ~(TRACE_PCross | TRACE_Impact); + // Trace(vector3 start, Sector sector, vector3 direction, double maxDist, ETraceFlags traceFlags) bool res = Trace(DVector3(start_x, start_y, start_z), sector, DVector3(direction_x, direction_y, direction_z), maxDist, (ActorFlag)0xFFFFFFFF, 0xFFFFFFFF, nullptr, self->Results, traceFlags, &DTracer::TraceCallback, self); diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 9db86bcda6..bef1751da8 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -471,8 +471,8 @@ enum ETraceStatus enum ETraceFlags { TRACE_NoSky = 1, // Hitting the sky returns TRACE_HitNone - TRACE_PCross = 2, // Trigger SPAC_PCROSS lines - TRACE_Impact = 4, // Trigger SPAC_IMPACT lines + //TRACE_PCross = 2, // Trigger SPAC_PCROSS lines + //TRACE_Impact = 4, // Trigger SPAC_IMPACT lines TRACE_PortalRestrict = 8, // Cannot go through portals without a static link offset. TRACE_ReportPortals = 16 // Report any portal crossing to the TraceCallback } From ce88830a5994e1e4167aad5b59360d7bf08fc2fc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 21 Jan 2018 10:58:12 +0100 Subject: [PATCH 24/29] - fixed a warning caused by the LZMA-SDK update. --- tools/zipdir/zipdir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/zipdir/zipdir.c b/tools/zipdir/zipdir.c index cee41b12ed..4cb98c1389 100644 --- a/tools/zipdir/zipdir.c +++ b/tools/zipdir/zipdir.c @@ -226,8 +226,8 @@ int copy_zip_file(FILE *zip, file_entry_t *file, FILE *ozip, CentralDirectoryEnt // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- -static void *SzAlloc(void *p, size_t size) { p = p; return malloc(size); } -static void SzFree(void *p, void *address) { p = p; free(address); } +static void *SzAlloc(ISzAllocPtr p, size_t size) { p = p; return malloc(size); } +static void SzFree(ISzAllocPtr p, void *address) { p = p; free(address); } // EXTERNAL DATA DECLARATIONS ---------------------------------------------- From e1d6f6f3b3960c40551595f38acee385cadfd09b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 21 Jan 2018 16:17:49 +0100 Subject: [PATCH 25/29] - fixed: precise rendering did not work anymore due to a missing reference operator in the setup function for the needed data. --- src/gl/data/gl_setup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl/data/gl_setup.cpp b/src/gl/data/gl_setup.cpp index 26aee78b76..35c33199ae 100644 --- a/src/gl/data/gl_setup.cpp +++ b/src/gl/data/gl_setup.cpp @@ -420,7 +420,7 @@ static void InitVertexData() for(unsigned i = 0; i < level.vertexes.Size(); ++i) { - auto vert = level.vertexes[i]; + auto &vert = level.vertexes[i]; int cnt = vt_sectorlists[i].Size(); vert.dirty = true; From 6438416adbef9984cab217ff83754134d0b95e42 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 21 Jan 2018 16:29:40 +0100 Subject: [PATCH 26/29] - fixed: The culling mode for translucent models must be inverted when rendering a mirror. --- src/gl/models/gl_models.cpp | 3 ++- src/gl/scene/gl_portal.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index f6ee0e9367..3bceeedf7b 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -46,6 +46,7 @@ #include "gl/system/gl_interface.h" #include "gl/renderer/gl_renderer.h" #include "gl/scene/gl_drawinfo.h" +#include "gl/scene/gl_portal.h" #include "gl/models/gl_models.h" #include "gl/textures/gl_material.h" #include "gl/utility/gl_convert.h" @@ -100,7 +101,7 @@ void FGLModelRenderer::BeginDrawHUDModel(AActor *actor, const VSMatrix &objectTo if (!(actor->RenderStyle == LegacyRenderStyles[STYLE_Normal])) { glEnable(GL_CULL_FACE); - glFrontFace(GL_CCW); + glFrontFace(GLPortal::isMirrored()? GL_CW : GL_CCW); } gl_RenderState.mModelMatrix = objectToWorldMatrix; diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index 010472c977..4eade59d2c 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -167,6 +167,8 @@ public: return recursion; } + static bool isMirrored() { return !!((MirrorFlag ^ PlaneMirrorFlag) & 1); } + virtual int ClipSeg(seg_t *seg) { return PClip_Inside; } virtual int ClipSubsector(subsector_t *sub) { return PClip_Inside; } virtual int ClipPoint(const DVector2 &pos) { return PClip_Inside; } From 09f1859c8343394340a0c22cf40a26b68d75b8f5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 21 Jan 2018 18:49:46 +0100 Subject: [PATCH 27/29] - allow retrieving the length of a string constant. --- src/scripting/backend/codegen.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/scripting/backend/codegen.cpp b/src/scripting/backend/codegen.cpp index a8aa1a897f..a9c7e4fcc9 100644 --- a/src/scripting/backend/codegen.cpp +++ b/src/scripting/backend/codegen.cpp @@ -9378,6 +9378,13 @@ FxExpression *FxStrLen::Resolve(FCompileContext &ctx) { SAFE_RESOLVE(Self, ctx); assert(Self->ValueType == TypeString); + if (Self->isConstant()) + { + auto constself = static_cast(Self); + auto constlen = new FxConstant((int)constself->GetValue().GetString().Len(), Self->ScriptPosition); + delete this; + return constlen->Resolve(ctx); + } ValueType = TypeUInt32; return this; } From 76d594f95266e3acb4e9f03c738efac945a6e89d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 21 Jan 2018 19:25:21 +0100 Subject: [PATCH 28/29] - reverted the hard offset for transferred skies. This is not the correct way to apply it. --- src/gl/scene/gl_sky.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl/scene/gl_sky.cpp b/src/gl/scene/gl_sky.cpp index 90642ddfdb..3186dc987c 100644 --- a/src/gl/scene/gl_sky.cpp +++ b/src/gl/scene/gl_sky.cpp @@ -69,7 +69,7 @@ void GLSkyInfo::init(int sky1, PalEntry FadeColor) if (!texture[0] || texture[0]->tex->UseType == FTexture::TEX_Null) goto normalsky; skytexno1 = texno; x_offset[0] = s->GetTextureXOffset(pos) * (360.f/65536.f); - y_offset = s->GetTextureYOffset(pos) - 28.0; + y_offset = s->GetTextureYOffset(pos); mirrored = !l->args[2]; } else From 47b276024e66385a45c2dd8113e8df466e68fa0e Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 22 Jan 2018 12:29:16 +0200 Subject: [PATCH 29/29] Fixed compilation warnings reported by MSVC src\p_map.cpp(4857): warning C4800: 'int': forcing value to bool 'true' or 'false' (performance warning) src\p_map.cpp(4858): warning C4800: 'int': forcing value to bool 'true' or 'false' (performance warning) --- src/p_map.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_map.cpp b/src/p_map.cpp index 6c269e8101..8e445862a3 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -4854,8 +4854,8 @@ bool P_LineTrace(AActor *t1, DAngle angle, double distance, FTraceResults trace; CheckLineData TData; TData.Caller = t1; - TData.ThruSpecies = (flags & TRF_THRUSPECIES); - TData.ThruActors = (flags & TRF_THRUACTORS); + TData.ThruSpecies = !!(flags & TRF_THRUSPECIES); + TData.ThruActors = !!(flags & TRF_THRUACTORS); TData.NumPortals = 0; DVector3 direction; double pc = pitch.Cos();