From 1ed1222e10d4fa26e1d9f5f1b6ee5aaf72eec3d4 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Mon, 2 Aug 2021 12:34:15 +1000 Subject: [PATCH 01/89] - Extend menu's `ListMenu` ZScript class with `mAnimated` already natively available, and use with Blood where `BloodDripDrawer` is defined. * Finalises the interpolated blood dripping code changes from 9884d5f396a952f992d3e943cb01c45c7f497c05. --- source/common/menu/menu.cpp | 1 + source/common/menu/menudef.cpp | 4 ++++ wadsrc/static/menudef.txt | 4 ++++ wadsrc/static/zscript/engine/ui/menu/listmenu.zs | 2 ++ 4 files changed, 11 insertions(+) diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index bf773214d..231fb94a5 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -1036,6 +1036,7 @@ DEFINE_FIELD(DListMenuDescriptor, mFont) DEFINE_FIELD(DListMenuDescriptor, mFontColor) DEFINE_FIELD(DListMenuDescriptor, mFontColor2) DEFINE_FIELD(DListMenuDescriptor, mAnimatedTransition) +DEFINE_FIELD(DListMenuDescriptor, mAnimated) DEFINE_FIELD(DListMenuDescriptor, mCenter) DEFINE_FIELD(DListMenuDescriptor, mVirtWidth) DEFINE_FIELD(DListMenuDescriptor, mVirtHeight) diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index da73517b0..c5ce40b2a 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -344,6 +344,10 @@ static void DoParseListMenuBody(FScanner &sc, DListMenuDescriptor *desc, bool &s { desc->mAnimatedTransition = true; } + else if (sc.Compare("animated")) + { + desc->mAnimated = true; + } else if (sc.Compare("MouseWindow")) { sc.MustGetNumber(); diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 16db5aae7..157946458 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -40,6 +40,7 @@ LISTMENU "MainMenu" BloodTextItem "$MNU_CREDITS", "c", "CreditsMenu" BloodTextItem "$MNU_QUITGAME", "q", "QuitMenu" BloodDripDrawer + animated } ifgame(ShadowWarrior) { @@ -112,6 +113,7 @@ LISTMENU "IngameMenu" BloodTextItem "$MNU_ENDGAME", "e", "EndgameMenu" BloodTextItem "$MNU_QUITGAME", "q", "QuitMenu" BloodDripDrawer + animated } ifgame(ShadowWarrior) { @@ -169,6 +171,7 @@ LISTMENU "EpisodeMenu" Linespacing 20 CaptionItem "$MNU_EPISODES" BloodDripDrawer + animated } ifgame(ShadowWarrior) { @@ -194,6 +197,7 @@ LISTMENU "SkillMenu" Linespacing 20 CaptionItem "$MNU_DIFFICULTY" BloodDripDrawer + animated } ifgame(ShadowWarrior) { diff --git a/wadsrc/static/zscript/engine/ui/menu/listmenu.zs b/wadsrc/static/zscript/engine/ui/menu/listmenu.zs index dc12f4129..14cd07569 100644 --- a/wadsrc/static/zscript/engine/ui/menu/listmenu.zs +++ b/wadsrc/static/zscript/engine/ui/menu/listmenu.zs @@ -56,6 +56,7 @@ class ListMenuDescriptor : MenuDescriptor native native int mFontColor2; native bool mCenter; native bool mAnimatedTransition; + native bool mAnimated; native int mVirtWidth, mVirtHeight; native void Reset(); @@ -87,6 +88,7 @@ class ListMenu : Menu Super.Init(parent); mDesc = desc; AnimatedTransition = mDesc.mAnimatedTransition; + Animated = mDesc.mAnimated; if (desc.mCenter) { double center = 160; From 0d9afc1aafd3eddbd5ddfe7274ab1a3bb5835ef7 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Thu, 5 Aug 2021 13:11:07 +1000 Subject: [PATCH 02/89] - Extend menu's `ImageScroller` ZScript class with `mAnimated` and use with Blood for the help and credits menu. --- source/common/menu/menu.cpp | 1 + source/common/menu/menu.h | 1 + source/common/menu/menudef.cpp | 4 ++++ wadsrc/static/menudef.txt | 2 ++ wadsrc/static/zscript/engine/ui/menu/imagescroller.zs | 5 ++++- 5 files changed, 12 insertions(+), 1 deletion(-) diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 231fb94a5..bbfe2f4a5 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -1067,6 +1067,7 @@ DEFINE_FIELD(DImageScrollerDescriptor, textBackgroundBrightness) DEFINE_FIELD(DImageScrollerDescriptor,textFont) DEFINE_FIELD(DImageScrollerDescriptor, textScale) DEFINE_FIELD(DImageScrollerDescriptor, mAnimatedTransition) +DEFINE_FIELD(DImageScrollerDescriptor, mAnimated) DEFINE_FIELD(DImageScrollerDescriptor, virtWidth) DEFINE_FIELD(DImageScrollerDescriptor, virtHeight) diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index d6f200bfc..a8ed61061 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -141,6 +141,7 @@ public: FFont *textFont; double textScale; bool mAnimatedTransition; + bool mAnimated; int virtWidth, virtHeight; }; diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index c5ce40b2a..3b6f25a1e 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -1216,6 +1216,10 @@ static void ParseImageScrollerBody(FScanner& sc, DImageScrollerDescriptor* desc) { desc->mAnimatedTransition = true; } + else if (sc.Compare("animated")) + { + desc->mAnimated = true; + } else if (sc.Compare("textBackground")) { sc.MustGetString(); diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 157946458..b0eb740d8 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -236,6 +236,7 @@ ImageScroller "HelpMenu" QAVDrawer "Help4.qav" QAVDrawer "Help5.qav" QAVDrawer "Help3b.qav" + animated } ifgame(ShadowWarrior) { @@ -356,6 +357,7 @@ ImageScroller "CreditsMenu" ifgame(blood) { QAVDrawer "Credits.qav" + animated } ifgame(ShadowWarrior) { diff --git a/wadsrc/static/zscript/engine/ui/menu/imagescroller.zs b/wadsrc/static/zscript/engine/ui/menu/imagescroller.zs index 45607448a..cab771ae7 100644 --- a/wadsrc/static/zscript/engine/ui/menu/imagescroller.zs +++ b/wadsrc/static/zscript/engine/ui/menu/imagescroller.zs @@ -40,6 +40,7 @@ class ImageScrollerDescriptor : MenuDescriptor native native Color textBackgroundBrightness; native double textScale; native bool mAnimatedTransition; + native bool mAnimated; native int virtWidth, virtHeight; } @@ -168,6 +169,7 @@ class ImageScrollerMenu : Menu index = 0; mDesc = desc; AnimatedTransition = desc.mAnimatedTransition; + Animated = desc.mAnimated; current = mDesc.mItems[0]; current.onStartPage(); previous = null; @@ -273,11 +275,12 @@ class ImageScrollerMenu : Menu { if (previous != null) { + bool wasAnimated = Animated; Animated = true; if (DrawTransition()) return; previous = null; + Animated = wasAnimated; } current.Drawer(false); - Animated = false; } } From 4a70f6efd0ffa83e99c5a7e981ee2cda8d5e821f Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sun, 1 Aug 2021 23:02:13 +1000 Subject: [PATCH 03/89] - Allow ticrate to be specified to timer code, while still defaulting to `GameTicRate`. Move out `I_GetBuildTime()` from common code to `gamefuncs.h` as part of this. * Allow specification of floating point ticrates as it's possible Blood's QAVs could have a fractional ticrate. --- source/common/utility/i_time.cpp | 39 +++++++++++--------------------- source/common/utility/i_time.h | 9 +++----- source/core/gamefuncs.h | 5 ++++ 3 files changed, 21 insertions(+), 32 deletions(-) diff --git a/source/common/utility/i_time.cpp b/source/common/utility/i_time.cpp index 0a7179660..cc8f5f1de 100644 --- a/source/common/utility/i_time.cpp +++ b/source/common/utility/i_time.cpp @@ -67,22 +67,14 @@ static uint64_t NSToMS(uint64_t ns) return static_cast(ns / 1'000'000); } -static int NSToTic(uint64_t ns) +static int NSToTic(uint64_t ns, double const ticrate) { - return static_cast(ns * GameTicRate / 1'000'000'000); + return static_cast(ns * ticrate / 1'000'000'000); } -static int NSToBuildTic(uint64_t ns) +static uint64_t TicToNS(double tic, double const ticrate) { - return static_cast(ns * 120 / 1'000'000'000); -} -static uint64_t TicToNS(int tic) -{ - return static_cast(tic) * 1'000'000'000 / GameTicRate; -} -static uint64_t BuildTicToNS(int tic) -{ - return static_cast(tic) * 1'000'000'000 / 120; + return static_cast(tic * 1'000'000'000 / ticrate); } void I_SetFrameTime() @@ -111,18 +103,18 @@ void I_WaitVBL(int count) I_SetFrameTime(); } -int I_WaitForTic(int prevtic) +int I_WaitForTic(int prevtic, double const ticrate) { // Waits until the current tic is greater than prevtic. Time must not be frozen. int time; - while ((time = I_GetTime()) <= prevtic) + while ((time = I_GetTime(ticrate)) <= prevtic) { // Windows-specific note: // The minimum amount of time a thread can sleep is controlled by timeBeginPeriod. // We set this to 1 ms in DoMain. - const uint64_t next = FirstFrameStartTime + TicToNS(prevtic + 1); + const uint64_t next = FirstFrameStartTime + TicToNS(prevtic + 1, ticrate); const uint64_t now = I_nsTime(); if (next > now) @@ -166,21 +158,16 @@ uint64_t I_GetTimeNS() return CurrentFrameStartTime - FirstFrameStartTime; } -int I_GetTime() +int I_GetTime(double const ticrate) { - return NSToTic(CurrentFrameStartTime - FirstFrameStartTime); + return NSToTic(CurrentFrameStartTime - FirstFrameStartTime, ticrate); } -int I_GetBuildTime() +double I_GetTimeFrac(double const ticrate) { - return NSToBuildTic(CurrentFrameStartTime - FirstFrameStartTime); -} - -double I_GetTimeFrac() -{ - int currentTic = NSToTic(CurrentFrameStartTime - FirstFrameStartTime); - uint64_t ticStartTime = FirstFrameStartTime + TicToNS(currentTic); - uint64_t ticNextTime = FirstFrameStartTime + TicToNS(currentTic + 1); + int currentTic = NSToTic(CurrentFrameStartTime - FirstFrameStartTime, ticrate); + uint64_t ticStartTime = FirstFrameStartTime + TicToNS(currentTic, ticrate); + uint64_t ticNextTime = FirstFrameStartTime + TicToNS(currentTic + 1, ticrate); return (CurrentFrameStartTime - ticStartTime) / (double)(ticNextTime - ticStartTime); } diff --git a/source/common/utility/i_time.h b/source/common/utility/i_time.h index 8b4eff05c..27ebdae2a 100644 --- a/source/common/utility/i_time.h +++ b/source/common/utility/i_time.h @@ -9,17 +9,14 @@ extern double TimeScale; void I_SetFrameTime(); // Called by D_DoomLoop, returns current time in tics. -int I_GetTime(); +int I_GetTime(double const ticrate = GameTicRate); // same, but using nanoseconds uint64_t I_GetTimeNS(); -// Called by Build games in lieu of totalclock, returns current time in tics at ticrate of 120. -int I_GetBuildTime(); - -double I_GetTimeFrac(); +double I_GetTimeFrac(double const ticrate = GameTicRate); // like I_GetTime, except it waits for a new tic before returning -int I_WaitForTic(int); +int I_WaitForTic(int prevtic, double const ticrate = GameTicRate); // Freezes tic counting temporarily. While frozen, calls to I_GetTime() // will always return the same value. diff --git a/source/core/gamefuncs.h b/source/core/gamefuncs.h index bc11f3428..7a287746d 100644 --- a/source/core/gamefuncs.h +++ b/source/core/gamefuncs.h @@ -156,3 +156,8 @@ inline int spriteGetSlope(int spritenum) auto spr = &sprite[spritenum]; return ((spr->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) != CSTAT_SPRITE_ALIGNMENT_SLOPE) ? 0 : uint8_t(spr->xoffset) + (uint8_t(spr->yoffset) << 8); } + +inline int I_GetBuildTime() +{ + return I_GetTime(120); +} From 502b76af7001a2ea1ff8894aa2d469cadcda4104 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Wed, 18 Aug 2021 20:00:15 +1000 Subject: [PATCH 04/89] - Blood: Parse the values of the QAV files instead of casting the binary data so we can extend the struct. --- source/games/blood/src/qav.cpp | 75 +++++++++++++++++++--------------- source/games/blood/src/qav.h | 4 -- 2 files changed, 41 insertions(+), 38 deletions(-) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 0501a4082..dbebc6ec3 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -222,37 +222,6 @@ void QAV::Precache(int palette) } -void ByteSwapQAV(void* p) -{ -#if B_BIG_ENDIAN == 1 - QAV* qav = (QAV*)p; - qav->nFrames = LittleLong(qav->nFrames); - qav->ticksPerFrame = LittleLong(qav->ticksPerFrame); - qav->version = LittleLong(qav->version); - qav->x = LittleLong(qav->x); - qav->y = LittleLong(qav->y); - qav->nSprite = LittleLong(qav->nSprite); - for (int i = 0; i < qav->nFrames; i++) - { - FRAMEINFO* pFrame = &qav->frames[i]; - SOUNDINFO* pSound = &pFrame->sound; - pFrame->nCallbackId = LittleLong(pFrame->nCallbackId); - pSound->sound = LittleLong(pSound->sound); - for (int j = 0; j < 8; j++) - { - TILE_FRAME* pTile = &pFrame->tiles[j]; - pTile->picnum = LittleLong(pTile->picnum); - pTile->x = LittleLong(pTile->x); - pTile->y = LittleLong(pTile->y); - pTile->z = LittleLong(pTile->z); - pTile->stat = LittleLong(pTile->stat); - pTile->angle = LittleShort(pTile->angle); - } - } -#endif -} - - // This is to eliminate a huge design issue in NBlood that was apparently copied verbatim from the DOS-Version. // Sequences were cached in the resource and directly returned from there in writable form, with byte swapping directly performed in the cache on Big Endian systems. // To avoid such unsafe operations this caches the read data separately. @@ -269,10 +238,48 @@ QAV* getQAV(int res_id) return nullptr; } auto fr = fileSystem.OpenFileReader(index); - auto qavdata = (QAV*)seqcache.Alloc(fr.GetLength()); - fr.Read(qavdata, fr.GetLength()); + + // Start reading QAV for nFrames, skipping padded data. + for (int i = 0; i < 8; i++) fr.ReadUInt8(); + int nFrames = fr.ReadInt32(); + auto qavdata = (QAV*)seqcache.Alloc(sizeof(QAV) + ((nFrames - 1) * sizeof(FRAMEINFO))); + + // Write out QAV data. + qavdata->nFrames = nFrames; + qavdata->ticksPerFrame = fr.ReadInt32(); + qavdata->duration = fr.ReadInt32(); + qavdata->x = fr.ReadInt32(); + qavdata->y = fr.ReadInt32(); + qavdata->nSprite = fr.ReadInt32(); + for (int i = 0; i < 4; i++) fr.ReadUInt8(); + + // Read FRAMEINFO data. + for (int i = 0; i < qavdata->nFrames; i++) + { + qavdata->frames[i].nCallbackId = fr.ReadInt32(); + + // Read SOUNDINFO data. + qavdata->frames[i].sound.sound = fr.ReadInt32(); + qavdata->frames[i].sound.priority = fr.ReadUInt8(); + qavdata->frames[i].sound.sndFlags = fr.ReadUInt8(); + qavdata->frames[i].sound.sndRange = fr.ReadUInt8(); + for (int i = 0; i < 1; i++) fr.ReadUInt8(); + + // Read TILE_FRAME data. + for (int j = 0; j < 8; j++) + { + qavdata->frames[i].tiles[j].picnum = fr.ReadInt32(); + qavdata->frames[i].tiles[j].x = fr.ReadInt32(); + qavdata->frames[i].tiles[j].y = fr.ReadInt32(); + qavdata->frames[i].tiles[j].z = fr.ReadInt32(); + qavdata->frames[i].tiles[j].stat = fr.ReadInt32(); + qavdata->frames[i].tiles[j].shade = fr.ReadInt8(); + qavdata->frames[i].tiles[j].palnum = fr.ReadUInt8(); + qavdata->frames[i].tiles[j].angle = fr.ReadUInt16(); + } + } + qavcache.Insert(res_id, qavdata); - ByteSwapQAV(qavdata); return qavdata; } diff --git a/source/games/blood/src/qav.h b/source/games/blood/src/qav.h index 63c0c98bb..798d0c03e 100644 --- a/source/games/blood/src/qav.h +++ b/source/games/blood/src/qav.h @@ -29,8 +29,6 @@ BEGIN_BLD_NS enum { kQavOrientationLeft = 4096 }; -#pragma pack(push, 1) - // by NoOne: add sound flags enum { @@ -86,8 +84,6 @@ struct QAV void Precache(int palette = 0); }; -#pragma pack(pop) - QAV* getQAV(int res_id); END_BLD_NS From c75778c08d671de4688b8d0f77e79a819f7f08bb Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Thu, 5 Aug 2021 14:48:32 +1000 Subject: [PATCH 05/89] - Blood: Re-time menu's blood dripping based on reworked timer and QAV struct code. --- source/games/blood/src/d_menu.cpp | 37 +++++++++---------------------- source/games/blood/src/qav.cpp | 18 +++++++++++++++ source/games/blood/src/qav.h | 3 ++- 3 files changed, 30 insertions(+), 28 deletions(-) diff --git a/source/games/blood/src/d_menu.cpp b/source/games/blood/src/d_menu.cpp index be4292249..b747adeaf 100644 --- a/source/games/blood/src/d_menu.cpp +++ b/source/games/blood/src/d_menu.cpp @@ -41,8 +41,7 @@ BEGIN_BLD_NS class CGameMenuItemQAV { public: - int m_nX, m_nY; - TArray raw; + QAV* data; int duration; int lastTick; bool bWideScreen; @@ -54,25 +53,20 @@ public: CGameMenuItemQAV::CGameMenuItemQAV(int a3, int a4, const char* name, bool widescreen, bool clearbackground) { - m_nY = a4; - m_nX = a3; bWideScreen = widescreen; bClearBackground = clearbackground; filename = name; if (name) { - // NBlood read this directly from the file system cache, but let's better store the data locally for robustness. - raw = fileSystem.LoadFile(name, 0); - if (raw.Size() != 0) + data = getQAV(fileSystem.GetResourceId(fileSystem.FindFile(name))); + if (data) { - auto data = (QAV*)raw.Data(); data->nSprite = -1; - data->x = m_nX; - data->y = m_nY; - //data->Preload(); + data->x = a3; + data->y = a4; duration = data->duration; - lastTick = I_GetTime(); + lastTick = I_GetTime(data->ticrate); } } } @@ -82,29 +76,18 @@ void CGameMenuItemQAV::Draw(void) if (bClearBackground) twod->ClearScreen(); - if (raw.Size() > 0) + if (data) { - auto data = (QAV*)raw.Data(); - - auto thisTick = I_GetTime(); - if (!lastTick) - { - lastTick = thisTick; - } - if (lastTick < thisTick) - { - lastTick = thisTick; - duration -= 4; - } + qavProcessTicker(data, &duration, &lastTick); if (duration <= 0 || duration > data->duration) { duration = data->duration; } auto currentDuration = data->duration - duration; - auto smoothratio = I_GetTimeFrac() * MaxSmoothRatio; + auto smoothratio = I_GetTimeFrac(data->ticrate) * MaxSmoothRatio; - data->Play(currentDuration - 4, currentDuration, -1, NULL); + data->Play(currentDuration - data->ticksPerFrame, currentDuration, -1, NULL); if (bWideScreen) { diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index dbebc6ec3..ef985fc9e 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -221,6 +221,21 @@ void QAV::Precache(int palette) } } +void qavProcessTicker(QAV* const pQAV, int* duration, int* lastTick) +{ + if (*duration > 0) + { + auto thisTick = I_GetTime(pQAV->ticrate); + auto numTicks = thisTick - (*lastTick); + if (numTicks) + { + *lastTick = thisTick; + *duration -= pQAV->ticksPerFrame * numTicks; + } + } + *duration = ClipLow(*duration, 0); +} + // This is to eliminate a huge design issue in NBlood that was apparently copied verbatim from the DOS-Version. // Sequences were cached in the resource and directly returned from there in writable form, with byte swapping directly performed in the cache on Big Endian systems. @@ -279,6 +294,9 @@ QAV* getQAV(int res_id) } } + // Write out additions. + qavdata->ticrate = 120. / qavdata->ticksPerFrame; + qavcache.Insert(res_id, qavdata); return qavdata; } diff --git a/source/games/blood/src/qav.h b/source/games/blood/src/qav.h index 798d0c03e..805fd3582 100644 --- a/source/games/blood/src/qav.h +++ b/source/games/blood/src/qav.h @@ -67,7 +67,7 @@ struct FRAMEINFO struct QAV { - char pad1[8]; // 0 + double ticrate; // 0 int nFrames; // 8 int ticksPerFrame; // C int duration; // 10 @@ -85,5 +85,6 @@ struct QAV }; QAV* getQAV(int res_id); +void qavProcessTicker(QAV* const pQAV, int* duration, int* lastTick); END_BLD_NS From ab502ebc666cb797a60bcb61b29b75554d56ce77 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Wed, 4 Aug 2021 11:38:00 +1000 Subject: [PATCH 06/89] - Blood: Ensure looped QAVs interpolate using last frame in the array. --- source/games/blood/src/d_menu.cpp | 14 +++++++------- source/games/blood/src/nnexts.cpp | 4 ++-- source/games/blood/src/qav.cpp | 7 ++++--- source/games/blood/src/qav.h | 7 ++++--- source/games/blood/src/weapon.cpp | 2 +- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/source/games/blood/src/d_menu.cpp b/source/games/blood/src/d_menu.cpp index b747adeaf..bb553e68b 100644 --- a/source/games/blood/src/d_menu.cpp +++ b/source/games/blood/src/d_menu.cpp @@ -46,16 +46,16 @@ public: int lastTick; bool bWideScreen; bool bClearBackground; - const char* filename; - CGameMenuItemQAV(int, int, const char*, bool widescreen = false, bool clearbackground = false); + bool bLooped; + CGameMenuItemQAV(int, int, const char*, bool widescreen = false, bool clearbackground = false, bool looped = false); void Draw(void); }; -CGameMenuItemQAV::CGameMenuItemQAV(int a3, int a4, const char* name, bool widescreen, bool clearbackground) +CGameMenuItemQAV::CGameMenuItemQAV(int a3, int a4, const char* name, bool widescreen, bool clearbackground, bool looped) { bWideScreen = widescreen; bClearBackground = clearbackground; - filename = name; + bLooped = looped; if (name) { @@ -96,13 +96,13 @@ void CGameMenuItemQAV::Draw(void) int backX = data->x; for (int i = 0; i < nCount; i++) { - data->Draw(currentDuration, 10 + kQavOrientationLeft, 0, 0, false, smoothratio, filename == "BDRIP.QAV"); + data->Draw(currentDuration, 10 + kQavOrientationLeft, 0, 0, false, smoothratio, bLooped); data->x += 320; } data->x = backX; } else - data->Draw(currentDuration, 10, 0, 0, false, smoothratio, filename == "BDRIP.QAV"); + data->Draw(currentDuration, 10, 0, 0, false, smoothratio, bLooped); } } @@ -137,7 +137,7 @@ void UpdateNetworkMenus(void) void GameInterface::MenuOpened() { - itemBloodQAV.reset(new CGameMenuItemQAV(160, 100, "BDRIP.QAV", true)); + itemBloodQAV.reset(new CGameMenuItemQAV(160, 100, "BDRIP.QAV", true, false, true)); } void GameInterface::MenuClosed() diff --git a/source/games/blood/src/nnexts.cpp b/source/games/blood/src/nnexts.cpp index 87efb285e..151f46a91 100644 --- a/source/games/blood/src/nnexts.cpp +++ b/source/games/blood/src/nnexts.cpp @@ -6200,13 +6200,13 @@ void playerQavSceneDraw(PLAYER* pPlayer, int a2, double a3, double a4, int a5, d if (!(pSprite->flags & kModernTypeFlag1)) { pQAV->x = int(a3); pQAV->y = int(a4); - pQAV->Draw(a3, a4, v4, flags, a2, a5, true, smoothratio); + pQAV->Draw(a3, a4, v4, flags, a2, a5, true, smoothratio, pPlayer->qavLoop); // draw fullscreen (currently 4:3 only) } else { // What an awful hack. This throws proper ordering out of the window, but there is no way to reproduce this better with strict layering of elements. // From the above commit it seems to be incomplete anyway... - pQAV->Draw(v4, flags, a2, a5, false, smoothratio); + pQAV->Draw(v4, flags, a2, a5, false, smoothratio, pPlayer->qavLoop); } } diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index ef985fc9e..084848be4 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -72,7 +72,7 @@ void DrawFrame(double x, double y, double z, double a, TILE_FRAME *pTile, int st } } -void QAV::Draw(double x, double y, int ticks, int stat, int shade, int palnum, bool to3dview, double const smoothratio, bool const menudrip) +void QAV::Draw(double x, double y, int ticks, int stat, int shade, int palnum, bool to3dview, double const smoothratio, bool const looped) { assert(ticksPerFrame > 0); @@ -89,7 +89,7 @@ void QAV::Draw(double x, double y, int ticks, int stat, int shade, int palnum, b lastframetic = 0; } - int oFrame = nFrame == 0 || (lastframetic && ticks > lastframetic) ? nFrame : nFrame - 1; + int oFrame = nFrame == 0 || (lastframetic && ticks > lastframetic) ? !looped ? nFrame : nFrames - 1 : nFrame - 1; assert(oFrame >= 0 && oFrame < nFrames); FRAMEINFO *prevFrame = &frames[oFrame]; @@ -126,7 +126,7 @@ void QAV::Draw(double x, double y, int ticks, int stat, int shade, int palnum, b if (thisTile->picnum > 0) { // Menu's blood drip requires special treatment. - if (menudrip) + if (res_id == 256) { if (i != 0) { @@ -295,6 +295,7 @@ QAV* getQAV(int res_id) } // Write out additions. + qavdata->res_id = res_id; qavdata->ticrate = 120. / qavdata->ticksPerFrame; qavcache.Insert(res_id, qavdata); diff --git a/source/games/blood/src/qav.h b/source/games/blood/src/qav.h index 805fd3582..e12bce495 100644 --- a/source/games/blood/src/qav.h +++ b/source/games/blood/src/qav.h @@ -75,11 +75,12 @@ struct QAV int y; // 18 int nSprite; // 1c //SPRITE *pSprite; // 1c - char pad3[3]; // 20 + char pad3[1]; // 20 char lastframetic; + unsigned short res_id; FRAMEINFO frames[1]; // 24 - void Draw(double x, double y, int ticks, int stat, int shade, int palnum, bool to3dview, double const smoothratio = 65536, bool const menudrip = false); - void Draw(int ticks, int stat, int shade, int palnum, bool to3dview, double const smoothratio = 65536, bool const menudrip = false) { Draw(x, y, ticks, stat, shade, palnum, to3dview, smoothratio, menudrip); } + void Draw(double x, double y, int ticks, int stat, int shade, int palnum, bool to3dview, double const smoothratio = 65536, bool const looped = false); + void Draw(int ticks, int stat, int shade, int palnum, bool to3dview, double const smoothratio = 65536, bool const looped = false) { Draw(x, y, ticks, stat, shade, palnum, to3dview, smoothratio, looped); } void Play(int, int, int, void *); void Precache(int palette = 0); }; diff --git a/source/games/blood/src/weapon.cpp b/source/games/blood/src/weapon.cpp index 51f690220..731c2849c 100644 --- a/source/games/blood/src/weapon.cpp +++ b/source/games/blood/src/weapon.cpp @@ -281,7 +281,7 @@ void WeaponDraw(PLAYER *pPlayer, int shade, double xpos, double ypos, int palnum shade = -128; flags |= 1; } - pQAV->Draw(xpos, ypos, duration, flags, shade, palnum, true, smoothratio); + pQAV->Draw(xpos, ypos, duration, flags, shade, palnum, true, smoothratio, pPlayer->qavLoop); } void WeaponPlay(PLAYER *pPlayer) From 24fbaa527c4a9a06b08dd25388877f7241e781ec Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Thu, 5 Aug 2021 12:38:26 +1000 Subject: [PATCH 07/89] - Blood: Re-time weapon and scene QAV code based on reworked timer and QAV struct code. --- source/games/blood/src/blood.cpp | 2 ++ source/games/blood/src/hudsprites.cpp | 8 ++++---- source/games/blood/src/misc.h | 2 +- source/games/blood/src/nnexts.cpp | 9 +++++++-- source/games/blood/src/nnexts.h | 2 +- source/games/blood/src/player.cpp | 6 ++++++ source/games/blood/src/player.h | 2 ++ source/games/blood/src/qav.cpp | 25 +++++++++++++++++++++++++ source/games/blood/src/qav.h | 1 + source/games/blood/src/weapon.cpp | 19 ++++++++++--------- 10 files changed, 59 insertions(+), 17 deletions(-) diff --git a/source/games/blood/src/blood.cpp b/source/games/blood/src/blood.cpp index c53284831..3693ad73f 100644 --- a/source/games/blood/src/blood.cpp +++ b/source/games/blood/src/blood.cpp @@ -201,6 +201,8 @@ void StartLevel(MapRecord* level, bool newgame) pPlayer->qavLoop = gPlayerTemp[i].qavLoop; pPlayer->weaponTimer = gPlayerTemp[i].weaponTimer; pPlayer->nextWeapon = gPlayerTemp[i].nextWeapon; + pPlayer->qavLastTick = gPlayerTemp[i].qavLastTick; + pPlayer->qavTimer = gPlayerTemp[i].qavTimer; } } PreloadCache(); diff --git a/source/games/blood/src/hudsprites.cpp b/source/games/blood/src/hudsprites.cpp index bb0f4a311..6af4b9dbf 100644 --- a/source/games/blood/src/hudsprites.cpp +++ b/source/games/blood/src/hudsprites.cpp @@ -127,14 +127,14 @@ void hudDraw(PLAYER *gView, int nSectnum, double bobx, double boby, double zDelt } #ifdef NOONE_EXTENSIONS - if (gView->sceneQav < 0) WeaponDraw(gView, nShade, cX, cY, nPalette, smoothratio); - else if (gView->pXSprite->health > 0) playerQavSceneDraw(gView, nShade, cX, cY, nPalette, smoothratio); + if (gView->sceneQav < 0) WeaponDraw(gView, nShade, cX, cY, nPalette); + else if (gView->pXSprite->health > 0) playerQavSceneDraw(gView, nShade, cX, cY, nPalette); else { gView->sceneQav = gView->weaponQav = -1; - gView->weaponTimer = gView->curWeapon = 0; + gView->qavTimer = gView->weaponTimer = gView->curWeapon = 0; } #else - WeaponDraw(gView, nShade, cX, cY, nPalette, smoothratio); + WeaponDraw(gView, nShade, cX, cY, nPalette); #endif } if (gViewPos == 0 && gView->pXSprite->burnTime > 60) diff --git a/source/games/blood/src/misc.h b/source/games/blood/src/misc.h index 3d2fbd214..fcd7b8da1 100644 --- a/source/games/blood/src/misc.h +++ b/source/games/blood/src/misc.h @@ -46,7 +46,7 @@ struct PLAYER; extern QAV* weaponQAV[]; void WeaponInit(void); -void WeaponDraw(PLAYER *pPlayer, int a2, double a3, double a4, int a5, double smoothratio); +void WeaponDraw(PLAYER *pPlayer, int a2, double a3, double a4, int a5); void WeaponRaise(PLAYER *pPlayer); void WeaponLower(PLAYER *pPlayer); int WeaponUpgrade(PLAYER *pPlayer, int newWeapon); diff --git a/source/games/blood/src/nnexts.cpp b/source/games/blood/src/nnexts.cpp index 151f46a91..ba6910953 100644 --- a/source/games/blood/src/nnexts.cpp +++ b/source/games/blood/src/nnexts.cpp @@ -1844,6 +1844,8 @@ void trPlayerCtrlStartScene(XSPRITE* pXSource, PLAYER* pPlayer, bool force) { pPlayer->weaponTimer = pCtrl->qavScene.qavResrc->duration; pPlayer->qavCallback = (pXSource->data3 > 0) ? ClipRange(pXSource->data3 - 1, 0, 32) : -1; pPlayer->qavLoop = false; + pPlayer->qavLastTick = I_GetTime(pCtrl->qavScene.qavResrc->ticrate); + pPlayer->qavTimer = pCtrl->qavScene.qavResrc->duration; } @@ -6180,7 +6182,7 @@ void playerQavSceneProcess(PLAYER* pPlayer, QAVSCENE* pQavScene) { } } -void playerQavSceneDraw(PLAYER* pPlayer, int a2, double a3, double a4, int a5, double smoothratio) { +void playerQavSceneDraw(PLAYER* pPlayer, int a2, double a3, double a4, int a5) { if (pPlayer == NULL || pPlayer->sceneQav == -1) return; QAVSCENE* pQavScene = &gPlayerCtrl[pPlayer->nPlayer].qavScene; @@ -6189,7 +6191,10 @@ void playerQavSceneDraw(PLAYER* pPlayer, int a2, double a3, double a4, int a5, d if (pQavScene->qavResrc != NULL) { QAV* pQAV = pQavScene->qavResrc; - int v4 = (pPlayer->weaponTimer == 0) ? ((PlayClock + MulScale(4, int(smoothratio), 16)) % pQAV->duration) : pQAV->duration - pPlayer->weaponTimer; + int v4; + double smoothratio; + + qavProcessTimer(pPlayer, pQAV, &v4, &smoothratio); int flags = 2; int nInv = powerupCheck(pPlayer, kPwUpShadowCloak); if (nInv >= 120 * 8 || (nInv != 0 && (PlayClock & 32))) { diff --git a/source/games/blood/src/nnexts.h b/source/games/blood/src/nnexts.h index 3c46d063b..044758c2a 100644 --- a/source/games/blood/src/nnexts.h +++ b/source/games/blood/src/nnexts.h @@ -384,7 +384,7 @@ void playerDeactivateShrooms(PLAYER* pPlayer); QAV* playerQavSceneLoad(int qavId); void playerQavSceneProcess(PLAYER* pPlayer, QAVSCENE* pQavScene); void playerQavScenePlay(PLAYER* pPlayer); -void playerQavSceneDraw(PLAYER* pPlayer, int a2, double a3, double a4, int a5, double smoothratio); +void playerQavSceneDraw(PLAYER* pPlayer, int a2, double a3, double a4, int a5); void playerQavSceneReset(PLAYER* pPlayer); // ------------------------------------------------------------------------- // void callbackUniMissileBurst(int nSprite); diff --git a/source/games/blood/src/player.cpp b/source/games/blood/src/player.cpp index df86d59eb..9cf0895eb 100644 --- a/source/games/blood/src/player.cpp +++ b/source/games/blood/src/player.cpp @@ -740,6 +740,8 @@ void playerStart(int nPlayer, int bNewLevel) pPlayer->weaponTimer = 0; pPlayer->weaponState = 0; pPlayer->weaponQav = -1; + pPlayer->qavLastTick = 0; + pPlayer->qavTimer = 0; #ifdef NOONE_EXTENSIONS playerQavSceneReset(pPlayer); // reset qav scene @@ -813,6 +815,8 @@ void playerReset(PLAYER *pPlayer) pPlayer->weaponState = 0; pPlayer->weaponQav = -1; pPlayer->qavLoop = 0; + pPlayer->qavLastTick = 0; + pPlayer->qavTimer = 0; pPlayer->packItemId = -1; for (int i = 0; i < 5; i++) { @@ -2249,6 +2253,8 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, PLAYER& w, PLAYER* .Array("weaponorder", &w.weaponOrder[0][0], 14*2) .Array("ammocount", w.ammoCount, countof(w.ammoCount)) ("qavloop", w.qavLoop) + ("qavlastTick", w.qavLastTick) + ("qavtimer", w.qavTimer) ("fusetime", w.fuseTime) ("throwtime", w.throwTime) ("throwpower", w.throwPower) diff --git a/source/games/blood/src/player.h b/source/games/blood/src/player.h index 245042027..1c0cfca62 100644 --- a/source/games/blood/src/player.h +++ b/source/games/blood/src/player.h @@ -127,6 +127,8 @@ struct PLAYER //int at149[14]; int ammoCount[12]; bool qavLoop; + int qavLastTick; + int qavTimer; int fuseTime; int throwTime; int throwPower; diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 084848be4..5d7adf60f 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -236,6 +236,31 @@ void qavProcessTicker(QAV* const pQAV, int* duration, int* lastTick) *duration = ClipLow(*duration, 0); } +void qavProcessTimer(PLAYER* const pPlayer, QAV* const pQAV, int* duration, double* smoothratio, bool const fixedduration) +{ + // Process clock based on QAV's ticrate and last tick value. + qavProcessTicker(pQAV, &pPlayer->qavTimer, &pPlayer->qavLastTick); + + if (pPlayer->weaponTimer == 0) + { + // Check if we're playing an idle QAV as per the ticker's weapon timer. + *duration = fixedduration ? pQAV->duration - 1 : I_GetBuildTime() % pQAV->duration; + *smoothratio = MaxSmoothRatio; + } + else if (pPlayer->qavTimer == 0) + { + // If qavTimer is 0, play the last frame uninterpolated. Sometimes the timer can be just ahead of weaponTimer. + *duration = pQAV->duration - 1; + *smoothratio = MaxSmoothRatio; + } + else + { + // Apply normal values. + *duration = pQAV->duration - pPlayer->qavTimer; + *smoothratio = I_GetTimeFrac(pQAV->ticrate) * MaxSmoothRatio; + } +} + // This is to eliminate a huge design issue in NBlood that was apparently copied verbatim from the DOS-Version. // Sequences were cached in the resource and directly returned from there in writable form, with byte swapping directly performed in the cache on Big Endian systems. diff --git a/source/games/blood/src/qav.h b/source/games/blood/src/qav.h index e12bce495..0571056d6 100644 --- a/source/games/blood/src/qav.h +++ b/source/games/blood/src/qav.h @@ -87,5 +87,6 @@ struct QAV QAV* getQAV(int res_id); void qavProcessTicker(QAV* const pQAV, int* duration, int* lastTick); +void qavProcessTimer(PLAYER* const pPlayer, QAV* const pQAV, int* duration, double* smoothratio, bool const fixedduration = false); END_BLD_NS diff --git a/source/games/blood/src/weapon.cpp b/source/games/blood/src/weapon.cpp index 731c2849c..ea97056c9 100644 --- a/source/games/blood/src/weapon.cpp +++ b/source/games/blood/src/weapon.cpp @@ -255,22 +255,16 @@ bool isOriginalQAV() return cached; } -void WeaponDraw(PLAYER *pPlayer, int shade, double xpos, double ypos, int palnum, double smoothratio) +void WeaponDraw(PLAYER *pPlayer, int shade, double xpos, double ypos, int palnum) { assert(pPlayer != NULL); if (pPlayer->weaponQav == -1) return; QAV * pQAV = weaponQAV[pPlayer->weaponQav]; int duration; + double smoothratio; - if (pPlayer->weaponTimer == 0) // playing idle QAV? - { - // Double shotgun fix from BloodGDX. - if (/*!IsOriginalDemo() &&*/ (pPlayer->weaponState == -1 || (pPlayer->curWeapon == 3 && pPlayer->weaponState == 7))/* && isOriginalQAV()*/) - duration = pQAV->duration - 1; - else duration = (PlayClock + MulScale(4, int(smoothratio), 16)) % pQAV->duration; - } - else duration = pQAV->duration - pPlayer->weaponTimer; + qavProcessTimer(pPlayer, pQAV, &duration, &smoothratio, pPlayer->weaponState == -1 || (pPlayer->curWeapon == 3 && pPlayer->weaponState == 7)); pQAV->x = int(xpos); pQAV->y = int(ypos); @@ -302,6 +296,8 @@ static void StartQAV(PLAYER *pPlayer, int nWeaponQAV, int callback, bool looped pPlayer->weaponTimer = weaponQAV[nWeaponQAV]->duration; pPlayer->qavCallback = callback; pPlayer->qavLoop = looped; + pPlayer->qavLastTick = I_GetTime(weaponQAV[nWeaponQAV]->ticrate); + pPlayer->qavTimer = weaponQAV[nWeaponQAV]->duration; //weaponQAV[nWeaponQAV]->Preload(); WeaponPlay(pPlayer); pPlayer->weaponTimer -= 4; @@ -1913,6 +1909,7 @@ static bool processProxy(PLAYER *pPlayer) case 9: pPlayer->throwPower = ClipHigh(DivScale(PlayClock-pPlayer->throwTime,240, 16), 65536); pPlayer->weaponTimer = 0; + pPlayer->qavTimer = 0; if (!(pPlayer->input.actions & SB_FIRE)) { pPlayer->weaponState = 8; @@ -2043,11 +2040,15 @@ void WeaponProcess(PLAYER *pPlayer) { if (bShoot && CheckAmmo(pPlayer, pPlayer->weaponAmmo, 1)) { while (pPlayer->weaponTimer <= 0) + { pPlayer->weaponTimer += weaponQAV[pPlayer->weaponQav]->duration; + pPlayer->qavTimer += weaponQAV[pPlayer->weaponQav]->duration; + } } else { pPlayer->weaponTimer = 0; + pPlayer->qavTimer = 0; pPlayer->qavLoop = 0; } return; From b01cef7f1529934eb32649a51dae273b5adc076e Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Fri, 6 Aug 2021 09:57:01 +1000 Subject: [PATCH 08/89] - Blood: Remove `lastframetic` hack from `QAV::Draw()` added in 99508e6f1530fb5da2ec4b21a081a275b4c79242 since we now use proper timing code. --- source/games/blood/src/qav.cpp | 15 ++------------- source/games/blood/src/qav.h | 3 +-- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 5d7adf60f..2709deea5 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -76,21 +76,10 @@ void QAV::Draw(double x, double y, int ticks, int stat, int shade, int palnum, b { assert(ticksPerFrame > 0); - int nFrame = ticks / ticksPerFrame; - assert(nFrame >= 0 && nFrame < nFrames); + auto const nFrame = clamp(ticks / ticksPerFrame, 0, nFrames - 1); FRAMEINFO *thisFrame = &frames[nFrame]; - if ((nFrame == (nFrames - 1)) && !lastframetic) - { - lastframetic = ticks; - } - else if (lastframetic > ticks) - { - lastframetic = 0; - } - - int oFrame = nFrame == 0 || (lastframetic && ticks > lastframetic) ? !looped ? nFrame : nFrames - 1 : nFrame - 1; - assert(oFrame >= 0 && oFrame < nFrames); + auto const oFrame = clamp((nFrame == 0 && looped ? nFrames : nFrame) - 1, 0, nFrames - 1); FRAMEINFO *prevFrame = &frames[oFrame]; auto drawTile = [&](TILE_FRAME *thisTile, TILE_FRAME *prevTile, bool const interpolate = true) diff --git a/source/games/blood/src/qav.h b/source/games/blood/src/qav.h index 0571056d6..71f987524 100644 --- a/source/games/blood/src/qav.h +++ b/source/games/blood/src/qav.h @@ -75,8 +75,7 @@ struct QAV int y; // 18 int nSprite; // 1c //SPRITE *pSprite; // 1c - char pad3[1]; // 20 - char lastframetic; + char pad3[2]; // 20 unsigned short res_id; FRAMEINFO frames[1]; // 24 void Draw(double x, double y, int ticks, int stat, int shade, int palnum, bool to3dview, double const smoothratio = 65536, bool const looped = false); From db5aa4ba17b60c4a80bf72bfb98d224503c77007 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Tue, 3 Aug 2021 10:58:15 +1000 Subject: [PATCH 09/89] - Blood: Backport voodoo doll fix from BloodGDX. --- source/games/blood/src/weapon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/games/blood/src/weapon.cpp b/source/games/blood/src/weapon.cpp index ea97056c9..ec9307b23 100644 --- a/source/games/blood/src/weapon.cpp +++ b/source/games/blood/src/weapon.cpp @@ -995,7 +995,7 @@ void WeaponUpdateState(PLAYER *pPlayer) pPlayer->weaponQav = 42; break; case 10: - if (pXSprite->height < 256 && abs(pPlayer->swayHeight) > 768) + if (pXSprite->height < 256 && abs(pPlayer->swayHeight) > 16) pPlayer->weaponQav = 102; else pPlayer->weaponQav = 101; From 6fec5d582ee02944666acf1e38b603012bd04af3 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Thu, 12 Aug 2021 14:13:25 +1000 Subject: [PATCH 10/89] - Blood: Define enum values for QAVs. Not in use yet. --- source/games/blood/src/qav.h | 148 +++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) diff --git a/source/games/blood/src/qav.h b/source/games/blood/src/qav.h index 71f987524..b3fb237ce 100644 --- a/source/games/blood/src/qav.h +++ b/source/games/blood/src/qav.h @@ -29,6 +29,154 @@ BEGIN_BLD_NS enum { kQavOrientationLeft = 4096 }; +enum +{ + kQAVFORKUP = 0, + kQAVFORKIDLE = 1, + kQAVPFORK = 2, + kQAVFORKDOWN = 3, + + kQAVLITEOPEN = 4, + kQAVLITEFLAM = 5, + kQAVLITEIDLE = 6, + kQAVLITECLO2 = 7, + + kQAVCANPREF = 8, + kQAVCANIDLE = 9, + kQAVCANFIRE = 10, + kQAVCANDOWN = 11, + kQAVCANFIRE2 = 12, + kQAVCANDROP = 13, + kQAVCANTHRO = 14, + kQAVCANBOOM = 15, + + kQAVBUNUP = 16, + kQAVBUNDOWN = 17, + kQAVBUNUP2 = 18, + kQAVBUNDOWN2 = 19, + kQAVBUNIDLE = 20, + kQAVBUNFUSE = 21, + kQAVBUNDROP = 22, + kQAVBUNTHRO = 23, + + kQAVDYNEXPLO = 24, + + kQAVPROXUP = 25, + kQAVPROXDOWN = 26, + kQAVPROXIDLE = 27, + kQAVPROXDROP = 28, + kQAVPROXTHRO = 29, + + kQAVREMUP1 = 30, + kQAVREMUP2 = 31, + kQAVREMUP3 = 32, + kQAVREMDOWN1 = 33, + kQAVREMDOWN2 = 34, + kQAVREMDOWN3 = 35, + kQAVREMIDLE1 = 36, + kQAVREMIDLE2 = 37, + kQAVREMDROP = 38, + kQAVREMTHRO = 39, + kQAVREMFIRE = 40, + + kQAVFLARUP = 41, + kQAVFLARIDLE = 42, + kQAVFLARFIR2 = 43, + kQAVFLARDOWN = 44, + + kQAVFLAR2UP = 45, + kQAVFLAR2I = 46, + kQAVFLAR2F = 47, + kQAVFLAR2FIR = 48, + kQAVFLAR2DWN = 49, + + kQAVSHOTUP = 50, + kQAVSHOTI3 = 51, + kQAVSHOTI2 = 52, + kQAVSHOTI1 = 53, + kQAVSHOTF1 = 54, + kQAVSHOTF2 = 55, + kQAVSHOTF3 = 56, + kQAVSHOTL1 = 57, + kQAVSHOTDOWN = 58, + + kQAV2SHOTUP = 59, + kQAV2SHOTI = 60, + kQAV2SHOTF2 = 61, + kQAV2SHOTFIR = 62, + kQAV2SHOTDWN = 63, + + kQAVTOMUP = 64, + kQAVTOMIDLE = 65, + kQAVTOMFIRE = 66, + kQAVTOMSPRED = 67, + kQAVTOMDOWN = 68, + + kQAV2TOMUP = 69, + kQAV2TOMIDLE = 70, + kQAV2TOMFIRE = 71, + kQAV2TOMDOWN = 72, + kQAV2TOMALT = 73, + + kQAVSGUNUP = 74, + kQAVSGUNIDL1 = 75, + kQAVSGUNIDL2 = 76, + kQAVSGUNFIR1 = 77, + kQAVSGUNFIR4 = 78, + kQAVSGUNPRE = 79, + kQAVSGUNPOST = 80, + kQAVSGUNDOWN = 81, + + kQAV2SGUNUP = 82, + kQAV2SGUNIDL = 83, + kQAV2SGUNFIR = 84, + kQAV2SGUNALT = 85, + kQAV2SGUNPRE = 86, + kQAV2SGUNPST = 87, + kQAV2SGUNDWN = 88, + + kQAVNAPUP = 89, + kQAVNAPIDLE = 90, + kQAVNAPFIRE = 91, + kQAVNAPDOWN = 92, + + kQAVBSTUP = 93, + kQAVBSTIDLE = 94, + kQAVBSTATAK1 = 95, + kQAVBSTATAK2 = 96, + kQAVBSTATAK3 = 97, + kQAVBSTATAK4 = 98, + kQAVBSTDOWN = 99, + + kQAVVDUP = 100, + kQAVVDIDLE1 = 101, + kQAVVDIDLE2 = 102, + kQAVVDFIRE1 = 103, + kQAVVDFIRE2 = 104, + kQAVVDFIRE3 = 105, + kQAVVDFIRE4 = 106, + kQAVVDFIRE5 = 107, + kQAVVDFIRE6 = 108, + kQAVVDDOWN = 109, + kQAVVDSPEL1 = 110, + + kQAVSTAFUP = 111, + kQAVSTAFIDL1 = 112, + kQAVSTAFIDL3 = 113, + kQAVSTAFIRE1 = 114, + kQAVSTAFIRE2 = 115, + kQAVSTAFIRE4 = 116, + kQAVSTAFPRE = 117, + kQAVSTAFPOST = 118, + kQAVSTAFDOWN = 119, + + kQAV2NAPUP = 120, + kQAV2NAPIDLE = 121, + kQAV2NAPFIRE = 122, + kQAV2NAPFIR2 = 123, + kQAV2NAPDOWN = 124, +}; + // by NoOne: add sound flags enum { From d93960287572eca416db2ce454dc5f01369d75c1 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Tue, 3 Aug 2021 20:08:44 +1000 Subject: [PATCH 11/89] - Blood: Define enum values for weapon numbers. Not in use yet. --- source/games/blood/src/common_game.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/source/games/blood/src/common_game.h b/source/games/blood/src/common_game.h index 192a42c4e..450a3ffb7 100644 --- a/source/games/blood/src/common_game.h +++ b/source/games/blood/src/common_game.h @@ -449,6 +449,25 @@ enum kAng360 = 2048, }; +// Weapon numbers +enum +{ + kWeapNone = 0, + kWeapPitchFork = 1, + kWeapFlareGun = 2, + kWeapShotgun = 3, + kWeapTommyGun = 4, + kWeapNapalm = 5, + kWeapDynamite = 6, + kWeapSpraycan = 7, + kWeapTeslaCannon = 8, + kWeapLifeLeech = 9, + kWeapVoodooDoll = 10, + kWeapProximity = 11, + kWeapRemote = 12, + kWeapBeast = 13, +}; + // ------------------------------- #pragma pack(push,1) From ba94614078c09ce1c57c2986b031a4d7a29d23bf Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Wed, 18 Aug 2021 19:56:06 +1000 Subject: [PATCH 12/89] - Blood: Replace all numerical constants for player's `curWeapon` with enum values. --- source/games/blood/src/animatesprite.cpp | 9 +- source/games/blood/src/messages.cpp | 4 +- source/games/blood/src/nnexts.cpp | 4 +- source/games/blood/src/player.cpp | 4 +- source/games/blood/src/triggers.cpp | 2 +- source/games/blood/src/weapon.cpp | 190 +++++++++++------------ 6 files changed, 106 insertions(+), 107 deletions(-) diff --git a/source/games/blood/src/animatesprite.cpp b/source/games/blood/src/animatesprite.cpp index e8eb065f9..8dd3d8a34 100644 --- a/source/games/blood/src/animatesprite.cpp +++ b/source/games/blood/src/animatesprite.cpp @@ -444,7 +444,7 @@ static tspritetype *viewAddEffect(spritetype* tsprite, int& spritesortcnt, int n assert(pTSprite->type >= kDudePlayer1 && pTSprite->type <= kDudePlayer8); PLAYER *pPlayer = &gPlayer[pTSprite->type-kDudePlayer1]; WEAPONICON weaponIcon = gWeaponIcon[pPlayer->curWeapon]; - const int nTile = weaponIcon.nTile; + auto& nTile = weaponIcon.nTile; if (nTile < 0) break; auto pNSprite = viewInsertTSprite(tsprite, spritesortcnt, pTSprite->sectnum, 32767, pTSprite); if (!pNSprite) @@ -457,15 +457,14 @@ static tspritetype *viewAddEffect(spritetype* tsprite, int& spritesortcnt, int n pNSprite->shade = pTSprite->shade; pNSprite->xrepeat = 32; pNSprite->yrepeat = 32; - const int nVoxel = voxelIndex[nTile]; + auto& nVoxel = voxelIndex[nTile]; if (cl_showweapon == 2 && r_voxels && nVoxel != -1) { pNSprite->cstat |= 48; pNSprite->cstat &= ~8; pNSprite->picnum = nVoxel; pNSprite->z -= weaponIcon.zOffset<<8; - const int lifeLeech = 9; - if (pPlayer->curWeapon == lifeLeech) + if (pPlayer->curWeapon == kWeapLifeLeech) { pNSprite->x -= MulScale(128, Cos(pNSprite->ang), 30); pNSprite->y -= MulScale(128, Sin(pNSprite->ang), 30); @@ -479,7 +478,7 @@ static tspritetype *viewAddEffect(spritetype* tsprite, int& spritesortcnt, int n static void viewApplyDefaultPal(tspritetype *pTSprite, sectortype const *pSector) { - int const nXSector = pSector->extra; + auto& nXSector = pSector->extra; XSECTOR const *pXSector = nXSector >= 0 ? &xsector[nXSector] : NULL; if (pXSector && pXSector->color && (VanillaMode() || pSector->floorpal != 0)) { diff --git a/source/games/blood/src/messages.cpp b/source/games/blood/src/messages.cpp index dd6a33ae5..7f7fe7cf0 100644 --- a/source/games/blood/src/messages.cpp +++ b/source/games/blood/src/messages.cpp @@ -102,7 +102,7 @@ void SetWeapons(bool stat) { // Keep the pitchfork to avoid freeze gMe->hasWeapon[1] = 1; - gMe->curWeapon = 0; + gMe->curWeapon = kWeapNone; gMe->nextWeapon = 1; } viewSetMessage(GStrings("TXTB_NOWEAP")); @@ -400,7 +400,7 @@ const char* GameInterface::GenericCheat(int player, int cheat) powerupActivate(gMe, kPwUpDeliriumShroom); gMe->pXSprite->health = 16; gMe->hasWeapon[1] = 1; - gMe->curWeapon = 0; + gMe->curWeapon = kWeapNone; gMe->nextWeapon = 1; break; diff --git a/source/games/blood/src/nnexts.cpp b/source/games/blood/src/nnexts.cpp index ba6910953..6ebf98fee 100644 --- a/source/games/blood/src/nnexts.cpp +++ b/source/games/blood/src/nnexts.cpp @@ -2039,7 +2039,7 @@ void trPlayerCtrlEraseStuff(XSPRITE* pXSource, PLAYER* pPlayer) { } pPlayer->hasWeapon[1] = true; - pPlayer->curWeapon = 0; + pPlayer->curWeapon = kWeapNone; pPlayer->nextWeapon = 1; WeaponRaise(pPlayer); @@ -5064,7 +5064,7 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite switch (cmd) { case 36: actHealDude(pPlayer->pXSprite, ((pXSprite->data2 > 0) ? ClipHigh(pXSprite->data2, 200) : getDudeInfo(pPlayer->pSprite->type)->startHealth), 200); - pPlayer->curWeapon = 1; + pPlayer->curWeapon = kWeapPitchFork; break; } diff --git a/source/games/blood/src/player.cpp b/source/games/blood/src/player.cpp index 9cf0895eb..f08d7b15d 100644 --- a/source/games/blood/src/player.cpp +++ b/source/games/blood/src/player.cpp @@ -794,7 +794,7 @@ void playerReset(PLAYER *pPlayer) pPlayer->weaponMode[i] = 0; } pPlayer->hasWeapon[1] = 1; - pPlayer->curWeapon = 0; + pPlayer->curWeapon = kWeapNone; pPlayer->qavCallback = -1; pPlayer->newWeapon = 1; for (int i = 0; i < 14; i++) @@ -1968,7 +1968,7 @@ int playerDamageSprite(DBloodActor* source, PLAYER *pPlayer, DAMAGE_TYPE nDamage } pPlayer->deathTime = 0; pPlayer->qavLoop = 0; - pPlayer->curWeapon = 0; + pPlayer->curWeapon = kWeapNone; pPlayer->fraggerId = nSource; pPlayer->voodooTargets = 0; if (nDamageType == kDamageExplode && nDamage < (9<<4)) diff --git a/source/games/blood/src/triggers.cpp b/source/games/blood/src/triggers.cpp index 16d641df2..ec15179de 100644 --- a/source/games/blood/src/triggers.cpp +++ b/source/games/blood/src/triggers.cpp @@ -208,7 +208,7 @@ void LifeLeechOperate(spritetype *pSprite, XSPRITE *pXSprite, EVENT event) { pPlayer->ammoCount[8] = ClipHigh(pPlayer->ammoCount[8]+pXSprite->data3, gAmmoInfo[8].max); pPlayer->hasWeapon[9] = 1; - if (pPlayer->curWeapon != 9) + if (pPlayer->curWeapon != kWeapLifeLeech) { pPlayer->weaponState = 0; pPlayer->nextWeapon = 9; diff --git a/source/games/blood/src/weapon.cpp b/source/games/blood/src/weapon.cpp index ec9307b23..70aeb86c3 100644 --- a/source/games/blood/src/weapon.cpp +++ b/source/games/blood/src/weapon.cpp @@ -148,7 +148,7 @@ static bool sub_4B1A4(PLAYER *pPlayer) { switch (pPlayer->curWeapon) { - case 7: + case kWeapSpraycan: switch (pPlayer->weaponState) { case 5: @@ -156,7 +156,7 @@ static bool sub_4B1A4(PLAYER *pPlayer) return 1; } break; - case 6: + case kWeapDynamite: switch (pPlayer->weaponState) { case 4: @@ -193,9 +193,9 @@ static bool CheckAmmo(PLAYER *pPlayer, int ammotype, int count) return 1; if (ammotype == -1) return 1; - if (pPlayer->curWeapon == 12 && pPlayer->weaponAmmo == 11 && pPlayer->weaponState == 11) + if (pPlayer->curWeapon == kWeapRemote && pPlayer->weaponAmmo == 11 && pPlayer->weaponState == 11) return 1; - if (pPlayer->curWeapon == 9 && pPlayer->pXSprite->health >= unsigned(count<<4)) + if (pPlayer->curWeapon == kWeapLifeLeech && pPlayer->pXSprite->health >= unsigned(count<<4)) return 1; return pPlayer->ammoCount[ammotype] >= count; } @@ -264,7 +264,7 @@ void WeaponDraw(PLAYER *pPlayer, int shade, double xpos, double ypos, int palnum int duration; double smoothratio; - qavProcessTimer(pPlayer, pQAV, &duration, &smoothratio, pPlayer->weaponState == -1 || (pPlayer->curWeapon == 3 && pPlayer->weaponState == 7)); + qavProcessTimer(pPlayer, pQAV, &duration, &smoothratio, pPlayer->weaponState == -1 || (pPlayer->curWeapon == kWeapShotgun && pPlayer->weaponState == 7)); pQAV->x = int(xpos); pQAV->y = int(ypos); @@ -346,7 +346,7 @@ void UpdateAimVector(PLAYER * pPlayer) int nTarget = -1; pPlayer->aimTargetsCount = 0; int autoaim = Autoaim(pPlayer->nPlayer); - if (autoaim == 1 || (autoaim == 2 && !pWeaponTrack->bIsProjectile) || pPlayer->curWeapon == 10 || pPlayer->curWeapon == 9) + if (autoaim == 1 || (autoaim == 2 && !pWeaponTrack->bIsProjectile) || pPlayer->curWeapon == kWeapVoodooDoll || pPlayer->curWeapon == kWeapLifeLeech) { int nClosest = 0x7fffffff; int nSprite; @@ -503,11 +503,11 @@ void WeaponRaise(PLAYER *pPlayer) pPlayer->weaponAmmo = weaponModes[pPlayer->curWeapon].ammoType; switch (pPlayer->curWeapon) { - case 1: // pitchfork + case kWeapPitchFork: pPlayer->weaponState = 0; StartQAV(pPlayer, 0, -1, 0); break; - case 7: // spraycan + case kWeapSpraycan: if (pPlayer->weaponState == 2) { pPlayer->weaponState = 3; @@ -519,7 +519,7 @@ void WeaponRaise(PLAYER *pPlayer) StartQAV(pPlayer, 4, -1, 0); } break; - case 6: // dynamite + case kWeapDynamite: if (gInfiniteAmmo || checkAmmo2(pPlayer, 5, 1)) { pPlayer->weaponState = 3; @@ -529,14 +529,14 @@ void WeaponRaise(PLAYER *pPlayer) StartQAV(pPlayer, 18, -1, 0); } break; - case 11: // proximity + case kWeapProximity: if (gInfiniteAmmo || checkAmmo2(pPlayer, 10, 1)) { pPlayer->weaponState = 7; StartQAV(pPlayer, 25, -1, 0); } break; - case 12: // remote + case kWeapRemote: if (gInfiniteAmmo || checkAmmo2(pPlayer, 11, 1)) { pPlayer->weaponState = 10; @@ -548,7 +548,7 @@ void WeaponRaise(PLAYER *pPlayer) pPlayer->weaponState = 11; } break; - case 3: // sawed off + case kWeapShotgun: if (powerupCheck(pPlayer, kPwUpTwoGuns)) { if (gInfiniteAmmo || pPlayer->ammoCount[2] >= 4) @@ -575,7 +575,7 @@ void WeaponRaise(PLAYER *pPlayer) StartQAV(pPlayer, 50, -1, 0); } break; - case 4: // tommy gun + case kWeapTommyGun: if (powerupCheck(pPlayer, kPwUpTwoGuns) && checkAmmo2(pPlayer, 3, 2)) { pPlayer->weaponState = 1; @@ -587,14 +587,14 @@ void WeaponRaise(PLAYER *pPlayer) StartQAV(pPlayer, 64, -1, 0); } break; - case 10: // voodoo + case kWeapVoodooDoll: if (gInfiniteAmmo || checkAmmo2(pPlayer, 9, 1)) { pPlayer->weaponState = 2; StartQAV(pPlayer, 100, -1, 0); } break; - case 2: // flaregun + case kWeapFlareGun: if (powerupCheck(pPlayer, kPwUpTwoGuns) && checkAmmo2(pPlayer, 1, 2)) { StartQAV(pPlayer, 45, -1, 0); @@ -606,7 +606,7 @@ void WeaponRaise(PLAYER *pPlayer) pPlayer->weaponState = 2; } break; - case 8: // tesla cannon + case kWeapTeslaCannon: if (checkAmmo2(pPlayer, 7, 1)) { pPlayer->weaponState = 2; @@ -621,7 +621,7 @@ void WeaponRaise(PLAYER *pPlayer) StartQAV(pPlayer, 74, -1, 0); } break; - case 5: // napalm + case kWeapNapalm: if (powerupCheck(pPlayer, kPwUpTwoGuns)) { StartQAV(pPlayer, 120, -1, 0); @@ -633,11 +633,11 @@ void WeaponRaise(PLAYER *pPlayer) pPlayer->weaponState = 2; } break; - case 9: // life leech + case kWeapLifeLeech: pPlayer->weaponState = 2; StartQAV(pPlayer, 111, -1, 0); break; - case 13: // beast + case kWeapBeast: pPlayer->weaponState = 2; StartQAV(pPlayer, 93, -1, 0); break; @@ -653,10 +653,10 @@ void WeaponLower(PLAYER *pPlayer) int prevState = pPlayer->weaponState; switch (pPlayer->curWeapon) { - case 1: + case kWeapPitchFork: StartQAV(pPlayer, 3, -1, 0); break; - case 7: + case kWeapSpraycan: sfxKill3DSound(pPlayer->pSprite, -1, 441); switch (prevState) { @@ -724,7 +724,7 @@ void WeaponLower(PLAYER *pPlayer) break; } break; - case 6: + case kWeapDynamite: switch (prevState) { case 1: @@ -761,7 +761,7 @@ void WeaponLower(PLAYER *pPlayer) break; } break; - case 11: + case kWeapProximity: switch (prevState) { case 7: @@ -769,7 +769,7 @@ void WeaponLower(PLAYER *pPlayer) break; } break; - case 12: + case kWeapRemote: switch (prevState) { case 10: @@ -780,47 +780,47 @@ void WeaponLower(PLAYER *pPlayer) break; } break; - case 3: + case kWeapShotgun: if (powerupCheck(pPlayer, kPwUpTwoGuns)) StartQAV(pPlayer, 63, -1, 0); else StartQAV(pPlayer, 58, -1, 0); break; - case 4: + case kWeapTommyGun: if (powerupCheck(pPlayer, kPwUpTwoGuns) && pPlayer->weaponState == 1) StartQAV(pPlayer, 72, -1, 0); else StartQAV(pPlayer, 68, -1, 0); break; - case 2: + case kWeapFlareGun: if (powerupCheck(pPlayer, kPwUpTwoGuns) && pPlayer->weaponState == 3) StartQAV(pPlayer, 49, -1, 0); else StartQAV(pPlayer, 44, -1, 0); break; - case 10: + case kWeapVoodooDoll: StartQAV(pPlayer, 109, -1, 0); break; - case 8: + case kWeapTeslaCannon: if (checkAmmo2(pPlayer, 7, 10) && powerupCheck(pPlayer, kPwUpTwoGuns)) StartQAV(pPlayer, 88, -1, 0); else StartQAV(pPlayer, 81, -1, 0); break; - case 5: + case kWeapNapalm: if (powerupCheck(pPlayer, kPwUpTwoGuns)) StartQAV(pPlayer, 124, -1, 0); else StartQAV(pPlayer, 92, -1, 0); break; - case 9: + case kWeapLifeLeech: StartQAV(pPlayer, 119, -1, 0); break; - case 13: + case kWeapBeast: StartQAV(pPlayer, 99, -1, 0); break; } - pPlayer->curWeapon = 0; + pPlayer->curWeapon = kWeapNone; pPlayer->qavLoop = 0; } @@ -838,10 +838,10 @@ void WeaponUpdateState(PLAYER *pPlayer) } switch (lastWeapon) { - case 1: + case kWeapPitchFork: pPlayer->weaponQav = 1; break; - case 7: + case kWeapSpraycan: switch (vb) { case 0: @@ -875,7 +875,7 @@ void WeaponUpdateState(PLAYER *pPlayer) break; } break; - case 6: + case kWeapDynamite: switch (vb) { case 1: @@ -903,7 +903,7 @@ void WeaponUpdateState(PLAYER *pPlayer) break; } break; - case 11: + case kWeapProximity: switch (vb) { case 7: @@ -915,7 +915,7 @@ void WeaponUpdateState(PLAYER *pPlayer) break; } break; - case 12: + case kWeapRemote: switch (vb) { case 10: @@ -935,7 +935,7 @@ void WeaponUpdateState(PLAYER *pPlayer) break; } break; - case 3: + case kWeapShotgun: switch (vb) { case 6: @@ -968,7 +968,7 @@ void WeaponUpdateState(PLAYER *pPlayer) break; } break; - case 4: + case kWeapTommyGun: if (powerupCheck(pPlayer, kPwUpTwoGuns) && checkAmmo2(pPlayer, 3, 2)) { pPlayer->weaponQav = 70; @@ -980,7 +980,7 @@ void WeaponUpdateState(PLAYER *pPlayer) pPlayer->weaponState = 0; } break; - case 2: + case kWeapFlareGun: if (powerupCheck(pPlayer, kPwUpTwoGuns)) { if (vb == 3 && checkAmmo2(pPlayer, 1, 2)) @@ -994,13 +994,13 @@ void WeaponUpdateState(PLAYER *pPlayer) else pPlayer->weaponQav = 42; break; - case 10: + case kWeapVoodooDoll: if (pXSprite->height < 256 && abs(pPlayer->swayHeight) > 16) pPlayer->weaponQav = 102; else pPlayer->weaponQav = 101; break; - case 8: + case kWeapTeslaCannon: switch (vb) { case 2: @@ -1014,7 +1014,7 @@ void WeaponUpdateState(PLAYER *pPlayer) break; } break; - case 5: + case kWeapNapalm: switch (vb) { case 3: @@ -1028,7 +1028,7 @@ void WeaponUpdateState(PLAYER *pPlayer) break; } break; - case 9: + case kWeapLifeLeech: switch (vb) { case 2: @@ -1036,7 +1036,7 @@ void WeaponUpdateState(PLAYER *pPlayer) break; } break; - case 13: + case kWeapBeast: pPlayer->weaponQav = 94; break; } @@ -1098,7 +1098,7 @@ void ExplodeCan(int, PLAYER *pPlayer) evPost(pSprite->index, 3, 0, kCmdOn); UseAmmo(pPlayer, 6, gAmmoItemData[0].count); StartQAV(pPlayer, 15, -1); - pPlayer->curWeapon = 0; + pPlayer->curWeapon = kWeapNone; pPlayer->throwPower = 0; } @@ -1133,7 +1133,7 @@ void ExplodeBundle(int, PLAYER *pPlayer) evPost(pSprite->index, 3, 0, kCmdOn); UseAmmo(pPlayer, 5, 1); StartQAV(pPlayer, 24, -1, 0); - pPlayer->curWeapon = 0; + pPlayer->curWeapon = kWeapNone; pPlayer->throwPower = 0; } @@ -1763,7 +1763,7 @@ static int WeaponFindNext(PLAYER *pPlayer, int *a2, int bDir) weapon = OrderPrev[weapon]; if (weaponModes[weapon].update && pPlayer->hasWeapon[weapon]) { - if (weapon == 9) + if (weapon == kWeapLifeLeech) { if (CheckAmmo(pPlayer, weaponModes[weapon].ammoType, 1)) break; @@ -1778,7 +1778,7 @@ static int WeaponFindNext(PLAYER *pPlayer, int *a2, int bDir) if (weapon == pPlayer->curWeapon) { if (!weaponModes[weapon].update || !CheckAmmo(pPlayer, weaponModes[weapon].ammoType, 1)) - weapon = 1; + weapon = kWeapPitchFork; } if (a2) *a2 = 0; @@ -1801,7 +1801,7 @@ static int WeaponFindLoaded(PLAYER *pPlayer, int *a2) } } } - if (v4 == 1) + if (v4 == kWeapPitchFork) { int vc = 0; for (int i = 0; i < 14; i++) @@ -2014,13 +2014,13 @@ void WeaponProcess(PLAYER *pPlayer) { { if (sub_4B1A4(pPlayer)) { - if (pPlayer->curWeapon == 7) + if (pPlayer->curWeapon == kWeapSpraycan) { pPlayer->fuseTime = pPlayer->weaponTimer; DropCan(1, pPlayer); pPlayer->weaponState = 3; } - else if (pPlayer->curWeapon == 6) + else if (pPlayer->curWeapon == kWeapDynamite) { pPlayer->fuseTime = pPlayer->weaponTimer; DropBundle(1, pPlayer); @@ -2056,34 +2056,34 @@ void WeaponProcess(PLAYER *pPlayer) { pPlayer->weaponTimer = ClipLow(pPlayer->weaponTimer, 0); switch (pPlayer->curWeapon) { - case 7: + case kWeapSpraycan: if (processSprayCan(pPlayer)) return; break; - case 6: + case kWeapDynamite: if (processTNT(pPlayer)) return; break; - case 11: + case kWeapProximity: if (processProxy(pPlayer)) return; break; - case 12: + case kWeapRemote: if (processRemote(pPlayer)) return; break; } if (pPlayer->weaponTimer > 0) return; - if (pPlayer->pXSprite->health == 0 || pPlayer->curWeapon == 0) + if (pPlayer->pXSprite->health == 0 || pPlayer->curWeapon == kWeapNone) pPlayer->weaponQav = -1; switch (pPlayer->curWeapon) { - case 9: + case kWeapLifeLeech: if (processLeech(pPlayer)) return; break; - case 8: + case kWeapTeslaCannon: if (processTesla(pPlayer)) return; break; @@ -2148,14 +2148,14 @@ void WeaponProcess(PLAYER *pPlayer) { switch (pPlayer->curWeapon) { - case 6: - weapon = 11; + case kWeapDynamite: + weapon = kWeapProximity; break; - case 11: - weapon = 12; + case kWeapProximity: + weapon = kWeapRemote; break; - case 12: - weapon = 6; + case kWeapRemote: + weapon = kWeapDynamite; break; default: return; @@ -2201,21 +2201,21 @@ void WeaponProcess(PLAYER *pPlayer) { { if (pPlayer->newWeapon == 6) { - if (pPlayer->curWeapon == 6) + if (pPlayer->curWeapon == kWeapDynamite) { if (checkAmmo2(pPlayer, 10, 1)) pPlayer->newWeapon = 11; else if (checkAmmo2(pPlayer, 11, 1)) pPlayer->newWeapon = 12; } - else if (pPlayer->curWeapon == 11) + else if (pPlayer->curWeapon == kWeapProximity) { if (checkAmmo2(pPlayer, 11, 1)) pPlayer->newWeapon = 12; else if (checkAmmo2(pPlayer, 5, 1) && pPlayer->isUnderwater == 0) pPlayer->newWeapon = 6; } - else if (pPlayer->curWeapon == 12) + else if (pPlayer->curWeapon == kWeapRemote) { if (checkAmmo2(pPlayer, 5, 1) && pPlayer->isUnderwater == 0) pPlayer->newWeapon = 6; @@ -2304,10 +2304,10 @@ void WeaponProcess(PLAYER *pPlayer) { { switch (pPlayer->curWeapon) { - case 1: + case kWeapPitchFork: StartQAV(pPlayer, 2, nClientFirePitchfork, 0); return; - case 7: + case kWeapSpraycan: switch (pPlayer->weaponState) { case 3: @@ -2316,7 +2316,7 @@ void WeaponProcess(PLAYER *pPlayer) { return; } break; - case 6: + case kWeapDynamite: switch (pPlayer->weaponState) { case 3: @@ -2327,7 +2327,7 @@ void WeaponProcess(PLAYER *pPlayer) { return; } break; - case 11: + case kWeapProximity: switch (pPlayer->weaponState) { case 7: @@ -2337,7 +2337,7 @@ void WeaponProcess(PLAYER *pPlayer) { return; } break; - case 12: + case kWeapRemote: switch (pPlayer->weaponState) { case 10: @@ -2351,7 +2351,7 @@ void WeaponProcess(PLAYER *pPlayer) { return; } break; - case 3: + case kWeapShotgun: switch (pPlayer->weaponState) { case 7: @@ -2368,19 +2368,19 @@ void WeaponProcess(PLAYER *pPlayer) { return; } break; - case 4: + case kWeapTommyGun: if (powerupCheck(pPlayer, kPwUpTwoGuns) && checkAmmo2(pPlayer, 3, 2)) StartQAV(pPlayer, 71, nClientFireTommy, 1); else StartQAV(pPlayer, 66, nClientFireTommy, 1); return; - case 2: + case kWeapFlareGun: if (powerupCheck(pPlayer, kPwUpTwoGuns) && checkAmmo2(pPlayer, 1, 2)) StartQAV(pPlayer, 48, nClientFireFlare, 0); else StartQAV(pPlayer, 43, nClientFireFlare, 0); return; - case 10: + case kWeapVoodooDoll: { static int nChance[] = { 0xa000, 0xc000, 0xe000, 0x10000 }; int nRand = wrand()*2; @@ -2394,7 +2394,7 @@ void WeaponProcess(PLAYER *pPlayer) { StartQAV(pPlayer,103+i, nClientFireVoodoo, 0); return; } - case 8: + case kWeapTeslaCannon: switch (pPlayer->weaponState) { case 2: @@ -2412,17 +2412,17 @@ void WeaponProcess(PLAYER *pPlayer) { return; } break; - case 5: + case kWeapNapalm: if (powerupCheck(pPlayer, kPwUpTwoGuns)) StartQAV(pPlayer, 122, nClientFireNapalm, 0); else StartQAV(pPlayer, 91, nClientFireNapalm, 0); return; - case 9: + case kWeapLifeLeech: sfxPlay3DSound(pPlayer->pSprite, 494, 2, 0); StartQAV(pPlayer, 116, nClientFireLifeLeech, 0); return; - case 13: + case kWeapBeast: StartQAV(pPlayer, 95+Random(4), nClientFireBeast, 0); return; } @@ -2431,10 +2431,10 @@ void WeaponProcess(PLAYER *pPlayer) { { switch (pPlayer->curWeapon) { - case 1: + case kWeapPitchFork: StartQAV(pPlayer, 2, nClientFirePitchfork, 0); return; - case 7: + case kWeapSpraycan: switch (pPlayer->weaponState) { case 3: @@ -2443,7 +2443,7 @@ void WeaponProcess(PLAYER *pPlayer) { return; } break; - case 6: + case kWeapDynamite: switch (pPlayer->weaponState) { case 3: @@ -2467,7 +2467,7 @@ void WeaponProcess(PLAYER *pPlayer) { return; } break; - case 11: + case kWeapProximity: switch (pPlayer->weaponState) { case 7: @@ -2476,7 +2476,7 @@ void WeaponProcess(PLAYER *pPlayer) { return; } break; - case 12: + case kWeapRemote: switch (pPlayer->weaponState) { case 10: @@ -2492,7 +2492,7 @@ void WeaponProcess(PLAYER *pPlayer) { return; } break; - case 3: + case kWeapShotgun: switch (pPlayer->weaponState) { case 7: @@ -2509,25 +2509,25 @@ void WeaponProcess(PLAYER *pPlayer) { return; } break; - case 4: + case kWeapTommyGun: if (powerupCheck(pPlayer, kPwUpTwoGuns) && checkAmmo2(pPlayer, 3, 2)) StartQAV(pPlayer, 73, nClientAltFireSpread2, 0); else StartQAV(pPlayer, 67, nClientAltFireSpread2, 0); return; - case 10: + case kWeapVoodooDoll: sfxPlay3DSound(pPlayer->pSprite, 461, 2, 0); StartQAV(pPlayer, 110, nClientAltFireVoodoo, 0); return; #if 0 - case 2: + case kWeapFlareGun: if (powerupCheck(pPlayer, kPwUpTwoGuns) && checkAmmo2(pPlayer, 1, 2)) StartQAV(pPlayer, 48, nClientFireFlare, 0); else StartQAV(pPlayer, 43, nClientFireFlare, 0); return; #endif - case 8: + case kWeapTeslaCannon: if (checkAmmo2(pPlayer, 7, 35)) { if (checkAmmo2(pPlayer, 7, 70) && powerupCheck(pPlayer, kPwUpTwoGuns)) @@ -2543,7 +2543,7 @@ void WeaponProcess(PLAYER *pPlayer) { StartQAV(pPlayer, 77, nClientFireTesla, 0); } return; - case 5: + case kWeapNapalm: if (powerupCheck(pPlayer, kPwUpTwoGuns)) // by NoOne: allow napalm launcher alt fire act like in v1.0x versions if (gGameOptions.weaponsV10x && !VanillaMode() && !DemoRecordStatus()) StartQAV(pPlayer, 123, nClientFireNapalm2, 0); @@ -2551,7 +2551,7 @@ void WeaponProcess(PLAYER *pPlayer) { else StartQAV(pPlayer, 91, (gGameOptions.weaponsV10x && !VanillaMode() && !DemoRecordStatus()) ? nClientFireNapalm : nClientAltFireNapalm, 0); return; - case 2: + case kWeapFlareGun: if (CheckAmmo(pPlayer, 1, 8)) { if (powerupCheck(pPlayer, kPwUpTwoGuns) && checkAmmo2(pPlayer, 1, 16)) @@ -2567,7 +2567,7 @@ void WeaponProcess(PLAYER *pPlayer) { StartQAV(pPlayer, 43, nClientFireFlare, 0); } return; - case 9: + case kWeapLifeLeech: if (gGameOptions.nGameType <= 1 && !checkAmmo2(pPlayer, 8, 1) && pPlayer->pXSprite->health < (25 << 4)) { sfxPlay3DSound(pPlayer->pSprite, 494, 2, 0); From 6f08eb22928b89d2f694614840f8809d1b277917 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Tue, 3 Aug 2021 20:23:39 +1000 Subject: [PATCH 13/89] - Blood: Replace all numerical constants for player's `newWeapon` with enum values. --- source/games/blood/src/nnexts.cpp | 4 +-- source/games/blood/src/player.cpp | 4 +-- source/games/blood/src/weapon.cpp | 53 ++++++++++++++----------------- 3 files changed, 28 insertions(+), 33 deletions(-) diff --git a/source/games/blood/src/nnexts.cpp b/source/games/blood/src/nnexts.cpp index 6ebf98fee..c7f01b176 100644 --- a/source/games/blood/src/nnexts.cpp +++ b/source/games/blood/src/nnexts.cpp @@ -2082,8 +2082,8 @@ void trPlayerCtrlGiveStuff(XSPRITE* pXSource, PLAYER* pPlayer, TRPLAYERCTRL* pCt break; } switch (weapon) { - case 11: // remote bomb - case 12: // prox bomb + case kWeapProximity: // remote bomb + case kWeapRemote: // prox bomb pPlayer->hasWeapon[weapon] = true; weapon--; pPlayer->ammoCount[weapon] = ClipHigh(pPlayer->ammoCount[weapon] + ((pXSource->data2 == 2) ? pXSource->data4 : 1), gAmmoInfo[weapon].max); diff --git a/source/games/blood/src/player.cpp b/source/games/blood/src/player.cpp index f08d7b15d..257a45478 100644 --- a/source/games/blood/src/player.cpp +++ b/source/games/blood/src/player.cpp @@ -796,7 +796,7 @@ void playerReset(PLAYER *pPlayer) pPlayer->hasWeapon[1] = 1; pPlayer->curWeapon = kWeapNone; pPlayer->qavCallback = -1; - pPlayer->newWeapon = 1; + pPlayer->newWeapon = kWeapPitchFork; for (int i = 0; i < 14; i++) { pPlayer->weaponOrder[0][i] = dword_136400[i]; @@ -2134,7 +2134,7 @@ void PlayerSurvive(int, DBloodActor* actor) sprintf(buffer, "%s lives again!", PlayerName(pPlayer->nPlayer)); viewSetMessage(buffer); } - pPlayer->newWeapon = 1; + pPlayer->newWeapon = kWeapPitchFork; } } } diff --git a/source/games/blood/src/weapon.cpp b/source/games/blood/src/weapon.cpp index 70aeb86c3..4685b66ca 100644 --- a/source/games/blood/src/weapon.cpp +++ b/source/games/blood/src/weapon.cpp @@ -499,7 +499,7 @@ void WeaponRaise(PLAYER *pPlayer) assert(pPlayer != NULL); int prevWeapon = pPlayer->curWeapon; pPlayer->curWeapon = pPlayer->newWeapon; - pPlayer->newWeapon = 0; + pPlayer->newWeapon = kWeapNone; pPlayer->weaponAmmo = weaponModes[pPlayer->curWeapon].ammoType; switch (pPlayer->curWeapon) { @@ -667,7 +667,7 @@ void WeaponLower(PLAYER *pPlayer) } else { - if (pPlayer->newWeapon == 6) + if (pPlayer->newWeapon == kWeapDynamite) { pPlayer->weaponState = 2; StartQAV(pPlayer, 11, -1, 0); @@ -685,12 +685,12 @@ void WeaponLower(PLAYER *pPlayer) StartQAV(pPlayer, 11, -1, 0); if (VanillaMode()) { - pPlayer->newWeapon = 0; + pPlayer->newWeapon = kWeapNone; WeaponLower(pPlayer); } else { - if (pPlayer->newWeapon == 6) + if (pPlayer->newWeapon == kWeapDynamite) { pPlayer->weaponState = 2; StartQAV(pPlayer, 11, -1, 0); @@ -703,17 +703,17 @@ void WeaponLower(PLAYER *pPlayer) } break; case 3: - if (pPlayer->newWeapon == 6) + if (pPlayer->newWeapon == kWeapDynamite) { pPlayer->weaponState = 2; StartQAV(pPlayer, 11, -1, 0); return; } - else if (pPlayer->newWeapon == 7) + else if (pPlayer->newWeapon == kWeapSpraycan) { pPlayer->weaponState = 1; StartQAV(pPlayer, 11, -1, 0); - pPlayer->newWeapon = 0; + pPlayer->newWeapon = kWeapNone; WeaponLower(pPlayer); } else @@ -734,7 +734,7 @@ void WeaponLower(PLAYER *pPlayer) } else { - if (pPlayer->newWeapon == 7) + if (pPlayer->newWeapon == kWeapSpraycan) { pPlayer->weaponState = 2; StartQAV(pPlayer, 17, -1, 0); @@ -747,7 +747,7 @@ void WeaponLower(PLAYER *pPlayer) WeaponRaise(pPlayer); break; case 3: - if (pPlayer->newWeapon == 7) + if (pPlayer->newWeapon == kWeapSpraycan) { pPlayer->weaponState = 2; StartQAV(pPlayer, 17, -1, 0); @@ -2199,47 +2199,42 @@ void WeaponProcess(PLAYER *pPlayer) { } if (pPlayer->newWeapon) { - if (pPlayer->newWeapon == 6) + if (pPlayer->newWeapon == kWeapDynamite) { if (pPlayer->curWeapon == kWeapDynamite) { if (checkAmmo2(pPlayer, 10, 1)) - pPlayer->newWeapon = 11; + pPlayer->newWeapon = kWeapProximity; else if (checkAmmo2(pPlayer, 11, 1)) - pPlayer->newWeapon = 12; + pPlayer->newWeapon = kWeapRemote; } else if (pPlayer->curWeapon == kWeapProximity) { if (checkAmmo2(pPlayer, 11, 1)) - pPlayer->newWeapon = 12; + pPlayer->newWeapon = kWeapRemote; else if (checkAmmo2(pPlayer, 5, 1) && pPlayer->isUnderwater == 0) - pPlayer->newWeapon = 6; + pPlayer->newWeapon = kWeapDynamite; } else if (pPlayer->curWeapon == kWeapRemote) { if (checkAmmo2(pPlayer, 5, 1) && pPlayer->isUnderwater == 0) - pPlayer->newWeapon = 6; + pPlayer->newWeapon = kWeapDynamite; else if (checkAmmo2(pPlayer, 10, 1)) - pPlayer->newWeapon = 11; + pPlayer->newWeapon = kWeapProximity; } else { if (checkAmmo2(pPlayer, 5, 1) && pPlayer->isUnderwater == 0) - pPlayer->newWeapon = 6; + pPlayer->newWeapon = kWeapDynamite; else if (checkAmmo2(pPlayer, 10, 1)) - pPlayer->newWeapon = 11; + pPlayer->newWeapon = kWeapVoodooDoll; else if (checkAmmo2(pPlayer, 11, 1)) - pPlayer->newWeapon = 12; + pPlayer->newWeapon = kWeapRemote; } } - if (pPlayer->pXSprite->health == 0 || pPlayer->hasWeapon[pPlayer->newWeapon] == 0) + if ((pPlayer->pXSprite->health == 0 || pPlayer->hasWeapon[pPlayer->newWeapon] == 0) || (pPlayer->isUnderwater && BannedUnderwater(pPlayer->newWeapon) && !sub_4B1A4(pPlayer))) { - pPlayer->newWeapon = 0; - return; - } - if (pPlayer->isUnderwater && BannedUnderwater(pPlayer->newWeapon) && !sub_4B1A4(pPlayer)) - { - pPlayer->newWeapon = 0; + pPlayer->newWeapon = kWeapNone; return; } int nWeapon = pPlayer->newWeapon; @@ -2251,7 +2246,7 @@ void WeaponProcess(PLAYER *pPlayer) { { if (CheckAmmo(pPlayer, nAmmoType, 1) || nAmmoType == 11) WeaponRaise(pPlayer); - pPlayer->newWeapon = 0; + pPlayer->newWeapon = kWeapNone; } else { @@ -2276,7 +2271,7 @@ void WeaponProcess(PLAYER *pPlayer) { } if (nWeapon == pPlayer->curWeapon && v4c <= 1) { - pPlayer->newWeapon = 0; + pPlayer->newWeapon = kWeapNone; return; } int i = 0; @@ -2292,7 +2287,7 @@ void WeaponProcess(PLAYER *pPlayer) { return; } } - pPlayer->newWeapon = 0; + pPlayer->newWeapon = kWeapNone; return; } if (pPlayer->curWeapon && !CheckAmmo(pPlayer, pPlayer->weaponAmmo, 1) && pPlayer->weaponAmmo != 11) From cd5e01818a595a5433a645ee1f23981ddc0d0bad Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Tue, 3 Aug 2021 20:23:48 +1000 Subject: [PATCH 14/89] - Blood: Replace all numerical constants for player's `nextWeapon` with enum values. --- source/games/blood/src/messages.cpp | 4 ++-- source/games/blood/src/nnexts.cpp | 4 ++-- source/games/blood/src/player.cpp | 2 +- source/games/blood/src/weapon.cpp | 10 +++++----- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/source/games/blood/src/messages.cpp b/source/games/blood/src/messages.cpp index 7f7fe7cf0..630be9550 100644 --- a/source/games/blood/src/messages.cpp +++ b/source/games/blood/src/messages.cpp @@ -103,7 +103,7 @@ void SetWeapons(bool stat) // Keep the pitchfork to avoid freeze gMe->hasWeapon[1] = 1; gMe->curWeapon = kWeapNone; - gMe->nextWeapon = 1; + gMe->nextWeapon = kWeapPitchFork; } viewSetMessage(GStrings("TXTB_NOWEAP")); } @@ -401,7 +401,7 @@ const char* GameInterface::GenericCheat(int player, int cheat) gMe->pXSprite->health = 16; gMe->hasWeapon[1] = 1; gMe->curWeapon = kWeapNone; - gMe->nextWeapon = 1; + gMe->nextWeapon = kWeapPitchFork; break; default: diff --git a/source/games/blood/src/nnexts.cpp b/source/games/blood/src/nnexts.cpp index c7f01b176..23f252f2e 100644 --- a/source/games/blood/src/nnexts.cpp +++ b/source/games/blood/src/nnexts.cpp @@ -2040,7 +2040,7 @@ void trPlayerCtrlEraseStuff(XSPRITE* pXSource, PLAYER* pPlayer) { pPlayer->hasWeapon[1] = true; pPlayer->curWeapon = kWeapNone; - pPlayer->nextWeapon = 1; + pPlayer->nextWeapon = kWeapPitchFork; WeaponRaise(pPlayer); if (pXSource->data2) break; @@ -2110,7 +2110,7 @@ void trPlayerCtrlGiveStuff(XSPRITE* pXSource, PLAYER* pPlayer, TRPLAYERCTRL* pCt break; } if (pPlayer->hasWeapon[weapon] && pXSource->data4 == 0) { // switch on it - pPlayer->nextWeapon = 0; + pPlayer->nextWeapon = kWeapNone; if (pPlayer->sceneQav >= 0 && spriRangeIsFine(pCtrl->qavScene.index)) { XSPRITE* pXScene = &xsprite[sprite[pCtrl->qavScene.index].extra]; diff --git a/source/games/blood/src/player.cpp b/source/games/blood/src/player.cpp index 257a45478..5e996b16b 100644 --- a/source/games/blood/src/player.cpp +++ b/source/games/blood/src/player.cpp @@ -722,7 +722,7 @@ void playerStart(int nPlayer, int bNewLevel) gFullMap = 0; pPlayer->throwPower = 0; pPlayer->deathTime = 0; - pPlayer->nextWeapon = 0; + pPlayer->nextWeapon = kWeapNone; xvel[pSprite->index] = yvel[pSprite->index] = zvel[pSprite->index] = 0; pInput->avel = 0; pInput->actions = 0; diff --git a/source/games/blood/src/weapon.cpp b/source/games/blood/src/weapon.cpp index 4685b66ca..5bbfa476f 100644 --- a/source/games/blood/src/weapon.cpp +++ b/source/games/blood/src/weapon.cpp @@ -2095,7 +2095,7 @@ void WeaponProcess(PLAYER *pPlayer) { sfxKill3DSound(pPlayer->pSprite, -1, 441); pPlayer->weaponState = 0; pPlayer->newWeapon = pPlayer->nextWeapon; - pPlayer->nextWeapon = 0; + pPlayer->nextWeapon = kWeapNone; } } if (pPlayer->input.getNewWeapon() == WeaponSel_Next) @@ -2105,7 +2105,7 @@ void WeaponProcess(PLAYER *pPlayer) { { pPlayer->weaponState = 0; } - pPlayer->nextWeapon = 0; + pPlayer->nextWeapon = kWeapNone; int t; int weapon = WeaponFindNext(pPlayer, &t, 1); pPlayer->weaponMode[weapon] = t; @@ -2127,7 +2127,7 @@ void WeaponProcess(PLAYER *pPlayer) { { pPlayer->weaponState = 0; } - pPlayer->nextWeapon = 0; + pPlayer->nextWeapon = kWeapNone; int t; int weapon = WeaponFindNext(pPlayer, &t, 0); pPlayer->weaponMode[weapon] = t; @@ -2163,7 +2163,7 @@ void WeaponProcess(PLAYER *pPlayer) { pPlayer->input.setNewWeapon(0); pPlayer->weaponState = 0; - pPlayer->nextWeapon = 0; + pPlayer->nextWeapon = kWeapNone; int t = 0; pPlayer->weaponMode[weapon] = t; if (pPlayer->curWeapon) @@ -2180,7 +2180,7 @@ void WeaponProcess(PLAYER *pPlayer) { { sfxKill3DSound(pPlayer->pSprite, -1, 441); pPlayer->newWeapon = pPlayer->nextWeapon; - pPlayer->nextWeapon = 0; + pPlayer->nextWeapon = kWeapNone; } } if (pPlayer->weaponState == -1) From 6a2a0da8193d07066375e881bb2137a2e5334922 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Tue, 3 Aug 2021 20:34:08 +1000 Subject: [PATCH 15/89] - Blood: Replace all numerical constants for player's `weaponQav` with enum values. --- source/games/blood/src/hudsprites.cpp | 2 +- source/games/blood/src/player.cpp | 4 +- source/games/blood/src/qav.h | 2 + source/games/blood/src/weapon.cpp | 68 +++++++++++++-------------- 4 files changed, 39 insertions(+), 37 deletions(-) diff --git a/source/games/blood/src/hudsprites.cpp b/source/games/blood/src/hudsprites.cpp index 6af4b9dbf..ac472252c 100644 --- a/source/games/blood/src/hudsprites.cpp +++ b/source/games/blood/src/hudsprites.cpp @@ -130,7 +130,7 @@ void hudDraw(PLAYER *gView, int nSectnum, double bobx, double boby, double zDelt if (gView->sceneQav < 0) WeaponDraw(gView, nShade, cX, cY, nPalette); else if (gView->pXSprite->health > 0) playerQavSceneDraw(gView, nShade, cX, cY, nPalette); else { - gView->sceneQav = gView->weaponQav = -1; + gView->sceneQav = gView->weaponQav = kQAVNone; gView->qavTimer = gView->weaponTimer = gView->curWeapon = 0; } #else diff --git a/source/games/blood/src/player.cpp b/source/games/blood/src/player.cpp index 5e996b16b..c0b0b7ca4 100644 --- a/source/games/blood/src/player.cpp +++ b/source/games/blood/src/player.cpp @@ -739,7 +739,7 @@ void playerStart(int nPlayer, int bNewLevel) pPlayer->handTime = 0; pPlayer->weaponTimer = 0; pPlayer->weaponState = 0; - pPlayer->weaponQav = -1; + pPlayer->weaponQav = kQAVNone; pPlayer->qavLastTick = 0; pPlayer->qavTimer = 0; #ifdef NOONE_EXTENSIONS @@ -813,7 +813,7 @@ void playerReset(PLAYER *pPlayer) pPlayer->armor[i] = 0; pPlayer->weaponTimer = 0; pPlayer->weaponState = 0; - pPlayer->weaponQav = -1; + pPlayer->weaponQav = kQAVNone; pPlayer->qavLoop = 0; pPlayer->qavLastTick = 0; pPlayer->qavTimer = 0; diff --git a/source/games/blood/src/qav.h b/source/games/blood/src/qav.h index b3fb237ce..d09f09c24 100644 --- a/source/games/blood/src/qav.h +++ b/source/games/blood/src/qav.h @@ -31,6 +31,8 @@ enum { kQavOrientationLeft = 4096 }; enum { + kQAVNone = -1, + kQAVFORKUP = 0, kQAVFORKIDLE = 1, kQAVPFORK = 2, diff --git a/source/games/blood/src/weapon.cpp b/source/games/blood/src/weapon.cpp index 5bbfa476f..d9e107b78 100644 --- a/source/games/blood/src/weapon.cpp +++ b/source/games/blood/src/weapon.cpp @@ -258,7 +258,7 @@ bool isOriginalQAV() void WeaponDraw(PLAYER *pPlayer, int shade, double xpos, double ypos, int palnum) { assert(pPlayer != NULL); - if (pPlayer->weaponQav == -1) + if (pPlayer->weaponQav == kQAVNone) return; QAV * pQAV = weaponQAV[pPlayer->weaponQav]; int duration; @@ -281,7 +281,7 @@ void WeaponDraw(PLAYER *pPlayer, int shade, double xpos, double ypos, int palnum void WeaponPlay(PLAYER *pPlayer) { assert(pPlayer != NULL); - if (pPlayer->weaponQav == -1) + if (pPlayer->weaponQav == kQAVNone) return; QAV *pQAV = weaponQAV[pPlayer->weaponQav]; pQAV->nSprite = pPlayer->pSprite->index; @@ -839,7 +839,7 @@ void WeaponUpdateState(PLAYER *pPlayer) switch (lastWeapon) { case kWeapPitchFork: - pPlayer->weaponQav = 1; + pPlayer->weaponQav = kQAVFORKIDLE; break; case kWeapSpraycan: switch (vb) @@ -855,15 +855,15 @@ void WeaponUpdateState(PLAYER *pPlayer) StartQAV(pPlayer, 8, -1, 0); } else - pPlayer->weaponQav = 6; + pPlayer->weaponQav = kQAVLITEIDLE; break; case 3: - pPlayer->weaponQav = 9; + pPlayer->weaponQav = kQAVCANIDLE; break; case 4: if (CheckAmmo(pPlayer, 6, 1)) { - pPlayer->weaponQav = 9; + pPlayer->weaponQav = kQAVCANIDLE; pPlayer->weaponState = 3; } else @@ -896,10 +896,10 @@ void WeaponUpdateState(PLAYER *pPlayer) StartQAV(pPlayer, 16, -1, 0); } else - pPlayer->weaponQav = 6; + pPlayer->weaponQav = kQAVLITEIDLE; break; case 3: - pPlayer->weaponQav = 20; + pPlayer->weaponQav = kQAVBUNIDLE; break; } break; @@ -907,7 +907,7 @@ void WeaponUpdateState(PLAYER *pPlayer) switch (vb) { case 7: - pPlayer->weaponQav = 27; + pPlayer->weaponQav = kQAVPROXIDLE; break; case 8: pPlayer->weaponState = 7; @@ -919,10 +919,10 @@ void WeaponUpdateState(PLAYER *pPlayer) switch (vb) { case 10: - pPlayer->weaponQav = 36; + pPlayer->weaponQav = kQAVREMIDLE1; break; case 11: - pPlayer->weaponQav = 37; + pPlayer->weaponQav = kQAVREMIDLE2; break; case 12: if (pPlayer->ammoCount[11] > 0) @@ -945,7 +945,7 @@ void WeaponUpdateState(PLAYER *pPlayer) pPlayer->weaponState = 1; break; case 7: - pPlayer->weaponQav = 60; + pPlayer->weaponQav = kQAV2SHOTI; break; case 1: if (CheckAmmo(pPlayer, 2, 1)) @@ -958,25 +958,25 @@ void WeaponUpdateState(PLAYER *pPlayer) pPlayer->weaponState = 2; } else - pPlayer->weaponQav = 51; + pPlayer->weaponQav = kQAVSHOTI3; break; case 2: - pPlayer->weaponQav = 52; + pPlayer->weaponQav = kQAVSHOTI2; break; case 3: - pPlayer->weaponQav = 53; + pPlayer->weaponQav = kQAVSHOTI1; break; } break; case kWeapTommyGun: if (powerupCheck(pPlayer, kPwUpTwoGuns) && checkAmmo2(pPlayer, 3, 2)) { - pPlayer->weaponQav = 70; + pPlayer->weaponQav = kQAV2TOMIDLE; pPlayer->weaponState = 1; } else { - pPlayer->weaponQav = 65; + pPlayer->weaponQav = kQAVTOMIDLE; pPlayer->weaponState = 0; } break; @@ -984,33 +984,33 @@ void WeaponUpdateState(PLAYER *pPlayer) if (powerupCheck(pPlayer, kPwUpTwoGuns)) { if (vb == 3 && checkAmmo2(pPlayer, 1, 2)) - pPlayer->weaponQav = 46; + pPlayer->weaponQav = kQAVFLAR2I; else { - pPlayer->weaponQav = 42; + pPlayer->weaponQav = kQAVFLARIDLE; pPlayer->weaponState = 2; } } else - pPlayer->weaponQav = 42; + pPlayer->weaponQav = kQAVFLARIDLE; break; case kWeapVoodooDoll: if (pXSprite->height < 256 && abs(pPlayer->swayHeight) > 16) - pPlayer->weaponQav = 102; + pPlayer->weaponQav = kQAVVDIDLE2; else - pPlayer->weaponQav = 101; + pPlayer->weaponQav = kQAVVDIDLE1; break; case kWeapTeslaCannon: switch (vb) { case 2: if (checkAmmo2(pPlayer, 7, 10) && powerupCheck(pPlayer, kPwUpTwoGuns)) - pPlayer->weaponQav = 83; + pPlayer->weaponQav = kQAV2SGUNIDL; else - pPlayer->weaponQav = 75; + pPlayer->weaponQav = kQAVSGUNIDL1; break; case 3: - pPlayer->weaponQav = 76; + pPlayer->weaponQav = kQAVSGUNIDL2; break; } break; @@ -1019,12 +1019,12 @@ void WeaponUpdateState(PLAYER *pPlayer) { case 3: if (powerupCheck(pPlayer, kPwUpTwoGuns) && (gInfiniteAmmo || CheckAmmo(pPlayer,4, 4))) - pPlayer->weaponQav = 121; + pPlayer->weaponQav = kQAV2NAPIDLE; else - pPlayer->weaponQav = 90; + pPlayer->weaponQav = kQAVNAPIDLE; break; case 2: - pPlayer->weaponQav = 90; + pPlayer->weaponQav = kQAVNAPIDLE; break; } break; @@ -1032,12 +1032,12 @@ void WeaponUpdateState(PLAYER *pPlayer) switch (vb) { case 2: - pPlayer->weaponQav = 112; + pPlayer->weaponQav = kQAVSTAFIDL1; break; } break; case kWeapBeast: - pPlayer->weaponQav = 94; + pPlayer->weaponQav = kQAVBSTIDLE; break; } } @@ -1592,7 +1592,7 @@ void FireTesla(int nTrigger, PLAYER *pPlayer) if (!checkAmmo2(pPlayer, 7, pMissile->ammouse)) { pPlayer->weaponState = -1; - pPlayer->weaponQav = 76; + pPlayer->weaponQav = kQAVSGUNIDL2; pPlayer->flashEffect = 0; return; } @@ -2076,7 +2076,7 @@ void WeaponProcess(PLAYER *pPlayer) { if (pPlayer->weaponTimer > 0) return; if (pPlayer->pXSprite->health == 0 || pPlayer->curWeapon == kWeapNone) - pPlayer->weaponQav = -1; + pPlayer->weaponQav = kQAVNone; switch (pPlayer->curWeapon) { case kWeapLifeLeech: @@ -2326,7 +2326,7 @@ void WeaponProcess(PLAYER *pPlayer) { switch (pPlayer->weaponState) { case 7: - pPlayer->weaponQav = 27; + pPlayer->weaponQav = kQAVPROXIDLE; pPlayer->weaponState = 9; pPlayer->throwTime = PlayClock; return; @@ -2336,7 +2336,7 @@ void WeaponProcess(PLAYER *pPlayer) { switch (pPlayer->weaponState) { case 10: - pPlayer->weaponQav = 36; + pPlayer->weaponQav = kQAVREMIDLE1; pPlayer->weaponState = 13; pPlayer->throwTime = PlayClock; return; From 77704d54d9b7cb566d26f480a7361ffceb4a40bd Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Tue, 3 Aug 2021 20:52:32 +1000 Subject: [PATCH 16/89] - Blood: Replace all numerical constants in calls to `StartQAV()` with enum values. --- source/games/blood/src/weapon.cpp | 256 +++++++++++++++--------------- 1 file changed, 128 insertions(+), 128 deletions(-) diff --git a/source/games/blood/src/weapon.cpp b/source/games/blood/src/weapon.cpp index d9e107b78..463386987 100644 --- a/source/games/blood/src/weapon.cpp +++ b/source/games/blood/src/weapon.cpp @@ -289,7 +289,7 @@ void WeaponPlay(PLAYER *pPlayer) pQAV->Play(nTicks-4, nTicks, pPlayer->qavCallback, pPlayer); } -static void StartQAV(PLAYER *pPlayer, int nWeaponQAV, int callback, bool looped = false) +static void StartQAV(PLAYER *pPlayer, int nWeaponQAV, int callback = -1, bool looped = false) { assert(nWeaponQAV < kQAVEnd); pPlayer->weaponQav = nWeaponQAV; @@ -505,18 +505,18 @@ void WeaponRaise(PLAYER *pPlayer) { case kWeapPitchFork: pPlayer->weaponState = 0; - StartQAV(pPlayer, 0, -1, 0); + StartQAV(pPlayer, kQAVFORKUP); break; case kWeapSpraycan: if (pPlayer->weaponState == 2) { pPlayer->weaponState = 3; - StartQAV(pPlayer, 8, -1, 0); + StartQAV(pPlayer, kQAVCANPREF); } else { pPlayer->weaponState = 0; - StartQAV(pPlayer, 4, -1, 0); + StartQAV(pPlayer, kQAVLITEOPEN); } break; case kWeapDynamite: @@ -524,27 +524,27 @@ void WeaponRaise(PLAYER *pPlayer) { pPlayer->weaponState = 3; if (prevWeapon == 7) - StartQAV(pPlayer, 16, -1, 0); + StartQAV(pPlayer, kQAVBUNUP); else - StartQAV(pPlayer, 18, -1, 0); + StartQAV(pPlayer, kQAVBUNUP2); } break; case kWeapProximity: if (gInfiniteAmmo || checkAmmo2(pPlayer, 10, 1)) { pPlayer->weaponState = 7; - StartQAV(pPlayer, 25, -1, 0); + StartQAV(pPlayer, kQAVPROXUP); } break; case kWeapRemote: if (gInfiniteAmmo || checkAmmo2(pPlayer, 11, 1)) { pPlayer->weaponState = 10; - StartQAV(pPlayer, 31, -1, 0); + StartQAV(pPlayer, kQAVREMUP2); } else { - StartQAV(pPlayer, 32, -1, 0); + StartQAV(pPlayer, kQAVREMUP3); pPlayer->weaponState = 11; } break; @@ -552,9 +552,9 @@ void WeaponRaise(PLAYER *pPlayer) if (powerupCheck(pPlayer, kPwUpTwoGuns)) { if (gInfiniteAmmo || pPlayer->ammoCount[2] >= 4) - StartQAV(pPlayer, 59, -1, 0); + StartQAV(pPlayer, kQAV2SHOTUP); else - StartQAV(pPlayer, 50, -1, 0); + StartQAV(pPlayer, kQAVSHOTUP); if (gInfiniteAmmo || pPlayer->ammoCount[2] >= 4) pPlayer->weaponState = 7; else if (pPlayer->ammoCount[2] > 1) @@ -572,37 +572,37 @@ void WeaponRaise(PLAYER *pPlayer) pPlayer->weaponState = 2; else pPlayer->weaponState = 1; - StartQAV(pPlayer, 50, -1, 0); + StartQAV(pPlayer, kQAVSHOTUP); } break; case kWeapTommyGun: if (powerupCheck(pPlayer, kPwUpTwoGuns) && checkAmmo2(pPlayer, 3, 2)) { pPlayer->weaponState = 1; - StartQAV(pPlayer, 69, -1, 0); + StartQAV(pPlayer, kQAV2TOMUP); } else { pPlayer->weaponState = 0; - StartQAV(pPlayer, 64, -1, 0); + StartQAV(pPlayer, kQAVTOMUP); } break; case kWeapVoodooDoll: if (gInfiniteAmmo || checkAmmo2(pPlayer, 9, 1)) { pPlayer->weaponState = 2; - StartQAV(pPlayer, 100, -1, 0); + StartQAV(pPlayer, kQAVVDUP); } break; case kWeapFlareGun: if (powerupCheck(pPlayer, kPwUpTwoGuns) && checkAmmo2(pPlayer, 1, 2)) { - StartQAV(pPlayer, 45, -1, 0); + StartQAV(pPlayer, kQAVFLAR2UP); pPlayer->weaponState = 3; } else { - StartQAV(pPlayer, 41, -1, 0); + StartQAV(pPlayer, kQAVFLARUP); pPlayer->weaponState = 2; } break; @@ -611,35 +611,35 @@ void WeaponRaise(PLAYER *pPlayer) { pPlayer->weaponState = 2; if (powerupCheck(pPlayer, kPwUpTwoGuns)) - StartQAV(pPlayer, 82, -1, 0); + StartQAV(pPlayer, kQAV2SGUNUP); else - StartQAV(pPlayer, 74, -1, 0); + StartQAV(pPlayer, kQAVSGUNUP); } else { pPlayer->weaponState = 3; - StartQAV(pPlayer, 74, -1, 0); + StartQAV(pPlayer, kQAVSGUNUP); } break; case kWeapNapalm: if (powerupCheck(pPlayer, kPwUpTwoGuns)) { - StartQAV(pPlayer, 120, -1, 0); + StartQAV(pPlayer, kQAV2NAPUP); pPlayer->weaponState = 3; } else { - StartQAV(pPlayer, 89, -1, 0); + StartQAV(pPlayer, kQAVNAPUP); pPlayer->weaponState = 2; } break; case kWeapLifeLeech: pPlayer->weaponState = 2; - StartQAV(pPlayer, 111, -1, 0); + StartQAV(pPlayer, kQAVSTAFUP); break; case kWeapBeast: pPlayer->weaponState = 2; - StartQAV(pPlayer, 93, -1, 0); + StartQAV(pPlayer, kQAVBSTUP); break; } } @@ -654,7 +654,7 @@ void WeaponLower(PLAYER *pPlayer) switch (pPlayer->curWeapon) { case kWeapPitchFork: - StartQAV(pPlayer, 3, -1, 0); + StartQAV(pPlayer, kQAVFORKDOWN); break; case kWeapSpraycan: sfxKill3DSound(pPlayer->pSprite, -1, 441); @@ -663,14 +663,14 @@ void WeaponLower(PLAYER *pPlayer) case 1: if (VanillaMode()) { - StartQAV(pPlayer, 7, -1, 0); + StartQAV(pPlayer, kQAVLITECLO2); } else { if (pPlayer->newWeapon == kWeapDynamite) { pPlayer->weaponState = 2; - StartQAV(pPlayer, 11, -1, 0); + StartQAV(pPlayer, kQAVCANDOWN); WeaponRaise(pPlayer); return; } @@ -682,7 +682,7 @@ void WeaponLower(PLAYER *pPlayer) return; case 4: pPlayer->weaponState = 1; - StartQAV(pPlayer, 11, -1, 0); + StartQAV(pPlayer, kQAVCANDOWN); if (VanillaMode()) { pPlayer->newWeapon = kWeapNone; @@ -693,7 +693,7 @@ void WeaponLower(PLAYER *pPlayer) if (pPlayer->newWeapon == kWeapDynamite) { pPlayer->weaponState = 2; - StartQAV(pPlayer, 11, -1, 0); + StartQAV(pPlayer, kQAVCANDOWN); return; } else @@ -706,20 +706,20 @@ void WeaponLower(PLAYER *pPlayer) if (pPlayer->newWeapon == kWeapDynamite) { pPlayer->weaponState = 2; - StartQAV(pPlayer, 11, -1, 0); + StartQAV(pPlayer, kQAVCANDOWN); return; } else if (pPlayer->newWeapon == kWeapSpraycan) { pPlayer->weaponState = 1; - StartQAV(pPlayer, 11, -1, 0); + StartQAV(pPlayer, kQAVCANDOWN); pPlayer->newWeapon = kWeapNone; WeaponLower(pPlayer); } else { pPlayer->weaponState = 1; - StartQAV(pPlayer, 11, -1, 0); + StartQAV(pPlayer, kQAVCANDOWN); } break; } @@ -730,14 +730,14 @@ void WeaponLower(PLAYER *pPlayer) case 1: if (VanillaMode()) { - StartQAV(pPlayer, 7, -1, 0); + StartQAV(pPlayer, kQAVLITECLO2); } else { if (pPlayer->newWeapon == kWeapSpraycan) { pPlayer->weaponState = 2; - StartQAV(pPlayer, 17, -1, 0); + StartQAV(pPlayer, kQAVBUNDOWN); WeaponRaise(pPlayer); return; } @@ -750,11 +750,11 @@ void WeaponLower(PLAYER *pPlayer) if (pPlayer->newWeapon == kWeapSpraycan) { pPlayer->weaponState = 2; - StartQAV(pPlayer, 17, -1, 0); + StartQAV(pPlayer, kQAVBUNDOWN); } else { - StartQAV(pPlayer, 19, -1, 0); + StartQAV(pPlayer, kQAVBUNDOWN2); } break; default: @@ -765,7 +765,7 @@ void WeaponLower(PLAYER *pPlayer) switch (prevState) { case 7: - StartQAV(pPlayer, 26, -1, 0); + StartQAV(pPlayer, kQAVPROXDOWN); break; } break; @@ -773,51 +773,51 @@ void WeaponLower(PLAYER *pPlayer) switch (prevState) { case 10: - StartQAV(pPlayer, 34, -1, 0); + StartQAV(pPlayer, kQAVREMDOWN2); break; case 11: - StartQAV(pPlayer, 35, -1, 0); + StartQAV(pPlayer, kQAVREMDOWN3); break; } break; case kWeapShotgun: if (powerupCheck(pPlayer, kPwUpTwoGuns)) - StartQAV(pPlayer, 63, -1, 0); + StartQAV(pPlayer, kQAV2SHOTDWN); else - StartQAV(pPlayer, 58, -1, 0); + StartQAV(pPlayer, kQAVSHOTDOWN); break; case kWeapTommyGun: if (powerupCheck(pPlayer, kPwUpTwoGuns) && pPlayer->weaponState == 1) - StartQAV(pPlayer, 72, -1, 0); + StartQAV(pPlayer, kQAV2TOMDOWN); else - StartQAV(pPlayer, 68, -1, 0); + StartQAV(pPlayer, kQAVTOMDOWN); break; case kWeapFlareGun: if (powerupCheck(pPlayer, kPwUpTwoGuns) && pPlayer->weaponState == 3) - StartQAV(pPlayer, 49, -1, 0); + StartQAV(pPlayer, kQAVFLAR2DWN); else - StartQAV(pPlayer, 44, -1, 0); + StartQAV(pPlayer, kQAVFLARDOWN); break; case kWeapVoodooDoll: - StartQAV(pPlayer, 109, -1, 0); + StartQAV(pPlayer, kQAVVDDOWN); break; case kWeapTeslaCannon: if (checkAmmo2(pPlayer, 7, 10) && powerupCheck(pPlayer, kPwUpTwoGuns)) - StartQAV(pPlayer, 88, -1, 0); + StartQAV(pPlayer, kQAV2SGUNDWN); else - StartQAV(pPlayer, 81, -1, 0); + StartQAV(pPlayer, kQAVSGUNDOWN); break; case kWeapNapalm: if (powerupCheck(pPlayer, kPwUpTwoGuns)) - StartQAV(pPlayer, 124, -1, 0); + StartQAV(pPlayer, kQAV2NAPDOWN); else - StartQAV(pPlayer, 92, -1, 0); + StartQAV(pPlayer, kQAVNAPDOWN); break; case kWeapLifeLeech: - StartQAV(pPlayer, 119, -1, 0); + StartQAV(pPlayer, kQAVSTAFDOWN); break; case kWeapBeast: - StartQAV(pPlayer, 99, -1, 0); + StartQAV(pPlayer, kQAVBSTDOWN); break; } pPlayer->curWeapon = kWeapNone; @@ -846,13 +846,13 @@ void WeaponUpdateState(PLAYER *pPlayer) { case 0: pPlayer->weaponState = 1; - StartQAV(pPlayer, 5, -1, 0); + StartQAV(pPlayer, kQAVLITEFLAM); break; case 1: if (CheckAmmo(pPlayer, 6, 1)) { pPlayer->weaponState = 3; - StartQAV(pPlayer, 8, -1, 0); + StartQAV(pPlayer, kQAVCANPREF); } else pPlayer->weaponQav = kQAVLITEIDLE; @@ -869,7 +869,7 @@ void WeaponUpdateState(PLAYER *pPlayer) else { pPlayer->weaponState = 1; - StartQAV(pPlayer, 11, -1, 0); + StartQAV(pPlayer, kQAVCANDOWN); } sfxKill3DSound(pPlayer->pSprite, -1, 441); break; @@ -882,18 +882,18 @@ void WeaponUpdateState(PLAYER *pPlayer) if (pPlayer->weaponAmmo == 5 && CheckAmmo(pPlayer, 5, 1)) { pPlayer->weaponState = 3; - StartQAV(pPlayer, 16, -1, 0); + StartQAV(pPlayer, kQAVBUNUP); } break; case 0: pPlayer->weaponState = 1; - StartQAV(pPlayer, 5, -1, 0); + StartQAV(pPlayer, kQAVLITEFLAM); break; case 2: if (pPlayer->ammoCount[5] > 0) { pPlayer->weaponState = 3; - StartQAV(pPlayer, 16, -1, 0); + StartQAV(pPlayer, kQAVBUNUP); } else pPlayer->weaponQav = kQAVLITEIDLE; @@ -911,7 +911,7 @@ void WeaponUpdateState(PLAYER *pPlayer) break; case 8: pPlayer->weaponState = 7; - StartQAV(pPlayer, 25, -1, 0); + StartQAV(pPlayer, kQAVPROXUP); break; } break; @@ -928,7 +928,7 @@ void WeaponUpdateState(PLAYER *pPlayer) if (pPlayer->ammoCount[11] > 0) { pPlayer->weaponState = 10; - StartQAV(pPlayer, 31, -1, 0); + StartQAV(pPlayer, kQAVREMUP2); } else pPlayer->weaponState = -1; @@ -951,7 +951,7 @@ void WeaponUpdateState(PLAYER *pPlayer) if (CheckAmmo(pPlayer, 2, 1)) { sfxPlay3DSound(pPlayer->pSprite, 410, 3, 2); - StartQAV(pPlayer, 57, nClientEjectShell, 0); + StartQAV(pPlayer, kQAVSHOTL1, nClientEjectShell); if (gInfiniteAmmo || pPlayer->ammoCount[2] > 1) pPlayer->weaponState = 3; else @@ -1097,7 +1097,7 @@ void ExplodeCan(int, PLAYER *pPlayer) spritetype *pSprite = playerFireThing(pPlayer, 0, 0, kThingArmedSpray, 0); evPost(pSprite->index, 3, 0, kCmdOn); UseAmmo(pPlayer, 6, gAmmoItemData[0].count); - StartQAV(pPlayer, 15, -1); + StartQAV(pPlayer, kQAVCANBOOM); pPlayer->curWeapon = kWeapNone; pPlayer->throwPower = 0; } @@ -1132,7 +1132,7 @@ void ExplodeBundle(int, PLAYER *pPlayer) spritetype *pSprite = playerFireThing(pPlayer, 0, 0, kThingArmedTNTBundle, 0); evPost(pSprite->index, 3, 0, kCmdOn); UseAmmo(pPlayer, 5, 1); - StartQAV(pPlayer, 24, -1, 0); + StartQAV(pPlayer, kQAVDYNEXPLO); pPlayer->curWeapon = kWeapNone; pPlayer->throwPower = 0; } @@ -1839,7 +1839,7 @@ int processSprayCan(PLAYER *pPlayer) { pPlayer->weaponState = 3; pPlayer->fuseTime = pPlayer->weaponTimer; - StartQAV(pPlayer, 13, nClientDropCan, 0); + StartQAV(pPlayer, kQAVCANDROP, nClientDropCan); } else if (pPlayer->input.actions & SB_FIRE) { @@ -1856,7 +1856,7 @@ int processSprayCan(PLAYER *pPlayer) if (!pPlayer->fuseTime) pPlayer->fuseTime = pPlayer->weaponTimer; pPlayer->weaponState = 1; - StartQAV(pPlayer, 14, nClientThrowCan, 0); + StartQAV(pPlayer, kQAVCANTHRO, nClientThrowCan); } return 1; } @@ -1877,7 +1877,7 @@ static bool processTNT(PLAYER *pPlayer) { pPlayer->weaponState = 1; pPlayer->fuseTime = pPlayer->weaponTimer; - StartQAV(pPlayer, 22, nClientDropBundle, 0); + StartQAV(pPlayer, kQAVBUNDROP, nClientDropBundle); } else if (pPlayer->input.actions & SB_FIRE) { @@ -1894,7 +1894,7 @@ static bool processTNT(PLAYER *pPlayer) if (!pPlayer->fuseTime) pPlayer->fuseTime = pPlayer->weaponTimer; pPlayer->weaponState = 1; - StartQAV(pPlayer, 23, nClientThrowBundle, 0); + StartQAV(pPlayer, kQAVBUNTHRO, nClientThrowBundle); } return 1; } @@ -1913,7 +1913,7 @@ static bool processProxy(PLAYER *pPlayer) if (!(pPlayer->input.actions & SB_FIRE)) { pPlayer->weaponState = 8; - StartQAV(pPlayer, 29, nClientThrowProx, 0); + StartQAV(pPlayer, kQAVPROXTHRO, nClientThrowProx); } break; } @@ -1929,7 +1929,7 @@ static bool processRemote(PLAYER *pPlayer) if (!(pPlayer->input.actions & SB_FIRE)) { pPlayer->weaponState = 11; - StartQAV(pPlayer, 39, nClientThrowRemote, 0); + StartQAV(pPlayer, kQAVREMTHRO, nClientThrowRemote); } break; } @@ -1942,19 +1942,19 @@ static bool processLeech(PLAYER *pPlayer) { case 4: pPlayer->weaponState = 6; - StartQAV(pPlayer, 114, nClientFireLifeLeech, 1); + StartQAV(pPlayer, kQAVSTAFIRE1, nClientFireLifeLeech, 1); return 1; case 6: if (!(pPlayer->input.actions & SB_ALTFIRE)) { pPlayer->weaponState = 2; - StartQAV(pPlayer, 118, -1, 0); + StartQAV(pPlayer, kQAVSTAFPOST); return 1; } break; case 8: pPlayer->weaponState = 2; - StartQAV(pPlayer, 118, -1, 0); + StartQAV(pPlayer, kQAVSTAFPOST); return 1; } return 0; @@ -1967,27 +1967,27 @@ static bool processTesla(PLAYER *pPlayer) case 4: pPlayer->weaponState = 5; if (checkAmmo2(pPlayer, 7, 10) && powerupCheck(pPlayer, kPwUpTwoGuns)) - StartQAV(pPlayer, 84, nClientFireTesla, 1); + StartQAV(pPlayer, kQAV2SGUNFIR, nClientFireTesla, 1); else - StartQAV(pPlayer, 77, nClientFireTesla, 1); + StartQAV(pPlayer, kQAVSGUNFIR1, nClientFireTesla, 1); return 1; case 5: if (!(pPlayer->input.actions & SB_FIRE)) { pPlayer->weaponState = 2; if (checkAmmo2(pPlayer, 7, 10) && powerupCheck(pPlayer, kPwUpTwoGuns)) - StartQAV(pPlayer, 87, -1, 0); + StartQAV(pPlayer, kQAV2SGUNPST); else - StartQAV(pPlayer, 80, -1, 0); + StartQAV(pPlayer, kQAVSGUNPOST); return 1; } break; case 7: pPlayer->weaponState = 2; if (checkAmmo2(pPlayer, 7, 10) && powerupCheck(pPlayer, kPwUpTwoGuns)) - StartQAV(pPlayer, 87, -1, 0); + StartQAV(pPlayer, kQAV2SGUNPST); else - StartQAV(pPlayer, 80, -1, 0); + StartQAV(pPlayer, kQAVSGUNPOST); return 1; } return 0; @@ -2300,14 +2300,14 @@ void WeaponProcess(PLAYER *pPlayer) { switch (pPlayer->curWeapon) { case kWeapPitchFork: - StartQAV(pPlayer, 2, nClientFirePitchfork, 0); + StartQAV(pPlayer, kQAVPFORK, nClientFirePitchfork); return; case kWeapSpraycan: switch (pPlayer->weaponState) { case 3: pPlayer->weaponState = 4; - StartQAV(pPlayer, 10, nClientFireSpray, 1); + StartQAV(pPlayer, kQAVCANFIRE, nClientFireSpray, 1); return; } break; @@ -2318,7 +2318,7 @@ void WeaponProcess(PLAYER *pPlayer) { pPlayer->weaponState = 6; pPlayer->fuseTime = -1; pPlayer->throwTime = PlayClock; - StartQAV(pPlayer, 21, nClientExplodeBundle, 0); + StartQAV(pPlayer, kQAVBUNFUSE, nClientExplodeBundle); return; } break; @@ -2342,7 +2342,7 @@ void WeaponProcess(PLAYER *pPlayer) { return; case 11: pPlayer->weaponState = 12; - StartQAV(pPlayer, 40, nClientFireRemote, 0); + StartQAV(pPlayer, kQAVREMFIRE, nClientFireRemote); return; } break; @@ -2351,29 +2351,29 @@ void WeaponProcess(PLAYER *pPlayer) { { case 7: pPlayer->weaponState = 6; - StartQAV(pPlayer, 61, nClientFireShotgun, 0); + StartQAV(pPlayer, kQAV2SHOTF2, nClientFireShotgun); return; case 3: pPlayer->weaponState = 2; - StartQAV(pPlayer, 54, nClientFireShotgun, 0); + StartQAV(pPlayer, kQAVSHOTF1, nClientFireShotgun); return; case 2: pPlayer->weaponState = 1; - StartQAV(pPlayer, 55, nClientFireShotgun, 0); + StartQAV(pPlayer, kQAVSHOTF2, nClientFireShotgun); return; } break; case kWeapTommyGun: if (powerupCheck(pPlayer, kPwUpTwoGuns) && checkAmmo2(pPlayer, 3, 2)) - StartQAV(pPlayer, 71, nClientFireTommy, 1); + StartQAV(pPlayer, kQAV2TOMFIRE, nClientFireTommy, 1); else - StartQAV(pPlayer, 66, nClientFireTommy, 1); + StartQAV(pPlayer, kQAVTOMFIRE, nClientFireTommy, 1); return; case kWeapFlareGun: if (powerupCheck(pPlayer, kPwUpTwoGuns) && checkAmmo2(pPlayer, 1, 2)) - StartQAV(pPlayer, 48, nClientFireFlare, 0); + StartQAV(pPlayer, kQAVFLAR2FIR, nClientFireFlare); else - StartQAV(pPlayer, 43, nClientFireFlare, 0); + StartQAV(pPlayer, kQAVFLARFIR2, nClientFireFlare); return; case kWeapVoodooDoll: { @@ -2386,7 +2386,7 @@ void WeaponProcess(PLAYER *pPlayer) { pPlayer->voodooTarget = pPlayer->aimTarget; if (pPlayer->voodooTarget == -1 || sprite[pPlayer->voodooTarget].statnum != kStatDude) i = 4; - StartQAV(pPlayer,103+i, nClientFireVoodoo, 0); + StartQAV(pPlayer,kQAVVDFIRE1 + i, nClientFireVoodoo); return; } case kWeapTeslaCannon: @@ -2395,30 +2395,30 @@ void WeaponProcess(PLAYER *pPlayer) { case 2: pPlayer->weaponState = 4; if (checkAmmo2(pPlayer, 7, 10) && powerupCheck(pPlayer, kPwUpTwoGuns)) - StartQAV(pPlayer, 84, nClientFireTesla, 0); + StartQAV(pPlayer, kQAV2SGUNFIR, nClientFireTesla); else - StartQAV(pPlayer, 77, nClientFireTesla, 0); + StartQAV(pPlayer, kQAVSGUNFIR1, nClientFireTesla); return; case 5: if (checkAmmo2(pPlayer, 7, 10) && powerupCheck(pPlayer, kPwUpTwoGuns)) - StartQAV(pPlayer, 84, nClientFireTesla, 0); + StartQAV(pPlayer, kQAV2SGUNFIR, nClientFireTesla); else - StartQAV(pPlayer, 77, nClientFireTesla, 0); + StartQAV(pPlayer, kQAVSGUNFIR1, nClientFireTesla); return; } break; case kWeapNapalm: if (powerupCheck(pPlayer, kPwUpTwoGuns)) - StartQAV(pPlayer, 122, nClientFireNapalm, 0); + StartQAV(pPlayer, kQAV2NAPFIRE, nClientFireNapalm); else - StartQAV(pPlayer, 91, nClientFireNapalm, 0); + StartQAV(pPlayer, kQAVNAPFIRE, nClientFireNapalm); return; case kWeapLifeLeech: sfxPlay3DSound(pPlayer->pSprite, 494, 2, 0); - StartQAV(pPlayer, 116, nClientFireLifeLeech, 0); + StartQAV(pPlayer, kQAVSTAFIRE4, nClientFireLifeLeech); return; case kWeapBeast: - StartQAV(pPlayer, 95+Random(4), nClientFireBeast, 0); + StartQAV(pPlayer, kQAVBSTATAK1 + Random(4), nClientFireBeast); return; } } @@ -2427,14 +2427,14 @@ void WeaponProcess(PLAYER *pPlayer) { switch (pPlayer->curWeapon) { case kWeapPitchFork: - StartQAV(pPlayer, 2, nClientFirePitchfork, 0); + StartQAV(pPlayer, kQAVPFORK, nClientFirePitchfork); return; case kWeapSpraycan: switch (pPlayer->weaponState) { case 3: pPlayer->weaponState = 5; - StartQAV(pPlayer, 12, nClientExplodeCan, 0); + StartQAV(pPlayer, kQAVCANFIRE2, nClientExplodeCan); return; } break; @@ -2443,21 +2443,21 @@ void WeaponProcess(PLAYER *pPlayer) { { case 3: pPlayer->weaponState = 4; - StartQAV(pPlayer, 21, nClientExplodeBundle, 0); + StartQAV(pPlayer, kQAVBUNFUSE, nClientExplodeBundle); return; case 7: pPlayer->weaponState = 8; - StartQAV(pPlayer, 28, nClientDropProx, 0); + StartQAV(pPlayer, kQAVPROXDROP, nClientDropProx); return; case 10: pPlayer->weaponState = 11; - StartQAV(pPlayer, 38, nClientDropRemote, 0); + StartQAV(pPlayer, kQAVREMDROP, nClientDropRemote); return; case 11: if (pPlayer->ammoCount[11] > 0) { pPlayer->weaponState = 10; - StartQAV(pPlayer, 30, -1, 0); + StartQAV(pPlayer, kQAVREMUP1); } return; } @@ -2467,7 +2467,7 @@ void WeaponProcess(PLAYER *pPlayer) { { case 7: pPlayer->weaponState = 8; - StartQAV(pPlayer, 28, nClientDropProx, 0); + StartQAV(pPlayer, kQAVPROXDROP, nClientDropProx); return; } break; @@ -2476,13 +2476,13 @@ void WeaponProcess(PLAYER *pPlayer) { { case 10: pPlayer->weaponState = 11; - StartQAV(pPlayer, 38, nClientDropRemote, 0); + StartQAV(pPlayer, kQAVREMDROP, nClientDropRemote); return; case 11: if (pPlayer->ammoCount[11] > 0) { pPlayer->weaponState = 10; - StartQAV(pPlayer, 30, -1, 0); + StartQAV(pPlayer, kQAVREMUP1); } return; } @@ -2492,85 +2492,85 @@ void WeaponProcess(PLAYER *pPlayer) { { case 7: pPlayer->weaponState = 6; - StartQAV(pPlayer, 62, nClientFireShotgun, 0); + StartQAV(pPlayer, kQAV2SHOTFIR, nClientFireShotgun); return; case 3: pPlayer->weaponState = 1; - StartQAV(pPlayer, 56, nClientFireShotgun, 0); + StartQAV(pPlayer, kQAVSHOTF3, nClientFireShotgun); return; case 2: pPlayer->weaponState = 1; - StartQAV(pPlayer, 55, nClientFireShotgun, 0); + StartQAV(pPlayer, kQAVSHOTF2, nClientFireShotgun); return; } break; case kWeapTommyGun: if (powerupCheck(pPlayer, kPwUpTwoGuns) && checkAmmo2(pPlayer, 3, 2)) - StartQAV(pPlayer, 73, nClientAltFireSpread2, 0); + StartQAV(pPlayer, kQAV2TOMALT, nClientAltFireSpread2); else - StartQAV(pPlayer, 67, nClientAltFireSpread2, 0); + StartQAV(pPlayer, kQAVTOMSPRED, nClientAltFireSpread2); return; case kWeapVoodooDoll: sfxPlay3DSound(pPlayer->pSprite, 461, 2, 0); - StartQAV(pPlayer, 110, nClientAltFireVoodoo, 0); + StartQAV(pPlayer, kQAVVDSPEL1, nClientAltFireVoodoo); return; #if 0 case kWeapFlareGun: if (powerupCheck(pPlayer, kPwUpTwoGuns) && checkAmmo2(pPlayer, 1, 2)) - StartQAV(pPlayer, 48, nClientFireFlare, 0); + StartQAV(pPlayer, kQAVFLAR2FIR, nClientFireFlare, 0); else - StartQAV(pPlayer, 43, nClientFireFlare, 0); + StartQAV(pPlayer, kQAVFLARFIR2, nClientFireFlare, 0); return; #endif case kWeapTeslaCannon: if (checkAmmo2(pPlayer, 7, 35)) { if (checkAmmo2(pPlayer, 7, 70) && powerupCheck(pPlayer, kPwUpTwoGuns)) - StartQAV(pPlayer, 85, nClientFireTesla, 0); + StartQAV(pPlayer, kQAV2SGUNALT, nClientFireTesla); else - StartQAV(pPlayer, 78, nClientFireTesla, 0); + StartQAV(pPlayer, kQAVSGUNFIR4, nClientFireTesla); } else { if (checkAmmo2(pPlayer, 7, 10) && powerupCheck(pPlayer, kPwUpTwoGuns)) - StartQAV(pPlayer, 84, nClientFireTesla, 0); + StartQAV(pPlayer, kQAV2SGUNFIR, nClientFireTesla); else - StartQAV(pPlayer, 77, nClientFireTesla, 0); + StartQAV(pPlayer, kQAVSGUNFIR1, nClientFireTesla); } return; case kWeapNapalm: if (powerupCheck(pPlayer, kPwUpTwoGuns)) // by NoOne: allow napalm launcher alt fire act like in v1.0x versions - if (gGameOptions.weaponsV10x && !VanillaMode() && !DemoRecordStatus()) StartQAV(pPlayer, 123, nClientFireNapalm2, 0); - else StartQAV(pPlayer, 122, nClientAltFireNapalm, 0); + if (gGameOptions.weaponsV10x && !VanillaMode() && !DemoRecordStatus()) StartQAV(pPlayer, kQAV2NAPFIR2, nClientFireNapalm2); + else StartQAV(pPlayer, kQAV2NAPFIRE, nClientAltFireNapalm, 0); else - StartQAV(pPlayer, 91, (gGameOptions.weaponsV10x && !VanillaMode() && !DemoRecordStatus()) ? nClientFireNapalm : nClientAltFireNapalm, 0); + StartQAV(pPlayer, kQAVNAPFIRE, (gGameOptions.weaponsV10x && !VanillaMode() && !DemoRecordStatus()) ? nClientFireNapalm : nClientAltFireNapalm); return; case kWeapFlareGun: if (CheckAmmo(pPlayer, 1, 8)) { if (powerupCheck(pPlayer, kPwUpTwoGuns) && checkAmmo2(pPlayer, 1, 16)) - StartQAV(pPlayer, 48, nClientAltFireFlare, 0); + StartQAV(pPlayer, kQAVFLAR2FIR, nClientAltFireFlare); else - StartQAV(pPlayer, 43, nClientAltFireFlare, 0); + StartQAV(pPlayer, kQAVFLARFIR2, nClientAltFireFlare); } else { if (powerupCheck(pPlayer, kPwUpTwoGuns) && checkAmmo2(pPlayer, 1, 2)) - StartQAV(pPlayer, 48, nClientFireFlare, 0); + StartQAV(pPlayer, kQAVFLAR2FIR, nClientFireFlare); else - StartQAV(pPlayer, 43, nClientFireFlare, 0); + StartQAV(pPlayer, kQAVFLARFIR2, nClientFireFlare); } return; case kWeapLifeLeech: if (gGameOptions.nGameType <= 1 && !checkAmmo2(pPlayer, 8, 1) && pPlayer->pXSprite->health < (25 << 4)) { sfxPlay3DSound(pPlayer->pSprite, 494, 2, 0); - StartQAV(pPlayer, 116, nClientFireLifeLeech, 0); + StartQAV(pPlayer, kQAVSTAFIRE4, nClientFireLifeLeech); } else { - StartQAV(pPlayer, 119, -1, 0); + StartQAV(pPlayer, kQAVSTAFDOWN); AltFireLifeLeech(1, pPlayer); pPlayer->weaponState = -1; } From 84496029a91598885ee8e0a193bc8f4682bb8b3a Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Wed, 18 Aug 2021 19:57:31 +1000 Subject: [PATCH 17/89] - Blood: Replace a few missed numerical constants with enums. --- source/games/blood/src/weapon.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/source/games/blood/src/weapon.cpp b/source/games/blood/src/weapon.cpp index 463386987..13f59e0de 100644 --- a/source/games/blood/src/weapon.cpp +++ b/source/games/blood/src/weapon.cpp @@ -171,7 +171,7 @@ static bool sub_4B1A4(PLAYER *pPlayer) static bool BannedUnderwater(int nWeapon) { - return nWeapon == 7 || nWeapon == 6; + return nWeapon == kWeapSpraycan || nWeapon == kWeapDynamite; } static bool CheckWeaponAmmo(PLAYER *pPlayer, int weapon, int ammotype, int count) @@ -180,9 +180,9 @@ static bool CheckWeaponAmmo(PLAYER *pPlayer, int weapon, int ammotype, int count return 1; if (ammotype == -1) return 1; - if (weapon == 12 && pPlayer->weaponAmmo == 11 && pPlayer->weaponState == 11) + if (weapon == kWeapRemote && pPlayer->weaponAmmo == 11 && pPlayer->weaponState == 11) return 1; - if (weapon == 9 && pPlayer->pXSprite->health > 0) + if (weapon == kWeapLifeLeech && pPlayer->pXSprite->health > 0) return 1; return pPlayer->ammoCount[ammotype] >= count; } @@ -523,7 +523,7 @@ void WeaponRaise(PLAYER *pPlayer) if (gInfiniteAmmo || checkAmmo2(pPlayer, 5, 1)) { pPlayer->weaponState = 3; - if (prevWeapon == 7) + if (prevWeapon == kWeapSpraycan) StartQAV(pPlayer, kQAVBUNUP); else StartQAV(pPlayer, kQAVBUNUP2); @@ -2100,7 +2100,7 @@ void WeaponProcess(PLAYER *pPlayer) { } if (pPlayer->input.getNewWeapon() == WeaponSel_Next) { - pPlayer->input.setNewWeapon(0); + pPlayer->input.setNewWeapon(kWeapNone); if (VanillaMode()) { pPlayer->weaponState = 0; @@ -2122,7 +2122,7 @@ void WeaponProcess(PLAYER *pPlayer) { } else if (pPlayer->input.getNewWeapon() == WeaponSel_Prev) { - pPlayer->input.setNewWeapon(0); + pPlayer->input.setNewWeapon(kWeapNone); if (VanillaMode()) { pPlayer->weaponState = 0; @@ -2161,7 +2161,7 @@ void WeaponProcess(PLAYER *pPlayer) { return; } - pPlayer->input.setNewWeapon(0); + pPlayer->input.setNewWeapon(kWeapNone); pPlayer->weaponState = 0; pPlayer->nextWeapon = kWeapNone; int t = 0; From 968708a6496e4bad9a5a20d15f209b9a26489fa8 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Wed, 4 Aug 2021 19:54:28 +1000 Subject: [PATCH 18/89] - Blood: Remove the extern for `weaponQAV[]` and move `kQAVEnd` enum into new enum from 9e84dd1ef6051f4e54d99dcfc6e3468560175e16 --- source/games/blood/src/misc.h | 2 -- source/games/blood/src/qav.h | 2 ++ source/games/blood/src/weapon.cpp | 4 +--- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/source/games/blood/src/misc.h b/source/games/blood/src/misc.h index fcd7b8da1..96914d50f 100644 --- a/source/games/blood/src/misc.h +++ b/source/games/blood/src/misc.h @@ -41,9 +41,7 @@ void DrawMirrors(int x, int y, int z, fixed_t a, fixed_t horiz, int smooth, int int qanimateoffs(int a1, int a2); void HookReplaceFunctions(); -struct QAV; struct PLAYER; -extern QAV* weaponQAV[]; void WeaponInit(void); void WeaponDraw(PLAYER *pPlayer, int a2, double a3, double a4, int a5); diff --git a/source/games/blood/src/qav.h b/source/games/blood/src/qav.h index d09f09c24..0cd90af1f 100644 --- a/source/games/blood/src/qav.h +++ b/source/games/blood/src/qav.h @@ -177,6 +177,8 @@ enum kQAV2NAPFIRE = 122, kQAV2NAPFIR2 = 123, kQAV2NAPDOWN = 124, + + kQAVEnd = 125, }; // by NoOne: add sound flags diff --git a/source/games/blood/src/weapon.cpp b/source/games/blood/src/weapon.cpp index 13f59e0de..225019f23 100644 --- a/source/games/blood/src/weapon.cpp +++ b/source/games/blood/src/weapon.cpp @@ -33,8 +33,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_BLD_NS -enum { kQAVEnd = 125 }; - void FirePitchfork(int, PLAYER *pPlayer); void FireSpray(int, PLAYER *pPlayer); void ThrowCan(int, PLAYER *pPlayer); @@ -142,7 +140,7 @@ enum nClientAltFireNapalm, }; -QAV *weaponQAV[kQAVEnd]; +static QAV *weaponQAV[kQAVEnd]; static bool sub_4B1A4(PLAYER *pPlayer) { From 20ea0acbec97ac7ea1fd405191ae1db1a1722302 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 21 Aug 2021 13:34:58 +1000 Subject: [PATCH 19/89] - Add `Contains()` method to `TArray` class, returning a true/false bool as appropriate. --- source/common/utility/tarray.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source/common/utility/tarray.h b/source/common/utility/tarray.h index 635f1cc75..2aaf5c0cf 100644 --- a/source/common/utility/tarray.h +++ b/source/common/utility/tarray.h @@ -292,6 +292,17 @@ public: return i; } + bool Contains(const T& item) const + { + unsigned int i; + for(i = 0;i < Count;++i) + { + if(Array[i] == item) + return true; + } + return false; + } + template unsigned int FindEx(Func compare) const { From 9251ce11c7112a866ac11fbbb6c3399be024668e Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 21 Aug 2021 13:35:41 +1000 Subject: [PATCH 20/89] - Blood: Remove unused `isOriginalQAV()` function from weapon.cpp. --- source/games/blood/src/weapon.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/source/games/blood/src/weapon.cpp b/source/games/blood/src/weapon.cpp index 225019f23..8671189a9 100644 --- a/source/games/blood/src/weapon.cpp +++ b/source/games/blood/src/weapon.cpp @@ -244,15 +244,6 @@ void WeaponPrecache() } } -bool isOriginalQAV() -{ - static int cached = -1; - if (cached != -1) return cached; - int lump = fileSystem.FindResource(60, "QAV"); - cached = lump >= 0 && fileSystem.GetFileContainer(lump) < fileSystem.GetMaxIwadNum(); - return cached; -} - void WeaponDraw(PLAYER *pPlayer, int shade, double xpos, double ypos, int palnum) { assert(pPlayer != NULL); From f67a09680e59745ae1cf6e5e1794ae2d0d195025 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 21 Aug 2021 19:55:02 +1000 Subject: [PATCH 21/89] - Blood: Rename CVAR `cl_bloodhudinterp` to `cl_bloodqavinterp`. --- source/core/gamecvars.cpp | 2 +- source/core/gamecvars.h | 2 +- source/games/blood/src/qav.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/core/gamecvars.cpp b/source/core/gamecvars.cpp index 2dee33550..6126cb691 100644 --- a/source/core/gamecvars.cpp +++ b/source/core/gamecvars.cpp @@ -84,7 +84,7 @@ CVARD(Bool, cl_exhumedoldturn, false, CVAR_ARCHIVE, "enable/disable legacy turni CVARD(Bool, cl_hudinterpolation, true, CVAR_ARCHIVE, "enable/disable HUD (weapon drawer) interpolation") CVARD(Bool, cl_bloodvanillarun, true, CVAR_ARCHIVE, "enable/disable Blood's vanilla run mode") CVARD(Bool, cl_bloodvanillabobbing, true, CVAR_ARCHIVE, "enable/disable Blood's vanilla bobbing while not using vanilla run mode") -CVARD(Bool, cl_bloodhudinterp, false, CVAR_ARCHIVE, "enable/disable Blood's HUD interpolation") +CVARD(Bool, cl_bloodqavinterp, false, CVAR_ARCHIVE, "enable/disable Blood's HUD interpolation") CVARD(Bool, cl_bloodoldweapbalance, false, CVAR_ARCHIVE, "enable/disable legacy 1.0 weapon handling for Blood") diff --git a/source/core/gamecvars.h b/source/core/gamecvars.h index d8d70cd5d..421080ab9 100644 --- a/source/core/gamecvars.h +++ b/source/core/gamecvars.h @@ -29,7 +29,7 @@ EXTERN_CVAR(Bool, cl_exhumedoldturn) EXTERN_CVAR(Bool, cl_hudinterpolation) EXTERN_CVAR(Bool, cl_bloodvanillarun) EXTERN_CVAR(Bool, cl_bloodvanillabobbing) -EXTERN_CVAR(Bool, cl_bloodhudinterp) +EXTERN_CVAR(Bool, cl_bloodqavinterp) EXTERN_CVAR(Bool, cl_bloodoldweapbalance) EXTERN_CVAR(Bool, demorec_seeds_cvar) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 2709deea5..955d445c5 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -89,7 +89,7 @@ void QAV::Draw(double x, double y, int ticks, int stat, int shade, int palnum, b double tileZ; double tileA; - if (cl_bloodhudinterp && prevTile && cl_hudinterpolation && (nFrames > 1) && (nFrame != oFrame) && (smoothratio != MaxSmoothRatio) && interpolate) + if (cl_bloodqavinterp && prevTile && cl_hudinterpolation && (nFrames > 1) && (nFrame != oFrame) && (smoothratio != MaxSmoothRatio) && interpolate) { tileX += interpolatedvaluef(prevTile->x, thisTile->x, smoothratio); tileY += interpolatedvaluef(prevTile->y, thisTile->y, smoothratio); From e273b93d12ece4934990d75afe6d02274d48c8b9 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 21 Aug 2021 21:25:26 +1000 Subject: [PATCH 22/89] - Blood: Overhaul entire QAV interpolation setup in preparation to exposing to DEF parsing. --- source/games/blood/src/qav.cpp | 211 +++++++++++++++++++++++++-------- source/games/blood/src/qav.h | 10 ++ 2 files changed, 169 insertions(+), 52 deletions(-) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 955d445c5..a17a2f2d3 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -34,6 +34,136 @@ BEGIN_BLD_NS extern void (*qavClientCallback[])(int, void *); +//========================================================================== +// +// QAV interpolation functions +// +//========================================================================== + +enum +{ + kQAVIsLoopable, +}; + +static TMap qavPrevTileFinders; +static TMap>> qavSkippedFrameTiles; +static TMap qavInterpProps; + +static void qavInitTileFinderMap() +{ + // Interpolate between frames if the picnums match. This is safest but could miss interpolations between suitable picnums. + qavPrevTileFinders.Insert("interpolate-picnum", [](FRAMEINFO* const thisFrame, FRAMEINFO* const prevFrame, const int& i) -> TILE_FRAME* { + return prevFrame->tiles[i].picnum == thisFrame->tiles[i].picnum ? &prevFrame->tiles[i] : nullptr; + }); + + // Interpolate between frames if the picnum is valid. This can be problematic if tile indices change between frames. + qavPrevTileFinders.Insert("interpolate-index", [](FRAMEINFO* const thisFrame, FRAMEINFO* const prevFrame, const int& i) -> TILE_FRAME* { + return prevFrame->tiles[i].picnum > 0 ? &prevFrame->tiles[i] : nullptr; + }); + + // Find previous frame by iterating all previous frame's tiles and return on first matched x coordinate. + qavPrevTileFinders.Insert("interpolate-x", [](FRAMEINFO* const thisFrame, FRAMEINFO* const prevFrame, const int& i) -> TILE_FRAME* { + for (int j = 0; j < 8; j++) if (thisFrame->tiles[i].x == prevFrame->tiles[j].x) + { + return &prevFrame->tiles[j]; + } + return nullptr; + }); + + // Find previous frame by iterating all previous frame's tiles and return on first matched y coordinate. + qavPrevTileFinders.Insert("interpolate-y", [](FRAMEINFO* const thisFrame, FRAMEINFO* const prevFrame, const int& i) -> TILE_FRAME* { + for (int j = 0; j < 8; j++) if (thisFrame->tiles[i].y == prevFrame->tiles[j].y) + { + return &prevFrame->tiles[j]; + } + return nullptr; + }); + + // When type is unspecified, default to using the safest interpolation option. + qavPrevTileFinders.Insert("interpolate", *qavPrevTileFinders.CheckKey("interpolate-picnum")); +} + +static bool qavCanInterpFrameTile(const int& res_id, const int& nFrame, const int& i) +{ + // Check whether this QAV has skippable tiles. + auto thisQAV = qavSkippedFrameTiles.CheckKey(res_id); + if (thisQAV) + { + // Check whether the current frame's tile is skippable. + auto thisFrame = thisQAV->CheckKey(nFrame); + if (thisFrame) + { + return !thisFrame->Contains(i); + } + } + + // Return true by default. + return true; +} + +QAVPrevTileFinder qavGetInterpType(const FString& type) +{ + if (!qavPrevTileFinders.CountUsed()) qavInitTileFinderMap(); + return *qavPrevTileFinders.CheckKey(type); +} + +void qavSetNonInterpFrameTile(const int& res_id, const int& nFrame, const int& i) +{ + // Check whether incoming resource is already in TMap. + auto thisQAV = qavSkippedFrameTiles.CheckKey(res_id); + if (!thisQAV) + { + TMap> framemap; + qavSkippedFrameTiles.Insert(res_id, std::move(framemap)); + thisQAV = qavSkippedFrameTiles.CheckKey(res_id); + } + + // Check whether this resource's TMap has a frame TMap. + auto thisFrame = thisQAV->CheckKey(nFrame); + if (!thisFrame) + { + TArray tilearray; + thisQAV->Insert(nFrame, std::move(tilearray)); + thisFrame = thisQAV->CheckKey(nFrame); + } + + // Check whether the TArray in this frame's TMap already contains the tile. + if (!thisFrame->Contains(i)) + { + thisFrame->Push(i); + } + + return; +} + +void qavBuildInterpProps(QAV* const pQAV) +{ + switch (pQAV->res_id) + { + case kQAVBDRIP: + { + QAVInterpProps interp{}; + interp.flags |= true << kQAVIsLoopable; + interp.PrevTileFinder = qavGetInterpType("interpolate-x"); + qavInterpProps.Insert(pQAV->res_id, std::move(interp)); + for (int i = 0; i < pQAV->nFrames; i++) + { + qavSetNonInterpFrameTile(pQAV->res_id, i, 0); + } + break; + } + default: + { + QAVInterpProps interp{}; + interp.flags = 0; + interp.PrevTileFinder = qavGetInterpType("interpolate-index"); + qavInterpProps.Insert(pQAV->res_id, std::move(interp)); + break; + } + } +} + + void DrawFrame(double x, double y, double z, double a, TILE_FRAME *pTile, int stat, int shade, int palnum, bool to3dview) { stat |= pTile->stat; @@ -76,70 +206,44 @@ void QAV::Draw(double x, double y, int ticks, int stat, int shade, int palnum, b { assert(ticksPerFrame > 0); + auto const interpdata = qavInterpProps.CheckKey(res_id); + auto const nFrame = clamp(ticks / ticksPerFrame, 0, nFrames - 1); - FRAMEINFO *thisFrame = &frames[nFrame]; + FRAMEINFO* const thisFrame = &frames[nFrame]; - auto const oFrame = clamp((nFrame == 0 && looped ? nFrames : nFrame) - 1, 0, nFrames - 1); - FRAMEINFO *prevFrame = &frames[oFrame]; + auto const oFrame = clamp((nFrame == 0 && (looped || interpdata && (interpdata->flags & kQAVIsLoopable)) ? nFrames : nFrame) - 1, 0, nFrames - 1); + FRAMEINFO* const prevFrame = &frames[oFrame]; - auto drawTile = [&](TILE_FRAME *thisTile, TILE_FRAME *prevTile, bool const interpolate = true) - { - double tileX = x; - double tileY = y; - double tileZ; - double tileA; - - if (cl_bloodqavinterp && prevTile && cl_hudinterpolation && (nFrames > 1) && (nFrame != oFrame) && (smoothratio != MaxSmoothRatio) && interpolate) - { - tileX += interpolatedvaluef(prevTile->x, thisTile->x, smoothratio); - tileY += interpolatedvaluef(prevTile->y, thisTile->y, smoothratio); - tileZ = interpolatedvaluef(prevTile->z, thisTile->z, smoothratio); - tileA = interpolatedangle(buildang(prevTile->angle), buildang(thisTile->angle), smoothratio).asbuildf(); - } - else - { - tileX += thisTile->x; - tileY += thisTile->y; - tileZ = thisTile->z; - tileA = thisTile->angle; - } - - DrawFrame(tileX, tileY, tileZ, tileA, thisTile, stat, shade, palnum, to3dview); - }; + bool const interpolate = interpdata && cl_hudinterpolation && cl_bloodqavinterp && (nFrames > 1) && (nFrame != oFrame) && (smoothratio != MaxSmoothRatio); for (int i = 0; i < 8; i++) { - TILE_FRAME *thisTile = &thisFrame->tiles[i]; - TILE_FRAME *prevTile = nullptr; - - if (thisTile->picnum > 0) + if (thisFrame->tiles[i].picnum > 0) { - // Menu's blood drip requires special treatment. - if (res_id == 256) - { - if (i != 0) - { - // Find previous frame by iterating all previous frame's tiles and match on the consistent x coordinate. - // Tile indices can change between frames for no reason, we need to accomodate that. - for (int j = 0; j < 8; j++) if (thisTile->x == prevFrame->tiles[j].x) - { - prevTile = &prevFrame->tiles[j]; - break; - } + TILE_FRAME* const thisTile = &thisFrame->tiles[i]; + TILE_FRAME* const prevTile = interpolate && qavCanInterpFrameTile(res_id, nFrame, i) ? interpdata->PrevTileFinder(thisFrame, prevFrame, i) : nullptr; - drawTile(thisTile, prevTile, true); - } - else - { - // First index is always the dripping bar at the top. - drawTile(thisTile, prevTile, false); - } + double tileX = x; + double tileY = y; + double tileZ; + double tileA; + + if (prevTile) + { + tileX += interpolatedvaluef(prevTile->x, thisTile->x, smoothratio); + tileY += interpolatedvaluef(prevTile->y, thisTile->y, smoothratio); + tileZ = interpolatedvaluef(prevTile->z, thisTile->z, smoothratio); + tileA = interpolatedangle(buildang(prevTile->angle), buildang(thisTile->angle), smoothratio).asbuildf(); } else { - prevTile = &prevFrame->tiles[i]; - drawTile(thisTile, prevTile, thisTile->picnum == prevTile->picnum); + tileX += thisTile->x; + tileY += thisTile->y; + tileZ = thisTile->z; + tileA = thisTile->angle; } + + DrawFrame(tileX, tileY, tileZ, tileA, thisTile, stat, shade, palnum, to3dview); } } } @@ -312,6 +416,9 @@ QAV* getQAV(int res_id) qavdata->res_id = res_id; qavdata->ticrate = 120. / qavdata->ticksPerFrame; + // Build QAVInterpProps struct here for now until we get DEF loading going. + qavBuildInterpProps(qavdata); + qavcache.Insert(res_id, qavdata); return qavdata; } diff --git a/source/games/blood/src/qav.h b/source/games/blood/src/qav.h index 0cd90af1f..372a6f64f 100644 --- a/source/games/blood/src/qav.h +++ b/source/games/blood/src/qav.h @@ -179,6 +179,8 @@ enum kQAV2NAPDOWN = 124, kQAVEnd = 125, + + kQAVBDRIP = 256, }; // by NoOne: add sound flags @@ -236,6 +238,14 @@ struct QAV void Precache(int palette = 0); }; +using QAVPrevTileFinder = TILE_FRAME* (*)(FRAMEINFO* const thisFrame, FRAMEINFO* const prevFrame, const int& i); + +struct QAVInterpProps +{ + int flags; + QAVPrevTileFinder PrevTileFinder; +}; + QAV* getQAV(int res_id); void qavProcessTicker(QAV* const pQAV, int* duration, int* lastTick); void qavProcessTimer(PLAYER* const pPlayer, QAV* const pQAV, int* duration, double* smoothratio, bool const fixedduration = false); From 6d06f002bc7787976c0418d175fc28ebec3415ee Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sun, 22 Aug 2021 07:47:42 +1000 Subject: [PATCH 23/89] - Blood: Mark `kQAVPFORK` (res_id: 2) as being loopable. --- source/games/blood/src/qav.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index a17a2f2d3..91f022bf4 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -152,6 +152,14 @@ void qavBuildInterpProps(QAV* const pQAV) } break; } + case kQAVPFORK: + { + QAVInterpProps interp{}; + interp.flags |= true << kQAVIsLoopable; + interp.PrevTileFinder = qavGetInterpType("interpolate-index"); + qavInterpProps.Insert(pQAV->res_id, std::move(interp)); + break; + } default: { QAVInterpProps interp{}; From f5533374cad0bee8f562acad1a81541722ae2124 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sun, 22 Aug 2021 07:48:48 +1000 Subject: [PATCH 24/89] - Blood: Disable interpolation for `kQAVLITEFLAM` (res_id: 5). --- source/games/blood/src/qav.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 91f022bf4..70a5c28b3 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -160,6 +160,10 @@ void qavBuildInterpProps(QAV* const pQAV) qavInterpProps.Insert(pQAV->res_id, std::move(interp)); break; } + case kQAVLITEFLAM: + { + break; + } default: { QAVInterpProps interp{}; From bcfcbf2666f8fab89d0a0e2718868b5afa66a003 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 21 Aug 2021 21:14:39 +1000 Subject: [PATCH 25/89] - Blood: Add interpolation repair for `kQAVCANDOWN` (res_id: 11). --- source/games/blood/src/qav.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 70a5c28b3..aa16c3a84 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -366,6 +366,27 @@ void qavProcessTimer(PLAYER* const pPlayer, QAV* const pQAV, int* duration, doub } } +static void qavRepairTileData(QAV* pQAV) +{ + int i, j, lastframe; + + switch (pQAV->res_id) + { + case kQAVCANDOWN: + // CANDOWN interpolates fine, but the starting frame in bringing the can down is lower than the can while idle. + // Do linear interpolation from 2nd last frame through to first frame, ending with coordinates of CANIDLE. + lastframe = pQAV->nFrames - 1; + for (i = lastframe, j = 0; i >= 0; i--, j++) + { + pQAV->frames[j].tiles[2].x = xs_CRoundToInt(pQAV->frames[lastframe].tiles[2].x - (double(pQAV->frames[lastframe].tiles[2].x - 11) / lastframe) * i); + pQAV->frames[j].tiles[2].y = xs_CRoundToInt(pQAV->frames[lastframe].tiles[2].y - (double(pQAV->frames[lastframe].tiles[2].y - -28) / lastframe) * i); + } + break; + default: + return; + } +} + // This is to eliminate a huge design issue in NBlood that was apparently copied verbatim from the DOS-Version. // Sequences were cached in the resource and directly returned from there in writable form, with byte swapping directly performed in the cache on Big Endian systems. @@ -428,6 +449,9 @@ QAV* getQAV(int res_id) qavdata->res_id = res_id; qavdata->ticrate = 120. / qavdata->ticksPerFrame; + // Repair tile data here for now until we export all repaired QAVs. + qavRepairTileData(qavdata); + // Build QAVInterpProps struct here for now until we get DEF loading going. qavBuildInterpProps(qavdata); From 28cbec5704077c4cb89dc8286668cf8acd2afa97 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 21 Aug 2021 21:26:40 +1000 Subject: [PATCH 26/89] - Blood: Add interpolation repair and properties for `kQAVCANFIRE2` (res_id: 12). --- source/games/blood/src/qav.cpp | 39 ++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index aa16c3a84..35b241ef4 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -164,6 +164,21 @@ void qavBuildInterpProps(QAV* const pQAV) { break; } + case kQAVCANFIRE2: + { + QAVInterpProps interp{}; + interp.flags = 0; + interp.PrevTileFinder = qavGetInterpType("interpolate-index"); + qavInterpProps.Insert(pQAV->res_id, std::move(interp)); + for (int i = 14; i < pQAV->nFrames; i++) + { + for (int j = 2; j < 4; j++) + { + qavSetNonInterpFrameTile(pQAV->res_id, i, j); + } + } + break; + } default: { QAVInterpProps interp{}; @@ -369,6 +384,7 @@ void qavProcessTimer(PLAYER* const pPlayer, QAV* const pQAV, int* duration, doub static void qavRepairTileData(QAV* pQAV) { int i, j, lastframe; + TILE_FRAME backup; switch (pQAV->res_id) { @@ -382,6 +398,29 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[j].tiles[2].y = xs_CRoundToInt(pQAV->frames[lastframe].tiles[2].y - (double(pQAV->frames[lastframe].tiles[2].y - -28) / lastframe) * i); } break; + case kQAVCANFIRE2: + // Handle some index swaps and cripple interpolation after 14th frame. + // Swap tile indices 1 and 2 around for frame's 0 and 1. + for (i = 0; i < 2; i++) + { + backup = pQAV->frames[i].tiles[2]; + pQAV->frames[i].tiles[2] = pQAV->frames[i].tiles[1]; + pQAV->frames[i].tiles[1] = backup; + } + + // Move what's now frame 0 tile 2 to tile 3 and disable original index of 2; + pQAV->frames[0].tiles[3] = pQAV->frames[0].tiles[2]; + pQAV->frames[0].tiles[2].picnum = -1; + + // For frame 11 until the end, move frame indices 0 and 1 to 2 and 3 respectively, and disable the original indices. + for (i = 11; i < pQAV->nFrames; i++) + { + pQAV->frames[i].tiles[2] = pQAV->frames[i].tiles[0]; + pQAV->frames[i].tiles[0].picnum = -1; + pQAV->frames[i].tiles[3] = pQAV->frames[i].tiles[1]; + pQAV->frames[i].tiles[1].picnum = -1; + } + break; default: return; } From 33d63724f794b9aa4ea3e053c28ea6c0fb726164 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Thu, 12 Aug 2021 12:59:11 +1000 Subject: [PATCH 27/89] - Blood: Add interpolation repair for `kQAVBUNUP` (res_id: 16). --- source/games/blood/src/qav.cpp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 35b241ef4..0176ee567 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -421,6 +421,39 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[i].tiles[1].picnum = -1; } break; + case kQAVBUNUP: + // BUNUP has several tile indices that require repairs here to minimise continual checks at draw time. + // For the 4th frame, clone tile indices 5 and 6 into 2 and 3 respectively where they should have been. + for (i = 5; i < 7; i++) + { + pQAV->frames[3].tiles[i - 3] = pQAV->frames[3].tiles[i]; + pQAV->frames[3].tiles[i].picnum = -1; + } + + // For the 2nd frame, clone tile indices 3 and 4 into 2 and 3 respectively where they should have been. + for (i = 3; i < 5; i++) + { + pQAV->frames[1].tiles[i - 1] = pQAV->frames[1].tiles[i]; + } + + // Clone 1st frame's tile index 2 to tile index 4 for 1st and 2nd frame, then disable original index of 2. + pQAV->frames[1].tiles[4] = pQAV->frames[0].tiles[4] = pQAV->frames[0].tiles[2]; + pQAV->frames[0].tiles[2].picnum = -1; + + // Clone 1st frame's tile index 0 to tile index 3, then disable original index of 0. + pQAV->frames[0].tiles[3] = pQAV->frames[0].tiles[0]; + pQAV->frames[0].tiles[0].picnum = -1; + + // Shift every tile up one index to leave more room at the end, should it be needed in the future. + for (i = 0; i < pQAV->nFrames; i++) + { + for (j = 1; j < 5; j++) + { + pQAV->frames[i].tiles[j - 1] = pQAV->frames[i].tiles[j]; + pQAV->frames[i].tiles[j].picnum = -1; + } + } + break; default: return; } From 037fcfd446e7b87d1d3b8f1438795311cec25b6c Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Thu, 12 Aug 2021 12:54:26 +1000 Subject: [PATCH 28/89] - Blood: Add interpolation repair for `kQAVBUNDOWN` (res_id: 17). --- source/games/blood/src/qav.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 0176ee567..1168a400e 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -454,6 +454,17 @@ static void qavRepairTileData(QAV* pQAV) } } break; + case kQAVBUNDOWN: + // BUNDOWN requires some tile index swaps to be cleaned up to avoid using our own callback. + // For frames 3 till the end, backup tile index 3, move indices 1 and 2 down, then restore backed up tile index 3 as 1. + for (i = 3; i < pQAV->nFrames; i++) + { + backup = pQAV->frames[i].tiles[3]; + pQAV->frames[i].tiles[3] = pQAV->frames[i].tiles[2]; + pQAV->frames[i].tiles[2] = pQAV->frames[i].tiles[1]; + pQAV->frames[i].tiles[1] = backup; + } + break; default: return; } From cb62692e37f79b0b21e08e63d409a0dc7871e8cb Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Tue, 10 Aug 2021 23:07:11 +1000 Subject: [PATCH 29/89] - Blood: Add interpolation repair for `kQAVBUNUP2` (res_id: 18). --- source/games/blood/src/qav.cpp | 35 ++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 1168a400e..436fce080 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -465,6 +465,41 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[i].tiles[1] = backup; } break; + case kQAVBUNUP2: + // BUNUP2 has a few uninterpolatable tiles that need moving, and some index swaps to handle. + // For frame 2, move tile index 1 to 3 and disable original index of 1. + pQAV->frames[2].tiles[3] = pQAV->frames[2].tiles[1]; + pQAV->frames[2].tiles[1].picnum = -1; + + // For frame 7, move tile index 1 into 6, 2 into 1 and 3 into 2, then disable the original index of 3. + pQAV->frames[7].tiles[6] = pQAV->frames[7].tiles[1]; + pQAV->frames[7].tiles[1] = pQAV->frames[7].tiles[2]; + pQAV->frames[7].tiles[2] = pQAV->frames[7].tiles[3]; + pQAV->frames[7].tiles[3].picnum = -1; + + // For frame 8, move tile index 1 into 5, 2 into 6, 3 into 1 and 4 into 2, then disable the original index of 4. + pQAV->frames[8].tiles[5] = pQAV->frames[8].tiles[1]; + pQAV->frames[8].tiles[6] = pQAV->frames[8].tiles[2]; + pQAV->frames[8].tiles[1] = pQAV->frames[8].tiles[3]; + pQAV->frames[8].tiles[2] = pQAV->frames[8].tiles[4]; + pQAV->frames[8].tiles[4].picnum = -1; + + // For frame 9, move tile index 1 into 5, 2 into 1 and 3 into 2, then disable the original index of 3. + pQAV->frames[9].tiles[5] = pQAV->frames[9].tiles[1]; + pQAV->frames[9].tiles[1] = pQAV->frames[9].tiles[2]; + pQAV->frames[9].tiles[2] = pQAV->frames[9].tiles[3]; + pQAV->frames[9].tiles[3].picnum = -1; + + // For frames 7 until the end, move indices 5 and 6 into 3 and 4, and disable original indices of 5 and 6. + for (i = 7; i < pQAV->nFrames; i++) + { + for (j = 5; j < 7; j++) + { + pQAV->frames[i].tiles[j - 2] = pQAV->frames[i].tiles[j]; + pQAV->frames[i].tiles[j].picnum = -1; + } + } + break; default: return; } From da95af0c04f116a4601b31229b652892c5f3b552 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Tue, 10 Aug 2021 23:20:15 +1000 Subject: [PATCH 30/89] - Blood: Add interpolation repair for `kQAVBUNDOWN2` (res_id: 19). --- source/games/blood/src/qav.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 436fce080..0750a8234 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -500,6 +500,20 @@ static void qavRepairTileData(QAV* pQAV) } } break; + case kQAVBUNDOWN2: + // BUNDOWN2 has some tile index swaps that require handling. + // For frames 3 and 4, move tile indices 1 and 2 into 2 and 3, and disable original index of 1. + for (i = 3; i < 5; i++) + { + pQAV->frames[i].tiles[3] = pQAV->frames[i].tiles[2]; + pQAV->frames[i].tiles[2] = pQAV->frames[i].tiles[1]; + pQAV->frames[i].tiles[1].picnum = -1; + } + + // For frame 5, move tile index 1 to 3 and disable original index of 1. + pQAV->frames[5].tiles[3] = pQAV->frames[5].tiles[1]; + pQAV->frames[5].tiles[1].picnum = -1; + break; default: return; } From 54cdc8ffc3bbdc7eb2803910de89a8f09acd6a47 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 21 Aug 2021 21:31:29 +1000 Subject: [PATCH 31/89] - Blood: Add interpolation repair and properties for `kQAVBUNFUSE` (res_id: 21). --- source/games/blood/src/qav.cpp | 38 ++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 0750a8234..714d1831d 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -179,6 +179,18 @@ void qavBuildInterpProps(QAV* const pQAV) } break; } + case kQAVBUNFUSE: + { + QAVInterpProps interp{}; + interp.flags = 0; + interp.PrevTileFinder = qavGetInterpType("interpolate-index"); + qavInterpProps.Insert(pQAV->res_id, std::move(interp)); + for (int i = 6; i < pQAV->nFrames; i++) + { + qavSetNonInterpFrameTile(pQAV->res_id, i, 4); + } + break; + } default: { QAVInterpProps interp{}; @@ -514,6 +526,32 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[5].tiles[3] = pQAV->frames[5].tiles[1]; pQAV->frames[5].tiles[1].picnum = -1; break; + case kQAVBUNFUSE: + // BUNFUSE has several tile indices that require repairs here to minimise continual checks at draw time. + // For frame 0, move tile indices 2 and 3 into 3 and 4, and disable original index of 2. + pQAV->frames[0].tiles[4] = pQAV->frames[0].tiles[3]; + pQAV->frames[0].tiles[3] = pQAV->frames[0].tiles[2]; + pQAV->frames[0].tiles[2].picnum = -1; + + // For frame 1, move tile indices 4 and 5 into 3 and 4, and disable original index of 5. + pQAV->frames[1].tiles[3] = pQAV->frames[1].tiles[4]; + pQAV->frames[1].tiles[4] = pQAV->frames[1].tiles[5]; + pQAV->frames[1].tiles[5].picnum = -1; + + // For frame 2, move tile indices 5 and 7 into 3 and 4, and disable original indices. + pQAV->frames[2].tiles[3] = pQAV->frames[2].tiles[5]; + pQAV->frames[2].tiles[4] = pQAV->frames[2].tiles[7]; + pQAV->frames[2].tiles[5].picnum = -1; + pQAV->frames[2].tiles[7].picnum = -1; + + // For frames 0-5, swap tile indices 2 and 4 around. + for (i = 0; i < 6; i++) + { + backup = pQAV->frames[i].tiles[4]; + pQAV->frames[i].tiles[4] = pQAV->frames[i].tiles[2]; + pQAV->frames[i].tiles[2] = backup; + } + break; default: return; } From 7f9f57e4e62c750d6b1baa936ca63dcf914f0687 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Mon, 9 Aug 2021 14:25:07 +1000 Subject: [PATCH 32/89] - Blood: Add interpolation repair for `kQAVBUNDROP` (res_id: 22). --- source/games/blood/src/qav.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 714d1831d..a4dabd9c3 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -552,6 +552,12 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[i].tiles[2] = backup; } break; + case kQAVBUNDROP: + // BUNDROP needs frame 3 tile 1 moved to tile 2 to avoid needing its own interpolation callback. + // For frame 3, move tile index 2 into 3, and disable original index of 2. + pQAV->frames[3].tiles[2] = pQAV->frames[3].tiles[1]; + pQAV->frames[3].tiles[1].picnum = -1; + break; default: return; } From 8944f2e57dedb0ac90e51e9ad7a9c9635a082e09 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Mon, 9 Aug 2021 14:25:36 +1000 Subject: [PATCH 33/89] - Blood: Add interpolation repair for `kQAVBUNTHRO` (res_id: 23). --- source/games/blood/src/qav.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index a4dabd9c3..e2c01fdf5 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -558,6 +558,14 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[3].tiles[2] = pQAV->frames[3].tiles[1]; pQAV->frames[3].tiles[1].picnum = -1; break; + case kQAVBUNTHRO: + // BUNTHRO has several tile indices that require repairs here to minimise continual checks at draw time. + // For frame 3, move tile indices 0 and 1 into 3 and 2, and disable original indices. + pQAV->frames[3].tiles[3] = pQAV->frames[3].tiles[0]; + pQAV->frames[3].tiles[2] = pQAV->frames[3].tiles[1]; + pQAV->frames[3].tiles[0].picnum = -1; + pQAV->frames[3].tiles[1].picnum = -1; + break; default: return; } From 34f31e535cd3bfaec32aefc8c9b87cec95edd79c Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Thu, 12 Aug 2021 12:57:49 +1000 Subject: [PATCH 34/89] - Blood: Add interpolation repair for `kQAVPROXUP` (res_id: 25). --- source/games/blood/src/qav.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index e2c01fdf5..7969302ea 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -566,6 +566,29 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[3].tiles[0].picnum = -1; pQAV->frames[3].tiles[1].picnum = -1; break; + case kQAVPROXUP: + // PROXUP has several tile indices that require repairs to avoid needing its own interpolation callback. + // Additionally, there are missing frames crucial to a proper interpolation experience. + + // For frame 3, move tile indices 1, 2 and 3 into 0, 1 and 2, and disable original index of 3. + for (i = 0; i < 3; i++) + { + pQAV->frames[3].tiles[i] = pQAV->frames[3].tiles[i + 1]; + } + pQAV->frames[3].tiles[3].picnum = -1; + + // For frame 0, move tile index 0 into 1. + pQAV->frames[0].tiles[1] = pQAV->frames[0].tiles[0]; + + // For frame 0, clone frame 1's tile indices 0 and 2 and adjust x/y coordinates. + // using difference between frame 0 and 1's tile index 1. + for (i = 0; i < 3; i += 2) + { + pQAV->frames[0].tiles[i] = pQAV->frames[1].tiles[i]; + pQAV->frames[0].tiles[i].x += pQAV->frames[0].tiles[1].x - pQAV->frames[1].tiles[1].x; + pQAV->frames[0].tiles[i].y += pQAV->frames[0].tiles[1].y - pQAV->frames[1].tiles[1].y; + } + break; default: return; } From 679903b90fdc047bc0257030618b9acc89d30e78 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Thu, 12 Aug 2021 12:58:23 +1000 Subject: [PATCH 35/89] - Blood: Add interpolation repair for `kQAVPROXDOWN` (res_id: 26). --- source/games/blood/src/qav.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 7969302ea..be19b754d 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -589,6 +589,22 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[0].tiles[i].y += pQAV->frames[0].tiles[1].y - pQAV->frames[1].tiles[1].y; } break; + case kQAVPROXDOWN: + // PROXUP has tile index that require repairs to avoid needing its own interpolation callback. + // Additionally, there are missing frames crucial to a proper interpolation experience. + + // For frame 4, move tile index 0 into 1. + pQAV->frames[4].tiles[1] = pQAV->frames[4].tiles[0]; + + // For frame 4, clone frame 3's tile indices 0 and 2 and adjust x/y coordinates. + // using difference between frame 4 and 3's tile index 1. + for (i = 0; i < 3; i += 2) + { + pQAV->frames[4].tiles[i] = pQAV->frames[3].tiles[i]; + pQAV->frames[4].tiles[i].x += pQAV->frames[4].tiles[1].x - pQAV->frames[3].tiles[1].x; + pQAV->frames[4].tiles[i].y += pQAV->frames[4].tiles[1].y - pQAV->frames[3].tiles[1].y; + } + break; default: return; } From 3cc2a6a486c130ed706775d7a566b696ee1fabe0 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Thu, 12 Aug 2021 13:06:26 +1000 Subject: [PATCH 36/89] - Blood: Add interpolation repair for `kQAVREMUP1` (res_id: 30) and `kQAVREMUP2` (res_id: 31). --- source/games/blood/src/qav.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index be19b754d..3e573b264 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -605,6 +605,32 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[4].tiles[i].y += pQAV->frames[4].tiles[1].y - pQAV->frames[3].tiles[1].y; } break; + case kQAVREMUP1: + case kQAVREMUP2: + // REMUP1 and REMUP2 have several tile indices that require repairs to avoid needing their own interpolation callback. + // Additionally, there are missing frames crucial to a proper interpolation experience. + + // For frame 0, move tile index 1 into 2, and disable original index of 1. + pQAV->frames[0].tiles[2] = pQAV->frames[0].tiles[1]; + pQAV->frames[0].tiles[1].picnum = -1; + + // For frame 0, clone frame 1 tile index 1 and adjust x/y coordinates + // using difference between frame 0 and 1's tile index 0. + pQAV->frames[0].tiles[1] = pQAV->frames[1].tiles[1]; + pQAV->frames[0].tiles[1].x += pQAV->frames[0].tiles[0].x - pQAV->frames[1].tiles[0].x; + pQAV->frames[0].tiles[1].y += pQAV->frames[0].tiles[0].y - pQAV->frames[1].tiles[0].y; + + // For frame 2, move tile index 2 and three around. + backup = pQAV->frames[2].tiles[2]; + pQAV->frames[2].tiles[2] = pQAV->frames[2].tiles[3]; + pQAV->frames[2].tiles[3] = backup; + + // For frame 1, clone frame 2 tile index 3 and adjust x/y coordinates + // using difference between frame 1 and 2's tile index 0. + pQAV->frames[1].tiles[3] = pQAV->frames[2].tiles[3]; + pQAV->frames[1].tiles[3].x += pQAV->frames[1].tiles[1].x - pQAV->frames[2].tiles[1].x; + pQAV->frames[1].tiles[3].y += pQAV->frames[1].tiles[1].y - pQAV->frames[2].tiles[1].y; + break; default: return; } From 226ba1477a131bd15d3812d52a8da1f834dbdf61 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Thu, 12 Aug 2021 13:01:36 +1000 Subject: [PATCH 37/89] - Blood: Add interpolation repair for `kQAVREMDOWN1` (res_id: 33). --- source/games/blood/src/qav.cpp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 3e573b264..861d87604 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -631,6 +631,39 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[1].tiles[3].x += pQAV->frames[1].tiles[1].x - pQAV->frames[2].tiles[1].x; pQAV->frames[1].tiles[3].y += pQAV->frames[1].tiles[1].y - pQAV->frames[2].tiles[1].y; break; + case kQAVREMDOWN1: + // REMDOWN1 has several tile indices that require repairs to avoid needing its own interpolation callback. + // Additionally, there are missing frames crucial to a proper interpolation experience. + + // For frame 1, move tile index 2 and 3 around. + backup = pQAV->frames[1].tiles[2]; + pQAV->frames[1].tiles[2] = pQAV->frames[1].tiles[3]; + pQAV->frames[1].tiles[3] = backup; + + // For frame 0, clone frame 1 tile index 3 and adjust x/y coordinates + // using difference between frame 0 and 1's tile index 1. + pQAV->frames[0].tiles[3] = pQAV->frames[1].tiles[3]; + pQAV->frames[0].tiles[3].x += pQAV->frames[0].tiles[1].x - pQAV->frames[1].tiles[1].x; + pQAV->frames[0].tiles[3].y += pQAV->frames[0].tiles[1].y - pQAV->frames[1].tiles[1].y; + + // For frame 4, move tile index 1 into 2. + pQAV->frames[4].tiles[2] = pQAV->frames[4].tiles[1]; + + // For frame 5, move tile index 0 into 2. + pQAV->frames[5].tiles[2] = pQAV->frames[5].tiles[0]; + + // Clone frame 3 tile index 0 and 1 into frames 4 and 5, and adjust x/y coordinates + // using difference between frames 4 and 3 and 5 and 4 on looped tile index. + for (i = 4; i < 6; i++) + { + for (j = 0; j < 2; j++) + { + pQAV->frames[i].tiles[j] = pQAV->frames[i - 1].tiles[j]; + pQAV->frames[i].tiles[j].x += pQAV->frames[i - 1].tiles[j].x - pQAV->frames[i - 2].tiles[j].x; + pQAV->frames[i].tiles[j].y += pQAV->frames[i - 1].tiles[j].y - pQAV->frames[i - 2].tiles[j].y; + } + } + break; default: return; } From 55b64534154aa507bb87793a8959503bf6b41390 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Thu, 12 Aug 2021 13:02:43 +1000 Subject: [PATCH 38/89] - Blood: Add interpolation repair for `kQAVREMDOWN2` (res_id: 34). --- source/games/blood/src/qav.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 861d87604..50df74413 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -664,6 +664,33 @@ static void qavRepairTileData(QAV* pQAV) } } break; + case kQAVREMDOWN2: + // REMDOWN2 has several tile indices that require repairs to avoid needing its own interpolation callback. + // Additionally, there are missing frames crucial to a proper interpolation experience. + + // For frame 1, move tile index 2 and 3 around. + backup = pQAV->frames[1].tiles[2]; + pQAV->frames[1].tiles[2] = pQAV->frames[1].tiles[3]; + pQAV->frames[1].tiles[3] = backup; + + // For frame 0, clone frame 1 tile index 3 and adjust x/y coordinates + // using difference between frame 0 and 1's tile index 1. + pQAV->frames[0].tiles[3] = pQAV->frames[1].tiles[3]; + pQAV->frames[0].tiles[3].x += pQAV->frames[0].tiles[1].x - pQAV->frames[1].tiles[1].x; + pQAV->frames[0].tiles[3].y += pQAV->frames[0].tiles[1].y - pQAV->frames[1].tiles[1].y; + + // Clone frame 3 tile index 0, 1, 2, 3 and 4 into frames 4 and 5, and adjust x/y coordinates + // using difference between frames 4 and 3 and 5 and 4 on looped tile index. + for (i = 4; i < 6; i++) + { + for (j = 0; j < 5; j++) + { + pQAV->frames[i].tiles[j] = pQAV->frames[i - 1].tiles[j]; + pQAV->frames[i].tiles[j].x += pQAV->frames[i - 1].tiles[j].x - pQAV->frames[i - 2].tiles[j].x; + pQAV->frames[i].tiles[j].y += pQAV->frames[i - 1].tiles[j].y - pQAV->frames[i - 2].tiles[j].y; + } + } + break; default: return; } From 92c5a53074f71ebb88d128bbeda46013822d51db Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sun, 22 Aug 2021 07:52:42 +1000 Subject: [PATCH 39/89] - Blood: Mark `kQAVREMIDLE1` (res_id: 36) and `kQAVREMIDLE2` (res_id: 37) as being loopable. --- source/games/blood/src/qav.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 50df74413..e891f2f51 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -153,6 +153,8 @@ void qavBuildInterpProps(QAV* const pQAV) break; } case kQAVPFORK: + case kQAVREMIDLE1: + case kQAVREMIDLE2: { QAVInterpProps interp{}; interp.flags |= true << kQAVIsLoopable; From 6d888bebd9c3bde3009e7e27ccde518ba87849e3 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Thu, 12 Aug 2021 13:03:27 +1000 Subject: [PATCH 40/89] - Blood: Add interpolation repair for `kQAVREMDROP` (res_id: 38). --- source/games/blood/src/qav.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index e891f2f51..6a84c9780 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -693,6 +693,24 @@ static void qavRepairTileData(QAV* pQAV) } } break; + case kQAVREMDROP: + // REMDROP has several tile indices that require repairs to avoid needing its own interpolation callback. + // Additionally, there are missing frames crucial to a proper interpolation experience. + + // For frame 1, move tile index 2 into 6, and 3 into 2, and disable original index of 3. + pQAV->frames[1].tiles[6] = pQAV->frames[1].tiles[2]; + pQAV->frames[1].tiles[2] = pQAV->frames[1].tiles[3]; + pQAV->frames[1].tiles[3].picnum = -1; + + // Clone frame 3 tile index 0 and 1 into frames 4, and adjust x/y coordinates + // using difference between frames 4 and 3 on looped tile index. + for (j = 0; j < 2; j++) + { + pQAV->frames[4].tiles[j] = pQAV->frames[3].tiles[j]; + pQAV->frames[4].tiles[j].x += pQAV->frames[3].tiles[j].x - pQAV->frames[2].tiles[j].x; + pQAV->frames[4].tiles[j].y += pQAV->frames[3].tiles[j].y - pQAV->frames[2].tiles[j].y; + } + break; default: return; } From 7e3307eb33f4c20ab6d95c9dba1e180aa2c21b26 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Thu, 12 Aug 2021 13:05:54 +1000 Subject: [PATCH 41/89] - Blood: Add interpolation repair for `kQAVREMTHRO` (res_id: 39). --- source/games/blood/src/qav.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 6a84c9780..d46fb820d 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -711,6 +711,34 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[4].tiles[j].y += pQAV->frames[3].tiles[j].y - pQAV->frames[2].tiles[j].y; } break; + case kQAVREMTHRO: + // REMTHRO has several tile indices that require repairs. + + // For frame 1, swap tile index 2 and 3 around. + backup = pQAV->frames[1].tiles[3]; + pQAV->frames[1].tiles[3] = pQAV->frames[1].tiles[2]; + pQAV->frames[1].tiles[2] = backup; + + // For frame 0, clone frame 1 tile index 3 and adjust x/y coordinates + // using difference between frame 0 and 1's tile index 1. + pQAV->frames[0].tiles[3] = pQAV->frames[1].tiles[3]; + pQAV->frames[0].tiles[3].x += pQAV->frames[0].tiles[1].x - pQAV->frames[1].tiles[1].x; + pQAV->frames[0].tiles[3].y += pQAV->frames[0].tiles[1].y - pQAV->frames[1].tiles[1].y; + + // For frame 4, move tile index 1 into 2, and disable original index of 1. + pQAV->frames[4].tiles[2] = pQAV->frames[4].tiles[1]; + pQAV->frames[4].tiles[1].picnum = -1; + + // For frames 5 until the end, move tile indices 0 and 1 to 2 and 3 respectively, and disable original indices. + for (i = 5; i < pQAV->nFrames; i++) + { + pQAV->frames[i].tiles[3] = pQAV->frames[i].tiles[1]; + pQAV->frames[i].tiles[2] = pQAV->frames[i].tiles[0]; + pQAV->frames[i].tiles[1].picnum = -1; + pQAV->frames[i].tiles[0].picnum = -1; + + } + break; default: return; } From dfa3a52fa82740e730e76e1c42a7069871148986 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Thu, 12 Aug 2021 13:18:53 +1000 Subject: [PATCH 42/89] - Blood: Add interpolation repair for `kQAVFLARUP` (res_id: 41). --- source/games/blood/src/qav.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index d46fb820d..5e9570056 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -739,6 +739,16 @@ static void qavRepairTileData(QAV* pQAV) } break; + case kQAVFLARUP: + // FLARUP interpolates fine, but the final frame in bringing the flaregun up is lower than the flaregun while idle. + // Do linear interpolation from 2nd frame through to last frame, ending with coordinates of FLARIDLE. + lastframe = pQAV->nFrames - 1; + for (i = 1; i < pQAV->nFrames; i++) + { + pQAV->frames[i].tiles[0].x = xs_CRoundToInt(pQAV->frames[0].tiles[0].x - (double(pQAV->frames[0].tiles[0].x - 57) / lastframe) * i); + pQAV->frames[i].tiles[0].y = xs_CRoundToInt(pQAV->frames[0].tiles[0].y - (double(pQAV->frames[0].tiles[0].y - -30) / lastframe) * i); + } + break; default: return; } From e70b395d764750d9fb4dcf2c9bd309580b00995a Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Thu, 12 Aug 2021 13:44:32 +1000 Subject: [PATCH 43/89] - Blood: Add interpolation repair for `kQAVFLARFIR2` (res_id: 43). --- source/games/blood/src/qav.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 5e9570056..0a072c7f7 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -749,6 +749,26 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[i].tiles[0].y = xs_CRoundToInt(pQAV->frames[0].tiles[0].y - (double(pQAV->frames[0].tiles[0].y - -30) / lastframe) * i); } break; + case kQAVFLARFIR2: + // FLARFIR2 has several index swaps that require accomodating. + // For frames 4 until end, move tile index 0 to 1 and disable original index of 0. + for (i = 4; i < pQAV->nFrames; i++) + { + pQAV->frames[i].tiles[1] = pQAV->frames[i].tiles[0]; + pQAV->frames[i].tiles[0].picnum = -1; + } + + // For frame 1, move tile indices 1 and 2 into 2 and 3, and disable original index of 1. + pQAV->frames[1].tiles[3] = pQAV->frames[1].tiles[2]; + pQAV->frames[1].tiles[2] = pQAV->frames[1].tiles[1]; + pQAV->frames[1].tiles[1].picnum = -1; + + // For frame 0, move tile indices 0 and 1 into 2 and 4, and disable original indices. + pQAV->frames[0].tiles[4] = pQAV->frames[0].tiles[1]; + pQAV->frames[0].tiles[2] = pQAV->frames[0].tiles[0]; + pQAV->frames[0].tiles[1].picnum = -1; + pQAV->frames[0].tiles[0].picnum = -1; + break; default: return; } From 37f7bcde2022cca1ec6169605c33a259fb9113ca Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Thu, 12 Aug 2021 13:24:04 +1000 Subject: [PATCH 44/89] - Blood: Mark `kQAVFLARFIR2` (res_id: 43) as being loopable. --- source/games/blood/src/qav.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 0a072c7f7..4cfdb7439 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -155,6 +155,7 @@ void qavBuildInterpProps(QAV* const pQAV) case kQAVPFORK: case kQAVREMIDLE1: case kQAVREMIDLE2: + case kQAVFLARFIR2: { QAVInterpProps interp{}; interp.flags |= true << kQAVIsLoopable; From e0bcd2d9e9024379c6a34e7da23d39c0e7d17e3b Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Thu, 12 Aug 2021 13:19:28 +1000 Subject: [PATCH 45/89] - Blood: Add interpolation repair for `kQAVFLARDOWN` (res_id: 44). --- source/games/blood/src/qav.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 4cfdb7439..0682ce3fe 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -770,6 +770,16 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[0].tiles[1].picnum = -1; pQAV->frames[0].tiles[0].picnum = -1; break; + case kQAVFLARDOWN: + // FLARDOWN interpolates fine, but the starting frame in bringing the flaregun down is lower than the flaregun while idle. + // Do linear interpolation from 2nd last frame through to first frame, ending with coordinates of FLARIDLE. + lastframe = pQAV->nFrames - 1; + for (i = lastframe, j = 0; i >= 0; i--, j++) + { + pQAV->frames[j].tiles[0].x = xs_CRoundToInt(pQAV->frames[lastframe].tiles[0].x - (double(pQAV->frames[lastframe].tiles[0].x - 57) / lastframe) * i); + pQAV->frames[j].tiles[0].y = xs_CRoundToInt(pQAV->frames[lastframe].tiles[0].y - (double(pQAV->frames[lastframe].tiles[0].y - -30) / lastframe) * i); + } + break; default: return; } From e00f76b0aac04b14835d5cb79f7c243b95cea131 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Thu, 12 Aug 2021 12:16:31 +1000 Subject: [PATCH 46/89] - Blood: Add interpolation repair for `kQAVFLAR2FIR` (res_id: 48). --- source/games/blood/src/qav.cpp | 72 ++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 0682ce3fe..4382eab03 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -780,6 +780,78 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[j].tiles[0].y = xs_CRoundToInt(pQAV->frames[lastframe].tiles[0].y - (double(pQAV->frames[lastframe].tiles[0].y - -30) / lastframe) * i); } break; + case kQAVFLAR2FIR: + // FLAR2FIR has several index swaps that require accomodating and to ensure it interpolates right. + + // Handle x > 0 side first. + // For frame 0, move tile indices 0 and 1 into 5 and 7, and disable original indices. + pQAV->frames[0].tiles[7] = pQAV->frames[0].tiles[1]; + pQAV->frames[0].tiles[5] = pQAV->frames[0].tiles[0]; + pQAV->frames[0].tiles[1].picnum = -1; + pQAV->frames[0].tiles[0].picnum = -1; + + // For frame 1, move tile indices 1 and 2 into 5 and 6, and disable original indices of 1 and 2. + for (i = 1; i < 3; i++) + { + pQAV->frames[1].tiles[i + 4] = pQAV->frames[1].tiles[i]; + pQAV->frames[1].tiles[i].picnum = -1; + } + + // For frames 2 and 3, move tile index 1 into 7, and disable original index of 1. + for (i = 2; i < 4; i++) + { + pQAV->frames[i].tiles[7] = pQAV->frames[i].tiles[1]; + pQAV->frames[i].tiles[1].picnum = -1; + } + + // For frames 4 until end, move tile index 0 into 7, and disable original index of 0. + for (i = 4; i < pQAV->nFrames; i++) + { + pQAV->frames[i].tiles[7] = pQAV->frames[i].tiles[0]; + pQAV->frames[i].tiles[0].picnum = -1; + } + + // Handle x < 0 now. + // For frame 0, move tile index 2 into 4, and disable the original index of 2. + pQAV->frames[0].tiles[4] = pQAV->frames[0].tiles[2]; + pQAV->frames[0].tiles[2].picnum = -1; + + // For frame 1, move tile index 3 into 4, and disable the original index of 3. + pQAV->frames[1].tiles[4] = pQAV->frames[1].tiles[3]; + pQAV->frames[1].tiles[3].picnum = -1; + + // For frames 2 and 3, move tile index 2 into 4, and disable the original index of 2. + for (i = 2; i < 4; i++) + { + pQAV->frames[i].tiles[4] = pQAV->frames[i].tiles[2]; + pQAV->frames[i].tiles[2].picnum = -1; + } + + // For frame 3, move tile index 3 into 6, and disable the original index of 3. + pQAV->frames[3].tiles[6] = pQAV->frames[3].tiles[3]; + pQAV->frames[3].tiles[3].picnum = -1; + + // For frame 4, move tile indices 2 and 3 into 4 and 5, and disable the original indices of 2 and 3. + for (i = 2; i < 4; i++) + { + pQAV->frames[4].tiles[i + 2] = pQAV->frames[4].tiles[i]; + pQAV->frames[4].tiles[i].picnum = -1; + } + + // For frames 5 and 6, move tile index 2 into 6, and disable the original index of 2. + for (i = 5; i < 7; i++) + { + pQAV->frames[i].tiles[6] = pQAV->frames[i].tiles[2]; + pQAV->frames[i].tiles[2].picnum = -1; + } + + // For frames 7 until end, move tile index 1 into 6, and disable original index of 1. + for (i = 7; i < pQAV->nFrames; i++) + { + pQAV->frames[i].tiles[6] = pQAV->frames[i].tiles[1]; + pQAV->frames[i].tiles[1].picnum = -1; + } + break; default: return; } From ba915900289445823585bab2a0609c492a804f86 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Thu, 12 Aug 2021 13:15:34 +1000 Subject: [PATCH 47/89] - Blood: Add interpolation repair for `kQAVSHOTUP` (res_id: 50). --- source/games/blood/src/qav.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 4382eab03..b26559643 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -852,6 +852,19 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[i].tiles[1].picnum = -1; } break; + case kQAVSHOTUP: + // SHOTUP is missing tiles for the first two frames. + // Clone from 3rd frame and amend x/y coordinates for tile indices 1 and 2 on frames 0 and 1. + for (i = 0; i < 2; i++) + { + for (j = 1; j < 3; j++) + { + pQAV->frames[i].tiles[j] = pQAV->frames[2].tiles[j]; + pQAV->frames[i].tiles[j].x += pQAV->frames[i].tiles[0].x - pQAV->frames[2].tiles[0].x; + pQAV->frames[i].tiles[j].y += pQAV->frames[i].tiles[0].y - pQAV->frames[2].tiles[0].y; + } + } + break; default: return; } From bfa509e45e2217b7d8e06f2ae1d1ea4bc3c8b40d Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sun, 22 Aug 2021 07:28:05 +1000 Subject: [PATCH 48/89] - Blood: Add interpolation properties for `kQAVSHOTL1` (res_id: 57). --- source/games/blood/src/qav.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index b26559643..b597dcf8f 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -194,6 +194,14 @@ void qavBuildInterpProps(QAV* const pQAV) } break; } + case kQAVSHOTL1: + { + QAVInterpProps interp{}; + interp.flags = 0; + interp.PrevTileFinder = qavGetInterpType("interpolate-picnum"); + qavInterpProps.Insert(pQAV->res_id, std::move(interp)); + break; + } default: { QAVInterpProps interp{}; From cdff574ef65c99637ef1f9410feba4ffb1774c67 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sun, 8 Aug 2021 14:34:12 +1000 Subject: [PATCH 49/89] - Blood: Add interpolation repair for `kQAV2SHOTF2` (res_id: 61). --- source/games/blood/src/qav.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index b597dcf8f..8b7f8c3c4 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -873,6 +873,25 @@ static void qavRepairTileData(QAV* pQAV) } } break; + case kQAV2SHOTF2: + // 2SHOTF2 has tiles 2630 and 2631 applied when it doesn't need to, + // and is missing a preceding frame of tile 2632 which the non-akimbo version has. + + // Patch left and right side respectively. + pQAV->frames[0].tiles[6] = pQAV->frames[1].tiles[6]; + pQAV->frames[0].tiles[6].x -= pQAV->frames[1].tiles[5].x - pQAV->frames[0].tiles[5].x; + pQAV->frames[0].tiles[6].y -= pQAV->frames[1].tiles[5].y - pQAV->frames[0].tiles[5].y; + pQAV->frames[3].tiles[3] = pQAV->frames[4].tiles[3]; + pQAV->frames[3].tiles[3].x -= pQAV->frames[4].tiles[2].x - pQAV->frames[3].tiles[2].x; + pQAV->frames[3].tiles[3].y -= pQAV->frames[4].tiles[2].y - pQAV->frames[3].tiles[2].y; + + // Stabilise frame 2 tile 2 by using x/y coordindates from next frame. + pQAV->frames[2].tiles[2].x = pQAV->frames[3].tiles[2].x; + pQAV->frames[2].tiles[2].y = pQAV->frames[3].tiles[2].y; + + // Disable frame 0 tile 7. + pQAV->frames[0].tiles[7].picnum = -1; + break; default: return; } From 3cd868c9f987f61e95e56a94c343e5ef6c030852 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Thu, 12 Aug 2021 18:06:43 +1000 Subject: [PATCH 50/89] - Blood: Add interpolation repair for `kQAV2SHOTFIR` (res_id: 62). --- source/games/blood/src/qav.cpp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 8b7f8c3c4..9a3dc2746 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -892,6 +892,39 @@ static void qavRepairTileData(QAV* pQAV) // Disable frame 0 tile 7. pQAV->frames[0].tiles[7].picnum = -1; break; + case kQAV2SHOTFIR: + // 2SHOTFIR has the issues of both SHOTUP and 2SHOTF2, fix both issues. + + // Fix missing tiles for 2630 and 2631 and amend x/y coordinates for 2630 and 2631 for right and left side respectively. + for (i = 8; i < 11; i++) + { + // Use difference from tile 2, it's the same for left and right side. + for (j = 3; j < 5; j++) + { + pQAV->frames[i].tiles[j] = pQAV->frames[11].tiles[j]; + pQAV->frames[i].tiles[j].x += pQAV->frames[i].tiles[2].x - pQAV->frames[11].tiles[2].x; + pQAV->frames[i].tiles[j].y += pQAV->frames[i].tiles[2].y - pQAV->frames[11].tiles[2].y; + } + for (j = 6; j < 8; j++) + { + pQAV->frames[i].tiles[j] = pQAV->frames[11].tiles[j]; + pQAV->frames[i].tiles[j].x -= pQAV->frames[i].tiles[2].x - pQAV->frames[11].tiles[2].x; + pQAV->frames[i].tiles[j].y += pQAV->frames[i].tiles[2].y - pQAV->frames[11].tiles[2].y; + } + } + + // Fix missing tiles for 2632 and patch coordinates on right and left side respectively. + for (i = 3; i < 7; i += 3) + { + pQAV->frames[0].tiles[i] = pQAV->frames[1].tiles[i]; + pQAV->frames[0].tiles[i].x -= pQAV->frames[1].tiles[i - 1].x - pQAV->frames[0].tiles[i - 1].x; + pQAV->frames[0].tiles[i].y -= pQAV->frames[1].tiles[i - 1].y - pQAV->frames[0].tiles[i - 1].y; + } + + // Disable frame 0 tile 4 and tile 7. + pQAV->frames[0].tiles[4].picnum = -1; + pQAV->frames[0].tiles[7].picnum = -1; + break; default: return; } From 6998772487a2bd9b4215f7df769f63f96a6fcc5b Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sun, 22 Aug 2021 07:33:46 +1000 Subject: [PATCH 51/89] - Blood: Add interpolation properties for `kQAVTOMFIRE` (res_id: 66). --- source/games/blood/src/qav.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 9a3dc2746..2fb1dd223 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -202,6 +202,18 @@ void qavBuildInterpProps(QAV* const pQAV) qavInterpProps.Insert(pQAV->res_id, std::move(interp)); break; } + case kQAVTOMFIRE: + { + QAVInterpProps interp{}; + interp.flags |= true << kQAVIsLoopable; + interp.PrevTileFinder = qavGetInterpType("interpolate-index"); + qavInterpProps.Insert(pQAV->res_id, std::move(interp)); + for (int i = 0; i < pQAV->nFrames; i++) + { + qavSetNonInterpFrameTile(pQAV->res_id, i, 0); + } + break; + } default: { QAVInterpProps interp{}; From c6c7ae76d625a8be8165d6b3508e1340f7341a8d Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sun, 22 Aug 2021 07:57:01 +1000 Subject: [PATCH 52/89] - Blood: Mark `kQAVTOMSPRED` (res_id: 67) as being loopable. --- source/games/blood/src/qav.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 2fb1dd223..b166f3996 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -156,6 +156,7 @@ void qavBuildInterpProps(QAV* const pQAV) case kQAVREMIDLE1: case kQAVREMIDLE2: case kQAVFLARFIR2: + case kQAVTOMSPRED: { QAVInterpProps interp{}; interp.flags |= true << kQAVIsLoopable; From c46c52a724a83fcc7db309700535fb96decb43b4 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sun, 22 Aug 2021 07:43:08 +1000 Subject: [PATCH 53/89] - Blood: Add interpolation properties for `kQAV2TOMFIRE` (res_id: 71). --- source/games/blood/src/qav.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index b166f3996..76aa2b6e8 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -215,6 +215,21 @@ void qavBuildInterpProps(QAV* const pQAV) } break; } + case kQAV2TOMFIRE: + { + QAVInterpProps interp{}; + interp.flags |= true << kQAVIsLoopable; + interp.PrevTileFinder = qavGetInterpType("interpolate-index"); + qavInterpProps.Insert(pQAV->res_id, std::move(interp)); + for (int i = 0; i < pQAV->nFrames; i++) + { + for (int j = 0; j < 3; j += 2) + { + qavSetNonInterpFrameTile(pQAV->res_id, i, j); + } + } + break; + } default: { QAVInterpProps interp{}; From df5185038fc72403732ca42bb96484850672ecad Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sun, 22 Aug 2021 07:57:45 +1000 Subject: [PATCH 54/89] - Blood: Mark `kQAV2TOMALT` (res_id: 73) as being loopable. --- source/games/blood/src/qav.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 76aa2b6e8..40ce2543b 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -157,6 +157,7 @@ void qavBuildInterpProps(QAV* const pQAV) case kQAVREMIDLE2: case kQAVFLARFIR2: case kQAVTOMSPRED: + case kQAV2TOMALT: { QAVInterpProps interp{}; interp.flags |= true << kQAVIsLoopable; From 7eca7ea166674f3cced47c9e789ad34b56182802 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 14 Aug 2021 08:47:28 +1000 Subject: [PATCH 55/89] - Blood: Add interpolation repair for `kQAVSGUNUP` (res_id: 74). --- source/games/blood/src/qav.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 40ce2543b..01d26c2a3 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -954,6 +954,13 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[0].tiles[4].picnum = -1; pQAV->frames[0].tiles[7].picnum = -1; break; + case kQAVSGUNUP: + // SGUNUP has a missing frame crucial to proper interpolation experience, so add it back + // in and adjust x/y coordinates using difference between frame 0 and 1's tile index 0. + pQAV->frames[0].tiles[1] = pQAV->frames[1].tiles[1]; + pQAV->frames[0].tiles[1].x -= pQAV->frames[1].tiles[0].x - pQAV->frames[0].tiles[0].x; + pQAV->frames[0].tiles[1].y -= pQAV->frames[1].tiles[0].y - pQAV->frames[0].tiles[0].y; + break; default: return; } From 5160b7649c72fefb22c13a3a48b0f38e188b43db Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 14 Aug 2021 11:53:35 +1000 Subject: [PATCH 56/89] - Blood: Add interpolation repair for `kQAVSGUNIDL1` (res_id: 75). --- source/games/blood/src/qav.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 01d26c2a3..15bf2b6b9 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -961,6 +961,14 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[0].tiles[1].x -= pQAV->frames[1].tiles[0].x - pQAV->frames[0].tiles[0].x; pQAV->frames[0].tiles[1].y -= pQAV->frames[1].tiles[0].y - pQAV->frames[0].tiles[0].y; break; + case kQAVSGUNIDL1: + // SGUNIDL1 has overlay 3232 permanently applied which is at odds with the weapon rising, + // and the other idling QAV. Disable it entirely. + for (i = 0; i < pQAV->nFrames; i++) + { + pQAV->frames[i].tiles[1].picnum = -1; + } + break; default: return; } From 2ff1bdfd7d64fb6f28d42102a21f1dfb3e804a0e Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 14 Aug 2021 11:06:44 +1000 Subject: [PATCH 57/89] - Blood: Add interpolation repair for `kQAVSGUNFIR1` (res_id: 77). Thanks to @Phredreeke for the tiles with overlays baked in for this to work properly. --- source/games/blood/src/qav.cpp | 18 ++++++++++++++++++ wadsrc/static/filter/blood/engine/engine.def | 7 +++++++ .../filter/blood/tiles/9300(3227+3228).png | Bin 0 -> 3993 bytes .../filter/blood/tiles/9301(3227+3229).png | Bin 0 -> 3985 bytes .../filter/blood/tiles/9302(3227+3230).png | Bin 0 -> 3988 bytes .../filter/blood/tiles/9303(3227+3231).png | Bin 0 -> 3968 bytes .../filter/blood/tiles/9304(3227+3232).png | Bin 0 -> 3977 bytes 7 files changed, 25 insertions(+) create mode 100644 wadsrc/static/filter/blood/tiles/9300(3227+3228).png create mode 100644 wadsrc/static/filter/blood/tiles/9301(3227+3229).png create mode 100644 wadsrc/static/filter/blood/tiles/9302(3227+3230).png create mode 100644 wadsrc/static/filter/blood/tiles/9303(3227+3231).png create mode 100644 wadsrc/static/filter/blood/tiles/9304(3227+3232).png diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 15bf2b6b9..2ced51015 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -969,6 +969,24 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[i].tiles[1].picnum = -1; } break; + case kQAVSGUNFIR1: + { + // SGUNFIR1's overlay sizes vary from tile to tile and don't interpolate properly. + // Use repaired tiles from Phredreeke where the overlays are baked in. + constexpr int tilearray[8] = { 9301, 9302, 9303, 9304, 9300, 9301, 9302, 3227 }; + + // Loop through each frame to remove overlay and replace use of 3227 with that from tilearray. + for (i = 0; i < pQAV->nFrames; i++) + { + pQAV->frames[i].tiles[0] = pQAV->frames[i].tiles[1]; + pQAV->frames[i].tiles[1] = pQAV->frames[i].tiles[3]; + pQAV->frames[i].tiles[0].picnum = tilearray[i]; + pQAV->frames[i].tiles[2].picnum = -1; + pQAV->frames[i].tiles[3].picnum = -1; + + } + break; + } default: return; } diff --git a/wadsrc/static/filter/blood/engine/engine.def b/wadsrc/static/filter/blood/engine/engine.def index e4843725b..2d63f1c5f 100644 --- a/wadsrc/static/filter/blood/engine/engine.def +++ b/wadsrc/static/filter/blood/engine/engine.def @@ -59,3 +59,10 @@ tilefromtexture 9277 { file "tiles/9277.png" } tilefromtexture 9278 { file "tiles/9278.png" } tilefromtexture 9279 { file "tiles/9279.png" } tilefromtexture 9280 { file "tiles/9280.png" } + +// Patched tiles for QAV interpolation, thanks to Phredreeke for supplying these. +tilefromtexture 9300 { file "tiles/9300(3227+3228).png" } +tilefromtexture 9301 { file "tiles/9301(3227+3229).png" } +tilefromtexture 9302 { file "tiles/9302(3227+3230).png" } +tilefromtexture 9303 { file "tiles/9303(3227+3231).png" } +tilefromtexture 9304 { file "tiles/9304(3227+3232).png" } diff --git a/wadsrc/static/filter/blood/tiles/9300(3227+3228).png b/wadsrc/static/filter/blood/tiles/9300(3227+3228).png new file mode 100644 index 0000000000000000000000000000000000000000..d3d11606045a20700f42ef10ef164333335fa259 GIT binary patch literal 3993 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 literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/tiles/9301(3227+3229).png b/wadsrc/static/filter/blood/tiles/9301(3227+3229).png new file mode 100644 index 0000000000000000000000000000000000000000..ab2ccc827629ee162c2b14f547cc70969957f476 GIT binary patch literal 3985 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 literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/tiles/9303(3227+3231).png b/wadsrc/static/filter/blood/tiles/9303(3227+3231).png new file mode 100644 index 0000000000000000000000000000000000000000..cc3047253efd9fa91d8bb408f718ae927d9e8354 GIT binary patch literal 3968 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 Date: Sat, 14 Aug 2021 11:07:04 +1000 Subject: [PATCH 58/89] - Blood: Mark `kQAVSGUNFIR1` (res_id: 77) as being loopable. --- source/games/blood/src/qav.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 2ced51015..d25edb9c3 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -158,6 +158,7 @@ void qavBuildInterpProps(QAV* const pQAV) case kQAVFLARFIR2: case kQAVTOMSPRED: case kQAV2TOMALT: + case kQAVSGUNFIR1: { QAVInterpProps interp{}; interp.flags |= true << kQAVIsLoopable; From 1033049b8c6fd41c5f14d9e158cfc5574f41a181 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sun, 22 Aug 2021 08:13:40 +1000 Subject: [PATCH 59/89] - Blood: Add interpolation repair for `kQAVSGUNFIR4` (res_id: 78). Thanks again to @Phredreeke for the tiles with overlays baked in for this to work properly. --- source/games/blood/src/qav.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index d25edb9c3..1d950eab8 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -988,6 +988,25 @@ static void qavRepairTileData(QAV* pQAV) } break; } + case kQAVSGUNFIR4: + { + // SGUNFIR4's overlay sizes vary from tile to tile and don't interpolate properly. + // Use repaired tiles from Phredreeke where the overlays are baked in. + constexpr int tilearray[46] = { 9304, 9304, 9300, 9300, 9301, 9301, 9302, 9302, 9303, 9303, 9304, 9300, 9301, 9302, 9303, 9304, 9300, 9301, 9302, 9303, 9304, 9300, 9301, 9302, 9303, 9304, 9300, 9301, 9302, 9303, 9300, 9302, 9304, 9301, 9303, 9300, 9302, 9304, 9301, 9303, 9301, 9304, 9302, 9300, 9303, 9301 }; + + // Loop through each frame to remove overlay and replace use of 3227 with that from tilearray. + for (i = 0; i < 46; i++) + { + pQAV->frames[i].tiles[0].picnum = tilearray[i]; + pQAV->frames[i].tiles[1].picnum = -1; + } + + // Swap frame 46 index 0 and 1. + backup = pQAV->frames[46].tiles[0]; + pQAV->frames[46].tiles[0] = pQAV->frames[46].tiles[1]; + pQAV->frames[46].tiles[1] = backup; + break; + } default: return; } From df3bc4d90ae7f873cf5846b5561c464517c5723c Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 14 Aug 2021 11:45:51 +1000 Subject: [PATCH 60/89] - Blood: Add interpolation repair for `kQAVSGUNPRE` (res_id: 79). Thanks again to @Phredreeke for the tiles with overlays baked in for this to work properly. --- source/games/blood/src/qav.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 1d950eab8..0b185b6b4 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -1007,6 +1007,17 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[46].tiles[1] = backup; break; } + case kQAVSGUNPRE: + // SGUNPRE's overlay sizes vary from tile to tile and don't interpolate properly. + // Use repaired tiles from Phredreeke where the overlays are baked in. + + // For the two last frames, change tile index 0 picnum from 3227 to 9300. + for (i = pQAV->nFrames - 2; i < pQAV->nFrames; i++) + { + pQAV->frames[i].tiles[0].picnum = 9300; + pQAV->frames[i].tiles[2].picnum = -1; + } + break; default: return; } From 7bbf47885916a1b51682b47b4e8d6651b05213f1 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 14 Aug 2021 11:49:24 +1000 Subject: [PATCH 61/89] - Blood: Add interpolation repair for `kQAVSGUNPOST` (res_id: 80). Thanks again to @Phredreeke for the tiles with overlays baked in for this to work properly. --- source/games/blood/src/qav.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 0b185b6b4..62aa56f1d 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -1018,6 +1018,21 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[i].tiles[2].picnum = -1; } break; + case kQAVSGUNPOST: + { + // SGUNPOST's overlay sizes vary from tile to tile and don't interpolate properly. + // Use repaired tiles from Phredreeke where the overlays are baked in. + constexpr int tilearray[8] = { 9301, 9301, 9302, 9302, 9303, 9303, 9304, 9304 }; + + // Loop through each frame to remove overlay and replace use of 3227 with that from tilearray. + for (i = 0; i < pQAV->nFrames; i++) + { + pQAV->frames[i].tiles[1].picnum = tilearray[i]; + pQAV->frames[i].tiles[2].picnum = -1; + + } + break; + } default: return; } From 073f0d953f5bf0a203a6e4954e11e5ed047b3ac4 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 14 Aug 2021 13:53:14 +1000 Subject: [PATCH 62/89] - Blood: Add interpolation repair for `kQAV2SGUNUP` (res_id: 82). --- source/games/blood/src/qav.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 62aa56f1d..e8fa5ef69 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -1033,6 +1033,19 @@ static void qavRepairTileData(QAV* pQAV) } break; } + case kQAV2SGUNUP: + // 2SGUNUP has a missing two frame tiles crucial to proper interpolation experience, so add them back + // in and adjust x/y coordinates using difference between frame 0 and 1's tile index 0 and 2. + for (i = 1; i < 4; i += 2) + { + pQAV->frames[0].tiles[i] = pQAV->frames[1].tiles[i]; + pQAV->frames[0].tiles[i].x -= pQAV->frames[1].tiles[i-1].x - pQAV->frames[0].tiles[i-1].x; + pQAV->frames[0].tiles[i].y -= pQAV->frames[1].tiles[i-1].y - pQAV->frames[0].tiles[i-1].y; + } + + // Set frame 0 tile 3 picnum to 3311. + pQAV->frames[0].tiles[3].picnum = 3311; + break; default: return; } From 22e348613fc251351b8374c2e6aff252de0bf1d1 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 14 Aug 2021 14:46:27 +1000 Subject: [PATCH 63/89] - Blood: Add interpolation repair for `kQAV2SGUNFIR` (res_id: 84). Thanks to @Phredreeke for the tiles with overlays baked in for this to work properly. --- source/games/blood/src/qav.cpp | 24 ++++++++++++++++++ wadsrc/static/filter/blood/engine/engine.def | 5 ++++ .../filter/blood/tiles/9305(3240+3228).png | Bin 0 -> 3070 bytes .../filter/blood/tiles/9306(3240+3229).png | Bin 0 -> 3064 bytes .../filter/blood/tiles/9307(3240+3230).png | Bin 0 -> 3068 bytes .../filter/blood/tiles/9308(3240+3231).png | Bin 0 -> 3046 bytes .../filter/blood/tiles/9309(3240+3232).png | Bin 0 -> 3055 bytes 7 files changed, 29 insertions(+) create mode 100644 wadsrc/static/filter/blood/tiles/9305(3240+3228).png create mode 100644 wadsrc/static/filter/blood/tiles/9306(3240+3229).png create mode 100644 wadsrc/static/filter/blood/tiles/9307(3240+3230).png create mode 100644 wadsrc/static/filter/blood/tiles/9308(3240+3231).png create mode 100644 wadsrc/static/filter/blood/tiles/9309(3240+3232).png diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index e8fa5ef69..801142c6e 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -1046,6 +1046,30 @@ static void qavRepairTileData(QAV* pQAV) // Set frame 0 tile 3 picnum to 3311. pQAV->frames[0].tiles[3].picnum = 3311; break; + case kQAV2SGUNFIR: + { + // 2SGUNFIR's overlay sizes vary from tile to tile and don't interpolate properly. + // Use repaired tiles from Phredreeke where the overlays are baked in. + constexpr int tilearray[2][8] = { + { + 9306, 9307, 9308, 9309, 9305, 9306, 9307, 3240 + }, + { + 3240, 9307, 9306, 9305, 9309, 9308, 9307, 9306 + } + }; + + // Loop through each frame to remove overlay and replace use of 3240 with that from tilearray and disable overlays. + for (i = 0; i < pQAV->nFrames; i++) + { + pQAV->frames[i].tiles[0].picnum = tilearray[0][i]; + pQAV->frames[i].tiles[4].picnum = -1; + + pQAV->frames[i].tiles[2].picnum = tilearray[1][i]; + pQAV->frames[i].tiles[5].picnum = -1; + } + break; + } default: return; } diff --git a/wadsrc/static/filter/blood/engine/engine.def b/wadsrc/static/filter/blood/engine/engine.def index 2d63f1c5f..128a463bd 100644 --- a/wadsrc/static/filter/blood/engine/engine.def +++ b/wadsrc/static/filter/blood/engine/engine.def @@ -66,3 +66,8 @@ tilefromtexture 9301 { file "tiles/9301(3227+3229).png" } tilefromtexture 9302 { file "tiles/9302(3227+3230).png" } tilefromtexture 9303 { file "tiles/9303(3227+3231).png" } tilefromtexture 9304 { file "tiles/9304(3227+3232).png" } +tilefromtexture 9305 { file "tiles/9305(3240+3228).png" } +tilefromtexture 9306 { file "tiles/9306(3240+3229).png" } +tilefromtexture 9307 { file "tiles/9307(3240+3230).png" } +tilefromtexture 9308 { file "tiles/9308(3240+3231).png" } +tilefromtexture 9309 { file "tiles/9309(3240+3232).png" } diff --git a/wadsrc/static/filter/blood/tiles/9305(3240+3228).png b/wadsrc/static/filter/blood/tiles/9305(3240+3228).png new file mode 100644 index 0000000000000000000000000000000000000000..5b5ae0b934c4531d59efae2cd82cccb41b178cfa GIT binary patch literal 3070 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 M07*qoM6N<$g6Oxx*Z=?k literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/tiles/9306(3240+3229).png b/wadsrc/static/filter/blood/tiles/9306(3240+3229).png new file mode 100644 index 0000000000000000000000000000000000000000..d49f9437e35d75d1dae0470dbe5c051171877010 GIT binary patch literal 3064 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 KMNUMnLSTZ&CGIQ$ literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/tiles/9308(3240+3231).png b/wadsrc/static/filter/blood/tiles/9308(3240+3231).png new file mode 100644 index 0000000000000000000000000000000000000000..cebf313f708cce10ef1c0546071e24c46c1ccd6f GIT binary patch literal 3046 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 literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/tiles/9309(3240+3232).png b/wadsrc/static/filter/blood/tiles/9309(3240+3232).png new file mode 100644 index 0000000000000000000000000000000000000000..6424284592067e2202636d30da3cdea4cbc74e61 GIT binary patch literal 3055 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 literal 0 HcmV?d00001 From b2637050e86816f2069333600d0d2deef05ee6c0 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 14 Aug 2021 14:46:40 +1000 Subject: [PATCH 64/89] - Blood: Mark `kQAV2SGUNFIR` (res_id: 84) as being loopable. --- source/games/blood/src/qav.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 801142c6e..9be5e73dc 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -159,6 +159,7 @@ void qavBuildInterpProps(QAV* const pQAV) case kQAVTOMSPRED: case kQAV2TOMALT: case kQAVSGUNFIR1: + case kQAV2SGUNFIR: { QAVInterpProps interp{}; interp.flags |= true << kQAVIsLoopable; From ed92ec9af9da73beae4c5ca0416f49262cb8a191 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 14 Aug 2021 22:19:07 +1000 Subject: [PATCH 65/89] - Blood: Add interpolation repair for `kQAV2SGUNALT` (res_id: 85). Thanks again to @Phredreeke for the tiles with overlays baked in for this to work properly. --- source/games/blood/src/qav.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 9be5e73dc..8891e2302 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -1071,6 +1071,33 @@ static void qavRepairTileData(QAV* pQAV) } break; } + case kQAV2SGUNALT: + { + // 2SGUNALT's overlay sizes vary from tile to tile and don't interpolate properly. + // Use repaired tiles from Phredreeke where the overlays are baked in. + constexpr int tilearray[2][30] = { + { + 9309, 9305, 9306, 9307, 9308, 9309, 9305, 9306, 9307, 9308, 9309, 9305, 9306, 9307, 9308, 9309, 9305, 9306, 9307, 9308, 9309, 9305, 9306, 9307, 9308, 9309, 9305, 9306, 9307, 9308 + }, + { + 9308, 9307, 9306, 9305, 9309, 9308, 9307, 9306, 9305, 9309, 9308, 9307, 9306, 9305, 9309, 9308, 9307, 9306, 9305, 9309, 9308, 9307, 9306, 9305, 9309, 9308, 9307, 9306, 9305, 9309 + } + }; + + // Loop through first 30 frames to remove overlay and replace use of 3240 with that from tilearray and disable overlays. + for (i = 0; i < 30; i++) + { + pQAV->frames[i].tiles[0].picnum = tilearray[0][i]; + pQAV->frames[i].tiles[4].picnum = -1; + + pQAV->frames[i].tiles[2].picnum = tilearray[1][i]; + pQAV->frames[i].tiles[5].picnum = -1; + } + + // Disable tiles 1, 3 and 6 on frame 29. + pQAV->frames[29].tiles[1].picnum = pQAV->frames[29].tiles[3].picnum = pQAV->frames[29].tiles[6].picnum = -1; + break; + } default: return; } From 99ab8fa7264727551020f208c121aa68f3abc793 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 14 Aug 2021 22:30:26 +1000 Subject: [PATCH 66/89] - Blood: Add interpolation repair for `kQAV2SGUNPRE` (res_id: 86). Thanks again to @Phredreeke for the tiles with overlays baked in for this to work properly. --- source/games/blood/src/qav.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 8891e2302..45bff7ede 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -1098,6 +1098,30 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[29].tiles[1].picnum = pQAV->frames[29].tiles[3].picnum = pQAV->frames[29].tiles[6].picnum = -1; break; } + case kQAV2SGUNPRE: + { + // 2SGUNPRE's overlay sizes vary from tile to tile and don't interpolate properly. + // Use repaired tiles from Phredreeke where the overlays are baked in. + constexpr int tilearray[2][30] = { + { + 9305, 9306, 9307, 9308 + }, + { + 9307, 9306, 9305, 9309 + } + }; + + // Loop through all frames to remove overlay and replace use of 3240 with that from tilearray and disable overlays. + for (i = 0; i < pQAV->nFrames; i++) + { + pQAV->frames[i].tiles[0].picnum = tilearray[0][i]; + pQAV->frames[i].tiles[4].picnum = -1; + + pQAV->frames[i].tiles[2].picnum = tilearray[1][i]; + pQAV->frames[i].tiles[5].picnum = -1; + } + break; + } default: return; } From d4fe734afa3da90b54243f95c9636de5f325dadc Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 14 Aug 2021 08:42:05 +1000 Subject: [PATCH 67/89] - Blood: Add interpolation repair for `kQAVNAPUP` (res_id: 89). --- source/games/blood/src/qav.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 45bff7ede..5f1af3a18 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -1122,6 +1122,16 @@ static void qavRepairTileData(QAV* pQAV) } break; } + case kQAVNAPUP: + // This QAV is missing picnum 2351 for the first two frames. Add it in to smooth interpolation. + for (i = 0; i < 2; i++) + { + pQAV->frames[i].tiles[1] = pQAV->frames[2].tiles[1]; + pQAV->frames[i].tiles[1].x += pQAV->frames[i].tiles[0].x - pQAV->frames[2].tiles[0].x; + pQAV->frames[i].tiles[1].y += pQAV->frames[i].tiles[0].y - pQAV->frames[2].tiles[0].y; + pQAV->frames[i].tiles[1].picnum = 2351; + } + break; default: return; } From 3a656c91cb9d421ea2677347d02550ddf34ac4d4 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 14 Aug 2021 08:42:44 +1000 Subject: [PATCH 68/89] - Blood: Mark `kQAVNAPFIRE` (res_id: 91) as being loopable. --- source/games/blood/src/qav.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 5f1af3a18..f8a488884 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -160,6 +160,7 @@ void qavBuildInterpProps(QAV* const pQAV) case kQAV2TOMALT: case kQAVSGUNFIR1: case kQAV2SGUNFIR: + case kQAVNAPFIRE: { QAVInterpProps interp{}; interp.flags |= true << kQAVIsLoopable; From 1fd66681d2bebc83fb5f8e0aa3fd15ffbefdf03f Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Fri, 13 Aug 2021 08:16:24 +1000 Subject: [PATCH 69/89] - Blood: Add interpolation repair for `kQAVVDUP` (res_id: 100). --- source/games/blood/src/qav.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index f8a488884..ee1adbb17 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -1133,6 +1133,12 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[i].tiles[1].picnum = 2351; } break; + case kQAVVDUP: + // VDUP requires tile indices on the last frame to be swapped around. + backup = pQAV->frames[pQAV->nFrames-1].tiles[0]; + pQAV->frames[pQAV->nFrames-1].tiles[0] = pQAV->frames[pQAV->nFrames - 1].tiles[1]; + pQAV->frames[pQAV->nFrames-1].tiles[1] = backup; + break; default: return; } From 803e9f8a04940392ef01f9ab789c73b0a352eb61 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Fri, 13 Aug 2021 11:58:14 +1000 Subject: [PATCH 70/89] - Blood: Add interpolation repair for `kQAVVDIDLE2` (res_id: 102). --- source/games/blood/src/qav.cpp | 52 ++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index ee1adbb17..323fe6da4 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -1139,6 +1139,58 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[pQAV->nFrames-1].tiles[0] = pQAV->frames[pQAV->nFrames - 1].tiles[1]; pQAV->frames[pQAV->nFrames-1].tiles[1] = backup; break; + case kQAVVDIDLE2: + { + // VDIDLE2 requires several tile indices to be swapped around to fix interpolation. + // For frames 5 and 7, move tile index 2 into 0 and disable the original index of 0. + for (i = 5; i < 8; i += 2) + { + pQAV->frames[i].tiles[0] = pQAV->frames[i].tiles[2]; + pQAV->frames[i].tiles[2].picnum = -1; + } + + // For frames 2-3, swap tile indices 0 and 1 around. + for (i = 2; i < 4; i++) + { + backup = pQAV->frames[i].tiles[0]; + pQAV->frames[i].tiles[0] = pQAV->frames[i].tiles[1]; + pQAV->frames[i].tiles[1] = backup; + } + + // For frames 9 til the end, swap tile indices 0 and 1 around. + for (i = 9; i < pQAV->nFrames; i++) + { + backup = pQAV->frames[i].tiles[0]; + pQAV->frames[i].tiles[0] = pQAV->frames[i].tiles[1]; + pQAV->frames[i].tiles[1] = backup; + } + + // Set frame 1 tile 0 x/y coordinates to that of values between frames 0 and 2. + pQAV->frames[1].tiles[0].x = -29; + pQAV->frames[1].tiles[0].y = -12; + + // Set frame 1 tile 1 y coordinates to that of values between frames 0 and 2. + pQAV->frames[1].tiles[1].y = -45; + + // Set frame 3 tile 1 y coordinates to that of values between frames 2 and 4. + pQAV->frames[3].tiles[1].y = -46; + + // Set frame 5 tile 1 y coordinates to that of values between frames 4 and 6. + pQAV->frames[5].tiles[1].y = -42; + + // Set frame 7 tile 1 y coordinates to that of values between frames 6 and 8. + pQAV->frames[7].tiles[1].y = -41; + + // Set frame 10 tile 1 y coordinates to that of values between frames 9 and 11. + pQAV->frames[10].tiles[1].y = -45; + + // Smooth out tile coordinates between high and low point for tile index 1 x across all frames. High point is frame 0/12, low point is 6. + for (i = 1, j = (pQAV->nFrames - 2); i < 6, j > 6; i++, j--) + { + pQAV->frames[i].tiles[1].x = pQAV->frames[j].tiles[1].x = xs_CRoundToInt(pQAV->frames[0].tiles[1].x - (double(pQAV->frames[0].tiles[1].x - pQAV->frames[6].tiles[1].x) / 6) * i); + } + break; + } default: return; } From cd092153eb247821b787b06b6c0180b92250f1dc Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Fri, 13 Aug 2021 11:58:55 +1000 Subject: [PATCH 71/89] - Blood: Mark `kQAVVDIDLE2` (res_id: 102) as being loopable. --- source/games/blood/src/qav.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 323fe6da4..dd29d1b35 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -161,6 +161,7 @@ void qavBuildInterpProps(QAV* const pQAV) case kQAVSGUNFIR1: case kQAV2SGUNFIR: case kQAVNAPFIRE: + case kQAVVDIDLE2: { QAVInterpProps interp{}; interp.flags |= true << kQAVIsLoopable; From dd1e7160820e4de517fab6aad5a569560456be1a Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Fri, 13 Aug 2021 15:18:02 +1000 Subject: [PATCH 72/89] - Blood: Extend backported voodoo doll fix from BloodGDX to always use `kQAVVDIDLE2` when the player is moving. As `kQAVVDIDLE2` has moving frames and is not a static idle animation, call it via `StartQAV()` so that `weaponTimer` is started. --- source/games/blood/src/weapon.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/games/blood/src/weapon.cpp b/source/games/blood/src/weapon.cpp index 8671189a9..cb3184ffb 100644 --- a/source/games/blood/src/weapon.cpp +++ b/source/games/blood/src/weapon.cpp @@ -984,8 +984,8 @@ void WeaponUpdateState(PLAYER *pPlayer) pPlayer->weaponQav = kQAVFLARIDLE; break; case kWeapVoodooDoll: - if (pXSprite->height < 256 && abs(pPlayer->swayHeight) > 16) - pPlayer->weaponQav = kQAVVDIDLE2; + if (pXSprite->height < 256 && pPlayer->swayHeight != 0) + StartQAV(pPlayer, kQAVVDIDLE2); else pPlayer->weaponQav = kQAVVDIDLE1; break; @@ -2024,6 +2024,7 @@ void WeaponProcess(PLAYER *pPlayer) { pPlayer->weaponTimer -= 4; bool bShoot = pPlayer->input.actions & SB_FIRE; bool bShoot2 = pPlayer->input.actions & SB_ALTFIRE; + if ((bShoot || bShoot2) && pPlayer->weaponQav == kQAVVDIDLE2) pPlayer->weaponTimer = 0; if (pPlayer->qavLoop && pPlayer->pXSprite->health > 0) { if (bShoot && CheckAmmo(pPlayer, pPlayer->weaponAmmo, 1)) From a3a2cd8da851602b5e8895d67afb38ff67af69af Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Fri, 13 Aug 2021 16:22:02 +1000 Subject: [PATCH 73/89] - Blood: Add interpolation repair for `kQAVVDFIRE1` (res_id: 103) and `kQAVVDFIRE2` (res_id: 104). --- source/games/blood/src/qav.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index dd29d1b35..a02b6b448 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -1192,6 +1192,38 @@ static void qavRepairTileData(QAV* pQAV) } break; } + case kQAVVDFIRE1: + case kQAVVDFIRE2: + // VDFIRE1 and VDFIRE2 requires several index swaps to repair interpolations. + // For frame 0, move tile index 1 to 2, and disable original index of 1. + pQAV->frames[0].tiles[2] = pQAV->frames[0].tiles[1]; + pQAV->frames[0].tiles[1].picnum = -1; + + // For frame 1, move tile index 0 to 2 and 1 to 0, and disable original index of 1. + pQAV->frames[0].tiles[2] = pQAV->frames[0].tiles[0]; + pQAV->frames[0].tiles[0] = pQAV->frames[0].tiles[1]; + pQAV->frames[0].tiles[1].picnum = -1; + + // For frame 7, swap tile indices 1 to 2. + backup = pQAV->frames[7].tiles[2]; + pQAV->frames[7].tiles[2] = pQAV->frames[7].tiles[1]; + pQAV->frames[7].tiles[1] = backup; + + // For frame 8-9, move tile index 1 to 2, and disable original index of 1. + for (i = 8; i < 10; i++) + { + pQAV->frames[i].tiles[2] = pQAV->frames[i].tiles[1]; + pQAV->frames[i].tiles[1].picnum = -1; + } + + // For frames 10 till end, move tile index 0 to 2 and 1 to 0, and disable original index of 1. + for (i = 10; i < pQAV->nFrames; i++) + { + pQAV->frames[i].tiles[2] = pQAV->frames[i].tiles[0]; + pQAV->frames[i].tiles[0] = pQAV->frames[i].tiles[1]; + pQAV->frames[i].tiles[1].picnum = -1; + } + break; default: return; } From d34fd124b74c313dc0a54a040634923f25e23187 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Fri, 13 Aug 2021 16:26:27 +1000 Subject: [PATCH 74/89] - Blood: Add interpolation repair for `kQAVVDFIRE3` (res_id: 105). --- source/games/blood/src/qav.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index a02b6b448..539c46d30 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -1224,6 +1224,21 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[i].tiles[1].picnum = -1; } break; + case kQAVVDFIRE3: + // VDFIRE3 requires several index swaps to repair interpolations. + // For frame 1, swap tile indices 0 and 1. + backup = pQAV->frames[1].tiles[1]; + pQAV->frames[1].tiles[1] = pQAV->frames[1].tiles[0]; + pQAV->frames[1].tiles[0] = backup; + + // For frames 13 till end, swap tile indices 0 and 1. + for (i = 13; i < pQAV->nFrames; i++) + { + backup = pQAV->frames[i].tiles[1]; + pQAV->frames[i].tiles[1] = pQAV->frames[i].tiles[0]; + pQAV->frames[i].tiles[0] = backup; + } + break; default: return; } From 95878bcea17c19763fd5b7cc87dd3e80f8cede21 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Fri, 13 Aug 2021 16:40:50 +1000 Subject: [PATCH 75/89] - Blood: Add interpolation repair for `kQAVVDFIRE4` (res_id: 106) and `kQAVVDFIRE5` (res_id: 107). --- source/games/blood/src/qav.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 539c46d30..3efea35a2 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -1239,6 +1239,22 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[i].tiles[0] = backup; } break; + case kQAVVDFIRE4: + case kQAVVDFIRE5: + // VDFIRE4 and requires several index swaps to repair interpolations. + // For frame 1, swap tile indices 0 and 1. + backup = pQAV->frames[1].tiles[1]; + pQAV->frames[1].tiles[1] = pQAV->frames[1].tiles[0]; + pQAV->frames[1].tiles[0] = backup; + + // For the last two frames, swap tile indices 0 and 1. + for (i = (pQAV->nFrames - 2); i < pQAV->nFrames; i++) + { + backup = pQAV->frames[i].tiles[1]; + pQAV->frames[i].tiles[1] = pQAV->frames[i].tiles[0]; + pQAV->frames[i].tiles[0] = backup; + } + break; default: return; } From 0172373650a4fc460459f2a5b7923eebf843d231 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Fri, 13 Aug 2021 16:42:22 +1000 Subject: [PATCH 76/89] - Blood: Add interpolation repair for `kQAVVDDOWN` (res_id: 109). --- source/games/blood/src/qav.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 3efea35a2..49fb465eb 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -1255,6 +1255,12 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[i].tiles[0] = backup; } break; + case kQAVVDDOWN: + // VDDOWN requires tile indices on the first frame to be swapped around. + backup = pQAV->frames[0].tiles[0]; + pQAV->frames[0].tiles[0] = pQAV->frames[0].tiles[1]; + pQAV->frames[0].tiles[1] = backup; + break; default: return; } From fb084734e37e0b9a9fa55152adbd8260efe60b38 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Fri, 13 Aug 2021 16:51:44 +1000 Subject: [PATCH 77/89] - Blood: Add interpolation repair for `kQAVVDSPEL1` (res_id: 110). --- source/games/blood/src/qav.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 49fb465eb..2a585ba0a 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -1261,6 +1261,36 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[0].tiles[0] = pQAV->frames[0].tiles[1]; pQAV->frames[0].tiles[1] = backup; break; + case kQAVVDSPEL1: + // VDSPEL1 requires several index swaps to repair interpolations. + // For frame 1, swap tile indices 0 and 1. + backup = pQAV->frames[1].tiles[1]; + pQAV->frames[1].tiles[1] = pQAV->frames[1].tiles[0]; + pQAV->frames[1].tiles[0] = backup; + + // For frame 2, move tile index 2 into 1, and disable original index of 2. + pQAV->frames[2].tiles[1] = pQAV->frames[2].tiles[2]; + pQAV->frames[2].tiles[2].picnum = -1; + + // For frames 7-9 , move tile index 1 to 2, and disable original index of 1. + for (i = 7; i < 10; i++) + { + pQAV->frames[i].tiles[2] = pQAV->frames[i].tiles[1]; + pQAV->frames[i].tiles[1].picnum = -1; + } + + // For frame 10, move tile index 0 into 2, and disable original index of 0. + pQAV->frames[10].tiles[2] = pQAV->frames[10].tiles[0]; + pQAV->frames[10].tiles[0].picnum = -1; + + // For frames 10 till end, swap tile indices 0 and 1. + for (i = 10; i < pQAV->nFrames; i++) + { + backup = pQAV->frames[i].tiles[1]; + pQAV->frames[i].tiles[1] = pQAV->frames[i].tiles[0]; + pQAV->frames[i].tiles[0] = backup; + } + break; default: return; } From a03848d1f839e23a9b1af83316316b6dfdd0c6ca Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 14 Aug 2021 08:23:35 +1000 Subject: [PATCH 78/89] - Blood: Add interpolation repair for `kQAVSTAFIRE4` (res_id: 116). --- source/games/blood/src/qav.cpp | 63 ++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 2a585ba0a..2993943d2 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -1291,6 +1291,69 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[i].tiles[0] = backup; } break; + case kQAVSTAFIRE4: + // STAFIRE4 requires several index swaps to repair interpolations. + // For frames 0-4, move tile index 0 to 1, and disable original index of 0. + for (i = 0; i < 5; i++) + { + pQAV->frames[i].tiles[1] = pQAV->frames[i].tiles[0]; + pQAV->frames[i].tiles[0].picnum = -1; + } + + // For frames 10 and 13, swap tile indices 0 and 1 around. + for (i = 10; i < 14; i += 3) + { + backup = pQAV->frames[i].tiles[0]; + pQAV->frames[i].tiles[0] = pQAV->frames[i].tiles[1]; + pQAV->frames[i].tiles[1] = backup; + } + + // For frame 16, move tile index 7 into 4, and disable original index of 7. + pQAV->frames[16].tiles[4] = pQAV->frames[16].tiles[7]; + pQAV->frames[16].tiles[7].picnum = -1; + + // For frames 21-22, move tile index 6 to 7, and disable original index of 6. + for (i = 21; i < 23; i++) + { + pQAV->frames[i].tiles[7] = pQAV->frames[i].tiles[6]; + pQAV->frames[i].tiles[6].picnum = -1; + } + + // For frames 22-23, move tile indices 6 and 7 across one frame. + for (i = 23; i > 21; i--) + { + for (j = 6; j < 8; j++) + { + pQAV->frames[i+1].tiles[j] = pQAV->frames[i].tiles[j]; + pQAV->frames[i].tiles[j].picnum = -1; + } + } + + // Move frame 24 tile 5 to frame 25 tile 5, and disable original index. + pQAV->frames[25].tiles[5] = pQAV->frames[24].tiles[5]; + pQAV->frames[24].tiles[5].picnum = -1; + + // For frames 28-30 , move tile index 1 and 2 to 5 and 6, and disable original indices. + for (i = 28; i < 31; i++) + { + for (j = 1; j < 3; j++) + { + pQAV->frames[i].tiles[j+4] = pQAV->frames[i].tiles[j]; + pQAV->frames[i].tiles[j].picnum = -1; + } + } + + // For frames 32 until the end, move tile index 0 to 1, and disable original index of 0. + for (i = 32; i < pQAV->nFrames; i++) + { + pQAV->frames[i].tiles[1] = pQAV->frames[i].tiles[0]; + pQAV->frames[i].tiles[0].picnum = -1; + } + + // For frame 32, change tile 0 picnum to 3317 and set angle to 128. + pQAV->frames[32].tiles[1].picnum = 3317; + pQAV->frames[32].tiles[1].angle = 128; + break; default: return; } From 7e8ec89a68d2fc6608b067d8fac19c461a4d4103 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 14 Aug 2021 08:35:43 +1000 Subject: [PATCH 79/89] - Blood: Add interpolation repair for `kQAVSTAFDOWN` (res_id: 119). --- source/games/blood/src/qav.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 2993943d2..fb1dec22c 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -1354,6 +1354,16 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[32].tiles[1].picnum = 3317; pQAV->frames[32].tiles[1].angle = 128; break; + case kQAVSTAFDOWN: + // STAFDOWN interpolates fine, but the starting frame in bringing the can down is lower than the can while idle. + // Do linear interpolation from 2nd last frame through to first frame, ending with coordinates of STAFIDLE. + lastframe = pQAV->nFrames - 1; + for (i = lastframe, j = 0; i >= 0; i--, j++) + { + pQAV->frames[j].tiles[0].x = xs_CRoundToInt(pQAV->frames[lastframe].tiles[0].x - (double(pQAV->frames[lastframe].tiles[0].x - -90) / lastframe) * i); + pQAV->frames[j].tiles[0].y = xs_CRoundToInt(pQAV->frames[lastframe].tiles[0].y - (double(pQAV->frames[lastframe].tiles[0].y - -50) / lastframe) * i); + } + break; default: return; } From 2edbd3447cfb3753d57605c6169a3bd4e9a71c08 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sun, 22 Aug 2021 10:55:01 +1000 Subject: [PATCH 80/89] - Blood: Extend interpolation properties for `kQAVBUNFUSE` (res_id: 21) to stop interpolating all tiles after frame 6 and not just tile index 4. --- source/games/blood/src/qav.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index fb1dec22c..f3b492bd3 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -196,7 +196,10 @@ void qavBuildInterpProps(QAV* const pQAV) qavInterpProps.Insert(pQAV->res_id, std::move(interp)); for (int i = 6; i < pQAV->nFrames; i++) { - qavSetNonInterpFrameTile(pQAV->res_id, i, 4); + for (int j = 0; j < 7; j++) + { + qavSetNonInterpFrameTile(pQAV->res_id, i, j); + } } break; } From 6256de8013ea558fc41973f98840419340736d78 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sun, 22 Aug 2021 11:23:29 +1000 Subject: [PATCH 81/89] - Blood: Extend interpolation repair for `kQAVBUNUP` (res_id: 16) to add missing tile in first frame. --- source/games/blood/src/qav.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index f3b492bd3..81deecd46 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -503,6 +503,11 @@ static void qavRepairTileData(QAV* pQAV) pQAV->frames[0].tiles[3] = pQAV->frames[0].tiles[0]; pQAV->frames[0].tiles[0].picnum = -1; + // Clone 2nd frame's tile index 2 into 1st frame and adjust x/y coordinates using difference between 1st and 2nd frame's tile index 3. + pQAV->frames[0].tiles[2] = pQAV->frames[1].tiles[2]; + pQAV->frames[0].tiles[2].x += pQAV->frames[0].tiles[3].x - pQAV->frames[1].tiles[3].x; + pQAV->frames[0].tiles[2].y += pQAV->frames[0].tiles[3].y - pQAV->frames[1].tiles[3].y; + // Shift every tile up one index to leave more room at the end, should it be needed in the future. for (i = 0; i < pQAV->nFrames; i++) { From a681aad2819714fd8ca6c18f9488c85c3135d9ad Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sun, 22 Aug 2021 15:03:20 +1000 Subject: [PATCH 82/89] - Blood: Add interpolation repair and properties for `kQAVLITEFLAM` (res_id: 5). --- source/games/blood/src/qav.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 81deecd46..c4f0776a3 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -171,6 +171,14 @@ void qavBuildInterpProps(QAV* const pQAV) } case kQAVLITEFLAM: { + QAVInterpProps interp{}; + interp.flags = 0; + interp.PrevTileFinder = qavGetInterpType("interpolate-index"); + qavInterpProps.Insert(pQAV->res_id, std::move(interp)); + for (int i = 3; i < pQAV->nFrames; i++) + { + qavSetNonInterpFrameTile(pQAV->res_id, i, 1); + } break; } case kQAVCANFIRE2: @@ -447,6 +455,15 @@ static void qavRepairTileData(QAV* pQAV) switch (pQAV->res_id) { + case kQAVLITEFLAM: + // LITEFLAM doesn't look right when interpolating. Move frames around to cause it not to interpolate. + // Move frames 1 and 2 tile 0 to tile 1 and disable original index of 0. + for (i = 1; i < 3; i++) + { + pQAV->frames[i].tiles[1] = pQAV->frames[i].tiles[0]; + pQAV->frames[i].tiles[0].picnum = -1; + } + break; case kQAVCANDOWN: // CANDOWN interpolates fine, but the starting frame in bringing the can down is lower than the can while idle. // Do linear interpolation from 2nd last frame through to first frame, ending with coordinates of CANIDLE. From 907e0974e96a592d4bba99a3839354533d524b1b Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 14 Aug 2021 23:48:52 +1000 Subject: [PATCH 83/89] - Add `GetLongName()` method to `FileSystem` class. --- source/common/filesystem/filesystem.cpp | 6 ++++++ source/common/filesystem/filesystem.h | 1 + 2 files changed, 7 insertions(+) diff --git a/source/common/filesystem/filesystem.cpp b/source/common/filesystem/filesystem.cpp index 4c5a5b910..1bf8c2f5a 100644 --- a/source/common/filesystem/filesystem.cpp +++ b/source/common/filesystem/filesystem.cpp @@ -899,6 +899,12 @@ LumpShortName& FileSystem::GetShortName(int i) return FileInfo[i].shortName; } +FString& FileSystem::GetLongName(int i) +{ + if ((unsigned)i >= NumEntries) I_Error("GetShortName: Invalid index"); + return FileInfo[i].longName; +} + void FileSystem::RenameFile(int num, const char* newfn) { if ((unsigned)num >= NumEntries) I_Error("RenameFile: Invalid index"); diff --git a/source/common/filesystem/filesystem.h b/source/common/filesystem/filesystem.h index 89cc288d3..5924e86c1 100644 --- a/source/common/filesystem/filesystem.h +++ b/source/common/filesystem/filesystem.h @@ -117,6 +117,7 @@ public: } LumpShortName& GetShortName(int i); // may only be called before the hash chains are set up. + FString& GetLongName(int i); // may only be called before the hash chains are set up. void RenameFile(int num, const char* fn); bool CreatePathlessCopy(const char* name, int id, int flags); From 499e400cdbf03bf54095464b11d1e200306a4ad6 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sun, 22 Aug 2021 15:22:45 +1000 Subject: [PATCH 84/89] - Blood: Add command-line switch to dump repaired QAVs back out to disk so that they can be included in raze.pk3. * This required restoring the original struct temporarily to ensure contents dumped to disk were 1:1 with how they came in. --- source/games/blood/src/qav.cpp | 59 ++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index c4f0776a3..15dc3d687 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -448,12 +448,13 @@ void qavProcessTimer(PLAYER* const pPlayer, QAV* const pQAV, int* duration, doub } } -static void qavRepairTileData(QAV* pQAV) +template +static void qavRepairTileData(T* pQAV, int const res_id) { int i, j, lastframe; TILE_FRAME backup; - switch (pQAV->res_id) + switch (res_id) { case kQAVLITEFLAM: // LITEFLAM doesn't look right when interpolating. Move frames around to cause it not to interpolate. @@ -1394,6 +1395,25 @@ static void qavRepairTileData(QAV* pQAV) } } +#pragma pack(push, 1) + +struct QAV2 +{ + char pad1[8]; // 0 + int nFrames; // 8 + int ticksPerFrame; // C + int duration; // 10 + int x; // 14 + int y; // 18 + int nSprite; // 1c + //SPRITE *pSprite; // 1c + char pad3[3]; // 20 + char lastframetic; + FRAMEINFO frames[1]; // 24 +}; + +#pragma pack(pop) + // This is to eliminate a huge design issue in NBlood that was apparently copied verbatim from the DOS-Version. // Sequences were cached in the resource and directly returned from there in writable form, with byte swapping directly performed in the cache on Big Endian systems. @@ -1457,11 +1477,44 @@ QAV* getQAV(int res_id) qavdata->ticrate = 120. / qavdata->ticksPerFrame; // Repair tile data here for now until we export all repaired QAVs. - qavRepairTileData(qavdata); + qavRepairTileData(qavdata, res_id); // Build QAVInterpProps struct here for now until we get DEF loading going. qavBuildInterpProps(qavdata); + auto fr2 = fileSystem.OpenFileReader(index); + auto qavdata2 = (QAV2*)seqcache.Alloc(fr2.GetLength()); + fr2.Read(qavdata2, fr2.GetLength()); + qavRepairTileData(qavdata2, res_id); + + // Erase all data for all tiles that don't have a valid picnum. + for (int i = 0; i < qavdata2->nFrames; i++) + { + for (int j = 0; j < 8; j++) + { + if (qavdata2->frames[i].tiles[j].picnum <= 0) + { + qavdata2->frames[i].tiles[j].picnum = 0; + qavdata2->frames[i].tiles[j].x = 0; + qavdata2->frames[i].tiles[j].y = 0; + qavdata2->frames[i].tiles[j].z = 0; + qavdata2->frames[i].tiles[j].stat = 0; + qavdata2->frames[i].tiles[j].shade = 0; + qavdata2->frames[i].tiles[j].palnum = 0; + qavdata2->frames[i].tiles[j].angle = 0; + } + } + } + + FString filename = fileSystem.GetLongName(index); + filename.AppendFormat(".%d", res_id); + FILE* f = fopen(filename.GetChars(), "wb"); + if (f) + { + fwrite(qavdata2, 1, fr2.GetLength(), f); + fclose(f); + } + qavcache.Insert(res_id, qavdata); return qavdata; } From da78160cd1f711ae2a4bbb254e7baa178134883a Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sun, 22 Aug 2021 21:20:06 +1000 Subject: [PATCH 85/89] - Blood: Revert code to dump out QAVs to disk and remove all hard-coded interpolation repairs. --- source/games/blood/src/qav.cpp | 1175 +------------------------------- 1 file changed, 1 insertion(+), 1174 deletions(-) diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 15dc3d687..314b0d104 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -83,180 +83,12 @@ static void qavInitTileFinderMap() qavPrevTileFinders.Insert("interpolate", *qavPrevTileFinders.CheckKey("interpolate-picnum")); } -static bool qavCanInterpFrameTile(const int& res_id, const int& nFrame, const int& i) -{ - // Check whether this QAV has skippable tiles. - auto thisQAV = qavSkippedFrameTiles.CheckKey(res_id); - if (thisQAV) - { - // Check whether the current frame's tile is skippable. - auto thisFrame = thisQAV->CheckKey(nFrame); - if (thisFrame) - { - return !thisFrame->Contains(i); - } - } - - // Return true by default. - return true; -} - QAVPrevTileFinder qavGetInterpType(const FString& type) { if (!qavPrevTileFinders.CountUsed()) qavInitTileFinderMap(); return *qavPrevTileFinders.CheckKey(type); } -void qavSetNonInterpFrameTile(const int& res_id, const int& nFrame, const int& i) -{ - // Check whether incoming resource is already in TMap. - auto thisQAV = qavSkippedFrameTiles.CheckKey(res_id); - if (!thisQAV) - { - TMap> framemap; - qavSkippedFrameTiles.Insert(res_id, std::move(framemap)); - thisQAV = qavSkippedFrameTiles.CheckKey(res_id); - } - - // Check whether this resource's TMap has a frame TMap. - auto thisFrame = thisQAV->CheckKey(nFrame); - if (!thisFrame) - { - TArray tilearray; - thisQAV->Insert(nFrame, std::move(tilearray)); - thisFrame = thisQAV->CheckKey(nFrame); - } - - // Check whether the TArray in this frame's TMap already contains the tile. - if (!thisFrame->Contains(i)) - { - thisFrame->Push(i); - } - - return; -} - -void qavBuildInterpProps(QAV* const pQAV) -{ - switch (pQAV->res_id) - { - case kQAVBDRIP: - { - QAVInterpProps interp{}; - interp.flags |= true << kQAVIsLoopable; - interp.PrevTileFinder = qavGetInterpType("interpolate-x"); - qavInterpProps.Insert(pQAV->res_id, std::move(interp)); - for (int i = 0; i < pQAV->nFrames; i++) - { - qavSetNonInterpFrameTile(pQAV->res_id, i, 0); - } - break; - } - case kQAVPFORK: - case kQAVREMIDLE1: - case kQAVREMIDLE2: - case kQAVFLARFIR2: - case kQAVTOMSPRED: - case kQAV2TOMALT: - case kQAVSGUNFIR1: - case kQAV2SGUNFIR: - case kQAVNAPFIRE: - case kQAVVDIDLE2: - { - QAVInterpProps interp{}; - interp.flags |= true << kQAVIsLoopable; - interp.PrevTileFinder = qavGetInterpType("interpolate-index"); - qavInterpProps.Insert(pQAV->res_id, std::move(interp)); - break; - } - case kQAVLITEFLAM: - { - QAVInterpProps interp{}; - interp.flags = 0; - interp.PrevTileFinder = qavGetInterpType("interpolate-index"); - qavInterpProps.Insert(pQAV->res_id, std::move(interp)); - for (int i = 3; i < pQAV->nFrames; i++) - { - qavSetNonInterpFrameTile(pQAV->res_id, i, 1); - } - break; - } - case kQAVCANFIRE2: - { - QAVInterpProps interp{}; - interp.flags = 0; - interp.PrevTileFinder = qavGetInterpType("interpolate-index"); - qavInterpProps.Insert(pQAV->res_id, std::move(interp)); - for (int i = 14; i < pQAV->nFrames; i++) - { - for (int j = 2; j < 4; j++) - { - qavSetNonInterpFrameTile(pQAV->res_id, i, j); - } - } - break; - } - case kQAVBUNFUSE: - { - QAVInterpProps interp{}; - interp.flags = 0; - interp.PrevTileFinder = qavGetInterpType("interpolate-index"); - qavInterpProps.Insert(pQAV->res_id, std::move(interp)); - for (int i = 6; i < pQAV->nFrames; i++) - { - for (int j = 0; j < 7; j++) - { - qavSetNonInterpFrameTile(pQAV->res_id, i, j); - } - } - break; - } - case kQAVSHOTL1: - { - QAVInterpProps interp{}; - interp.flags = 0; - interp.PrevTileFinder = qavGetInterpType("interpolate-picnum"); - qavInterpProps.Insert(pQAV->res_id, std::move(interp)); - break; - } - case kQAVTOMFIRE: - { - QAVInterpProps interp{}; - interp.flags |= true << kQAVIsLoopable; - interp.PrevTileFinder = qavGetInterpType("interpolate-index"); - qavInterpProps.Insert(pQAV->res_id, std::move(interp)); - for (int i = 0; i < pQAV->nFrames; i++) - { - qavSetNonInterpFrameTile(pQAV->res_id, i, 0); - } - break; - } - case kQAV2TOMFIRE: - { - QAVInterpProps interp{}; - interp.flags |= true << kQAVIsLoopable; - interp.PrevTileFinder = qavGetInterpType("interpolate-index"); - qavInterpProps.Insert(pQAV->res_id, std::move(interp)); - for (int i = 0; i < pQAV->nFrames; i++) - { - for (int j = 0; j < 3; j += 2) - { - qavSetNonInterpFrameTile(pQAV->res_id, i, j); - } - } - break; - } - default: - { - QAVInterpProps interp{}; - interp.flags = 0; - interp.PrevTileFinder = qavGetInterpType("interpolate-index"); - qavInterpProps.Insert(pQAV->res_id, std::move(interp)); - break; - } - } -} - void DrawFrame(double x, double y, double z, double a, TILE_FRAME *pTile, int stat, int shade, int palnum, bool to3dview) { @@ -315,7 +147,7 @@ void QAV::Draw(double x, double y, int ticks, int stat, int shade, int palnum, b if (thisFrame->tiles[i].picnum > 0) { TILE_FRAME* const thisTile = &thisFrame->tiles[i]; - TILE_FRAME* const prevTile = interpolate && qavCanInterpFrameTile(res_id, nFrame, i) ? interpdata->PrevTileFinder(thisFrame, prevFrame, i) : nullptr; + TILE_FRAME* const prevTile = interpolate ? interpdata->PrevTileFinder(thisFrame, prevFrame, i) : nullptr; double tileX = x; double tileY = y; @@ -448,972 +280,6 @@ void qavProcessTimer(PLAYER* const pPlayer, QAV* const pQAV, int* duration, doub } } -template -static void qavRepairTileData(T* pQAV, int const res_id) -{ - int i, j, lastframe; - TILE_FRAME backup; - - switch (res_id) - { - case kQAVLITEFLAM: - // LITEFLAM doesn't look right when interpolating. Move frames around to cause it not to interpolate. - // Move frames 1 and 2 tile 0 to tile 1 and disable original index of 0. - for (i = 1; i < 3; i++) - { - pQAV->frames[i].tiles[1] = pQAV->frames[i].tiles[0]; - pQAV->frames[i].tiles[0].picnum = -1; - } - break; - case kQAVCANDOWN: - // CANDOWN interpolates fine, but the starting frame in bringing the can down is lower than the can while idle. - // Do linear interpolation from 2nd last frame through to first frame, ending with coordinates of CANIDLE. - lastframe = pQAV->nFrames - 1; - for (i = lastframe, j = 0; i >= 0; i--, j++) - { - pQAV->frames[j].tiles[2].x = xs_CRoundToInt(pQAV->frames[lastframe].tiles[2].x - (double(pQAV->frames[lastframe].tiles[2].x - 11) / lastframe) * i); - pQAV->frames[j].tiles[2].y = xs_CRoundToInt(pQAV->frames[lastframe].tiles[2].y - (double(pQAV->frames[lastframe].tiles[2].y - -28) / lastframe) * i); - } - break; - case kQAVCANFIRE2: - // Handle some index swaps and cripple interpolation after 14th frame. - // Swap tile indices 1 and 2 around for frame's 0 and 1. - for (i = 0; i < 2; i++) - { - backup = pQAV->frames[i].tiles[2]; - pQAV->frames[i].tiles[2] = pQAV->frames[i].tiles[1]; - pQAV->frames[i].tiles[1] = backup; - } - - // Move what's now frame 0 tile 2 to tile 3 and disable original index of 2; - pQAV->frames[0].tiles[3] = pQAV->frames[0].tiles[2]; - pQAV->frames[0].tiles[2].picnum = -1; - - // For frame 11 until the end, move frame indices 0 and 1 to 2 and 3 respectively, and disable the original indices. - for (i = 11; i < pQAV->nFrames; i++) - { - pQAV->frames[i].tiles[2] = pQAV->frames[i].tiles[0]; - pQAV->frames[i].tiles[0].picnum = -1; - pQAV->frames[i].tiles[3] = pQAV->frames[i].tiles[1]; - pQAV->frames[i].tiles[1].picnum = -1; - } - break; - case kQAVBUNUP: - // BUNUP has several tile indices that require repairs here to minimise continual checks at draw time. - // For the 4th frame, clone tile indices 5 and 6 into 2 and 3 respectively where they should have been. - for (i = 5; i < 7; i++) - { - pQAV->frames[3].tiles[i - 3] = pQAV->frames[3].tiles[i]; - pQAV->frames[3].tiles[i].picnum = -1; - } - - // For the 2nd frame, clone tile indices 3 and 4 into 2 and 3 respectively where they should have been. - for (i = 3; i < 5; i++) - { - pQAV->frames[1].tiles[i - 1] = pQAV->frames[1].tiles[i]; - } - - // Clone 1st frame's tile index 2 to tile index 4 for 1st and 2nd frame, then disable original index of 2. - pQAV->frames[1].tiles[4] = pQAV->frames[0].tiles[4] = pQAV->frames[0].tiles[2]; - pQAV->frames[0].tiles[2].picnum = -1; - - // Clone 1st frame's tile index 0 to tile index 3, then disable original index of 0. - pQAV->frames[0].tiles[3] = pQAV->frames[0].tiles[0]; - pQAV->frames[0].tiles[0].picnum = -1; - - // Clone 2nd frame's tile index 2 into 1st frame and adjust x/y coordinates using difference between 1st and 2nd frame's tile index 3. - pQAV->frames[0].tiles[2] = pQAV->frames[1].tiles[2]; - pQAV->frames[0].tiles[2].x += pQAV->frames[0].tiles[3].x - pQAV->frames[1].tiles[3].x; - pQAV->frames[0].tiles[2].y += pQAV->frames[0].tiles[3].y - pQAV->frames[1].tiles[3].y; - - // Shift every tile up one index to leave more room at the end, should it be needed in the future. - for (i = 0; i < pQAV->nFrames; i++) - { - for (j = 1; j < 5; j++) - { - pQAV->frames[i].tiles[j - 1] = pQAV->frames[i].tiles[j]; - pQAV->frames[i].tiles[j].picnum = -1; - } - } - break; - case kQAVBUNDOWN: - // BUNDOWN requires some tile index swaps to be cleaned up to avoid using our own callback. - // For frames 3 till the end, backup tile index 3, move indices 1 and 2 down, then restore backed up tile index 3 as 1. - for (i = 3; i < pQAV->nFrames; i++) - { - backup = pQAV->frames[i].tiles[3]; - pQAV->frames[i].tiles[3] = pQAV->frames[i].tiles[2]; - pQAV->frames[i].tiles[2] = pQAV->frames[i].tiles[1]; - pQAV->frames[i].tiles[1] = backup; - } - break; - case kQAVBUNUP2: - // BUNUP2 has a few uninterpolatable tiles that need moving, and some index swaps to handle. - // For frame 2, move tile index 1 to 3 and disable original index of 1. - pQAV->frames[2].tiles[3] = pQAV->frames[2].tiles[1]; - pQAV->frames[2].tiles[1].picnum = -1; - - // For frame 7, move tile index 1 into 6, 2 into 1 and 3 into 2, then disable the original index of 3. - pQAV->frames[7].tiles[6] = pQAV->frames[7].tiles[1]; - pQAV->frames[7].tiles[1] = pQAV->frames[7].tiles[2]; - pQAV->frames[7].tiles[2] = pQAV->frames[7].tiles[3]; - pQAV->frames[7].tiles[3].picnum = -1; - - // For frame 8, move tile index 1 into 5, 2 into 6, 3 into 1 and 4 into 2, then disable the original index of 4. - pQAV->frames[8].tiles[5] = pQAV->frames[8].tiles[1]; - pQAV->frames[8].tiles[6] = pQAV->frames[8].tiles[2]; - pQAV->frames[8].tiles[1] = pQAV->frames[8].tiles[3]; - pQAV->frames[8].tiles[2] = pQAV->frames[8].tiles[4]; - pQAV->frames[8].tiles[4].picnum = -1; - - // For frame 9, move tile index 1 into 5, 2 into 1 and 3 into 2, then disable the original index of 3. - pQAV->frames[9].tiles[5] = pQAV->frames[9].tiles[1]; - pQAV->frames[9].tiles[1] = pQAV->frames[9].tiles[2]; - pQAV->frames[9].tiles[2] = pQAV->frames[9].tiles[3]; - pQAV->frames[9].tiles[3].picnum = -1; - - // For frames 7 until the end, move indices 5 and 6 into 3 and 4, and disable original indices of 5 and 6. - for (i = 7; i < pQAV->nFrames; i++) - { - for (j = 5; j < 7; j++) - { - pQAV->frames[i].tiles[j - 2] = pQAV->frames[i].tiles[j]; - pQAV->frames[i].tiles[j].picnum = -1; - } - } - break; - case kQAVBUNDOWN2: - // BUNDOWN2 has some tile index swaps that require handling. - // For frames 3 and 4, move tile indices 1 and 2 into 2 and 3, and disable original index of 1. - for (i = 3; i < 5; i++) - { - pQAV->frames[i].tiles[3] = pQAV->frames[i].tiles[2]; - pQAV->frames[i].tiles[2] = pQAV->frames[i].tiles[1]; - pQAV->frames[i].tiles[1].picnum = -1; - } - - // For frame 5, move tile index 1 to 3 and disable original index of 1. - pQAV->frames[5].tiles[3] = pQAV->frames[5].tiles[1]; - pQAV->frames[5].tiles[1].picnum = -1; - break; - case kQAVBUNFUSE: - // BUNFUSE has several tile indices that require repairs here to minimise continual checks at draw time. - // For frame 0, move tile indices 2 and 3 into 3 and 4, and disable original index of 2. - pQAV->frames[0].tiles[4] = pQAV->frames[0].tiles[3]; - pQAV->frames[0].tiles[3] = pQAV->frames[0].tiles[2]; - pQAV->frames[0].tiles[2].picnum = -1; - - // For frame 1, move tile indices 4 and 5 into 3 and 4, and disable original index of 5. - pQAV->frames[1].tiles[3] = pQAV->frames[1].tiles[4]; - pQAV->frames[1].tiles[4] = pQAV->frames[1].tiles[5]; - pQAV->frames[1].tiles[5].picnum = -1; - - // For frame 2, move tile indices 5 and 7 into 3 and 4, and disable original indices. - pQAV->frames[2].tiles[3] = pQAV->frames[2].tiles[5]; - pQAV->frames[2].tiles[4] = pQAV->frames[2].tiles[7]; - pQAV->frames[2].tiles[5].picnum = -1; - pQAV->frames[2].tiles[7].picnum = -1; - - // For frames 0-5, swap tile indices 2 and 4 around. - for (i = 0; i < 6; i++) - { - backup = pQAV->frames[i].tiles[4]; - pQAV->frames[i].tiles[4] = pQAV->frames[i].tiles[2]; - pQAV->frames[i].tiles[2] = backup; - } - break; - case kQAVBUNDROP: - // BUNDROP needs frame 3 tile 1 moved to tile 2 to avoid needing its own interpolation callback. - // For frame 3, move tile index 2 into 3, and disable original index of 2. - pQAV->frames[3].tiles[2] = pQAV->frames[3].tiles[1]; - pQAV->frames[3].tiles[1].picnum = -1; - break; - case kQAVBUNTHRO: - // BUNTHRO has several tile indices that require repairs here to minimise continual checks at draw time. - // For frame 3, move tile indices 0 and 1 into 3 and 2, and disable original indices. - pQAV->frames[3].tiles[3] = pQAV->frames[3].tiles[0]; - pQAV->frames[3].tiles[2] = pQAV->frames[3].tiles[1]; - pQAV->frames[3].tiles[0].picnum = -1; - pQAV->frames[3].tiles[1].picnum = -1; - break; - case kQAVPROXUP: - // PROXUP has several tile indices that require repairs to avoid needing its own interpolation callback. - // Additionally, there are missing frames crucial to a proper interpolation experience. - - // For frame 3, move tile indices 1, 2 and 3 into 0, 1 and 2, and disable original index of 3. - for (i = 0; i < 3; i++) - { - pQAV->frames[3].tiles[i] = pQAV->frames[3].tiles[i + 1]; - } - pQAV->frames[3].tiles[3].picnum = -1; - - // For frame 0, move tile index 0 into 1. - pQAV->frames[0].tiles[1] = pQAV->frames[0].tiles[0]; - - // For frame 0, clone frame 1's tile indices 0 and 2 and adjust x/y coordinates. - // using difference between frame 0 and 1's tile index 1. - for (i = 0; i < 3; i += 2) - { - pQAV->frames[0].tiles[i] = pQAV->frames[1].tiles[i]; - pQAV->frames[0].tiles[i].x += pQAV->frames[0].tiles[1].x - pQAV->frames[1].tiles[1].x; - pQAV->frames[0].tiles[i].y += pQAV->frames[0].tiles[1].y - pQAV->frames[1].tiles[1].y; - } - break; - case kQAVPROXDOWN: - // PROXUP has tile index that require repairs to avoid needing its own interpolation callback. - // Additionally, there are missing frames crucial to a proper interpolation experience. - - // For frame 4, move tile index 0 into 1. - pQAV->frames[4].tiles[1] = pQAV->frames[4].tiles[0]; - - // For frame 4, clone frame 3's tile indices 0 and 2 and adjust x/y coordinates. - // using difference between frame 4 and 3's tile index 1. - for (i = 0; i < 3; i += 2) - { - pQAV->frames[4].tiles[i] = pQAV->frames[3].tiles[i]; - pQAV->frames[4].tiles[i].x += pQAV->frames[4].tiles[1].x - pQAV->frames[3].tiles[1].x; - pQAV->frames[4].tiles[i].y += pQAV->frames[4].tiles[1].y - pQAV->frames[3].tiles[1].y; - } - break; - case kQAVREMUP1: - case kQAVREMUP2: - // REMUP1 and REMUP2 have several tile indices that require repairs to avoid needing their own interpolation callback. - // Additionally, there are missing frames crucial to a proper interpolation experience. - - // For frame 0, move tile index 1 into 2, and disable original index of 1. - pQAV->frames[0].tiles[2] = pQAV->frames[0].tiles[1]; - pQAV->frames[0].tiles[1].picnum = -1; - - // For frame 0, clone frame 1 tile index 1 and adjust x/y coordinates - // using difference between frame 0 and 1's tile index 0. - pQAV->frames[0].tiles[1] = pQAV->frames[1].tiles[1]; - pQAV->frames[0].tiles[1].x += pQAV->frames[0].tiles[0].x - pQAV->frames[1].tiles[0].x; - pQAV->frames[0].tiles[1].y += pQAV->frames[0].tiles[0].y - pQAV->frames[1].tiles[0].y; - - // For frame 2, move tile index 2 and three around. - backup = pQAV->frames[2].tiles[2]; - pQAV->frames[2].tiles[2] = pQAV->frames[2].tiles[3]; - pQAV->frames[2].tiles[3] = backup; - - // For frame 1, clone frame 2 tile index 3 and adjust x/y coordinates - // using difference between frame 1 and 2's tile index 0. - pQAV->frames[1].tiles[3] = pQAV->frames[2].tiles[3]; - pQAV->frames[1].tiles[3].x += pQAV->frames[1].tiles[1].x - pQAV->frames[2].tiles[1].x; - pQAV->frames[1].tiles[3].y += pQAV->frames[1].tiles[1].y - pQAV->frames[2].tiles[1].y; - break; - case kQAVREMDOWN1: - // REMDOWN1 has several tile indices that require repairs to avoid needing its own interpolation callback. - // Additionally, there are missing frames crucial to a proper interpolation experience. - - // For frame 1, move tile index 2 and 3 around. - backup = pQAV->frames[1].tiles[2]; - pQAV->frames[1].tiles[2] = pQAV->frames[1].tiles[3]; - pQAV->frames[1].tiles[3] = backup; - - // For frame 0, clone frame 1 tile index 3 and adjust x/y coordinates - // using difference between frame 0 and 1's tile index 1. - pQAV->frames[0].tiles[3] = pQAV->frames[1].tiles[3]; - pQAV->frames[0].tiles[3].x += pQAV->frames[0].tiles[1].x - pQAV->frames[1].tiles[1].x; - pQAV->frames[0].tiles[3].y += pQAV->frames[0].tiles[1].y - pQAV->frames[1].tiles[1].y; - - // For frame 4, move tile index 1 into 2. - pQAV->frames[4].tiles[2] = pQAV->frames[4].tiles[1]; - - // For frame 5, move tile index 0 into 2. - pQAV->frames[5].tiles[2] = pQAV->frames[5].tiles[0]; - - // Clone frame 3 tile index 0 and 1 into frames 4 and 5, and adjust x/y coordinates - // using difference between frames 4 and 3 and 5 and 4 on looped tile index. - for (i = 4; i < 6; i++) - { - for (j = 0; j < 2; j++) - { - pQAV->frames[i].tiles[j] = pQAV->frames[i - 1].tiles[j]; - pQAV->frames[i].tiles[j].x += pQAV->frames[i - 1].tiles[j].x - pQAV->frames[i - 2].tiles[j].x; - pQAV->frames[i].tiles[j].y += pQAV->frames[i - 1].tiles[j].y - pQAV->frames[i - 2].tiles[j].y; - } - } - break; - case kQAVREMDOWN2: - // REMDOWN2 has several tile indices that require repairs to avoid needing its own interpolation callback. - // Additionally, there are missing frames crucial to a proper interpolation experience. - - // For frame 1, move tile index 2 and 3 around. - backup = pQAV->frames[1].tiles[2]; - pQAV->frames[1].tiles[2] = pQAV->frames[1].tiles[3]; - pQAV->frames[1].tiles[3] = backup; - - // For frame 0, clone frame 1 tile index 3 and adjust x/y coordinates - // using difference between frame 0 and 1's tile index 1. - pQAV->frames[0].tiles[3] = pQAV->frames[1].tiles[3]; - pQAV->frames[0].tiles[3].x += pQAV->frames[0].tiles[1].x - pQAV->frames[1].tiles[1].x; - pQAV->frames[0].tiles[3].y += pQAV->frames[0].tiles[1].y - pQAV->frames[1].tiles[1].y; - - // Clone frame 3 tile index 0, 1, 2, 3 and 4 into frames 4 and 5, and adjust x/y coordinates - // using difference between frames 4 and 3 and 5 and 4 on looped tile index. - for (i = 4; i < 6; i++) - { - for (j = 0; j < 5; j++) - { - pQAV->frames[i].tiles[j] = pQAV->frames[i - 1].tiles[j]; - pQAV->frames[i].tiles[j].x += pQAV->frames[i - 1].tiles[j].x - pQAV->frames[i - 2].tiles[j].x; - pQAV->frames[i].tiles[j].y += pQAV->frames[i - 1].tiles[j].y - pQAV->frames[i - 2].tiles[j].y; - } - } - break; - case kQAVREMDROP: - // REMDROP has several tile indices that require repairs to avoid needing its own interpolation callback. - // Additionally, there are missing frames crucial to a proper interpolation experience. - - // For frame 1, move tile index 2 into 6, and 3 into 2, and disable original index of 3. - pQAV->frames[1].tiles[6] = pQAV->frames[1].tiles[2]; - pQAV->frames[1].tiles[2] = pQAV->frames[1].tiles[3]; - pQAV->frames[1].tiles[3].picnum = -1; - - // Clone frame 3 tile index 0 and 1 into frames 4, and adjust x/y coordinates - // using difference between frames 4 and 3 on looped tile index. - for (j = 0; j < 2; j++) - { - pQAV->frames[4].tiles[j] = pQAV->frames[3].tiles[j]; - pQAV->frames[4].tiles[j].x += pQAV->frames[3].tiles[j].x - pQAV->frames[2].tiles[j].x; - pQAV->frames[4].tiles[j].y += pQAV->frames[3].tiles[j].y - pQAV->frames[2].tiles[j].y; - } - break; - case kQAVREMTHRO: - // REMTHRO has several tile indices that require repairs. - - // For frame 1, swap tile index 2 and 3 around. - backup = pQAV->frames[1].tiles[3]; - pQAV->frames[1].tiles[3] = pQAV->frames[1].tiles[2]; - pQAV->frames[1].tiles[2] = backup; - - // For frame 0, clone frame 1 tile index 3 and adjust x/y coordinates - // using difference between frame 0 and 1's tile index 1. - pQAV->frames[0].tiles[3] = pQAV->frames[1].tiles[3]; - pQAV->frames[0].tiles[3].x += pQAV->frames[0].tiles[1].x - pQAV->frames[1].tiles[1].x; - pQAV->frames[0].tiles[3].y += pQAV->frames[0].tiles[1].y - pQAV->frames[1].tiles[1].y; - - // For frame 4, move tile index 1 into 2, and disable original index of 1. - pQAV->frames[4].tiles[2] = pQAV->frames[4].tiles[1]; - pQAV->frames[4].tiles[1].picnum = -1; - - // For frames 5 until the end, move tile indices 0 and 1 to 2 and 3 respectively, and disable original indices. - for (i = 5; i < pQAV->nFrames; i++) - { - pQAV->frames[i].tiles[3] = pQAV->frames[i].tiles[1]; - pQAV->frames[i].tiles[2] = pQAV->frames[i].tiles[0]; - pQAV->frames[i].tiles[1].picnum = -1; - pQAV->frames[i].tiles[0].picnum = -1; - - } - break; - case kQAVFLARUP: - // FLARUP interpolates fine, but the final frame in bringing the flaregun up is lower than the flaregun while idle. - // Do linear interpolation from 2nd frame through to last frame, ending with coordinates of FLARIDLE. - lastframe = pQAV->nFrames - 1; - for (i = 1; i < pQAV->nFrames; i++) - { - pQAV->frames[i].tiles[0].x = xs_CRoundToInt(pQAV->frames[0].tiles[0].x - (double(pQAV->frames[0].tiles[0].x - 57) / lastframe) * i); - pQAV->frames[i].tiles[0].y = xs_CRoundToInt(pQAV->frames[0].tiles[0].y - (double(pQAV->frames[0].tiles[0].y - -30) / lastframe) * i); - } - break; - case kQAVFLARFIR2: - // FLARFIR2 has several index swaps that require accomodating. - // For frames 4 until end, move tile index 0 to 1 and disable original index of 0. - for (i = 4; i < pQAV->nFrames; i++) - { - pQAV->frames[i].tiles[1] = pQAV->frames[i].tiles[0]; - pQAV->frames[i].tiles[0].picnum = -1; - } - - // For frame 1, move tile indices 1 and 2 into 2 and 3, and disable original index of 1. - pQAV->frames[1].tiles[3] = pQAV->frames[1].tiles[2]; - pQAV->frames[1].tiles[2] = pQAV->frames[1].tiles[1]; - pQAV->frames[1].tiles[1].picnum = -1; - - // For frame 0, move tile indices 0 and 1 into 2 and 4, and disable original indices. - pQAV->frames[0].tiles[4] = pQAV->frames[0].tiles[1]; - pQAV->frames[0].tiles[2] = pQAV->frames[0].tiles[0]; - pQAV->frames[0].tiles[1].picnum = -1; - pQAV->frames[0].tiles[0].picnum = -1; - break; - case kQAVFLARDOWN: - // FLARDOWN interpolates fine, but the starting frame in bringing the flaregun down is lower than the flaregun while idle. - // Do linear interpolation from 2nd last frame through to first frame, ending with coordinates of FLARIDLE. - lastframe = pQAV->nFrames - 1; - for (i = lastframe, j = 0; i >= 0; i--, j++) - { - pQAV->frames[j].tiles[0].x = xs_CRoundToInt(pQAV->frames[lastframe].tiles[0].x - (double(pQAV->frames[lastframe].tiles[0].x - 57) / lastframe) * i); - pQAV->frames[j].tiles[0].y = xs_CRoundToInt(pQAV->frames[lastframe].tiles[0].y - (double(pQAV->frames[lastframe].tiles[0].y - -30) / lastframe) * i); - } - break; - case kQAVFLAR2FIR: - // FLAR2FIR has several index swaps that require accomodating and to ensure it interpolates right. - - // Handle x > 0 side first. - // For frame 0, move tile indices 0 and 1 into 5 and 7, and disable original indices. - pQAV->frames[0].tiles[7] = pQAV->frames[0].tiles[1]; - pQAV->frames[0].tiles[5] = pQAV->frames[0].tiles[0]; - pQAV->frames[0].tiles[1].picnum = -1; - pQAV->frames[0].tiles[0].picnum = -1; - - // For frame 1, move tile indices 1 and 2 into 5 and 6, and disable original indices of 1 and 2. - for (i = 1; i < 3; i++) - { - pQAV->frames[1].tiles[i + 4] = pQAV->frames[1].tiles[i]; - pQAV->frames[1].tiles[i].picnum = -1; - } - - // For frames 2 and 3, move tile index 1 into 7, and disable original index of 1. - for (i = 2; i < 4; i++) - { - pQAV->frames[i].tiles[7] = pQAV->frames[i].tiles[1]; - pQAV->frames[i].tiles[1].picnum = -1; - } - - // For frames 4 until end, move tile index 0 into 7, and disable original index of 0. - for (i = 4; i < pQAV->nFrames; i++) - { - pQAV->frames[i].tiles[7] = pQAV->frames[i].tiles[0]; - pQAV->frames[i].tiles[0].picnum = -1; - } - - // Handle x < 0 now. - // For frame 0, move tile index 2 into 4, and disable the original index of 2. - pQAV->frames[0].tiles[4] = pQAV->frames[0].tiles[2]; - pQAV->frames[0].tiles[2].picnum = -1; - - // For frame 1, move tile index 3 into 4, and disable the original index of 3. - pQAV->frames[1].tiles[4] = pQAV->frames[1].tiles[3]; - pQAV->frames[1].tiles[3].picnum = -1; - - // For frames 2 and 3, move tile index 2 into 4, and disable the original index of 2. - for (i = 2; i < 4; i++) - { - pQAV->frames[i].tiles[4] = pQAV->frames[i].tiles[2]; - pQAV->frames[i].tiles[2].picnum = -1; - } - - // For frame 3, move tile index 3 into 6, and disable the original index of 3. - pQAV->frames[3].tiles[6] = pQAV->frames[3].tiles[3]; - pQAV->frames[3].tiles[3].picnum = -1; - - // For frame 4, move tile indices 2 and 3 into 4 and 5, and disable the original indices of 2 and 3. - for (i = 2; i < 4; i++) - { - pQAV->frames[4].tiles[i + 2] = pQAV->frames[4].tiles[i]; - pQAV->frames[4].tiles[i].picnum = -1; - } - - // For frames 5 and 6, move tile index 2 into 6, and disable the original index of 2. - for (i = 5; i < 7; i++) - { - pQAV->frames[i].tiles[6] = pQAV->frames[i].tiles[2]; - pQAV->frames[i].tiles[2].picnum = -1; - } - - // For frames 7 until end, move tile index 1 into 6, and disable original index of 1. - for (i = 7; i < pQAV->nFrames; i++) - { - pQAV->frames[i].tiles[6] = pQAV->frames[i].tiles[1]; - pQAV->frames[i].tiles[1].picnum = -1; - } - break; - case kQAVSHOTUP: - // SHOTUP is missing tiles for the first two frames. - // Clone from 3rd frame and amend x/y coordinates for tile indices 1 and 2 on frames 0 and 1. - for (i = 0; i < 2; i++) - { - for (j = 1; j < 3; j++) - { - pQAV->frames[i].tiles[j] = pQAV->frames[2].tiles[j]; - pQAV->frames[i].tiles[j].x += pQAV->frames[i].tiles[0].x - pQAV->frames[2].tiles[0].x; - pQAV->frames[i].tiles[j].y += pQAV->frames[i].tiles[0].y - pQAV->frames[2].tiles[0].y; - } - } - break; - case kQAV2SHOTF2: - // 2SHOTF2 has tiles 2630 and 2631 applied when it doesn't need to, - // and is missing a preceding frame of tile 2632 which the non-akimbo version has. - - // Patch left and right side respectively. - pQAV->frames[0].tiles[6] = pQAV->frames[1].tiles[6]; - pQAV->frames[0].tiles[6].x -= pQAV->frames[1].tiles[5].x - pQAV->frames[0].tiles[5].x; - pQAV->frames[0].tiles[6].y -= pQAV->frames[1].tiles[5].y - pQAV->frames[0].tiles[5].y; - pQAV->frames[3].tiles[3] = pQAV->frames[4].tiles[3]; - pQAV->frames[3].tiles[3].x -= pQAV->frames[4].tiles[2].x - pQAV->frames[3].tiles[2].x; - pQAV->frames[3].tiles[3].y -= pQAV->frames[4].tiles[2].y - pQAV->frames[3].tiles[2].y; - - // Stabilise frame 2 tile 2 by using x/y coordindates from next frame. - pQAV->frames[2].tiles[2].x = pQAV->frames[3].tiles[2].x; - pQAV->frames[2].tiles[2].y = pQAV->frames[3].tiles[2].y; - - // Disable frame 0 tile 7. - pQAV->frames[0].tiles[7].picnum = -1; - break; - case kQAV2SHOTFIR: - // 2SHOTFIR has the issues of both SHOTUP and 2SHOTF2, fix both issues. - - // Fix missing tiles for 2630 and 2631 and amend x/y coordinates for 2630 and 2631 for right and left side respectively. - for (i = 8; i < 11; i++) - { - // Use difference from tile 2, it's the same for left and right side. - for (j = 3; j < 5; j++) - { - pQAV->frames[i].tiles[j] = pQAV->frames[11].tiles[j]; - pQAV->frames[i].tiles[j].x += pQAV->frames[i].tiles[2].x - pQAV->frames[11].tiles[2].x; - pQAV->frames[i].tiles[j].y += pQAV->frames[i].tiles[2].y - pQAV->frames[11].tiles[2].y; - } - for (j = 6; j < 8; j++) - { - pQAV->frames[i].tiles[j] = pQAV->frames[11].tiles[j]; - pQAV->frames[i].tiles[j].x -= pQAV->frames[i].tiles[2].x - pQAV->frames[11].tiles[2].x; - pQAV->frames[i].tiles[j].y += pQAV->frames[i].tiles[2].y - pQAV->frames[11].tiles[2].y; - } - } - - // Fix missing tiles for 2632 and patch coordinates on right and left side respectively. - for (i = 3; i < 7; i += 3) - { - pQAV->frames[0].tiles[i] = pQAV->frames[1].tiles[i]; - pQAV->frames[0].tiles[i].x -= pQAV->frames[1].tiles[i - 1].x - pQAV->frames[0].tiles[i - 1].x; - pQAV->frames[0].tiles[i].y -= pQAV->frames[1].tiles[i - 1].y - pQAV->frames[0].tiles[i - 1].y; - } - - // Disable frame 0 tile 4 and tile 7. - pQAV->frames[0].tiles[4].picnum = -1; - pQAV->frames[0].tiles[7].picnum = -1; - break; - case kQAVSGUNUP: - // SGUNUP has a missing frame crucial to proper interpolation experience, so add it back - // in and adjust x/y coordinates using difference between frame 0 and 1's tile index 0. - pQAV->frames[0].tiles[1] = pQAV->frames[1].tiles[1]; - pQAV->frames[0].tiles[1].x -= pQAV->frames[1].tiles[0].x - pQAV->frames[0].tiles[0].x; - pQAV->frames[0].tiles[1].y -= pQAV->frames[1].tiles[0].y - pQAV->frames[0].tiles[0].y; - break; - case kQAVSGUNIDL1: - // SGUNIDL1 has overlay 3232 permanently applied which is at odds with the weapon rising, - // and the other idling QAV. Disable it entirely. - for (i = 0; i < pQAV->nFrames; i++) - { - pQAV->frames[i].tiles[1].picnum = -1; - } - break; - case kQAVSGUNFIR1: - { - // SGUNFIR1's overlay sizes vary from tile to tile and don't interpolate properly. - // Use repaired tiles from Phredreeke where the overlays are baked in. - constexpr int tilearray[8] = { 9301, 9302, 9303, 9304, 9300, 9301, 9302, 3227 }; - - // Loop through each frame to remove overlay and replace use of 3227 with that from tilearray. - for (i = 0; i < pQAV->nFrames; i++) - { - pQAV->frames[i].tiles[0] = pQAV->frames[i].tiles[1]; - pQAV->frames[i].tiles[1] = pQAV->frames[i].tiles[3]; - pQAV->frames[i].tiles[0].picnum = tilearray[i]; - pQAV->frames[i].tiles[2].picnum = -1; - pQAV->frames[i].tiles[3].picnum = -1; - - } - break; - } - case kQAVSGUNFIR4: - { - // SGUNFIR4's overlay sizes vary from tile to tile and don't interpolate properly. - // Use repaired tiles from Phredreeke where the overlays are baked in. - constexpr int tilearray[46] = { 9304, 9304, 9300, 9300, 9301, 9301, 9302, 9302, 9303, 9303, 9304, 9300, 9301, 9302, 9303, 9304, 9300, 9301, 9302, 9303, 9304, 9300, 9301, 9302, 9303, 9304, 9300, 9301, 9302, 9303, 9300, 9302, 9304, 9301, 9303, 9300, 9302, 9304, 9301, 9303, 9301, 9304, 9302, 9300, 9303, 9301 }; - - // Loop through each frame to remove overlay and replace use of 3227 with that from tilearray. - for (i = 0; i < 46; i++) - { - pQAV->frames[i].tiles[0].picnum = tilearray[i]; - pQAV->frames[i].tiles[1].picnum = -1; - } - - // Swap frame 46 index 0 and 1. - backup = pQAV->frames[46].tiles[0]; - pQAV->frames[46].tiles[0] = pQAV->frames[46].tiles[1]; - pQAV->frames[46].tiles[1] = backup; - break; - } - case kQAVSGUNPRE: - // SGUNPRE's overlay sizes vary from tile to tile and don't interpolate properly. - // Use repaired tiles from Phredreeke where the overlays are baked in. - - // For the two last frames, change tile index 0 picnum from 3227 to 9300. - for (i = pQAV->nFrames - 2; i < pQAV->nFrames; i++) - { - pQAV->frames[i].tiles[0].picnum = 9300; - pQAV->frames[i].tiles[2].picnum = -1; - } - break; - case kQAVSGUNPOST: - { - // SGUNPOST's overlay sizes vary from tile to tile and don't interpolate properly. - // Use repaired tiles from Phredreeke where the overlays are baked in. - constexpr int tilearray[8] = { 9301, 9301, 9302, 9302, 9303, 9303, 9304, 9304 }; - - // Loop through each frame to remove overlay and replace use of 3227 with that from tilearray. - for (i = 0; i < pQAV->nFrames; i++) - { - pQAV->frames[i].tiles[1].picnum = tilearray[i]; - pQAV->frames[i].tiles[2].picnum = -1; - - } - break; - } - case kQAV2SGUNUP: - // 2SGUNUP has a missing two frame tiles crucial to proper interpolation experience, so add them back - // in and adjust x/y coordinates using difference between frame 0 and 1's tile index 0 and 2. - for (i = 1; i < 4; i += 2) - { - pQAV->frames[0].tiles[i] = pQAV->frames[1].tiles[i]; - pQAV->frames[0].tiles[i].x -= pQAV->frames[1].tiles[i-1].x - pQAV->frames[0].tiles[i-1].x; - pQAV->frames[0].tiles[i].y -= pQAV->frames[1].tiles[i-1].y - pQAV->frames[0].tiles[i-1].y; - } - - // Set frame 0 tile 3 picnum to 3311. - pQAV->frames[0].tiles[3].picnum = 3311; - break; - case kQAV2SGUNFIR: - { - // 2SGUNFIR's overlay sizes vary from tile to tile and don't interpolate properly. - // Use repaired tiles from Phredreeke where the overlays are baked in. - constexpr int tilearray[2][8] = { - { - 9306, 9307, 9308, 9309, 9305, 9306, 9307, 3240 - }, - { - 3240, 9307, 9306, 9305, 9309, 9308, 9307, 9306 - } - }; - - // Loop through each frame to remove overlay and replace use of 3240 with that from tilearray and disable overlays. - for (i = 0; i < pQAV->nFrames; i++) - { - pQAV->frames[i].tiles[0].picnum = tilearray[0][i]; - pQAV->frames[i].tiles[4].picnum = -1; - - pQAV->frames[i].tiles[2].picnum = tilearray[1][i]; - pQAV->frames[i].tiles[5].picnum = -1; - } - break; - } - case kQAV2SGUNALT: - { - // 2SGUNALT's overlay sizes vary from tile to tile and don't interpolate properly. - // Use repaired tiles from Phredreeke where the overlays are baked in. - constexpr int tilearray[2][30] = { - { - 9309, 9305, 9306, 9307, 9308, 9309, 9305, 9306, 9307, 9308, 9309, 9305, 9306, 9307, 9308, 9309, 9305, 9306, 9307, 9308, 9309, 9305, 9306, 9307, 9308, 9309, 9305, 9306, 9307, 9308 - }, - { - 9308, 9307, 9306, 9305, 9309, 9308, 9307, 9306, 9305, 9309, 9308, 9307, 9306, 9305, 9309, 9308, 9307, 9306, 9305, 9309, 9308, 9307, 9306, 9305, 9309, 9308, 9307, 9306, 9305, 9309 - } - }; - - // Loop through first 30 frames to remove overlay and replace use of 3240 with that from tilearray and disable overlays. - for (i = 0; i < 30; i++) - { - pQAV->frames[i].tiles[0].picnum = tilearray[0][i]; - pQAV->frames[i].tiles[4].picnum = -1; - - pQAV->frames[i].tiles[2].picnum = tilearray[1][i]; - pQAV->frames[i].tiles[5].picnum = -1; - } - - // Disable tiles 1, 3 and 6 on frame 29. - pQAV->frames[29].tiles[1].picnum = pQAV->frames[29].tiles[3].picnum = pQAV->frames[29].tiles[6].picnum = -1; - break; - } - case kQAV2SGUNPRE: - { - // 2SGUNPRE's overlay sizes vary from tile to tile and don't interpolate properly. - // Use repaired tiles from Phredreeke where the overlays are baked in. - constexpr int tilearray[2][30] = { - { - 9305, 9306, 9307, 9308 - }, - { - 9307, 9306, 9305, 9309 - } - }; - - // Loop through all frames to remove overlay and replace use of 3240 with that from tilearray and disable overlays. - for (i = 0; i < pQAV->nFrames; i++) - { - pQAV->frames[i].tiles[0].picnum = tilearray[0][i]; - pQAV->frames[i].tiles[4].picnum = -1; - - pQAV->frames[i].tiles[2].picnum = tilearray[1][i]; - pQAV->frames[i].tiles[5].picnum = -1; - } - break; - } - case kQAVNAPUP: - // This QAV is missing picnum 2351 for the first two frames. Add it in to smooth interpolation. - for (i = 0; i < 2; i++) - { - pQAV->frames[i].tiles[1] = pQAV->frames[2].tiles[1]; - pQAV->frames[i].tiles[1].x += pQAV->frames[i].tiles[0].x - pQAV->frames[2].tiles[0].x; - pQAV->frames[i].tiles[1].y += pQAV->frames[i].tiles[0].y - pQAV->frames[2].tiles[0].y; - pQAV->frames[i].tiles[1].picnum = 2351; - } - break; - case kQAVVDUP: - // VDUP requires tile indices on the last frame to be swapped around. - backup = pQAV->frames[pQAV->nFrames-1].tiles[0]; - pQAV->frames[pQAV->nFrames-1].tiles[0] = pQAV->frames[pQAV->nFrames - 1].tiles[1]; - pQAV->frames[pQAV->nFrames-1].tiles[1] = backup; - break; - case kQAVVDIDLE2: - { - // VDIDLE2 requires several tile indices to be swapped around to fix interpolation. - // For frames 5 and 7, move tile index 2 into 0 and disable the original index of 0. - for (i = 5; i < 8; i += 2) - { - pQAV->frames[i].tiles[0] = pQAV->frames[i].tiles[2]; - pQAV->frames[i].tiles[2].picnum = -1; - } - - // For frames 2-3, swap tile indices 0 and 1 around. - for (i = 2; i < 4; i++) - { - backup = pQAV->frames[i].tiles[0]; - pQAV->frames[i].tiles[0] = pQAV->frames[i].tiles[1]; - pQAV->frames[i].tiles[1] = backup; - } - - // For frames 9 til the end, swap tile indices 0 and 1 around. - for (i = 9; i < pQAV->nFrames; i++) - { - backup = pQAV->frames[i].tiles[0]; - pQAV->frames[i].tiles[0] = pQAV->frames[i].tiles[1]; - pQAV->frames[i].tiles[1] = backup; - } - - // Set frame 1 tile 0 x/y coordinates to that of values between frames 0 and 2. - pQAV->frames[1].tiles[0].x = -29; - pQAV->frames[1].tiles[0].y = -12; - - // Set frame 1 tile 1 y coordinates to that of values between frames 0 and 2. - pQAV->frames[1].tiles[1].y = -45; - - // Set frame 3 tile 1 y coordinates to that of values between frames 2 and 4. - pQAV->frames[3].tiles[1].y = -46; - - // Set frame 5 tile 1 y coordinates to that of values between frames 4 and 6. - pQAV->frames[5].tiles[1].y = -42; - - // Set frame 7 tile 1 y coordinates to that of values between frames 6 and 8. - pQAV->frames[7].tiles[1].y = -41; - - // Set frame 10 tile 1 y coordinates to that of values between frames 9 and 11. - pQAV->frames[10].tiles[1].y = -45; - - // Smooth out tile coordinates between high and low point for tile index 1 x across all frames. High point is frame 0/12, low point is 6. - for (i = 1, j = (pQAV->nFrames - 2); i < 6, j > 6; i++, j--) - { - pQAV->frames[i].tiles[1].x = pQAV->frames[j].tiles[1].x = xs_CRoundToInt(pQAV->frames[0].tiles[1].x - (double(pQAV->frames[0].tiles[1].x - pQAV->frames[6].tiles[1].x) / 6) * i); - } - break; - } - case kQAVVDFIRE1: - case kQAVVDFIRE2: - // VDFIRE1 and VDFIRE2 requires several index swaps to repair interpolations. - // For frame 0, move tile index 1 to 2, and disable original index of 1. - pQAV->frames[0].tiles[2] = pQAV->frames[0].tiles[1]; - pQAV->frames[0].tiles[1].picnum = -1; - - // For frame 1, move tile index 0 to 2 and 1 to 0, and disable original index of 1. - pQAV->frames[0].tiles[2] = pQAV->frames[0].tiles[0]; - pQAV->frames[0].tiles[0] = pQAV->frames[0].tiles[1]; - pQAV->frames[0].tiles[1].picnum = -1; - - // For frame 7, swap tile indices 1 to 2. - backup = pQAV->frames[7].tiles[2]; - pQAV->frames[7].tiles[2] = pQAV->frames[7].tiles[1]; - pQAV->frames[7].tiles[1] = backup; - - // For frame 8-9, move tile index 1 to 2, and disable original index of 1. - for (i = 8; i < 10; i++) - { - pQAV->frames[i].tiles[2] = pQAV->frames[i].tiles[1]; - pQAV->frames[i].tiles[1].picnum = -1; - } - - // For frames 10 till end, move tile index 0 to 2 and 1 to 0, and disable original index of 1. - for (i = 10; i < pQAV->nFrames; i++) - { - pQAV->frames[i].tiles[2] = pQAV->frames[i].tiles[0]; - pQAV->frames[i].tiles[0] = pQAV->frames[i].tiles[1]; - pQAV->frames[i].tiles[1].picnum = -1; - } - break; - case kQAVVDFIRE3: - // VDFIRE3 requires several index swaps to repair interpolations. - // For frame 1, swap tile indices 0 and 1. - backup = pQAV->frames[1].tiles[1]; - pQAV->frames[1].tiles[1] = pQAV->frames[1].tiles[0]; - pQAV->frames[1].tiles[0] = backup; - - // For frames 13 till end, swap tile indices 0 and 1. - for (i = 13; i < pQAV->nFrames; i++) - { - backup = pQAV->frames[i].tiles[1]; - pQAV->frames[i].tiles[1] = pQAV->frames[i].tiles[0]; - pQAV->frames[i].tiles[0] = backup; - } - break; - case kQAVVDFIRE4: - case kQAVVDFIRE5: - // VDFIRE4 and requires several index swaps to repair interpolations. - // For frame 1, swap tile indices 0 and 1. - backup = pQAV->frames[1].tiles[1]; - pQAV->frames[1].tiles[1] = pQAV->frames[1].tiles[0]; - pQAV->frames[1].tiles[0] = backup; - - // For the last two frames, swap tile indices 0 and 1. - for (i = (pQAV->nFrames - 2); i < pQAV->nFrames; i++) - { - backup = pQAV->frames[i].tiles[1]; - pQAV->frames[i].tiles[1] = pQAV->frames[i].tiles[0]; - pQAV->frames[i].tiles[0] = backup; - } - break; - case kQAVVDDOWN: - // VDDOWN requires tile indices on the first frame to be swapped around. - backup = pQAV->frames[0].tiles[0]; - pQAV->frames[0].tiles[0] = pQAV->frames[0].tiles[1]; - pQAV->frames[0].tiles[1] = backup; - break; - case kQAVVDSPEL1: - // VDSPEL1 requires several index swaps to repair interpolations. - // For frame 1, swap tile indices 0 and 1. - backup = pQAV->frames[1].tiles[1]; - pQAV->frames[1].tiles[1] = pQAV->frames[1].tiles[0]; - pQAV->frames[1].tiles[0] = backup; - - // For frame 2, move tile index 2 into 1, and disable original index of 2. - pQAV->frames[2].tiles[1] = pQAV->frames[2].tiles[2]; - pQAV->frames[2].tiles[2].picnum = -1; - - // For frames 7-9 , move tile index 1 to 2, and disable original index of 1. - for (i = 7; i < 10; i++) - { - pQAV->frames[i].tiles[2] = pQAV->frames[i].tiles[1]; - pQAV->frames[i].tiles[1].picnum = -1; - } - - // For frame 10, move tile index 0 into 2, and disable original index of 0. - pQAV->frames[10].tiles[2] = pQAV->frames[10].tiles[0]; - pQAV->frames[10].tiles[0].picnum = -1; - - // For frames 10 till end, swap tile indices 0 and 1. - for (i = 10; i < pQAV->nFrames; i++) - { - backup = pQAV->frames[i].tiles[1]; - pQAV->frames[i].tiles[1] = pQAV->frames[i].tiles[0]; - pQAV->frames[i].tiles[0] = backup; - } - break; - case kQAVSTAFIRE4: - // STAFIRE4 requires several index swaps to repair interpolations. - // For frames 0-4, move tile index 0 to 1, and disable original index of 0. - for (i = 0; i < 5; i++) - { - pQAV->frames[i].tiles[1] = pQAV->frames[i].tiles[0]; - pQAV->frames[i].tiles[0].picnum = -1; - } - - // For frames 10 and 13, swap tile indices 0 and 1 around. - for (i = 10; i < 14; i += 3) - { - backup = pQAV->frames[i].tiles[0]; - pQAV->frames[i].tiles[0] = pQAV->frames[i].tiles[1]; - pQAV->frames[i].tiles[1] = backup; - } - - // For frame 16, move tile index 7 into 4, and disable original index of 7. - pQAV->frames[16].tiles[4] = pQAV->frames[16].tiles[7]; - pQAV->frames[16].tiles[7].picnum = -1; - - // For frames 21-22, move tile index 6 to 7, and disable original index of 6. - for (i = 21; i < 23; i++) - { - pQAV->frames[i].tiles[7] = pQAV->frames[i].tiles[6]; - pQAV->frames[i].tiles[6].picnum = -1; - } - - // For frames 22-23, move tile indices 6 and 7 across one frame. - for (i = 23; i > 21; i--) - { - for (j = 6; j < 8; j++) - { - pQAV->frames[i+1].tiles[j] = pQAV->frames[i].tiles[j]; - pQAV->frames[i].tiles[j].picnum = -1; - } - } - - // Move frame 24 tile 5 to frame 25 tile 5, and disable original index. - pQAV->frames[25].tiles[5] = pQAV->frames[24].tiles[5]; - pQAV->frames[24].tiles[5].picnum = -1; - - // For frames 28-30 , move tile index 1 and 2 to 5 and 6, and disable original indices. - for (i = 28; i < 31; i++) - { - for (j = 1; j < 3; j++) - { - pQAV->frames[i].tiles[j+4] = pQAV->frames[i].tiles[j]; - pQAV->frames[i].tiles[j].picnum = -1; - } - } - - // For frames 32 until the end, move tile index 0 to 1, and disable original index of 0. - for (i = 32; i < pQAV->nFrames; i++) - { - pQAV->frames[i].tiles[1] = pQAV->frames[i].tiles[0]; - pQAV->frames[i].tiles[0].picnum = -1; - } - - // For frame 32, change tile 0 picnum to 3317 and set angle to 128. - pQAV->frames[32].tiles[1].picnum = 3317; - pQAV->frames[32].tiles[1].angle = 128; - break; - case kQAVSTAFDOWN: - // STAFDOWN interpolates fine, but the starting frame in bringing the can down is lower than the can while idle. - // Do linear interpolation from 2nd last frame through to first frame, ending with coordinates of STAFIDLE. - lastframe = pQAV->nFrames - 1; - for (i = lastframe, j = 0; i >= 0; i--, j++) - { - pQAV->frames[j].tiles[0].x = xs_CRoundToInt(pQAV->frames[lastframe].tiles[0].x - (double(pQAV->frames[lastframe].tiles[0].x - -90) / lastframe) * i); - pQAV->frames[j].tiles[0].y = xs_CRoundToInt(pQAV->frames[lastframe].tiles[0].y - (double(pQAV->frames[lastframe].tiles[0].y - -50) / lastframe) * i); - } - break; - default: - return; - } -} - -#pragma pack(push, 1) - -struct QAV2 -{ - char pad1[8]; // 0 - int nFrames; // 8 - int ticksPerFrame; // C - int duration; // 10 - int x; // 14 - int y; // 18 - int nSprite; // 1c - //SPRITE *pSprite; // 1c - char pad3[3]; // 20 - char lastframetic; - FRAMEINFO frames[1]; // 24 -}; - -#pragma pack(pop) - // This is to eliminate a huge design issue in NBlood that was apparently copied verbatim from the DOS-Version. // Sequences were cached in the resource and directly returned from there in writable form, with byte swapping directly performed in the cache on Big Endian systems. @@ -1476,45 +342,6 @@ QAV* getQAV(int res_id) qavdata->res_id = res_id; qavdata->ticrate = 120. / qavdata->ticksPerFrame; - // Repair tile data here for now until we export all repaired QAVs. - qavRepairTileData(qavdata, res_id); - - // Build QAVInterpProps struct here for now until we get DEF loading going. - qavBuildInterpProps(qavdata); - - auto fr2 = fileSystem.OpenFileReader(index); - auto qavdata2 = (QAV2*)seqcache.Alloc(fr2.GetLength()); - fr2.Read(qavdata2, fr2.GetLength()); - qavRepairTileData(qavdata2, res_id); - - // Erase all data for all tiles that don't have a valid picnum. - for (int i = 0; i < qavdata2->nFrames; i++) - { - for (int j = 0; j < 8; j++) - { - if (qavdata2->frames[i].tiles[j].picnum <= 0) - { - qavdata2->frames[i].tiles[j].picnum = 0; - qavdata2->frames[i].tiles[j].x = 0; - qavdata2->frames[i].tiles[j].y = 0; - qavdata2->frames[i].tiles[j].z = 0; - qavdata2->frames[i].tiles[j].stat = 0; - qavdata2->frames[i].tiles[j].shade = 0; - qavdata2->frames[i].tiles[j].palnum = 0; - qavdata2->frames[i].tiles[j].angle = 0; - } - } - } - - FString filename = fileSystem.GetLongName(index); - filename.AppendFormat(".%d", res_id); - FILE* f = fopen(filename.GetChars(), "wb"); - if (f) - { - fwrite(qavdata2, 1, fr2.GetLength(), f); - fclose(f); - } - qavcache.Insert(res_id, qavdata); return qavdata; } From 916241dcdbb3f83ce842cebda51e3def1a571eca Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Mon, 23 Aug 2021 09:00:30 +1000 Subject: [PATCH 86/89] - Blood: Implement `defineqav` DEF parser with hookup to game-side code. --- source/core/defparser.cpp | 162 +++++++++++++++++++++++++++++++++ source/core/gamestruct.h | 3 + source/games/blood/src/blood.h | 3 + source/games/blood/src/qav.cpp | 29 ++++-- source/games/blood/src/qav.h | 8 ++ 5 files changed, 196 insertions(+), 9 deletions(-) diff --git a/source/core/defparser.cpp b/source/core/defparser.cpp index 11c92a3ae..4d8c68a8d 100644 --- a/source/core/defparser.cpp +++ b/source/core/defparser.cpp @@ -40,6 +40,7 @@ #include "buildtiles.h" #include "bitmap.h" #include "m_argv.h" +#include "gamestruct.h" #include "gamecontrol.h" #include "palettecontainer.h" #include "mapinfo.h" @@ -2008,6 +2009,166 @@ void parseModel(FScanner& sc, FScriptPosition& pos) } } + +//=========================================================================== +// +// +// +//=========================================================================== + +static bool parseDefineQAVInterpolateIgnoreBlock(FScanner& sc, const int& res_id, TMap>& ignoredata, const int& numframes) +{ + FScanner::SavedPos blockend; + FScriptPosition pos = sc; + + FString scframes, sctiles; + TArray framearray, tilearray; + + if (sc.StartBraces(&blockend)) + { + pos.Message(MSG_ERROR, "defineqav (%d): interpolate: malformed syntax, unable to continue", res_id); + return false; + } + while (!sc.FoundEndBrace(blockend)) + { + sc.GetString(); + if (sc.Compare("frames")) sc.GetString(scframes); + else if (sc.Compare("tiles")) sc.GetString(sctiles); + } + + // Confirm we received something for 'frames' and 'tiles'. + if (scframes.IsEmpty() || sctiles.IsEmpty()) + { + pos.Message(MSG_ERROR, "defineqav (%d): interpolate: unable to get any values for 'frames' or 'tiles', unable to continue", res_id); + return false; + } + + auto arraybuilder = [&](const FString& input, TArray& output, const int& maxvalue) -> bool + { + // Split input if it is an array, otherwise push the singular value twice. + if (input.IndexOf("-") != -1) + { + auto temparray = input.Split("-"); + for (auto& value : temparray) output.Push(atoi(value)); + } + else + { + auto tempvalue = atoi(input); + for (auto i = 0; i < 2; i++) output.Push(tempvalue); + } + if (output.Size() != 2 || output[0] > output[1] || output[1] > maxvalue) + { + pos.Message(MSG_ERROR, "defineqav (%d): interpolate: ignore: value of '%s' is malformed, unable to continue", res_id, input.GetChars()); + return false; + } + return true; + }; + + if (!arraybuilder(scframes, framearray, numframes - 1)) return false; + if (!arraybuilder(sctiles, tilearray, 7)) return false; + + // Process arrays and add ignored frames as required. + for (auto i = framearray[0]; i <= framearray[1]; i++) + { + auto& frametiles = ignoredata[i]; + for (auto j = tilearray[0]; j <= tilearray[1]; j++) + { + if (!frametiles.Contains(j)) frametiles.Push(j); + } + } + return true; +} + +static bool parseDefineQAVInterpolateBlock(FScanner& sc, const int& res_id, const int& numframes) +{ + FScanner::SavedPos blockend; + FScriptPosition pos = sc; + + FString interptype; + bool loopable = false; + TMap> ignoredata; + + if (sc.StartBraces(&blockend)) + { + pos.Message(MSG_ERROR, "defineqav (%d): interpolate (%s): malformed syntax, unable to continue", res_id, interptype.GetChars()); + return false; + } + while (!sc.FoundEndBrace(blockend)) + { + sc.GetString(); + if (sc.Compare("type")) + { + sc.GetString(interptype); + if (!gi->IsQAVInterpTypeValid(interptype)) + { + pos.Message(MSG_ERROR, "defineqav (%d): interpolate (%s): interpolation type not found", res_id, interptype.GetChars()); + return false; + } + } + else if (sc.Compare("loopable")) loopable = true; + else if (sc.Compare("ignore")) if (!parseDefineQAVInterpolateIgnoreBlock(sc, res_id, ignoredata, numframes)) return false; + } + + // Add interpolation properties to game for processing while drawing. + gi->AddQAVInterpProps(res_id, interptype, loopable, ignoredata); + return true; +} + +void parseDefineQAV(FScanner& sc, FScriptPosition& pos) +{ + FScanner::SavedPos blockend; + FString fn; + int res_id = -1; + int numframes = -1; + bool interpolate = false; + + if (!sc.GetNumber(res_id, true)) + { + pos.Message(MSG_ERROR, "defineqav: invalid or non-defined resource ID"); + return; + } + + if (sc.StartBraces(&blockend)) + { + pos.Message(MSG_ERROR, "defineqav (%d): malformed syntax, unable to continue", res_id); + return; + } + while (!sc.FoundEndBrace(blockend)) + { + sc.MustGetString(); + if (sc.Compare("file")) + { + sc.GetString(fn); + + // Test file's validity. + FixPathSeperator(fn); + auto lump = fileSystem.FindFile(fn); + if (lump < 0) + { + pos.Message(MSG_ERROR, "defineqav (%d): file '%s' could not be found", res_id, fn.GetChars()); + return; + } + + // Read file to get number of frames from QAV, skipping first 8 bytes. + auto fr = fileSystem.OpenFileReader(lump); + fr.ReadUInt64(); + numframes = fr.ReadInt32(); + } + else if (sc.Compare("interpolate")) + { + interpolate = true; + if (!parseDefineQAVInterpolateBlock(sc, res_id, numframes)) return; + } + } + + // If we're not interpolating, remove any reference to interpolation data for this res_id. + if (!interpolate) gi->RemoveQAVInterpProps(res_id); + + // Add new file to filesystem. + fileSystem.CreatePathlessCopy(fn, res_id, 0); +} + + //=========================================================================== // // @@ -2098,6 +2259,7 @@ static const dispatch basetokens[] = { "shadefactor", parseSkip<1> }, { "newgamechoices", parseEmptyBlock }, { "rffdefineid", parseRffDefineId }, + { "defineqav", parseDefineQAV }, { nullptr, nullptr }, }; diff --git a/source/core/gamestruct.h b/source/core/gamestruct.h index 5b864412b..c1212b088 100644 --- a/source/core/gamestruct.h +++ b/source/core/gamestruct.h @@ -122,6 +122,9 @@ struct GameInterface virtual int Voxelize(int sprnum) { return -1; } virtual void AddExcludedEpisode(FString episode) {} virtual int GetCurrentSkill() { return -1; } + virtual bool IsQAVInterpTypeValid(const FString& type) { return false; } + virtual void AddQAVInterpProps(const int& res_id, const FString& interptype, const bool& loopable, const TMap>& ignoredata) { } + virtual void RemoveQAVInterpProps(const int& res_id) { } virtual FString statFPS() { diff --git a/source/games/blood/src/blood.h b/source/games/blood/src/blood.h index 69b92a1e2..33d012bb6 100644 --- a/source/games/blood/src/blood.h +++ b/source/games/blood/src/blood.h @@ -150,6 +150,9 @@ struct GameInterface : public ::GameInterface void LeavePortal(spritetype* viewer, int type) override; void LoadGameTextures() override; int GetCurrentSkill() override; + bool IsQAVInterpTypeValid(const FString& type) override; + void AddQAVInterpProps(const int& res_id, const FString& interptype, const bool& loopable, const TMap>& ignoredata) override; + void RemoveQAVInterpProps(const int& res_id) override; GameStats getStats() override; }; diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 314b0d104..874726c55 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -46,23 +46,22 @@ enum }; static TMap qavPrevTileFinders; -static TMap>> qavSkippedFrameTiles; static TMap qavInterpProps; static void qavInitTileFinderMap() { // Interpolate between frames if the picnums match. This is safest but could miss interpolations between suitable picnums. - qavPrevTileFinders.Insert("interpolate-picnum", [](FRAMEINFO* const thisFrame, FRAMEINFO* const prevFrame, const int& i) -> TILE_FRAME* { + qavPrevTileFinders.Insert("picnum", [](FRAMEINFO* const thisFrame, FRAMEINFO* const prevFrame, const int& i) -> TILE_FRAME* { return prevFrame->tiles[i].picnum == thisFrame->tiles[i].picnum ? &prevFrame->tiles[i] : nullptr; }); // Interpolate between frames if the picnum is valid. This can be problematic if tile indices change between frames. - qavPrevTileFinders.Insert("interpolate-index", [](FRAMEINFO* const thisFrame, FRAMEINFO* const prevFrame, const int& i) -> TILE_FRAME* { + qavPrevTileFinders.Insert("index", [](FRAMEINFO* const thisFrame, FRAMEINFO* const prevFrame, const int& i) -> TILE_FRAME* { return prevFrame->tiles[i].picnum > 0 ? &prevFrame->tiles[i] : nullptr; }); // Find previous frame by iterating all previous frame's tiles and return on first matched x coordinate. - qavPrevTileFinders.Insert("interpolate-x", [](FRAMEINFO* const thisFrame, FRAMEINFO* const prevFrame, const int& i) -> TILE_FRAME* { + qavPrevTileFinders.Insert("x", [](FRAMEINFO* const thisFrame, FRAMEINFO* const prevFrame, const int& i) -> TILE_FRAME* { for (int j = 0; j < 8; j++) if (thisFrame->tiles[i].x == prevFrame->tiles[j].x) { return &prevFrame->tiles[j]; @@ -71,16 +70,13 @@ static void qavInitTileFinderMap() }); // Find previous frame by iterating all previous frame's tiles and return on first matched y coordinate. - qavPrevTileFinders.Insert("interpolate-y", [](FRAMEINFO* const thisFrame, FRAMEINFO* const prevFrame, const int& i) -> TILE_FRAME* { + qavPrevTileFinders.Insert("y", [](FRAMEINFO* const thisFrame, FRAMEINFO* const prevFrame, const int& i) -> TILE_FRAME* { for (int j = 0; j < 8; j++) if (thisFrame->tiles[i].y == prevFrame->tiles[j].y) { return &prevFrame->tiles[j]; } return nullptr; }); - - // When type is unspecified, default to using the safest interpolation option. - qavPrevTileFinders.Insert("interpolate", *qavPrevTileFinders.CheckKey("interpolate-picnum")); } QAVPrevTileFinder qavGetInterpType(const FString& type) @@ -89,6 +85,21 @@ QAVPrevTileFinder qavGetInterpType(const FString& type) return *qavPrevTileFinders.CheckKey(type); } +bool GameInterface::IsQAVInterpTypeValid(const FString& type) +{ + return qavGetInterpType(type) != nullptr; +} + +void GameInterface::AddQAVInterpProps(const int& res_id, const FString& interptype, const bool& loopable, const TMap>& ignoredata) +{ + qavInterpProps.Insert(res_id, { loopable << kQAVIsLoopable, qavGetInterpType(interptype), ignoredata }); +} + +void GameInterface::RemoveQAVInterpProps(const int& res_id) +{ + qavInterpProps.Remove(res_id); +} + void DrawFrame(double x, double y, double z, double a, TILE_FRAME *pTile, int stat, int shade, int palnum, bool to3dview) { @@ -147,7 +158,7 @@ void QAV::Draw(double x, double y, int ticks, int stat, int shade, int palnum, b if (thisFrame->tiles[i].picnum > 0) { TILE_FRAME* const thisTile = &thisFrame->tiles[i]; - TILE_FRAME* const prevTile = interpolate ? interpdata->PrevTileFinder(thisFrame, prevFrame, i) : nullptr; + TILE_FRAME* const prevTile = interpolate && interpdata->CanInterpFrameTile(nFrame, i) ? interpdata->PrevTileFinder(thisFrame, prevFrame, i) : nullptr; double tileX = x; double tileY = y; diff --git a/source/games/blood/src/qav.h b/source/games/blood/src/qav.h index 372a6f64f..57a9bed2f 100644 --- a/source/games/blood/src/qav.h +++ b/source/games/blood/src/qav.h @@ -244,6 +244,14 @@ struct QAVInterpProps { int flags; QAVPrevTileFinder PrevTileFinder; + TMap> IgnoreData; + + bool CanInterpFrameTile(const int& nFrame, const int& i) + { + // Check whether the current frame's tile is skippable. + auto thisFrame = IgnoreData.CheckKey(nFrame); + return thisFrame ? !thisFrame->Contains(i) : true; + } }; QAV* getQAV(int res_id); From 5bfdd748440d043989dc23db0e10757786a9f662 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Mon, 23 Aug 2021 09:32:00 +1000 Subject: [PATCH 87/89] - Blood: Revert "- Blood: Ensure looped QAVs interpolate using last frame in the array." --- source/games/blood/src/d_menu.cpp | 12 +++++------- source/games/blood/src/nnexts.cpp | 4 ++-- source/games/blood/src/qav.cpp | 4 ++-- source/games/blood/src/qav.h | 4 ++-- source/games/blood/src/weapon.cpp | 2 +- 5 files changed, 12 insertions(+), 14 deletions(-) diff --git a/source/games/blood/src/d_menu.cpp b/source/games/blood/src/d_menu.cpp index bb553e68b..3be8a729b 100644 --- a/source/games/blood/src/d_menu.cpp +++ b/source/games/blood/src/d_menu.cpp @@ -46,16 +46,14 @@ public: int lastTick; bool bWideScreen; bool bClearBackground; - bool bLooped; - CGameMenuItemQAV(int, int, const char*, bool widescreen = false, bool clearbackground = false, bool looped = false); + CGameMenuItemQAV(int, int, const char*, bool widescreen = false, bool clearbackground = false); void Draw(void); }; -CGameMenuItemQAV::CGameMenuItemQAV(int a3, int a4, const char* name, bool widescreen, bool clearbackground, bool looped) +CGameMenuItemQAV::CGameMenuItemQAV(int a3, int a4, const char* name, bool widescreen, bool clearbackground) { bWideScreen = widescreen; bClearBackground = clearbackground; - bLooped = looped; if (name) { @@ -96,13 +94,13 @@ void CGameMenuItemQAV::Draw(void) int backX = data->x; for (int i = 0; i < nCount; i++) { - data->Draw(currentDuration, 10 + kQavOrientationLeft, 0, 0, false, smoothratio, bLooped); + data->Draw(currentDuration, 10 + kQavOrientationLeft, 0, 0, false, smoothratio); data->x += 320; } data->x = backX; } else - data->Draw(currentDuration, 10, 0, 0, false, smoothratio, bLooped); + data->Draw(currentDuration, 10, 0, 0, false, smoothratio); } } @@ -137,7 +135,7 @@ void UpdateNetworkMenus(void) void GameInterface::MenuOpened() { - itemBloodQAV.reset(new CGameMenuItemQAV(160, 100, "BDRIP.QAV", true, false, true)); + itemBloodQAV.reset(new CGameMenuItemQAV(160, 100, "BDRIP.QAV", true)); } void GameInterface::MenuClosed() diff --git a/source/games/blood/src/nnexts.cpp b/source/games/blood/src/nnexts.cpp index 23f252f2e..c4a3a4c28 100644 --- a/source/games/blood/src/nnexts.cpp +++ b/source/games/blood/src/nnexts.cpp @@ -6205,13 +6205,13 @@ void playerQavSceneDraw(PLAYER* pPlayer, int a2, double a3, double a4, int a5) { if (!(pSprite->flags & kModernTypeFlag1)) { pQAV->x = int(a3); pQAV->y = int(a4); - pQAV->Draw(a3, a4, v4, flags, a2, a5, true, smoothratio, pPlayer->qavLoop); + pQAV->Draw(a3, a4, v4, flags, a2, a5, true, smoothratio); // draw fullscreen (currently 4:3 only) } else { // What an awful hack. This throws proper ordering out of the window, but there is no way to reproduce this better with strict layering of elements. // From the above commit it seems to be incomplete anyway... - pQAV->Draw(v4, flags, a2, a5, false, smoothratio, pPlayer->qavLoop); + pQAV->Draw(v4, flags, a2, a5, false, smoothratio); } } diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 874726c55..7937b6d84 100644 --- a/source/games/blood/src/qav.cpp +++ b/source/games/blood/src/qav.cpp @@ -139,7 +139,7 @@ void DrawFrame(double x, double y, double z, double a, TILE_FRAME *pTile, int st } } -void QAV::Draw(double x, double y, int ticks, int stat, int shade, int palnum, bool to3dview, double const smoothratio, bool const looped) +void QAV::Draw(double x, double y, int ticks, int stat, int shade, int palnum, bool to3dview, double const smoothratio) { assert(ticksPerFrame > 0); @@ -148,7 +148,7 @@ void QAV::Draw(double x, double y, int ticks, int stat, int shade, int palnum, b auto const nFrame = clamp(ticks / ticksPerFrame, 0, nFrames - 1); FRAMEINFO* const thisFrame = &frames[nFrame]; - auto const oFrame = clamp((nFrame == 0 && (looped || interpdata && (interpdata->flags & kQAVIsLoopable)) ? nFrames : nFrame) - 1, 0, nFrames - 1); + auto const oFrame = clamp((nFrame == 0 && (interpdata && (interpdata->flags & kQAVIsLoopable)) ? nFrames : nFrame) - 1, 0, nFrames - 1); FRAMEINFO* const prevFrame = &frames[oFrame]; bool const interpolate = interpdata && cl_hudinterpolation && cl_bloodqavinterp && (nFrames > 1) && (nFrame != oFrame) && (smoothratio != MaxSmoothRatio); diff --git a/source/games/blood/src/qav.h b/source/games/blood/src/qav.h index 57a9bed2f..611dd3eea 100644 --- a/source/games/blood/src/qav.h +++ b/source/games/blood/src/qav.h @@ -232,8 +232,8 @@ struct QAV char pad3[2]; // 20 unsigned short res_id; FRAMEINFO frames[1]; // 24 - void Draw(double x, double y, int ticks, int stat, int shade, int palnum, bool to3dview, double const smoothratio = 65536, bool const looped = false); - void Draw(int ticks, int stat, int shade, int palnum, bool to3dview, double const smoothratio = 65536, bool const looped = false) { Draw(x, y, ticks, stat, shade, palnum, to3dview, smoothratio, looped); } + void Draw(double x, double y, int ticks, int stat, int shade, int palnum, bool to3dview, double const smoothratio = 65536); + void Draw(int ticks, int stat, int shade, int palnum, bool to3dview, double const smoothratio = 65536) { Draw(x, y, ticks, stat, shade, palnum, to3dview, smoothratio); } void Play(int, int, int, void *); void Precache(int palette = 0); }; diff --git a/source/games/blood/src/weapon.cpp b/source/games/blood/src/weapon.cpp index cb3184ffb..0a942e515 100644 --- a/source/games/blood/src/weapon.cpp +++ b/source/games/blood/src/weapon.cpp @@ -264,7 +264,7 @@ void WeaponDraw(PLAYER *pPlayer, int shade, double xpos, double ypos, int palnum shade = -128; flags |= 1; } - pQAV->Draw(xpos, ypos, duration, flags, shade, palnum, true, smoothratio, pPlayer->qavLoop); + pQAV->Draw(xpos, ypos, duration, flags, shade, palnum, true, smoothratio); } void WeaponPlay(PLAYER *pPlayer) From 6975997ae382773deb0730dc134d372afc20c9f6 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Mon, 23 Aug 2021 10:49:47 +1000 Subject: [PATCH 88/89] - Blood: Remove `weaponQAV[]` array entirely. --- source/games/blood/src/weapon.cpp | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/source/games/blood/src/weapon.cpp b/source/games/blood/src/weapon.cpp index 0a942e515..890b4d060 100644 --- a/source/games/blood/src/weapon.cpp +++ b/source/games/blood/src/weapon.cpp @@ -140,8 +140,6 @@ enum nClientAltFireNapalm, }; -static QAV *weaponQAV[kQAVEnd]; - static bool sub_4B1A4(PLAYER *pPlayer) { switch (pPlayer->curWeapon) @@ -228,10 +226,10 @@ void WeaponInit(void) { for (int i = 0; i < kQAVEnd; i++) { - weaponQAV[i] = getQAV(i); - if (!weaponQAV[i]) + auto pQAV = getQAV(i); + if (!pQAV) I_Error("Could not load QAV %d\n", i); - weaponQAV[i]->nSprite = -1; + pQAV->nSprite = -1; } } @@ -239,8 +237,9 @@ void WeaponPrecache() { for (int i = 0; i < kQAVEnd; i++) { - if (weaponQAV[i]) - weaponQAV[i]->Precache(); + auto pQAV = getQAV(i); + if (pQAV) + pQAV->Precache(); } } @@ -249,7 +248,7 @@ void WeaponDraw(PLAYER *pPlayer, int shade, double xpos, double ypos, int palnum assert(pPlayer != NULL); if (pPlayer->weaponQav == kQAVNone) return; - QAV * pQAV = weaponQAV[pPlayer->weaponQav]; + auto pQAV = getQAV(pPlayer->weaponQav); int duration; double smoothratio; @@ -272,7 +271,7 @@ void WeaponPlay(PLAYER *pPlayer) assert(pPlayer != NULL); if (pPlayer->weaponQav == kQAVNone) return; - QAV *pQAV = weaponQAV[pPlayer->weaponQav]; + auto pQAV = getQAV(pPlayer->weaponQav); pQAV->nSprite = pPlayer->pSprite->index; int nTicks = pQAV->duration - pPlayer->weaponTimer; pQAV->Play(nTicks-4, nTicks, pPlayer->qavCallback, pPlayer); @@ -281,13 +280,14 @@ void WeaponPlay(PLAYER *pPlayer) static void StartQAV(PLAYER *pPlayer, int nWeaponQAV, int callback = -1, bool looped = false) { assert(nWeaponQAV < kQAVEnd); + auto pQAV = getQAV(nWeaponQAV); pPlayer->weaponQav = nWeaponQAV; - pPlayer->weaponTimer = weaponQAV[nWeaponQAV]->duration; + pPlayer->weaponTimer = pQAV->duration; pPlayer->qavCallback = callback; pPlayer->qavLoop = looped; - pPlayer->qavLastTick = I_GetTime(weaponQAV[nWeaponQAV]->ticrate); - pPlayer->qavTimer = weaponQAV[nWeaponQAV]->duration; - //weaponQAV[nWeaponQAV]->Preload(); + pPlayer->qavLastTick = I_GetTime(pQAV->ticrate); + pPlayer->qavTimer = pQAV->duration; + //pQAV->Preload(); WeaponPlay(pPlayer); pPlayer->weaponTimer -= 4; } @@ -2029,10 +2029,11 @@ void WeaponProcess(PLAYER *pPlayer) { { if (bShoot && CheckAmmo(pPlayer, pPlayer->weaponAmmo, 1)) { + auto pQAV = getQAV(pPlayer->weaponQav); while (pPlayer->weaponTimer <= 0) { - pPlayer->weaponTimer += weaponQAV[pPlayer->weaponQav]->duration; - pPlayer->qavTimer += weaponQAV[pPlayer->weaponQav]->duration; + pPlayer->weaponTimer += pQAV->duration; + pPlayer->qavTimer += pQAV->duration; } } else From d7450e12f0f2c9963632592232e8fb19b20c4c08 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Mon, 23 Aug 2021 10:55:00 +1000 Subject: [PATCH 89/89] - Blood: Re-add interpolated weapon QAVs in an externalised, disabled-by-default fashion. --- source/core/gamecvars.cpp | 3 +- source/core/gamecvars.h | 1 + source/games/blood/src/qav.h | 11 + source/games/blood/src/weapon.cpp | 67 +- wadsrc/static/filter/blood/engine/engine.def | 797 +++++++++++++++++++ wadsrc/static/filter/blood/qavs/2NAPDOWN.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/2NAPFIR2.QAV | Bin 0 -> 1872 bytes wadsrc/static/filter/blood/qavs/2NAPFIRE.QAV | Bin 0 -> 2076 bytes wadsrc/static/filter/blood/qavs/2NAPIDLE.QAV | Bin 0 -> 2076 bytes wadsrc/static/filter/blood/qavs/2NAPUP.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/2SGUNALT.QAV | Bin 0 -> 7176 bytes wadsrc/static/filter/blood/qavs/2SGUNDWN.QAV | Bin 0 -> 852 bytes wadsrc/static/filter/blood/qavs/2SGUNFIR.QAV | Bin 0 -> 1668 bytes wadsrc/static/filter/blood/qavs/2SGUNIDL.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/2SGUNPRE.QAV | Bin 0 -> 852 bytes wadsrc/static/filter/blood/qavs/2SGUNPST.QAV | Bin 0 -> 852 bytes wadsrc/static/filter/blood/qavs/2SGUNUP.QAV | Bin 0 -> 1056 bytes wadsrc/static/filter/blood/qavs/2SHOTDWN.QAV | Bin 0 -> 1056 bytes wadsrc/static/filter/blood/qavs/2SHOTF2.QAV | Bin 0 -> 1668 bytes wadsrc/static/filter/blood/qavs/2SHOTFIR.QAV | Bin 0 -> 2688 bytes wadsrc/static/filter/blood/qavs/2SHOTI.QAV | Bin 0 -> 240 bytes wadsrc/static/filter/blood/qavs/2SHOTUP.QAV | Bin 0 -> 1056 bytes wadsrc/static/filter/blood/qavs/2TOMALT.QAV | Bin 0 -> 2892 bytes wadsrc/static/filter/blood/qavs/2TOMDOWN.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/2TOMFIRE.QAV | Bin 0 -> 1668 bytes wadsrc/static/filter/blood/qavs/2TOMIDLE.QAV | Bin 0 -> 240 bytes wadsrc/static/filter/blood/qavs/2TOMUP.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/BDRIP.QAV | Bin 0 -> 4932 bytes wadsrc/static/filter/blood/qavs/BSTATAK1.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/BSTATAK2.QAV | Bin 0 -> 1668 bytes wadsrc/static/filter/blood/qavs/BSTATAK3.QAV | Bin 0 -> 1464 bytes wadsrc/static/filter/blood/qavs/BSTATAK4.QAV | Bin 0 -> 1668 bytes wadsrc/static/filter/blood/qavs/BSTDOWN.QAV | Bin 0 -> 1464 bytes wadsrc/static/filter/blood/qavs/BSTIDLE.QAV | Bin 0 -> 3300 bytes wadsrc/static/filter/blood/qavs/BSTUP.QAV | Bin 0 -> 1464 bytes wadsrc/static/filter/blood/qavs/BUNDOWN.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/BUNDOWN2.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/BUNDROP.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/BUNFUSE.QAV | Bin 0 -> 13500 bytes wadsrc/static/filter/blood/qavs/BUNIDLE.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/BUNTHRO.QAV | Bin 0 -> 3504 bytes wadsrc/static/filter/blood/qavs/BUNUP.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/BUNUP2.QAV | Bin 0 -> 2076 bytes wadsrc/static/filter/blood/qavs/CANBOOM.QAV | Bin 0 -> 1056 bytes wadsrc/static/filter/blood/qavs/CANDOWN.QAV | Bin 0 -> 1056 bytes wadsrc/static/filter/blood/qavs/CANDROP.QAV | Bin 0 -> 2280 bytes wadsrc/static/filter/blood/qavs/CANFIRE.QAV | Bin 0 -> 852 bytes wadsrc/static/filter/blood/qavs/CANFIRE2.QAV | Bin 0 -> 20436 bytes wadsrc/static/filter/blood/qavs/CANIDLE.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/CANPREF.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/CANTHRO.QAV | Bin 0 -> 2280 bytes wadsrc/static/filter/blood/qavs/CREDITS.QAV | Bin 0 -> 236676 bytes wadsrc/static/filter/blood/qavs/DYNEXPLO.QAV | Bin 0 -> 648 bytes wadsrc/static/filter/blood/qavs/FLAR2DWN.QAV | Bin 0 -> 1056 bytes wadsrc/static/filter/blood/qavs/FLAR2F.QAV | Bin 0 -> 4116 bytes wadsrc/static/filter/blood/qavs/FLAR2FIR.QAV | Bin 0 -> 2076 bytes wadsrc/static/filter/blood/qavs/FLAR2I.QAV | Bin 0 -> 444 bytes wadsrc/static/filter/blood/qavs/FLAR2UP.QAV | Bin 0 -> 1056 bytes wadsrc/static/filter/blood/qavs/FLARDOWN.QAV | Bin 0 -> 1056 bytes wadsrc/static/filter/blood/qavs/FLARFIR2.QAV | Bin 0 -> 1668 bytes wadsrc/static/filter/blood/qavs/FLARIDLE.QAV | Bin 0 -> 240 bytes wadsrc/static/filter/blood/qavs/FLARUP.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/FORKDOWN.QAV | Bin 0 -> 1056 bytes wadsrc/static/filter/blood/qavs/FORKIDLE.QAV | Bin 0 -> 240 bytes wadsrc/static/filter/blood/qavs/FORKUP.QAV | Bin 0 -> 1056 bytes wadsrc/static/filter/blood/qavs/LITECLO2.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/LITEFLAM.QAV | Bin 0 -> 1464 bytes wadsrc/static/filter/blood/qavs/LITEIDLE.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/LITEOPEN.QAV | Bin 0 -> 1668 bytes wadsrc/static/filter/blood/qavs/NAPDOWN.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/NAPFIRE.QAV | Bin 0 -> 1872 bytes wadsrc/static/filter/blood/qavs/NAPIDLE.QAV | Bin 0 -> 2076 bytes wadsrc/static/filter/blood/qavs/NAPUP.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/PFORK.QAV | Bin 0 -> 2076 bytes wadsrc/static/filter/blood/qavs/PROXDOWN.QAV | Bin 0 -> 1056 bytes wadsrc/static/filter/blood/qavs/PROXDROP.QAV | Bin 0 -> 852 bytes wadsrc/static/filter/blood/qavs/PROXIDLE.QAV | Bin 0 -> 2076 bytes wadsrc/static/filter/blood/qavs/PROXTHRO.QAV | Bin 0 -> 2688 bytes wadsrc/static/filter/blood/qavs/PROXUP.QAV | Bin 0 -> 1056 bytes wadsrc/static/filter/blood/qavs/REMDOWN1.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/REMDOWN2.QAV | Bin 0 -> 1056 bytes wadsrc/static/filter/blood/qavs/REMDOWN3.QAV | Bin 0 -> 852 bytes wadsrc/static/filter/blood/qavs/REMDROP.QAV | Bin 0 -> 1056 bytes wadsrc/static/filter/blood/qavs/REMFIRE.QAV | Bin 0 -> 1872 bytes wadsrc/static/filter/blood/qavs/REMIDLE1.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/REMIDLE2.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/REMTHRO.QAV | Bin 0 -> 2688 bytes wadsrc/static/filter/blood/qavs/REMUP1.QAV | Bin 0 -> 1056 bytes wadsrc/static/filter/blood/qavs/REMUP2.QAV | Bin 0 -> 1056 bytes wadsrc/static/filter/blood/qavs/REMUP3.QAV | Bin 0 -> 852 bytes wadsrc/static/filter/blood/qavs/SGUNDOWN.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/SGUNFIR1.QAV | Bin 0 -> 1668 bytes wadsrc/static/filter/blood/qavs/SGUNFIR4.QAV | Bin 0 -> 11256 bytes wadsrc/static/filter/blood/qavs/SGUNIDL1.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/SGUNIDL2.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/SGUNPOST.QAV | Bin 0 -> 1668 bytes wadsrc/static/filter/blood/qavs/SGUNPRE.QAV | Bin 0 -> 852 bytes wadsrc/static/filter/blood/qavs/SGUNUP.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/SHOTDOWN.QAV | Bin 0 -> 1056 bytes wadsrc/static/filter/blood/qavs/SHOTF1.QAV | Bin 0 -> 1668 bytes wadsrc/static/filter/blood/qavs/SHOTF2.QAV | Bin 0 -> 1668 bytes wadsrc/static/filter/blood/qavs/SHOTF3.QAV | Bin 0 -> 1668 bytes wadsrc/static/filter/blood/qavs/SHOTI1.QAV | Bin 0 -> 240 bytes wadsrc/static/filter/blood/qavs/SHOTI2.QAV | Bin 0 -> 240 bytes wadsrc/static/filter/blood/qavs/SHOTI3.QAV | Bin 0 -> 240 bytes wadsrc/static/filter/blood/qavs/SHOTL1.QAV | Bin 0 -> 2892 bytes wadsrc/static/filter/blood/qavs/SHOTUP.QAV | Bin 0 -> 1056 bytes wadsrc/static/filter/blood/qavs/STAFDOWN.QAV | Bin 0 -> 852 bytes wadsrc/static/filter/blood/qavs/STAFIDL1.QAV | Bin 0 -> 240 bytes wadsrc/static/filter/blood/qavs/STAFIDL3.QAV | Bin 0 -> 444 bytes wadsrc/static/filter/blood/qavs/STAFIRE1.QAV | Bin 0 -> 2688 bytes wadsrc/static/filter/blood/qavs/STAFIRE2.QAV | Bin 0 -> 1872 bytes wadsrc/static/filter/blood/qavs/STAFIRE4.QAV | Bin 0 -> 7380 bytes wadsrc/static/filter/blood/qavs/STAFPOST.QAV | Bin 0 -> 1668 bytes wadsrc/static/filter/blood/qavs/STAFPRE.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/STAFUP.QAV | Bin 0 -> 1056 bytes wadsrc/static/filter/blood/qavs/TOMDOWN.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/TOMFIRE.QAV | Bin 0 -> 1668 bytes wadsrc/static/filter/blood/qavs/TOMIDLE.QAV | Bin 0 -> 240 bytes wadsrc/static/filter/blood/qavs/TOMSPRED.QAV | Bin 0 -> 2892 bytes wadsrc/static/filter/blood/qavs/TOMUP.QAV | Bin 0 -> 1260 bytes wadsrc/static/filter/blood/qavs/VDDOWN.QAV | Bin 0 -> 852 bytes wadsrc/static/filter/blood/qavs/VDFIRE1.QAV | Bin 0 -> 2484 bytes wadsrc/static/filter/blood/qavs/VDFIRE2.QAV | Bin 0 -> 2484 bytes wadsrc/static/filter/blood/qavs/VDFIRE3.QAV | Bin 0 -> 3504 bytes wadsrc/static/filter/blood/qavs/VDFIRE4.QAV | Bin 0 -> 5544 bytes wadsrc/static/filter/blood/qavs/VDFIRE5.QAV | Bin 0 -> 2484 bytes wadsrc/static/filter/blood/qavs/VDFIRE6.QAV | Bin 0 -> 5748 bytes wadsrc/static/filter/blood/qavs/VDIDLE1.QAV | Bin 0 -> 240 bytes wadsrc/static/filter/blood/qavs/VDIDLE2.QAV | Bin 0 -> 2688 bytes wadsrc/static/filter/blood/qavs/VDSPEL1.QAV | Bin 0 -> 2892 bytes wadsrc/static/filter/blood/qavs/VDUP.QAV | Bin 0 -> 852 bytes wadsrc/static/menudef.txt | 6 + 133 files changed, 851 insertions(+), 34 deletions(-) create mode 100644 wadsrc/static/filter/blood/qavs/2NAPDOWN.QAV create mode 100644 wadsrc/static/filter/blood/qavs/2NAPFIR2.QAV create mode 100644 wadsrc/static/filter/blood/qavs/2NAPFIRE.QAV create mode 100644 wadsrc/static/filter/blood/qavs/2NAPIDLE.QAV create mode 100644 wadsrc/static/filter/blood/qavs/2NAPUP.QAV create mode 100644 wadsrc/static/filter/blood/qavs/2SGUNALT.QAV create mode 100644 wadsrc/static/filter/blood/qavs/2SGUNDWN.QAV create mode 100644 wadsrc/static/filter/blood/qavs/2SGUNFIR.QAV create mode 100644 wadsrc/static/filter/blood/qavs/2SGUNIDL.QAV create mode 100644 wadsrc/static/filter/blood/qavs/2SGUNPRE.QAV create mode 100644 wadsrc/static/filter/blood/qavs/2SGUNPST.QAV create mode 100644 wadsrc/static/filter/blood/qavs/2SGUNUP.QAV create mode 100644 wadsrc/static/filter/blood/qavs/2SHOTDWN.QAV create mode 100644 wadsrc/static/filter/blood/qavs/2SHOTF2.QAV create mode 100644 wadsrc/static/filter/blood/qavs/2SHOTFIR.QAV create mode 100644 wadsrc/static/filter/blood/qavs/2SHOTI.QAV create mode 100644 wadsrc/static/filter/blood/qavs/2SHOTUP.QAV create mode 100644 wadsrc/static/filter/blood/qavs/2TOMALT.QAV create mode 100644 wadsrc/static/filter/blood/qavs/2TOMDOWN.QAV create mode 100644 wadsrc/static/filter/blood/qavs/2TOMFIRE.QAV create mode 100644 wadsrc/static/filter/blood/qavs/2TOMIDLE.QAV create mode 100644 wadsrc/static/filter/blood/qavs/2TOMUP.QAV create mode 100644 wadsrc/static/filter/blood/qavs/BDRIP.QAV create mode 100644 wadsrc/static/filter/blood/qavs/BSTATAK1.QAV create mode 100644 wadsrc/static/filter/blood/qavs/BSTATAK2.QAV create mode 100644 wadsrc/static/filter/blood/qavs/BSTATAK3.QAV create mode 100644 wadsrc/static/filter/blood/qavs/BSTATAK4.QAV create mode 100644 wadsrc/static/filter/blood/qavs/BSTDOWN.QAV create mode 100644 wadsrc/static/filter/blood/qavs/BSTIDLE.QAV create mode 100644 wadsrc/static/filter/blood/qavs/BSTUP.QAV create mode 100644 wadsrc/static/filter/blood/qavs/BUNDOWN.QAV create mode 100644 wadsrc/static/filter/blood/qavs/BUNDOWN2.QAV create mode 100644 wadsrc/static/filter/blood/qavs/BUNDROP.QAV create mode 100644 wadsrc/static/filter/blood/qavs/BUNFUSE.QAV create mode 100644 wadsrc/static/filter/blood/qavs/BUNIDLE.QAV create mode 100644 wadsrc/static/filter/blood/qavs/BUNTHRO.QAV create mode 100644 wadsrc/static/filter/blood/qavs/BUNUP.QAV create mode 100644 wadsrc/static/filter/blood/qavs/BUNUP2.QAV create mode 100644 wadsrc/static/filter/blood/qavs/CANBOOM.QAV create mode 100644 wadsrc/static/filter/blood/qavs/CANDOWN.QAV create mode 100644 wadsrc/static/filter/blood/qavs/CANDROP.QAV create mode 100644 wadsrc/static/filter/blood/qavs/CANFIRE.QAV create mode 100644 wadsrc/static/filter/blood/qavs/CANFIRE2.QAV create mode 100644 wadsrc/static/filter/blood/qavs/CANIDLE.QAV create mode 100644 wadsrc/static/filter/blood/qavs/CANPREF.QAV create mode 100644 wadsrc/static/filter/blood/qavs/CANTHRO.QAV create mode 100644 wadsrc/static/filter/blood/qavs/CREDITS.QAV create mode 100644 wadsrc/static/filter/blood/qavs/DYNEXPLO.QAV create mode 100644 wadsrc/static/filter/blood/qavs/FLAR2DWN.QAV create mode 100644 wadsrc/static/filter/blood/qavs/FLAR2F.QAV create mode 100644 wadsrc/static/filter/blood/qavs/FLAR2FIR.QAV create mode 100644 wadsrc/static/filter/blood/qavs/FLAR2I.QAV create mode 100644 wadsrc/static/filter/blood/qavs/FLAR2UP.QAV create mode 100644 wadsrc/static/filter/blood/qavs/FLARDOWN.QAV create mode 100644 wadsrc/static/filter/blood/qavs/FLARFIR2.QAV create mode 100644 wadsrc/static/filter/blood/qavs/FLARIDLE.QAV create mode 100644 wadsrc/static/filter/blood/qavs/FLARUP.QAV create mode 100644 wadsrc/static/filter/blood/qavs/FORKDOWN.QAV create mode 100644 wadsrc/static/filter/blood/qavs/FORKIDLE.QAV create mode 100644 wadsrc/static/filter/blood/qavs/FORKUP.QAV create mode 100644 wadsrc/static/filter/blood/qavs/LITECLO2.QAV create mode 100644 wadsrc/static/filter/blood/qavs/LITEFLAM.QAV create mode 100644 wadsrc/static/filter/blood/qavs/LITEIDLE.QAV create mode 100644 wadsrc/static/filter/blood/qavs/LITEOPEN.QAV create mode 100644 wadsrc/static/filter/blood/qavs/NAPDOWN.QAV create mode 100644 wadsrc/static/filter/blood/qavs/NAPFIRE.QAV create mode 100644 wadsrc/static/filter/blood/qavs/NAPIDLE.QAV create mode 100644 wadsrc/static/filter/blood/qavs/NAPUP.QAV create mode 100644 wadsrc/static/filter/blood/qavs/PFORK.QAV create mode 100644 wadsrc/static/filter/blood/qavs/PROXDOWN.QAV create mode 100644 wadsrc/static/filter/blood/qavs/PROXDROP.QAV create mode 100644 wadsrc/static/filter/blood/qavs/PROXIDLE.QAV create mode 100644 wadsrc/static/filter/blood/qavs/PROXTHRO.QAV create mode 100644 wadsrc/static/filter/blood/qavs/PROXUP.QAV create mode 100644 wadsrc/static/filter/blood/qavs/REMDOWN1.QAV create mode 100644 wadsrc/static/filter/blood/qavs/REMDOWN2.QAV create mode 100644 wadsrc/static/filter/blood/qavs/REMDOWN3.QAV create mode 100644 wadsrc/static/filter/blood/qavs/REMDROP.QAV create mode 100644 wadsrc/static/filter/blood/qavs/REMFIRE.QAV create mode 100644 wadsrc/static/filter/blood/qavs/REMIDLE1.QAV create mode 100644 wadsrc/static/filter/blood/qavs/REMIDLE2.QAV create mode 100644 wadsrc/static/filter/blood/qavs/REMTHRO.QAV create mode 100644 wadsrc/static/filter/blood/qavs/REMUP1.QAV create mode 100644 wadsrc/static/filter/blood/qavs/REMUP2.QAV create mode 100644 wadsrc/static/filter/blood/qavs/REMUP3.QAV create mode 100644 wadsrc/static/filter/blood/qavs/SGUNDOWN.QAV create mode 100644 wadsrc/static/filter/blood/qavs/SGUNFIR1.QAV create mode 100644 wadsrc/static/filter/blood/qavs/SGUNFIR4.QAV create mode 100644 wadsrc/static/filter/blood/qavs/SGUNIDL1.QAV create mode 100644 wadsrc/static/filter/blood/qavs/SGUNIDL2.QAV create mode 100644 wadsrc/static/filter/blood/qavs/SGUNPOST.QAV create mode 100644 wadsrc/static/filter/blood/qavs/SGUNPRE.QAV create mode 100644 wadsrc/static/filter/blood/qavs/SGUNUP.QAV create mode 100644 wadsrc/static/filter/blood/qavs/SHOTDOWN.QAV create mode 100644 wadsrc/static/filter/blood/qavs/SHOTF1.QAV create mode 100644 wadsrc/static/filter/blood/qavs/SHOTF2.QAV create mode 100644 wadsrc/static/filter/blood/qavs/SHOTF3.QAV create mode 100644 wadsrc/static/filter/blood/qavs/SHOTI1.QAV create mode 100644 wadsrc/static/filter/blood/qavs/SHOTI2.QAV create mode 100644 wadsrc/static/filter/blood/qavs/SHOTI3.QAV create mode 100644 wadsrc/static/filter/blood/qavs/SHOTL1.QAV create mode 100644 wadsrc/static/filter/blood/qavs/SHOTUP.QAV create mode 100644 wadsrc/static/filter/blood/qavs/STAFDOWN.QAV create mode 100644 wadsrc/static/filter/blood/qavs/STAFIDL1.QAV create mode 100644 wadsrc/static/filter/blood/qavs/STAFIDL3.QAV create mode 100644 wadsrc/static/filter/blood/qavs/STAFIRE1.QAV create mode 100644 wadsrc/static/filter/blood/qavs/STAFIRE2.QAV create mode 100644 wadsrc/static/filter/blood/qavs/STAFIRE4.QAV create mode 100644 wadsrc/static/filter/blood/qavs/STAFPOST.QAV create mode 100644 wadsrc/static/filter/blood/qavs/STAFPRE.QAV create mode 100644 wadsrc/static/filter/blood/qavs/STAFUP.QAV create mode 100644 wadsrc/static/filter/blood/qavs/TOMDOWN.QAV create mode 100644 wadsrc/static/filter/blood/qavs/TOMFIRE.QAV create mode 100644 wadsrc/static/filter/blood/qavs/TOMIDLE.QAV create mode 100644 wadsrc/static/filter/blood/qavs/TOMSPRED.QAV create mode 100644 wadsrc/static/filter/blood/qavs/TOMUP.QAV create mode 100644 wadsrc/static/filter/blood/qavs/VDDOWN.QAV create mode 100644 wadsrc/static/filter/blood/qavs/VDFIRE1.QAV create mode 100644 wadsrc/static/filter/blood/qavs/VDFIRE2.QAV create mode 100644 wadsrc/static/filter/blood/qavs/VDFIRE3.QAV create mode 100644 wadsrc/static/filter/blood/qavs/VDFIRE4.QAV create mode 100644 wadsrc/static/filter/blood/qavs/VDFIRE5.QAV create mode 100644 wadsrc/static/filter/blood/qavs/VDFIRE6.QAV create mode 100644 wadsrc/static/filter/blood/qavs/VDIDLE1.QAV create mode 100644 wadsrc/static/filter/blood/qavs/VDIDLE2.QAV create mode 100644 wadsrc/static/filter/blood/qavs/VDSPEL1.QAV create mode 100644 wadsrc/static/filter/blood/qavs/VDUP.QAV diff --git a/source/core/gamecvars.cpp b/source/core/gamecvars.cpp index 6126cb691..ba4d1ae5d 100644 --- a/source/core/gamecvars.cpp +++ b/source/core/gamecvars.cpp @@ -84,7 +84,8 @@ CVARD(Bool, cl_exhumedoldturn, false, CVAR_ARCHIVE, "enable/disable legacy turni CVARD(Bool, cl_hudinterpolation, true, CVAR_ARCHIVE, "enable/disable HUD (weapon drawer) interpolation") CVARD(Bool, cl_bloodvanillarun, true, CVAR_ARCHIVE, "enable/disable Blood's vanilla run mode") CVARD(Bool, cl_bloodvanillabobbing, true, CVAR_ARCHIVE, "enable/disable Blood's vanilla bobbing while not using vanilla run mode") -CVARD(Bool, cl_bloodqavinterp, false, CVAR_ARCHIVE, "enable/disable Blood's HUD interpolation") +CVARD(Bool, cl_bloodqavinterp, true, CVAR_ARCHIVE, "enable/disable Blood's QAV interpolation") +CVARD(Bool, cl_bloodweapinterp, false, CVAR_ARCHIVE, "enable/disable Blood's weapon interpolation. Depends on 'cl_bloodqavinterp'") CVARD(Bool, cl_bloodoldweapbalance, false, CVAR_ARCHIVE, "enable/disable legacy 1.0 weapon handling for Blood") diff --git a/source/core/gamecvars.h b/source/core/gamecvars.h index 421080ab9..80b2d5344 100644 --- a/source/core/gamecvars.h +++ b/source/core/gamecvars.h @@ -30,6 +30,7 @@ EXTERN_CVAR(Bool, cl_hudinterpolation) EXTERN_CVAR(Bool, cl_bloodvanillarun) EXTERN_CVAR(Bool, cl_bloodvanillabobbing) EXTERN_CVAR(Bool, cl_bloodqavinterp) +EXTERN_CVAR(Bool, cl_bloodweapinterp) EXTERN_CVAR(Bool, cl_bloodoldweapbalance) EXTERN_CVAR(Bool, demorec_seeds_cvar) diff --git a/source/games/blood/src/qav.h b/source/games/blood/src/qav.h index 611dd3eea..50c6a74f1 100644 --- a/source/games/blood/src/qav.h +++ b/source/games/blood/src/qav.h @@ -258,4 +258,15 @@ QAV* getQAV(int res_id); void qavProcessTicker(QAV* const pQAV, int* duration, int* lastTick); void qavProcessTimer(PLAYER* const pPlayer, QAV* const pQAV, int* duration, double* smoothratio, bool const fixedduration = false); +inline bool qavIsOriginal(const int& res_id) +{ + auto const lump = fileSystem.FindResource(res_id, "QAV"); + return lump >= 0 && fileSystem.GetFileContainer(lump) < fileSystem.GetMaxIwadNum(); +} + +inline int qavGetCorrectID(const int& res_id) +{ + return cl_bloodweapinterp && qavIsOriginal(res_id) && fileSystem.FindResource(res_id + 10000, "QAV") != -1 ? res_id + 10000 : res_id; +} + END_BLD_NS diff --git a/source/games/blood/src/weapon.cpp b/source/games/blood/src/weapon.cpp index 890b4d060..28cf4446b 100644 --- a/source/games/blood/src/weapon.cpp +++ b/source/games/blood/src/weapon.cpp @@ -280,8 +280,9 @@ void WeaponPlay(PLAYER *pPlayer) static void StartQAV(PLAYER *pPlayer, int nWeaponQAV, int callback = -1, bool looped = false) { assert(nWeaponQAV < kQAVEnd); - auto pQAV = getQAV(nWeaponQAV); - pPlayer->weaponQav = nWeaponQAV; + auto res_id = qavGetCorrectID(nWeaponQAV); + auto pQAV = getQAV(res_id); + pPlayer->weaponQav = res_id; pPlayer->weaponTimer = pQAV->duration; pPlayer->qavCallback = callback; pPlayer->qavLoop = looped; @@ -828,7 +829,7 @@ void WeaponUpdateState(PLAYER *pPlayer) switch (lastWeapon) { case kWeapPitchFork: - pPlayer->weaponQav = kQAVFORKIDLE; + pPlayer->weaponQav = qavGetCorrectID(kQAVFORKIDLE); break; case kWeapSpraycan: switch (vb) @@ -844,15 +845,15 @@ void WeaponUpdateState(PLAYER *pPlayer) StartQAV(pPlayer, kQAVCANPREF); } else - pPlayer->weaponQav = kQAVLITEIDLE; + pPlayer->weaponQav = qavGetCorrectID(kQAVLITEIDLE); break; case 3: - pPlayer->weaponQav = kQAVCANIDLE; + pPlayer->weaponQav = qavGetCorrectID(kQAVCANIDLE); break; case 4: if (CheckAmmo(pPlayer, 6, 1)) { - pPlayer->weaponQav = kQAVCANIDLE; + pPlayer->weaponQav = qavGetCorrectID(kQAVCANIDLE); pPlayer->weaponState = 3; } else @@ -885,10 +886,10 @@ void WeaponUpdateState(PLAYER *pPlayer) StartQAV(pPlayer, kQAVBUNUP); } else - pPlayer->weaponQav = kQAVLITEIDLE; + pPlayer->weaponQav = qavGetCorrectID(kQAVLITEIDLE); break; case 3: - pPlayer->weaponQav = kQAVBUNIDLE; + pPlayer->weaponQav = qavGetCorrectID(kQAVBUNIDLE); break; } break; @@ -896,7 +897,7 @@ void WeaponUpdateState(PLAYER *pPlayer) switch (vb) { case 7: - pPlayer->weaponQav = kQAVPROXIDLE; + pPlayer->weaponQav = qavGetCorrectID(kQAVPROXIDLE); break; case 8: pPlayer->weaponState = 7; @@ -908,10 +909,10 @@ void WeaponUpdateState(PLAYER *pPlayer) switch (vb) { case 10: - pPlayer->weaponQav = kQAVREMIDLE1; + pPlayer->weaponQav = qavGetCorrectID(kQAVREMIDLE1); break; case 11: - pPlayer->weaponQav = kQAVREMIDLE2; + pPlayer->weaponQav = qavGetCorrectID(kQAVREMIDLE2); break; case 12: if (pPlayer->ammoCount[11] > 0) @@ -934,7 +935,7 @@ void WeaponUpdateState(PLAYER *pPlayer) pPlayer->weaponState = 1; break; case 7: - pPlayer->weaponQav = kQAV2SHOTI; + pPlayer->weaponQav = qavGetCorrectID(kQAV2SHOTI); break; case 1: if (CheckAmmo(pPlayer, 2, 1)) @@ -947,25 +948,25 @@ void WeaponUpdateState(PLAYER *pPlayer) pPlayer->weaponState = 2; } else - pPlayer->weaponQav = kQAVSHOTI3; + pPlayer->weaponQav = qavGetCorrectID(kQAVSHOTI3); break; case 2: - pPlayer->weaponQav = kQAVSHOTI2; + pPlayer->weaponQav = qavGetCorrectID(kQAVSHOTI2); break; case 3: - pPlayer->weaponQav = kQAVSHOTI1; + pPlayer->weaponQav = qavGetCorrectID(kQAVSHOTI1); break; } break; case kWeapTommyGun: if (powerupCheck(pPlayer, kPwUpTwoGuns) && checkAmmo2(pPlayer, 3, 2)) { - pPlayer->weaponQav = kQAV2TOMIDLE; + pPlayer->weaponQav = qavGetCorrectID(kQAV2TOMIDLE); pPlayer->weaponState = 1; } else { - pPlayer->weaponQav = kQAVTOMIDLE; + pPlayer->weaponQav = qavGetCorrectID(kQAVTOMIDLE); pPlayer->weaponState = 0; } break; @@ -973,33 +974,33 @@ void WeaponUpdateState(PLAYER *pPlayer) if (powerupCheck(pPlayer, kPwUpTwoGuns)) { if (vb == 3 && checkAmmo2(pPlayer, 1, 2)) - pPlayer->weaponQav = kQAVFLAR2I; + pPlayer->weaponQav = qavGetCorrectID(kQAVFLAR2I); else { - pPlayer->weaponQav = kQAVFLARIDLE; + pPlayer->weaponQav = qavGetCorrectID(kQAVFLARIDLE); pPlayer->weaponState = 2; } } else - pPlayer->weaponQav = kQAVFLARIDLE; + pPlayer->weaponQav = qavGetCorrectID(kQAVFLARIDLE); break; case kWeapVoodooDoll: if (pXSprite->height < 256 && pPlayer->swayHeight != 0) StartQAV(pPlayer, kQAVVDIDLE2); else - pPlayer->weaponQav = kQAVVDIDLE1; + pPlayer->weaponQav = qavGetCorrectID(kQAVVDIDLE1); break; case kWeapTeslaCannon: switch (vb) { case 2: if (checkAmmo2(pPlayer, 7, 10) && powerupCheck(pPlayer, kPwUpTwoGuns)) - pPlayer->weaponQav = kQAV2SGUNIDL; + pPlayer->weaponQav = qavGetCorrectID(kQAV2SGUNIDL); else - pPlayer->weaponQav = kQAVSGUNIDL1; + pPlayer->weaponQav = qavGetCorrectID(kQAVSGUNIDL1); break; case 3: - pPlayer->weaponQav = kQAVSGUNIDL2; + pPlayer->weaponQav = qavGetCorrectID(kQAVSGUNIDL2); break; } break; @@ -1008,12 +1009,12 @@ void WeaponUpdateState(PLAYER *pPlayer) { case 3: if (powerupCheck(pPlayer, kPwUpTwoGuns) && (gInfiniteAmmo || CheckAmmo(pPlayer,4, 4))) - pPlayer->weaponQav = kQAV2NAPIDLE; + pPlayer->weaponQav = qavGetCorrectID(kQAV2NAPIDLE); else - pPlayer->weaponQav = kQAVNAPIDLE; + pPlayer->weaponQav = qavGetCorrectID(kQAVNAPIDLE); break; case 2: - pPlayer->weaponQav = kQAVNAPIDLE; + pPlayer->weaponQav = qavGetCorrectID(kQAVNAPIDLE); break; } break; @@ -1021,12 +1022,12 @@ void WeaponUpdateState(PLAYER *pPlayer) switch (vb) { case 2: - pPlayer->weaponQav = kQAVSTAFIDL1; + pPlayer->weaponQav = qavGetCorrectID(kQAVSTAFIDL1); break; } break; case kWeapBeast: - pPlayer->weaponQav = kQAVBSTIDLE; + pPlayer->weaponQav = qavGetCorrectID(kQAVBSTIDLE); break; } } @@ -1581,7 +1582,7 @@ void FireTesla(int nTrigger, PLAYER *pPlayer) if (!checkAmmo2(pPlayer, 7, pMissile->ammouse)) { pPlayer->weaponState = -1; - pPlayer->weaponQav = kQAVSGUNIDL2; + pPlayer->weaponQav = qavGetCorrectID(kQAVSGUNIDL2); pPlayer->flashEffect = 0; return; } @@ -2024,7 +2025,7 @@ void WeaponProcess(PLAYER *pPlayer) { pPlayer->weaponTimer -= 4; bool bShoot = pPlayer->input.actions & SB_FIRE; bool bShoot2 = pPlayer->input.actions & SB_ALTFIRE; - if ((bShoot || bShoot2) && pPlayer->weaponQav == kQAVVDIDLE2) pPlayer->weaponTimer = 0; + if ((bShoot || bShoot2) && pPlayer->weaponQav == qavGetCorrectID(kQAVVDIDLE2)) pPlayer->weaponTimer = 0; if (pPlayer->qavLoop && pPlayer->pXSprite->health > 0) { if (bShoot && CheckAmmo(pPlayer, pPlayer->weaponAmmo, 1)) @@ -2317,7 +2318,7 @@ void WeaponProcess(PLAYER *pPlayer) { switch (pPlayer->weaponState) { case 7: - pPlayer->weaponQav = kQAVPROXIDLE; + pPlayer->weaponQav = qavGetCorrectID(kQAVPROXIDLE); pPlayer->weaponState = 9; pPlayer->throwTime = PlayClock; return; @@ -2327,7 +2328,7 @@ void WeaponProcess(PLAYER *pPlayer) { switch (pPlayer->weaponState) { case 10: - pPlayer->weaponQav = kQAVREMIDLE1; + pPlayer->weaponQav = qavGetCorrectID(kQAVREMIDLE1); pPlayer->weaponState = 13; pPlayer->throwTime = PlayClock; return; diff --git a/wadsrc/static/filter/blood/engine/engine.def b/wadsrc/static/filter/blood/engine/engine.def index 128a463bd..9f614c3bd 100644 --- a/wadsrc/static/filter/blood/engine/engine.def +++ b/wadsrc/static/filter/blood/engine/engine.def @@ -71,3 +71,800 @@ tilefromtexture 9306 { file "tiles/9306(3240+3229).png" } tilefromtexture 9307 { file "tiles/9307(3240+3230).png" } tilefromtexture 9308 { file "tiles/9308(3240+3231).png" } tilefromtexture 9309 { file "tiles/9309(3240+3232).png" } + +// Interpolatable QAV files. +defineqav 10000 { + file "qavs/FORKUP.QAV" + interpolate { + type "index" + } +} +defineqav 10001 { + file "qavs/FORKIDLE.QAV" + interpolate { + type "index" + } +} +defineqav 10002 { + file "qavs/PFORK.QAV" + interpolate { + type "index" + loopable + } +} +defineqav 10003 { + file "qavs/FORKDOWN.QAV" + interpolate { + type "index" + } +} +defineqav 10004 { + file "qavs/LITEOPEN.QAV" + interpolate { + type "index" + } +} +defineqav 10005 { + file "qavs/LITEFLAM.QAV" + interpolate { + type "index" + ignore { + frames 3-6 tiles 1 + } + } +} +defineqav 10006 { + file "qavs/LITEIDLE.QAV" + interpolate { + type "index" + } +} +defineqav 10007 { + file "qavs/LITECLO2.QAV" + interpolate { + type "index" + } +} +defineqav 10008 { + file "qavs/CANPREF.QAV" + interpolate { + type "index" + } +} +defineqav 10009 { + file "qavs/CANIDLE.QAV" + interpolate { + type "index" + } +} +defineqav 10010 { + file "qavs/CANFIRE.QAV" + interpolate { + type "index" + } +} +defineqav 10011 { + file "qavs/CANDOWN.QAV" + interpolate { + type "index" + } +} +defineqav 10012 { + file "qavs/CANFIRE2.QAV" + interpolate { + type "index" + ignore { + frames 14-99 tiles 2-3 + } + } +} +defineqav 10013 { + file "qavs/CANDROP.QAV" + interpolate { + type "index" + } +} +defineqav 10014 { + file "qavs/CANTHRO.QAV" + interpolate { + type "index" + } +} +defineqav 10015 { + file "qavs/CANBOOM.QAV" + interpolate { + type "index" + } +} +defineqav 10016 { + file "qavs/BUNUP.QAV" + interpolate { + type "index" + } +} +defineqav 10017 { + file "qavs/BUNDOWN.QAV" + interpolate { + type "index" + } +} +defineqav 10018 { + file "qavs/BUNUP2.QAV" + interpolate { + type "index" + } +} +defineqav 10019 { + file "qavs/BUNDOWN2.QAV" + interpolate { + type "index" + } +} +defineqav 10020 { + file "qavs/BUNIDLE.QAV" + interpolate { + type "index" + } +} +defineqav 10021 { + file "qavs/BUNFUSE.QAV" + interpolate { + type "index" + ignore { + frames 6-65 tiles 0-7 + } + } +} +defineqav 10022 { + file "qavs/BUNDROP.QAV" + interpolate { + type "index" + } +} +defineqav 10023 { + file "qavs/BUNTHRO.QAV" + interpolate { + type "index" + } +} +defineqav 10024 { + file "qavs/DYNEXPLO.QAV" + interpolate { + type "index" + } +} +defineqav 10025 { + file "qavs/PROXUP.QAV" + interpolate { + type "index" + } +} +defineqav 10026 { + file "qavs/PROXDOWN.QAV" + interpolate { + type "index" + } +} +defineqav 10027 { + file "qavs/PROXIDLE.QAV" + interpolate { + type "index" + } +} +defineqav 10028 { + file "qavs/PROXDROP.QAV" + interpolate { + type "index" + } +} +defineqav 10029 { + file "qavs/PROXTHRO.QAV" + interpolate { + type "index" + } +} +defineqav 10030 { + file "qavs/REMUP1.QAV" + interpolate { + type "index" + } +} +defineqav 10031 { + file "qavs/REMUP2.QAV" + interpolate { + type "index" + } +} +defineqav 10032 { + file "qavs/REMUP3.QAV" + interpolate { + type "index" + } +} +defineqav 10033 { + file "qavs/REMDOWN1.QAV" + interpolate { + type "index" + } +} +defineqav 10034 { + file "qavs/REMDOWN2.QAV" + interpolate { + type "index" + } +} +defineqav 10035 { + file "qavs/REMDOWN3.QAV" + interpolate { + type "index" + } +} +defineqav 10036 { + file "qavs/REMIDLE1.QAV" + interpolate { + type "index" + loopable + } +} +defineqav 10037 { + file "qavs/REMIDLE2.QAV" + interpolate { + type "index" + loopable + } +} +defineqav 10038 { + file "qavs/REMDROP.QAV" + interpolate { + type "index" + } +} +defineqav 10039 { + file "qavs/REMTHRO.QAV" + interpolate { + type "index" + } +} +defineqav 10040 { + file "qavs/REMFIRE.QAV" + interpolate { + type "index" + } +} +defineqav 10041 { + file "qavs/FLARUP.QAV" + interpolate { + type "index" + } +} +defineqav 10042 { + file "qavs/FLARIDLE.QAV" + interpolate { + type "index" + } +} +defineqav 10043 { + file "qavs/FLARFIR2.QAV" + interpolate { + type "index" + loopable + } +} +defineqav 10044 { + file "qavs/FLARDOWN.QAV" + interpolate { + type "index" + } +} +defineqav 10045 { + file "qavs/FLAR2UP.QAV" + interpolate { + type "index" + } +} +defineqav 10046 { + file "qavs/FLAR2I.QAV" + interpolate { + type "index" + } +} +defineqav 10047 { + file "qavs/FLAR2F.QAV" + interpolate { + type "index" + } +} +defineqav 10048 { + file "qavs/FLAR2FIR.QAV" + interpolate { + type "index" + } +} +defineqav 10049 { + file "qavs/FLAR2DWN.QAV" + interpolate { + type "index" + } +} +defineqav 10050 { + file "qavs/SHOTUP.QAV" + interpolate { + type "index" + } +} +defineqav 10051 { + file "qavs/SHOTI3.QAV" + interpolate { + type "index" + } +} +defineqav 10052 { + file "qavs/SHOTI2.QAV" + interpolate { + type "index" + } +} +defineqav 10053 { + file "qavs/SHOTI1.QAV" + interpolate { + type "index" + } +} +defineqav 10054 { + file "qavs/SHOTF1.QAV" + interpolate { + type "index" + } +} +defineqav 10055 { + file "qavs/SHOTF2.QAV" + interpolate { + type "index" + } +} +defineqav 10056 { + file "qavs/SHOTF3.QAV" + interpolate { + type "index" + } +} +defineqav 10057 { + file "qavs/SHOTL1.QAV" + interpolate { + type "picnum" + } +} +defineqav 10058 { + file "qavs/SHOTDOWN.QAV" + interpolate { + type "index" + } +} +defineqav 10059 { + file "qavs/2SHOTUP.QAV" + interpolate { + type "index" + } +} +defineqav 10060 { + file "qavs/2SHOTI.QAV" + interpolate { + type "index" + } +} +defineqav 10061 { + file "qavs/2SHOTF2.QAV" + interpolate { + type "index" + } +} +defineqav 10062 { + file "qavs/2SHOTFIR.QAV" + interpolate { + type "index" + } +} +defineqav 10063 { + file "qavs/2SHOTDWN.QAV" + interpolate { + type "index" + } +} +defineqav 10064 { + file "qavs/TOMUP.QAV" + interpolate { + type "index" + } +} +defineqav 10065 { + file "qavs/TOMIDLE.QAV" + interpolate { + type "index" + } +} +defineqav 10066 { + file "qavs/TOMFIRE.QAV" + interpolate { + type "index" + loopable + ignore { + frames 0-7 tiles 0 + } + } +} +defineqav 10067 { + file "qavs/TOMSPRED.QAV" + interpolate { + type "index" + loopable + } +} +defineqav 10068 { + file "qavs/TOMDOWN.QAV" + interpolate { + type "index" + } +} +defineqav 10069 { + file "qavs/2TOMUP.QAV" + interpolate { + type "index" + } +} +defineqav 10070 { + file "qavs/2TOMIDLE.QAV" + interpolate { + type "index" + } +} +defineqav 10071 { + file "qavs/2TOMFIRE.QAV" + interpolate { + type "index" + loopable + ignore { + frames 0-7 tiles 0 + } + ignore { + frames 0-7 tiles 2 + } + } +} +defineqav 10072 { + file "qavs/2TOMDOWN.QAV" + interpolate { + type "index" + } +} +defineqav 10073 { + file "qavs/2TOMALT.QAV" + interpolate { + type "index" + loopable + } +} +defineqav 10074 { + file "qavs/SGUNUP.QAV" + interpolate { + type "index" + } +} +defineqav 10075 { + file "qavs/SGUNIDL1.QAV" + interpolate { + type "index" + } +} +defineqav 10076 { + file "qavs/SGUNIDL2.QAV" + interpolate { + type "index" + } +} +defineqav 10077 { + file "qavs/SGUNFIR1.QAV" + interpolate { + type "index" + loopable + } +} +defineqav 10078 { + file "qavs/SGUNFIR4.QAV" + interpolate { + type "index" + } +} +defineqav 10079 { + file "qavs/SGUNPRE.QAV" + interpolate { + type "index" + } +} +defineqav 10080 { + file "qavs/SGUNPOST.QAV" + interpolate { + type "index" + } +} +defineqav 10081 { + file "qavs/SGUNDOWN.QAV" + interpolate { + type "index" + } +} +defineqav 10082 { + file "qavs/2SGUNUP.QAV" + interpolate { + type "index" + } +} +defineqav 10083 { + file "qavs/2SGUNIDL.QAV" + interpolate { + type "index" + } +} +defineqav 10084 { + file "qavs/2SGUNFIR.QAV" + interpolate { + type "index" + loopable + } +} +defineqav 10085 { + file "qavs/2SGUNALT.QAV" + interpolate { + type "index" + } +} +defineqav 10086 { + file "qavs/2SGUNPRE.QAV" + interpolate { + type "index" + } +} +defineqav 10087 { + file "qavs/2SGUNPST.QAV" + interpolate { + type "index" + } +} +defineqav 10088 { + file "qavs/2SGUNDWN.QAV" + interpolate { + type "index" + } +} +defineqav 10089 { + file "qavs/NAPUP.QAV" + interpolate { + type "index" + } +} +defineqav 10090 { + file "qavs/NAPIDLE.QAV" + interpolate { + type "index" + } +} +defineqav 10091 { + file "qavs/NAPFIRE.QAV" + interpolate { + type "index" + loopable + } +} +defineqav 10092 { + file "qavs/NAPDOWN.QAV" + interpolate { + type "index" + } +} +defineqav 10093 { + file "qavs/BSTUP.QAV" + interpolate { + type "index" + } +} +defineqav 10094 { + file "qavs/BSTIDLE.QAV" + interpolate { + type "index" + } +} +defineqav 10095 { + file "qavs/BSTATAK1.QAV" + interpolate { + type "index" + } +} +defineqav 10096 { + file "qavs/BSTATAK2.QAV" + interpolate { + type "index" + } +} +defineqav 10097 { + file "qavs/BSTATAK3.QAV" + interpolate { + type "index" + } +} +defineqav 10098 { + file "qavs/BSTATAK4.QAV" + interpolate { + type "index" + } +} +defineqav 10099 { + file "qavs/BSTDOWN.QAV" + interpolate { + type "index" + } +} +defineqav 10100 { + file "qavs/VDUP.QAV" + interpolate { + type "index" + } +} +defineqav 10101 { + file "qavs/VDIDLE1.QAV" + interpolate { + type "index" + } +} +defineqav 10102 { + file "qavs/VDIDLE2.QAV" + interpolate { + type "index" + loopable + } +} +defineqav 10103 { + file "qavs/VDFIRE1.QAV" + interpolate { + type "index" + } +} +defineqav 10104 { + file "qavs/VDFIRE2.QAV" + interpolate { + type "index" + } +} +defineqav 10105 { + file "qavs/VDFIRE3.QAV" + interpolate { + type "index" + } +} +defineqav 10106 { + file "qavs/VDFIRE4.QAV" + interpolate { + type "index" + } +} +defineqav 10107 { + file "qavs/VDFIRE5.QAV" + interpolate { + type "index" + } +} +defineqav 10108 { + file "qavs/VDFIRE6.QAV" + interpolate { + type "index" + } +} +defineqav 10109 { + file "qavs/VDDOWN.QAV" + interpolate { + type "index" + } +} +defineqav 10110 { + file "qavs/VDSPEL1.QAV" + interpolate { + type "index" + } +} +defineqav 10111 { + file "qavs/STAFUP.QAV" + interpolate { + type "index" + } +} +defineqav 10112 { + file "qavs/STAFIDL1.QAV" + interpolate { + type "index" + } +} +defineqav 10113 { + file "qavs/STAFIDL3.QAV" + interpolate { + type "index" + } +} +defineqav 10114 { + file "qavs/STAFIRE1.QAV" + interpolate { + type "index" + } +} +defineqav 10115 { + file "qavs/STAFIRE2.QAV" + interpolate { + type "index" + } +} +defineqav 10116 { + file "qavs/STAFIRE4.QAV" + interpolate { + type "index" + } +} +defineqav 10117 { + file "qavs/STAFPRE.QAV" + interpolate { + type "index" + } +} +defineqav 10118 { + file "qavs/STAFPOST.QAV" + interpolate { + type "index" + } +} +defineqav 10119 { + file "qavs/STAFDOWN.QAV" + interpolate { + type "index" + } +} +defineqav 10120 { + file "qavs/2NAPUP.QAV" + interpolate { + type "index" + } +} +defineqav 10121 { + file "qavs/2NAPIDLE.QAV" + interpolate { + type "index" + } +} +defineqav 10122 { + file "qavs/2NAPFIRE.QAV" + interpolate { + type "index" + } +} +defineqav 10123 { + file "qavs/2NAPFIR2.QAV" + interpolate { + type "index" + } +} +defineqav 10124 { + file "qavs/2NAPDOWN.QAV" + interpolate { + type "index" + } +} +defineqav 10256 { + file "qavs/BDRIP.QAV" + interpolate { + type "x" + ignore { + frames 0-23 tiles 0 + } + } +} +defineqav 10257 { + file "qavs/CREDITS.QAV" + interpolate { + type "index" + } +} diff --git a/wadsrc/static/filter/blood/qavs/2NAPDOWN.QAV b/wadsrc/static/filter/blood/qavs/2NAPDOWN.QAV new file mode 100644 index 0000000000000000000000000000000000000000..4a63dce6310b3fb03aff412eb63b83108048071b GIT binary patch literal 1260 zcmc(dF$%&!5Jg8t!P3^k!UL$$6WAzXWh2-oIhdU%P|yo_20KgBiWYfvI7yN;#gfmcE3(5b%kx~ML46E;iQO&Gl|Miu z?^={ULnrS?ac0#E%km67PvC8V!|#D^S;#xj%3r{euQAK_n|T9~%kn76Lf*9~uUW|Z zQB_|D=i9yX3dI|k!rKbkyCe&F*P{Fh?8|sRif2{5uq?wM%M9Mu&{~0R{}_4aS@|P! WkgqXI6nHMSe_ob_d<~v|ZG8ZtbZ6)Q literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/2NAPFIR2.QAV b/wadsrc/static/filter/blood/qavs/2NAPFIR2.QAV new file mode 100644 index 0000000000000000000000000000000000000000..3c927d976c523ba1e056d95182e0e64e904aa685 GIT binary patch literal 1872 zcmb`IF-ikL7=_26h=mvM0(PQaK%*kq2sVNs7D+m7^aOhXZM0A^MiI0W3k3y%JY5nMZhvhmSxtTL>B3d z#x|UDYCq$8vIG>1vxVk3R&T`VMBl~3B!Do>TSN+2ZBgL-m>=WkDz z4K&9AmB#VYTT}P&kfqd@Wer{LY5b1a#}+E}2leC{&tJ--p4k4YC+ldAgPz8z=l(Al7C@7S9Bb&! zCaR{~MLoH}^SiQ$gXe%noFbazpr>(CZqf9s5*{X~s(&u}9b1ZZo27^AQS@2XM|rk7 zmqr|AsY)*+*ev24qJ?~kd}7WSy5pdCIu2|W=K)~Al!ryuP)~RsL7zc?kmrOh&Mn%D z^iv8L0aKhKG{>=?#koLtoPWrod-{ev`2Jsp(Wlwq`sv%8(8Tfm?}&3r7RPBb%P$av B_j3RM literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/2NAPFIRE.QAV b/wadsrc/static/filter/blood/qavs/2NAPFIRE.QAV new file mode 100644 index 0000000000000000000000000000000000000000..e291171da94ac94776931574723039dcb4e85948 GIT binary patch literal 2076 zcmchYyGjE=6oy9&MZp*F1?;@G7Dhx1ZEOS;ERu9u`2_m}R$8d2QM^2XC|FsDh=plH z1(lQryhLjuerIPVtcTrANTLg~v-$VTng5%avzboKbeq;kg7Rr2?$TK(PhjSgFeJ_-j4R@dSF?k{|>Q; z9(M`*A+fJ6KA5Br{S@s{>2Y})(YIhpk-%pu*-Rdtuq@NJ`;s*lp!$lw3Cliyzm(^G z^b@parR(v{_`MCw2#KQhWeMF<*!xq$gu-%w-;(k?fG+!Tuk?geb-&8NGRkPpBHk99 z9;z4dHi>@cyah8$d{n&*qRYPAxOlrP!KlW&TGENPsM?n^GmeE@=Pj_a&YH;jzldHy zWD<`~&gvRkrS1ZqSO0bi%N(=4DbKPm6X=>{6P7b#{qLC6U5I4`y;67RNp<%ZfWk6Q z;!njQXC~^5$v5QOu@ru@tfGTpMIMss&JSzy&F#y(Vi|&Ein;Pi-+|>KhGh@kuSeM| u3)N(|$?4+iMgA}3j6EopU0ANr{Cbf?glCUV@SAAgm=7=6(b=nJ$r)nyscN6^pEo?Hh5q7PMnaUIoV-xDx;@ z{PWMbh;LIkLEprb0%3W@s#{*L)AKsQ=eyxzdBy6#a)#}Tr4kg z5ng*RVSP!d7FbK_>j0hgMJ}?h)XPIThTzhqT*S9I{PX8rx!4@Z#quH-doPiTkbMZJ$hO7$h~^%>zKijanfWVN<2!VzqRfa)D`eYYEu*<%^y5IeDr~BR;RHpjY_rIr3om1z3>eT(_=>3o1HjIa` zV+dgb`YQS@^wsosduOb9I&G&AmN5K%{rdGGWRT}|n}%>SpP#kx$n&Yl-vst&!Sj?K zkY5G%MGIGc(6-}7Asoo0*VQu>!X)Du;{3VjISJdABG{PJ^W{5iI~M%gVq4M~!YRnF z0CS(xtUTpM4d+s~`#-r`FL;`*{yJQiQ# zhHdTg{{n!@nf#@kIhFAb#Wu!~Zhl=4R(;RD$jQ6FtMA~-58B*+x&1=1nQ^2WuS58J zTikdh{r$dZ+u6v}eP(QvGjgo%Gvi3t_iNEteb2tg$veQS??d`x?mvj054Cw&jmwyM zv_I>=BaSZ%l0E&tl-x(;ALp3+^K}c4Jj==DU>ub+49>pD$y>qK75O23(dPTnQSxFz zqi0MX_h!X(zEvOleKD8MO?GA5@>tHC#Q2+H8{hh`w{pgOskSkWbbU82zo@g7FLKhgK5pU4 z584)D^E2p3zD$)IUp^-H9st+R-dWv$ACNQWvtZ>+UR=(c!nksVaiq)18_`$qJUK3M zQV!HR54iG!w#z4)y8V_mvscY|)zlaBDEUHMns~)N_2%+9Ac*yGOwODL-sPC`*CX4_ zeK~1;88!Fi(t)g->PRd$hjF?02>Oj#?>>NFtGUl|tegAgJ~mzMTVJYtj*FbMzEt@k z<06;##h!GI-CH;o$32rDLVvoa)wq<3&^RRj7c)exFD`QCDDZAvO5Ojp$Y)>Vq;dJA zg~w)zf&O}q?Zu4b3pVGPIBvWiLwC9l%;1Z*oypv8-Ip`RflpWW&6k>A*%vu!zSR60 zGA?pyAJ$F#zpUqr@$#&GiQeK^UY!XvbKkpVWVxxcscYE&9nB!kiVOH8GEr|@&3*QFWw*Y_8SmcR`cmqCmCsR@lh&6ipKNF?G{>QNaVWB> zCdL|jhAcSXjLUh01P-4Sr&q;>y;qG!l_QP;4o z)cr2UV7@LbH0@OSUtmsjEniw_9fR5R-V0;+^?L;Q#{Aa{mL1}k*@qT?EiG<*zMq>=8L{~ zuJp%+h3C-R=QEJ&p2>3N81U|yTV7fcTcWUu)ki{+GI6 z8WAbsk~WsElQsrs^ISOUHs z(38&X_;N1T=E}Pe|F|K~SN=`#CyKl_plPg literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/2SGUNDWN.QAV b/wadsrc/static/filter/blood/qavs/2SGUNDWN.QAV new file mode 100644 index 0000000000000000000000000000000000000000..eb1c89c37e4889e79cd0f854eef26b14ddadeacc GIT binary patch literal 852 zcmWG^43lDDVqjolU|?VcVi6!-0K~_E7#mo@!@v*^l=%7o|9=JsM!1sCKyg1H?>Ulq z1CS3=zYr(}R}a3kVu^X>nI4b4 zk26xwr`)!y+|@qVKiaWXvn?~*AohqS;)C$P7;fphkZgfQfp0c*Qor2PTDQ9`3do_qt(+PM_;paqYz zU*s8iEPv;s`Xs$c#bPq)aE>X**~SN@{M EKR-dK<^TWy literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/2SGUNIDL.QAV b/wadsrc/static/filter/blood/qavs/2SGUNIDL.QAV new file mode 100644 index 0000000000000000000000000000000000000000..f50cd17d7aa9394cf74e9770a9da9d63b95d364b GIT binary patch literal 1260 zcmWG^43lDDVqjonU|?VcVmTmQ0K~_E7#mo@!@v*=l=$%f|9=JsM!1qsKye=+?;etP z1CS3=zZfV6R}azcpF;JQz#V?>VIavJyN;9PR1(YTS!Y=^FWU5C1 literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/2SGUNPRE.QAV b/wadsrc/static/filter/blood/qavs/2SGUNPRE.QAV new file mode 100644 index 0000000000000000000000000000000000000000..b71ca0f1eb77f19dbc05b6829c4f6b15ebb03776 GIT binary patch literal 852 zcmcJNEe^s!5Jm@591?}*B6v&DW?S}nfSDGS$h_uKKxgk%ai-s#0$32mlG0pQ_q*}?^A_Mr@gx{wUGzK8 zY4~*>Z1Wf1M$~tY8|L~SSFloV4||~B!*5OxSAE^#zsnSF3mX1ewW4<>f+x-!wIO5l XOISc%?6O<*PVV5D)5A@nsrT^%t#4^d literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/2SGUNPST.QAV b/wadsrc/static/filter/blood/qavs/2SGUNPST.QAV new file mode 100644 index 0000000000000000000000000000000000000000..7b907a9d31d5f410a4e4134d9309ee6cddba425f GIT binary patch literal 852 zcmb`FO=Hs? z=xSPU6S1JCyS{l{{c4!g!&c48W)(9#AnW8c`9yAuQPu2{7t))Ril-hkc$0OW=ehHY zTKX$k)Q2PA@OyaF!=)d<+pLSw$8Qk7h5d>*O3BTLcMN&E;Ot+x%iGA?3B^akGivF3 zu$A**ZVrEdy(e7yAzZV}0{2FEL;2qXaad~F15Wj=%dzLP}{U0bUQq5gQtW)>KJ|i{D02cMZoc_s2 Yc+@AeoN?|=eV*g!o3n`fkZAuCYo3>)Hvj+t literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/2SGUNUP.QAV b/wadsrc/static/filter/blood/qavs/2SGUNUP.QAV new file mode 100644 index 0000000000000000000000000000000000000000..cd282710e2a94ff0437ad20a0a8f0f53d1f3da21 GIT binary patch literal 1056 zcmc(eu?_)25Qc})Y3OJ@iC!cWRHD!*J;FYMQX?T68ijZVZ=qE>*Qw4oyPL^M)OVZP z%+9y}Wd2F^#)D~3>LN`EyGz`&@9cl;)Dl^9(f5}%lf2*yvUb89XVq_tqA-0dQT+jK zdbsM#TPxWOk^|qv8!#9n_IIFh_G57ug zcjT(y!Au`Z-tY_D^cBsbZ|ReGCKdHIB0dxD$aNNdOQw&r<{aO#T*@BBFQJF7ge=x%wWjsUsT>2mti!;L-tZs37PRQoOJk`q;ykv2D yHsCdj>*a?xW>}zBoL_j3$X3<$Xyga~IcpU5vO-Zi&X84L_S3UNFRj?~r(RwVNmAYb literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/2SHOTF2.QAV b/wadsrc/static/filter/blood/qavs/2SHOTF2.QAV new file mode 100644 index 0000000000000000000000000000000000000000..c973e9c4490b2d01b09bcc789a661b035067c0a6 GIT binary patch literal 1668 zcmcJPzb*t(6o)SgA`*pyh({2OhLXfmh(uvUp_$nSnWqpc5=xcA6OaueQ7Y(dD-n$t z-|x=c*~#XP`Lo>Q&Yn4Q&Ueml=gi$*YtNg}UT?w}GtORNpR&8`APB-R>~t_2uZ>A# zcF6vWe9lrcBt zJypzA58GfrT)e+TsaKpc7?fwxQQEV#T;P9q{1PqsLTzAoPJw5~!H#?dQ=haP5xZdT6D@DQ#1}mxvvg_pmWX;7 z=uJHw;-9vJgcM;*%K^Xn*^|F$iE|8l&ITk}ieiWLYxWj_+8Cx@XFHL4cS}tLKIewL4`D2~xL9;Y?#?~z(j_*va%lQEm C?v(NX literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/2SHOTFIR.QAV b/wadsrc/static/filter/blood/qavs/2SHOTFIR.QAV new file mode 100644 index 0000000000000000000000000000000000000000..3acf42e1f8e030b1235cb68806a7eae8c60a3add GIT binary patch literal 2688 zcmeH}yGjE=7=_0RD57W~2o@q*+1OZ!V58u*5K@>Ff88g`OgM+CNq`ocg^K;mvgQSZ3XQRt%R1( z=c6bp6wpn5%yc-ngwfBHO2xS*dFH_varI<)QFlLf=sCx;@&pw<7vS=Mf8}X4>g7)7 zCUE`08V0LEjwLUFi3cZZSi}83v|5%TdaQx(?UkO8k^HlRo+CUfPw>-o0xr)tS*$;c zn#TZcSwl~ph5Qao++^V&JM1OZ=O3-`hka(*hhHA3(s=B2In+E3aL+8}eUjgRdCrU> ziyhnOH{L+w4g8-s!0%6lxI;d2^*hGyEI8Mlkp!Ou-vS#=aC#2#ZILIa=;68}PvG=y zgUb_7?agU^Si>p?YF!8t*06y7fWM9>Vhx*M`u2wB={ZJi@|Y}_;PRL(JK*xfQv~Dh zPplz_VeNisEM%5xu{|pQuT@c^~ z6t@I2|DlPy1I0lGFoTsL)Pu~~1XK$*2Py?J=QvOtZVpr&WX>F*INThBQ4j|ZNdf>X CQzat+ literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/2SHOTUP.QAV b/wadsrc/static/filter/blood/qavs/2SHOTUP.QAV new file mode 100644 index 0000000000000000000000000000000000000000..81888852dc72c27a77fc459c3f9ce75c6b120216 GIT binary patch literal 1056 zcmc(eJqp4=5JtzSAS(Wp3gS5|EK;bQphX%h6AKG(V`CwRg@uiU2e7coS#km!F@6)W zlQ7t18w0!SzRbRzkC27y^~s5%DiQJMVVp2R4Bz*IAlPiMlxI>WT4Og%NJ)6n1$)kM z91o1gURCsJsplS6*tJX#@}}5=Jr`tY8_%Dzc(|XxAyL-A6ur41O~q&6JFu?eoaKrv z6~j{%dmi8o#o4n5?y?z;1EwP%M;u&^(kl1 v0bD%U6-lMd#68S$@bx3h2>hcs_rO1#&d8oSYQ>Yw5`v2-m*og99?L9WIqXu_ literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/2TOMALT.QAV b/wadsrc/static/filter/blood/qavs/2TOMALT.QAV new file mode 100644 index 0000000000000000000000000000000000000000..023a6d5545de508cf4bf0d06890f7297efe49469 GIT binary patch literal 2892 zcmchZyH8a?5QkUA2fjjWVMAfVe_&y5Lo6_cn2>;t6oepQx3&`P5P zJ`f+oLP`n}5(+N9z!wSs!R7lM&TJ+d+H)q^yF1^VyJu#9yL)bLqwice9KzWU!U@_f z+GE;Rn%Qw1(BC~BLW6#>)oO)ssQ4!GIRYP`|LOQH{%!bs*hj}L{u%7Iai&sy)ppc9 zK)GGQe`7f?jM-64lAoDY@*<47BY_t5`! zT(wBYDVVhJI;!>uu)KDDQmO6lr2R)|oi8x_l;x&cF2nyjZhP!LY{@v2MdGw4XJBcM z!Rpv!9H(Sj=ks{^c^QK@;9Hh6W923tBkY~=vKHww3;SlgjHj#A+T83qFP-@Ld66#N z@b6h}(s3I0#kkYu5p3HyzpX=;W3Cph^F{mxmqWzYp1DHbbX>Vf$A_?a@f83TX*&CJ zupe2xzOT}BSDR^_uj0IRIYfNr)<>V`CLLc9`&RKCh*IjJ_~)>HHV?cGT~3mtnbvt2 zr^wB{UzFP*{8yHnbXT+TIUJ; zgLJt8SKh^;DA!p!F2j~eZna29-G%8Mt4Wtrt`@EHD1QDPmoC@g={;WNCLKSMv)vU| zi{f9xa~<8IDjBxBS+&l+__~|?e-fSjet6Sy-AmF@_i=i+mU~RPJcVysd`-IS0U5T8 AlK=n! literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/2TOMDOWN.QAV b/wadsrc/static/filter/blood/qavs/2TOMDOWN.QAV new file mode 100644 index 0000000000000000000000000000000000000000..63ad09a522ed4c3b526a3f83ca0fac3fc0049e37 GIT binary patch literal 1260 zcmWG^43lDDdij!#fq{V)h~l z9VR|R{E`54KNH9gXlZO7&>wK|A>x-rpf7+)4Z|<9fqvnFi4PIKBmvzk1#>fqhUS;) MK)*=9#0S_f00_}N6#xJL literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/2TOMFIRE.QAV b/wadsrc/static/filter/blood/qavs/2TOMFIRE.QAV new file mode 100644 index 0000000000000000000000000000000000000000..785bc9d230d6574b51f55c4899c9279c261f7ac7 GIT binary patch literal 1668 zcmc(fy-EW?6os#%#KIzlm6gw-h{iXtu@noj(MFB^yoVNBD7L(k+v2ZZ$bm}ME^UNrtQH$hkGyn8M&Z2*-S%x|hY5L2QmvO!44e+i3=B~~RZsr^|IfexG7SiT U27<&_0L7lc#9={gakopAx&z3;) literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/BDRIP.QAV b/wadsrc/static/filter/blood/qavs/BDRIP.QAV new file mode 100644 index 0000000000000000000000000000000000000000..cbfedffda7b89f7028cb1e5b190048c97a57f758 GIT binary patch literal 4932 zcmd6rTdPe`6vr3J|ZDJkWWh!lBnd-Mgo`ULU;wB(XoxrLIPN%7!% zc%dkZ63TH7jtDvCZ_GW+x#yX4FZ(!7M(wfJ{O_^G{Qu^fYn{c0<(sDz!;4~aQ4}NX zXTSZF_Osi5Qt^J2QxEs`^%cdi-zD#?e$Z-X68c_Sbu!YsZ2cswZ>57FxuDNgTl<~* zQq`hB|7JBlas6yt)`@=B*Z;{;9m^GZMvSmrNa%Q;$fPC7g?b*(&^V2Zj^|ec@a(%Z zAJwtkPI!i;Bca1Gm-Z#e1=owUpUKcTjf@VjO~yKw9|>=;#CuO!UMA{c*@4lL>RF!oZF-g|5-G>RT&%y`7m4*>ExkOWuK%Kh&N_F%K1iMu7$SXW z?6LScrYtw`5U{9cxo3lQM#uA`A@Dp+Vejp++6nZ^cSS#7hw`2l>6@&6jQW6G_vBPs1UkckMjgx749leqi@c{* z-VKbf$a_NISy>iS8tDGa_K)gV#?Z3U_tooiE5mXvp~E8VfoEmeNb5lNGqr#8$*vob z`di8UGMyh2EYA|2*<*JTI)8KIx)^)V2)$miCPT!sfVmSay$R2-q!?kjNWHNKjo`X) zz2w<4L@aBWJ7B>B_x=R*isS+vmhJ>2EY~wEQa?y6z19Pf+hg)~B*8MDlPZ!6Wf{S+ zavGVv1k3%11)cY2dA^lYxG7S7;1B{p3K!3a&27a*x`sF>)AOD7^ FUjQ;~HeCP! literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/BSTATAK2.QAV b/wadsrc/static/filter/blood/qavs/BSTATAK2.QAV new file mode 100644 index 0000000000000000000000000000000000000000..73e007b72f29910e82f63af6ae3ae5b53863f89b GIT binary patch literal 1668 zcmWG^43lDDdij!rfq{V)h&6zC0T3St;-sXcn4*&oEpA9U+2p1oU z43J-L0sV3ph#44$wqKlpe)$FT$AMwu7am}O+BppT;tY%zRiIxE4FkWp0R3VE^vlIz X;+G(xUw#Y|zeEE4A`8Sru^a;cH|Q;g literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/BSTATAK3.QAV b/wadsrc/static/filter/blood/qavs/BSTATAK3.QAV new file mode 100644 index 0000000000000000000000000000000000000000..7a76b2c2d4a6f7461b4aa1d2f4b0c258f251c05c GIT binary patch literal 1464 zcmWG^43lDDdij!_fq{V)h?RkO0T3St;-sXc^K=1<^p*~|NsBbz`zI> zABqf+U&??EKQs*dVh{977|<^#hlyWofquC*4E*8%j2AJWU!D&Wzx)LH0|bV8-Ur3Y OBcMOTfpIew{Q>|$!YU>J literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/BSTATAK4.QAV b/wadsrc/static/filter/blood/qavs/BSTATAK4.QAV new file mode 100644 index 0000000000000000000000000000000000000000..f5570fa03e472a6e9baeeaa402d4e2c9459352c5 GIT binary patch literal 1668 zcmWG^43lDDdij!rfq{V)h&6zC0T3St;-sXc^T`276Ey8|NsBbz`zI> zABqf+U($dMKQs*dVh8k#_b~E{>@e|*12A6R1Jl>}VUWf^ez^zq$E{)FmmNTV{2nHL PnFsWT47d;;dSx;I-`O=O literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/BSTDOWN.QAV b/wadsrc/static/filter/blood/qavs/BSTDOWN.QAV new file mode 100644 index 0000000000000000000000000000000000000000..24563d9693f3e49cf57db06d513ba17845e0fca7 GIT binary patch literal 1464 zcmWG^43lDDVqjorU|?VcVr3v+0K~_E7#pzUWMG&Cln?+*GQyR(0>u~o|Ns9p5Hm0! z#Ni4CA;Sjf<{3cu{zh}NJy5(3=w1b|n@9aZ@2Il{hJQCOPQIhXivv)63eYiy$lvWg^Ok5nnj{Do_IY`MrNK`(04%) zJW&6-U68`YB`=)+%w`NOKQwLVdoXz`;^LAQ&i{byOTs4pzf7P#LoU%POEGPYYhK0( z_?F1O16~_w6$xJf6zr3^xa4IBPnQ^%Yo56*pjDM|8DPKmOq9>*q|%Fr{73Ne3AqRd zq6YLSw5%d7u6gm1eIb!QbD4w7E5S>arF3F0KKAB<7rt9A;iV>7N9PFNZB}4%SHwlT FmoFL4lDq%_ literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/BSTUP.QAV b/wadsrc/static/filter/blood/qavs/BSTUP.QAV new file mode 100644 index 0000000000000000000000000000000000000000..96465360ba9c96d9f0cc4cb2f35ee6b7e7329fc6 GIT binary patch literal 1464 zcmWG^43lDDVqjorU|?VcVr3v+0K~_E7#pzVWMF9j|NlP=SdtO0!~rNi9mvx_6Nf7p zgpA?lmu_IZd#g#VdjYiYcLj;&6wD90^I7m|!P+Sm5A3+lb$MED)#7g?a# z#X;zoDbRS?h2*vdpj$!l5(}h7fEYO*L4MH$iabVA4^~1)0$03X^9#sXAitymX+^Lb zA@R}xWP|)-1f)L90^I7m|!P+Sm5A3+lb$>*o~-u(FBS;Mp6$}LPw$>=r&Ni{3g;3Aitym-KPk4Bg8KaKsG2|jDR%A z|FC!jE1@F+^2<@6{hVMs5#fx>2_U}|03~&i)HeXxAivlE=|2PPmpwrH#gN?V?U15jNLP<$g$j1z1EMEwUKyBa7i3Z$)6fd-sc?R^yE;PS@ f!sIAW>J80YiLHO&8txwozP zc}=b&%So&~ZGF}syr;%i;B~^Wlcfcltvz9R4EuL$J~eg)^J%+p*>l+I7-Tt%g_jnK zx1EJ!vTVZZb88QraufD1uyNlKU&8Vbw%?YWELSoAuQNaALNyGsoX5HwinTS%KG>$L zy>SZTd?2UP>8w)kI8r$ao5kIEF zLXB}>?)O~ALXE8j%bNsQL}M?Uy_K<0W2|!@+Vhv;I2FHyXbd?2HHPoNXZXf`h{l-5 zbi9nSbVVP&EFl_W9@8w*F^UC!S>oie&9%VzvV>@ie$jdFL=r3^8e<+4jhURB21|&> z*dG;jpUnWAsak@gjMw>U9`iyI?<-avrOC9fq}%J&drJ9_C`aAhA~RjTh0FtC_OvFuXoS zjY-`%EY=1h9{RF~#;W>7G$t(EdY(-t(ZhuH{GzdxSVUt!vA+=jDf-1%V~qW|{aAl$ zjIqz0tj}MlwD`j}_CqzM<0U=^SM+5Oja7{oYHU3|$DLmXjW3ID9_t5L(}7-L`8*0?P4#q>gB^ox#{G+09N*cPy8O{T#j8q=DY|C&;&ehJBA zTNCw5h{m>qMc4iQ)fnSN|BjpnONhp{Eh3HW0E^DaIV|yqZ+($GruQ~~9%Jm=_s`@w zv#ewIvWUj2=4AF`jD7vPKpHHP$8_y0_Y3>6onX=I%{tr?-1FynJ(F?DVWB1u!0yzeT3A9f z#yz{SFS+`Y%5Uag)BTt)dC#0v*W;I%8e^aKxy@qsZ0-T3#)Q2JOX&H2h{pC}Z=x|A zLjTPoF38f&FGpbK-v)HIr8(G}?LPqwSQ)=jQ7)bv}EFi zEE4-TgeL1@5sg)4;rBm;{kZjojI5!ev386Xb>|T5qOpZyAAjC6JACVlXsjv=H8zA# Vb7P;3jD7Kouy8(OU;MHV%RkO(1mpk! literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/BUNIDLE.QAV b/wadsrc/static/filter/blood/qavs/BUNIDLE.QAV new file mode 100644 index 0000000000000000000000000000000000000000..22799431846ebd4f4600b2306cbfb0064f61c799 GIT binary patch literal 1260 zcmWG^43lDDdij!#fq{V)h~^`j~Mj}X1q)R#>)p_oa`C~ S@iLtJG8Gyx!y&&6lwSb;ueP!P literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/BUNTHRO.QAV b/wadsrc/static/filter/blood/qavs/BUNTHRO.QAV new file mode 100644 index 0000000000000000000000000000000000000000..f046513858b448deeddfa5be35cf8f3a9b5d1e64 GIT binary patch literal 3504 zcmeH|&nrYx6vr=RAxab?TRZ=RKfwZ#h2Bj504t5nv#^_;vGAkF!a_+lLMb~bX|fZN zNDT{;m4)YXE;Dl$Z)VlO*uRPKE&?R^E_kncnbUq>{{V2eo63suvQ!4*Z-aMJoo_5 zSLL6!KGB?6yYD5@b)|eCMNO1FXaHt`9AemjgII_-ILi zbw#LU1#YvP-xH97EFq{fiMD9u4?>;%r|K3dknz7$?8zxKEa z8|nQCV)og%rL{)*An7l e%XF1~k-QwK`>)r$G?EtSeaXvV1LURFwEO^MV?1~O literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/BUNUP.QAV b/wadsrc/static/filter/blood/qavs/BUNUP.QAV new file mode 100644 index 0000000000000000000000000000000000000000..918c95e4cfc1f4d45b7d1d619732722d8fe46d47 GIT binary patch literal 1260 zcmWG^43lDDdij!#fq{V)h~1G4G-C&nITyfc=tto5OC-=4;%IIL`9&2d z_6*6*ASHv{FJ3@5{z7u|40#xQ2YZ>Y!{L^D1PY)@WqQ0&>d`F0T3St;-sXcAJ_GiP7EtUlieJtQ3cqv% z!}$!*U2jm_#=roImnfi{nNj?51MC+?pxAXZ^qIGKnmoSPe8H#AaM%HNr;K~ mNql~>2Wkbm57`YMzkteveQ4s7p?=u~5<7#KbbS-->r{qhpUF9Jg-HV{q)#Y-WOdmY6uIS2(qhz0V?LZEvup!g+W$oK#N D1OOWy literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/CANDOWN.QAV b/wadsrc/static/filter/blood/qavs/CANDOWN.QAV new file mode 100644 index 0000000000000000000000000000000000000000..fb9b4b5323585672e4a87171b98918e6425456b8 GIT binary patch literal 1056 zcmWG^43lDDVqjopfM7`=y#R=h12Hzx!^6OE?*IS)uYj0=ff20a1CX2y6n_sC+kqs0 z0Vv)M6z2xgPmsiafOQQ#L5^SefzJMc>A2y`!yVqmxcbNJx%3lq#~qx5J9jE2By2#kin MXb6mk0M-xy09{8B3IG5A literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/CANFIRE.QAV b/wadsrc/static/filter/blood/qavs/CANFIRE.QAV new file mode 100644 index 0000000000000000000000000000000000000000..83d52db5a700bc8ae5da66d4dda6baf16aafff3c GIT binary patch literal 852 zcmWG^43lDDdij!tfq{V)h(&;S0T3St;-sXcX`GGz)2BYrF*1VzL` zF@>1*qgYgM)ygWKb9e7%Chh~3@WQ!fVDnyX9&hHyojLdHyv?3EetKWpl+xLh(l)&A z;d}*on<%f_92UZNt3nrZ}JayEI!BT z@{-S`Zj%EZ(bs%`X{5Da>EQlToBMO}0rPdT-(i*BaLG2-)`Ep|?;=>ffx}qN_lIAl z$BnZ*!5FAnxsGw|e@5(n7Wehi!ceulhsL2O$RG(wa3pJT6>T`^F zp(YR4{u}~miff;Fp(c;xXmd=Mg?XVSlf~wkFbnfiX!4L{QnJ2K$67)1LLDQE`LSVM zH0wTfEXsNbt7C0UHZ;}xLLFnRwDr;^i6#r{i+juW^!#m-XtJ=rxVMaum%>}NnHAl< z6q?*N6v?&U!_cY8T>IuN#aaCQzIjV=7T4qmEYxJqu?Q@MPZpnJg-;e|DcWesw`{W3DDSWbcUg(qg%+q{w2PbH% z^@W-og{9Esj-^F5FVti{f3dv_aTfQq`U{ z_sPc60~DHS-7hp*oTc!|;w*(Gi?g^U+unsZi~D4IUn$PwKH2=3IE!m?1eR!;+(Lbf zkQdkF2rL_#OxL!4ZPe$+DZ%cOBh(jaGT)0uU@7*K#cL&f@}VGkaZQde$2K&1{q&eU z|1X+60oEvc7u*|<;KzLLB7%+;nw-YCv}E_k3QZPgDfTYJSqh&l&O)Eey>ZhqaTfYy z{y(zS7jYJU#utHwn#{Uy&&9;^5>1nt7pwc?dGY<^2rSg({m4uHy)nwq_^8Pd>I*eF q3QIJfJpBBaxQ@9`j!-M3`Q#RKtZ6@nuf6-{R=1~AJmYI{z5D_IvEs1+ literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/CANIDLE.QAV b/wadsrc/static/filter/blood/qavs/CANIDLE.QAV new file mode 100644 index 0000000000000000000000000000000000000000..f8fc684cf28f475131e541d42b09626119df077c GIT binary patch literal 1260 zcmWG^43lDDVqjonU|?VcVmTmQ0K~_E7#rx}VPH7-|NsA2K+M3v2v+g|NVWsTxqviM5HEwxF90RZkqZC- literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/CANPREF.QAV b/wadsrc/static/filter/blood/qavs/CANPREF.QAV new file mode 100644 index 0000000000000000000000000000000000000000..def057abf2ae179ebc3be41f8ee7d0369b4fa262 GIT binary patch literal 1260 zcmWG^43lDDVqjonU|?VcVmTmQ0K~_E7#rx}VPH7-|NsA2K+M3v2v+g|NKOWdzXyu# zKoY+I6mJKLn*wP?uu6z}Fmn(P>A2y`!yVqmxcbNJBo3(WPS^uUC`OkjQ~0$MEw zwjPpSJ`9Xg$g&lY!xOG5(5;tKTP}*1@z0^Vd9tY eVV1^#Neu{wUfu^g8%lukek71B3FZ$yzW@NPb1tX= literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/CREDITS.QAV b/wadsrc/static/filter/blood/qavs/CREDITS.QAV new file mode 100644 index 0000000000000000000000000000000000000000..80d4b8a34f77680ae15fb5278bea6db6b2f0994b GIT binary patch literal 236676 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 TQ2mkx^NRyST!5ir(D?-b!VNUK literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/FLAR2DWN.QAV b/wadsrc/static/filter/blood/qavs/FLAR2DWN.QAV new file mode 100644 index 0000000000000000000000000000000000000000..26d93c3d4ffbafded5c9d36ec9494139ae2b2d6e GIT binary patch literal 1056 zcmWG^43lDDdij!-fq?;pC4qPW5FZEPq@<+eB-BpG?UZ=$HD7XKk#qD7-(6s&{=t`PH0=p3^Tp%KSIBv` zCvswub8!LRTVR~|l5qRa9ZJ3z`w?GqVv(M3g(un*I_yhsEJJ+Jp3re$a$yPokZt$n E7hGzV6aWAK literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/FLAR2FIR.QAV b/wadsrc/static/filter/blood/qavs/FLAR2FIR.QAV new file mode 100644 index 0000000000000000000000000000000000000000..770bd07737066ebf078672227d66573a18ef528e GIT binary patch literal 2076 zcmd6nu};G<5QYr{1L6r7%M0)TFtD(*lo3b*%t(w3U68u)1PG~JnGpkwAj$v(Y#@dJ zQ#alqd_RgUr*hI3P?S?ow$J~a|KGlJW39btW{1OhW6T`Bg7@$N9z{_c$4SDpHj5XG zInT1}9XDp?=cmIJZ!^017)A;Bbujm~PL8Ldvu!ZTtS&uF$L;=oGL4p$<96Y*%II@e zd=lFscM0Hijat%4h>c+O;CW1J;PD)-6M<=gxv&@>t;71iEc7mEMRE1g6lp3J{+zsJhTs`sAA^LtOZ(^^Q2YN(fP0-Ve0OG}?kr?Cteh^zPBILq(7-)ISx zt_+Fu3FkiG{(ptyr({0ccx9F1rg|?W&-EVLb!j=`+&jxTZ=!wp9Khk##*1_txzha~ y!uQc~MvLxHTDBNJZM>1}i=?Eb3*Q&ZIoG1^ZWHK-jTh4zxzhdj;OjV#(ee!xuFt6e literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/FLAR2I.QAV b/wadsrc/static/filter/blood/qavs/FLAR2I.QAV new file mode 100644 index 0000000000000000000000000000000000000000..ba7564bcf3325af9891b1981931988abbe3b5c32 GIT binary patch literal 444 zcmWG^43lDDdij!xfq{V;h}nR60T3St;-sXcy!hpPo|NsAIU|@uc Y<6?l+uL7!tt0$}lmr+y~AL@Pq0CU|SlmGw# literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/FLAR2UP.QAV b/wadsrc/static/filter/blood/qavs/FLAR2UP.QAV new file mode 100644 index 0000000000000000000000000000000000000000..a31a4e24094929385d16c60b5034eb24e5818097 GIT binary patch literal 1056 zcmWG^43lDDdij!-fq?;pC4qPW5FZEPq@<+exSGMn0Qm*vId-ta5Do^3&jtF01164;8f;#Gy9eavI3VvU(A^9S2nU127X!t9 z!o(3$aJ_?#0djK`&{3~pZiYG#B)$wN_68nW1U7^DsD6nCiXTN1{{U7w zxCoFxKmebsK=G0YRB#cj4&q0A>IX^=>=6QfNeB8R2yf`B|#um~eud?+$N we(?o5Tw<8`#RKRMu3_RAXP`g+{{R1Xo&g+073&7%K!iX literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/FORKDOWN.QAV b/wadsrc/static/filter/blood/qavs/FORKDOWN.QAV new file mode 100644 index 0000000000000000000000000000000000000000..fcc4a6134cfec2cb95caf06d52a626664172b40a GIT binary patch literal 1056 zcmWG^43lDDdij!-fq?;pC4qPW5FZEPq@<+ed3jo>~Cbs|p literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/FORKIDLE.QAV b/wadsrc/static/filter/blood/qavs/FORKIDLE.QAV new file mode 100644 index 0000000000000000000000000000000000000000..46be09bbe75f4b95840a85b1d73210ceab9a05f4 GIT binary patch literal 240 zcmWG^43lDDdij!(fq{V)iWdOs<3OC0l$4yDoRR`$!of5i28RDY@CJw(7(lv)761T; CHV^0k literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/FORKUP.QAV b/wadsrc/static/filter/blood/qavs/FORKUP.QAV new file mode 100644 index 0000000000000000000000000000000000000000..cef42c9570ff8749193c27ffde0f76a01ae0f106 GIT binary patch literal 1056 zcmWG^43lDDdij!-fq?;pC4qPW5FZEPq@<+ek}9g>?tE(Q7J6HpA~PnaJY2B#MoCPJeCz8swLwK!0$89gfH^L(Lx`_k#Sg2j~~EA?g literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/LITEFLAM.QAV b/wadsrc/static/filter/blood/qavs/LITEFLAM.QAV new file mode 100644 index 0000000000000000000000000000000000000000..5510da7f853c41f2bb6f4f28a89c3249318c89b3 GIT binary patch literal 1464 zcmWG^43lDDVqjorU|?VcVr3v+0K~_E7#rx}VPH7-|NsA2K+M3vh)v0m7wZQ4@dVI+ zuZMsiClQE(q2w1>!oiisCII8*6EIHpBgM-Fn5IEWb%7 literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/LITEIDLE.QAV b/wadsrc/static/filter/blood/qavs/LITEIDLE.QAV new file mode 100644 index 0000000000000000000000000000000000000000..20b670d2656215faca4f96bd92df5d642975d1a0 GIT binary patch literal 1260 zcmWG^43lDDVqjonU|?VcVmTmQ0K~_E7#rx}VPH7-|NsA2K+M3v2v+g|NKOWdzXyu# oKoY-z&4589HWK_Y1sE?MfN`>G7{tqP^2=0cybOo@GF1Em04Jt!YXATM literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/LITEOPEN.QAV b/wadsrc/static/filter/blood/qavs/LITEOPEN.QAV new file mode 100644 index 0000000000000000000000000000000000000000..cd42e930cd84fa6b7f54597b1d7791858c74df17 GIT binary patch literal 1668 zcmWG^43lDDVqoB4U|?VcVhtc(0K~_E7#ry1VPM$t|Nnnsup}ckB|}CGF$JjT9_fxL@I;t$}mgOdUBi#E_{Z;;#!a;X7OTmnenKoWldk{HAQet;zY03L0MNZrc8k`3cqpwevIVY+8!72oW?sLLw0# zQO}u9>*l6o{GN;g$uLB#tYy*Y+e4P>Z>+(0Is+bU%2Nxu*qqIoc+98&r1@V zqiQ`?Y;cA&Kf^s0-$L}-_QBQfm%>v#xUjJz_#2q3dlIk(UN*_uN2+=~HV^(H4LXQ8 zadZ7inx)Hqzfy3#Hr;i&a9#8}Hd)2JmpJ=b@G;hcw0WGZ zk>-1_i>l@bZO7ir#}D~BBPzDN7pGyj!nQ2(GQsNbfaV$S5%7G-i+bh;%-#Puga|J% Wel5QHf0@S1Fe<`z`88pogFXS$m+2n> literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/NAPIDLE.QAV b/wadsrc/static/filter/blood/qavs/NAPIDLE.QAV new file mode 100644 index 0000000000000000000000000000000000000000..94da83788362a0b0453f1b96b5437ac311bda01d GIT binary patch literal 2076 zcmWG^43lDDdg;K$z`(!?#70280EmwRu|oq8I6684nQ)-T$-tlv9%cOM0%(xszF^*&N=UWU1LmI4@3^wmXUN4FTq#XhK6gp<~cCS9@dIz z??1~NjBg_H;Tq?BKg?3W9vbw^vH_TZJVOXyuGn)Hvy?FSGM?#o3qCz26?!d?BH^Y^OjKwSq_`4g=v|E9X&@YB751Hu=Nzg3Y literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/PFORK.QAV b/wadsrc/static/filter/blood/qavs/PFORK.QAV new file mode 100644 index 0000000000000000000000000000000000000000..8eaed610c0ca3851f78ab60bfe9cf3c7d1cc0173 GIT binary patch literal 2076 zcmWG^43lDDVqoB6U|?VcVk0140K~_E7#oI|fYpKsi24RNe_$CPza#*ipbvHis$cAYV*F_0AivlH#Xxy!F!%)kgp539 literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/PROXDROP.QAV b/wadsrc/static/filter/blood/qavs/PROXDROP.QAV new file mode 100644 index 0000000000000000000000000000000000000000..5a114e5b5676eed70d076ea07c88c8757eb44ff6 GIT binary patch literal 852 zcmWG^43lDDdij!tfq{V)h(&;S0T3St;-sXcQQUln9po1op!jVx@p_=RJW%{On)qPw8ptp1K!^NA zaa#l2FK^Mr8-VH+f$D#ti4T-t5Gjd)0pyoZphG}u5s}6Mz<$vHig2NcgSmr<006zU BGP?i( literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/PROXIDLE.QAV b/wadsrc/static/filter/blood/qavs/PROXIDLE.QAV new file mode 100644 index 0000000000000000000000000000000000000000..a4712ee73a319563cb341a13b93d7d7ebc94e033 GIT binary patch literal 2076 zcmWG^43lDDdij!zfq{V)h>d`F0T3St;-sXcfm{Ugivp0oiYDF&6jua_KSUC5 z0P+U|0Qtoo=#aliZUeasqe1_1I)D9|AyV8@`QF=L?E z7bG`>loSBfn}F4V2#ERyIDcRnAipF7ouC7D2C82ifnq>uAV7$Nxue8@g}_W;gcJd7 z7X!Os@Wu-}4c3sxTh literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/PROXUP.QAV b/wadsrc/static/filter/blood/qavs/PROXUP.QAV new file mode 100644 index 0000000000000000000000000000000000000000..a7c412e0b0bdb8ec3fc69c8b2b5deb8ad743cc4c GIT binary patch literal 1056 zcmd7Pu?_)25XSLEbfOhUK|!gYmN<=CA|BxG9zdy*c4E*gMNIV}35XOz@ie-nw`3hwQQ-#>dMn|7C#RJh%7|e<-)iWhmKY wPLP+%Cb?vn9{0ubJ>JLf$}MvlN_LqNpF literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/REMDOWN1.QAV b/wadsrc/static/filter/blood/qavs/REMDOWN1.QAV new file mode 100644 index 0000000000000000000000000000000000000000..38035184c064c246cca5aa2b9c3c1e46c3292ea2 GIT binary patch literal 1260 zcmWG^43lDDdij!#fq{V)h~c)7vlZKsWqFa|6gPnn3XvXyUm10#u3>(AzJeKv#%>U4oj% w%z$3@BwX>Uy4A zZm-ij38&8c=ht)3IZyAc7VDM@UoH`)6f=n&A=gOTwjIZ5G;j=}8C9x)+s*Slr9uI3 zgQsxY3f={ug6#$GfLqY-1aE;a!R8uwgD&4a&`Sv=?^-W*pqDiEgW&Ws2D=JQFZ6yC zoL&}SD~-F*{UYe4g2E527yHml2K!lXdKrK*^mpVprl6M@v>Q$DnuK3q^io5em|yGt zAIpQundzkum=JpZYFOxH0{!VvUL4Gj6|?bO%3yK9>7|Fca)SF;!$L1Z=oznfbPc*s F(GyzJe{}!= literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/REMDOWN3.QAV b/wadsrc/static/filter/blood/qavs/REMDOWN3.QAV new file mode 100644 index 0000000000000000000000000000000000000000..69b899bffca5a5e6172c0342dce2296e494330a2 GIT binary patch literal 852 zcmWG^43lDDdij!tfq{V)h(&;S0T3St;-sXcgKnE~{NI5<%ay)*^@pC=>+ literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/REMDROP.QAV b/wadsrc/static/filter/blood/qavs/REMDROP.QAV new file mode 100644 index 0000000000000000000000000000000000000000..e3fa9bffa8518adf611afcc44b6f5cba9971b2cf GIT binary patch literal 1056 zcmWG^43lDDdij!-fq?;pC4qPW5FZEPq@<+eQ;)quozA&G-*28mMwKz?xo8t@g# zE(V4p>>$4=0>z)9iPPFIEkJu^f%d*avzHh@g8bqRRQMM~Zwc5h%0Th&XyWAf1v&gd zZfXEx^!TDyym$l6<^*Cy8q)#$MI9)@jV3%;ePylevIm0!aozYHh8Yz4*%H#iFn{c>zL`DF(%UgU>pyZ``w%te?0 literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/REMIDLE1.QAV b/wadsrc/static/filter/blood/qavs/REMIDLE1.QAV new file mode 100644 index 0000000000000000000000000000000000000000..01bfe7726a713b4a389b75389d949008d751b79a GIT binary patch literal 1260 zcmWG^43lDDdij!#fq{Vsh&_OK0T3St;-sXc*m@-K2B`RUByo_+k&enIx*P>&a6KMobY;L0!5h!+59 C_t~HT literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/REMIDLE2.QAV b/wadsrc/static/filter/blood/qavs/REMIDLE2.QAV new file mode 100644 index 0000000000000000000000000000000000000000..bac9aa63b25d76093e1918b80507611268ac7886 GIT binary patch literal 1260 zcmWG^43lDDVqjonU|`?@VhDq8mc|Nr|y%)r11S5gTS-wYI6k0jmz zlm&@zM-m6=0ErI2%EC-RuNb>_OCzUQ3p_x{c~S95)9naaPvFH%Yspw**|q8*@x z!{JCI5{=@|)YVg{R2`n4lgXq~c`4opUXG^=A0Ggp0E_#0KX@7RmpUmP*{Oe4JUPz!Da(P|U*YHx_q2Z-T7|?m)*Z+k*d9mPU;I zCg#GU&QgW@osToi44BPp*(LCz=L6`O$JE_H1;}^7Haz}USz6$tSUa)TSPdAaN_n7! zS-55%EZ(kr2mR3VF|<2EZ?YVLu{O-;W^sas_%`Dji$Gnid!(~u8h}~WF#nVArc`Gp zxqkoW(C!Pp$#M#|=kcFr`Py+tYq~DXV%Noe6G6RLmlNo>JkQjaEUcH|Kg|*}=XV+F zG6xUW!W;VzgLmUzq6bR9EoM1{c0uSJXvn!=40p5W&RP3mmd|H$BE&3RaPclY(-b|g zgG~$Wc${Y&&k?a-LhO^Ri&=&+zkMd3g<{~`HF3|I@xv_RVCMakV~vH#Ck6M`Sk|)) z!o!Q@+0D`cpF!Ws5opc6kXgnA&sCNfJUpVA?}btcU6(c(4O(MdlfLhZt_#1phUaR( vjKagMl|?D8u}oR!pNf+`u18YefTo68T##QPfQE^H4MeyNN~5ayBoXi-cneid z@Gkocj?dt^=fz^y{D2B&K=T?GIRJS*4$ literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/SGUNFIR1.QAV b/wadsrc/static/filter/blood/qavs/SGUNFIR1.QAV new file mode 100644 index 0000000000000000000000000000000000000000..fe2526330a8d49a69b244f423be13cd049a0de51 GIT binary patch literal 1668 zcmWG^43lDDdij!rfq{Vyhz)>v0T3St;-sXcl*h8{2Pp=oR=#Y+g#FP>Q9vjEc1ki;865`!4b2D%wkCVxY6GswB1atu@^KS2_207(oo005Ay BS|0!a literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/SGUNFIR4.QAV b/wadsrc/static/filter/blood/qavs/SGUNFIR4.QAV new file mode 100644 index 0000000000000000000000000000000000000000..c53cfd76d639204825c88bb3192af1c91ae76414 GIT binary patch literal 11256 zcmd6tO^6&t7=|lxvm1h9#Q&h^nryO04?&{_6^!CV2$)DrygAWD^dbvFJPCCZ)I&Ub za4xxcTKrv6$)J%C{|NpIiaGcb_25Q5>_J`Mr)H|RrgyrhYNmUgf=Rl+{<`XW`>Xf; zs;hV3od-6VwZ`0Hj5$ZYqxv=VJE33LzFpHkdti$(H|y}{rKKffI>yj3cl_76#%z`C zi@@LJeEzS~R4l)bFqZv^dHJIvESuLGbBPjoiu~>{W>Ux2*zsX8^HLRGriA4JVL1twy&j7hDlfgTES4m?D!yzLmh&{u39vM(!E&HSUdpg6 zR5Zu73Co5RSZ3ChJjTA4Qn8$^2ut6<25>l-n3q%?L$9t?TyJ;tVt`2d-;#3`?qxp;userAx1D zpQr}AoT|yA%>7gyt4fmxd-COX)y@6#(W|@43O|+mshSM;uhBT~bn(Sh&V8_?a=%E& zs3VuEzYmBxTVL66H2G@T-|Et_>al1Dlgj-f9rNp6hozBe?>Kq6QscY{mLtn{#;&?m z#eHIC4S$@N?Q+a$@+R4xCeIl&rOBYnmCrE^VN$tYq{+k#mSbRPE@NR0dAaN_dwUy; zEY&y9{WFZ!dEYOqm3|HLW#DfW7BPdx&86ltmTB2}e{@(HJ}>pv{hKsaEEaT(HB}x9 zF@xn*FlM}P+b6QFPJ{bk3HM>j@`8?mWfb>eQn_EGV?|FMt-eSXKP6w8RuA_sTr?Kk zXD=-_FRWo$E5_yptp>{{U}<biSJ zZu&XaswFS**OEHeROPE{%?TYdMpti6m(B&V~*Xbn_{_-j%}BJEcel| z3`--^u{Ly6UOKe`?3v(PxF$EPf3W%Y8H% zEcsgL-z(i(<%o~jj{CYl2gataFLM*>qVh)F-=$t-xlgT}mVci6K4!;@)-smL11{(g z9V0L3SZsaqI+m|5et*oZyP6)$nZoan_+O=QPm-^O_a9CZ{QJvq^ck^tfsT=vZvua- zbJi+we;&IG?e%c+9tHmF4LW``s=?xQEH*EGPbr@lV!J}Iz1zXUdeZ7w)X+V?BfD?n z)?-;;n8%`iLOb>4Mj3t#o^#nc8BL~Md=~gyof8|{>+;g{vB^--&^^ArzE3}yR_q=M zi{I<}A&9LEi+`_lb)+*VtzsfJ_GjFBxYZvEx|dp{Z(yJZjg zh5vS8nNc5))6WhR6292A*!epsx6j?Dy!{%`sso#nz0i!OnW`d-`cEu$=BZXJMhf9F+ZE`po9o9)|^eJ&Ije z#^htoafgL(;)k)fbl_r}cUT_O>5JIGqGrv4>xa61w&UOKr;X)l`MC9o%`mROGAkeA z_OYEdGv<(D-YAP(M=1cFwB4}Npkt5dSVIL^W?T%<%l0gGu(+5Xbyz0le;@Xi4%DpK z@31_h<0r9adD+h}12^*Wl}gHAB)AW$3_Lqe<_aCl>h($ literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/SGUNIDL1.QAV b/wadsrc/static/filter/blood/qavs/SGUNIDL1.QAV new file mode 100644 index 0000000000000000000000000000000000000000..78fc956c6b8f95c10e9803c0c9bea575be5293fa GIT binary patch literal 1260 zcmWG^43lDDVqjonU|`?^VjCb{0K~_E7#o<)!@yt$lz9IC|9=JsMr=w@#J&L4s{uu> jBB^gcQ892FQvLFN82RPHF!IaCVdR%j!^kh62bo_0Ns2%V literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/SGUNIDL2.QAV b/wadsrc/static/filter/blood/qavs/SGUNIDL2.QAV new file mode 100644 index 0000000000000000000000000000000000000000..343dab4ecebd3055120e5fbdc6830f7b59b27797 GIT binary patch literal 1260 zcmWG^43lDDVqjonU|`?^VjCb{0K~_E7#o<)!@yt$lz9IC|9=JsM!1qMKyfu7?<$gb h16+1+GI06j{V?*&hhgNGkHg3>pN5fNJ`WMU003NHKnnl> literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/SGUNPOST.QAV b/wadsrc/static/filter/blood/qavs/SGUNPOST.QAV new file mode 100644 index 0000000000000000000000000000000000000000..6f7ecfb8e8750534cf82d466cbc013d614b5f63f GIT binary patch literal 1668 zcmchXyGjF56h)7sU}0e?Rw=~7LbOoSLJX)_DrkHa!c0Iv<9>pl5K#Za&My$bLINTZ zFy`f}8`qu;$yJ~jx$pFNYgo7vo$^_NORW;VdcFba%IMi2yH80PbATX8yU zwgq~MqR6a|Uo*DH&DPkyCHW+sy42yBxo0KvO@$b9y)ME=q1t&>g#o+%1$ym|-zPcP^6aERvD_p-x#StMWb zdIP3L6`n~>uf2K)7Qg;u73KA;*elOmVL6_=F?|4yTD9o_ literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/SGUNPRE.QAV b/wadsrc/static/filter/blood/qavs/SGUNPRE.QAV new file mode 100644 index 0000000000000000000000000000000000000000..29b60237ff1f6901ba94a34aaafe9556847b2f54 GIT binary patch literal 852 zcmWG^43lDDdij!tfq?;p1%P+~5FZEPq@<+e(r~m)|GcXJtzt{lX z{1eH|Aa8vH`b7swKSvU807(pD0E!n&p!+@`xf$f#Pe5@^Abk%>ya6OJhylniWF$+_X_}~G%cb4 literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/SHOTDOWN.QAV b/wadsrc/static/filter/blood/qavs/SHOTDOWN.QAV new file mode 100644 index 0000000000000000000000000000000000000000..3b71ed7f7a07f0c73104bb04b712a832069d6366 GIT binary patch literal 1056 zcmWG^43lDDdij!-fq?;pC4qQ85FZEPq@<+e7q*C literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/SHOTF2.QAV b/wadsrc/static/filter/blood/qavs/SHOTF2.QAV new file mode 100644 index 0000000000000000000000000000000000000000..af5ea80f062f3eee833cf28ee96cf9a86afd724b GIT binary patch literal 1668 zcmWG^43lDDdij!rfq{V)h&6zCJ`f)V;-sXc9bDI8X>H@Bpfp1Ij!kQax5fC=|r!7cHRKKqmqL#E%caZ0rQcFKR%k z4@iE&ryjd0l!=A`<3#{y#1SMnGywUac+myYfehCN0 zizv`}N3p~UD6fI?94ubI%t1`x^NTXj-G7n%IEcN0*J+^qA`evYZJ78)2I!ZMgWN9w Dfmk#X|V}q60LYA8Z4}FAwn82J#Ci z+`c0D1)q96Mv*NQ28`L z<3#}IzGGP81>_e6u-hT=0%i_k0-s;>fbItQbEw1%*r`|uP&uXw7atn&0(UMN1LPMO Ppx8&GatTezpx^=kPHR1V literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/SHOTI1.QAV b/wadsrc/static/filter/blood/qavs/SHOTI1.QAV new file mode 100644 index 0000000000000000000000000000000000000000..97f44fe2062e255c7ad41fb6a361c406a2f289a2 GIT binary patch literal 240 zcmWG^43lDDdij!(fq{V)isu9A<3OC0l$4yDoRR`$!htIn1A`2Z_woP#{|pQuT@c^~ Z6lVuAf1ruG1I3Mi;(yV^q1xz90RVWd=71qHPTE;E%GDy2x)2f349N>GF)TgMHlw! zn{IR&fDH|&O9nPITw~%zmjyb!FH*fr54@%QzML*Qu&&`66EC{V(cuw7_!zMg@6w6g isxDh_{=dK9YfQZ8!vE#=$E68=H=K9bfIkgSrSSqMmLCTI literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/STAFDOWN.QAV b/wadsrc/static/filter/blood/qavs/STAFDOWN.QAV new file mode 100644 index 0000000000000000000000000000000000000000..90361e198ac4f93c573e89946681dc5932cafae8 GIT binary patch literal 852 zcmWG^43lDDN-SexU|?VcVi6!-0K~_ExFoeGH#5(G5y*stuRIJ4%l`lWe-4Nl7*M3( iYK95}l-v)^oEgNjFJ5Ef=~bqQh8XsAp7OVAayGtXTkhp z2v$f;X+g-ufs=>%MQ0fKMSU3gMRpkZMPwNHg=rZ1Nu2gX%8Qhb5Lt$^a{Ksp6Y94Iv4fLOmM z0$thw#OQv3i4V9(fDRzmFQB+=0Ah5%z{G)40}im|{Rac?D)Jlv^UD*Y^gq=7@*2r6 K=mG#kKYo4y literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/STAFIRE4.QAV b/wadsrc/static/filter/blood/qavs/STAFIRE4.QAV new file mode 100644 index 0000000000000000000000000000000000000000..b6d7fc432d62d7b0c133b76b3a4d41d392e7396f GIT binary patch literal 7380 zcmdU!$%|b@6vl7j7^g%95fN=Mj;J&kkhr@32QM2}BG-ir#YAyhMXiN9Q6H`p5#BI_w{v+kmc zPbijOcH`=zC=S&#v8*V1`rM}H`pd6ff5nDLA%kW25k>Lf%*@PNdWvGGC4-GFk_KEh zi^tm$m*W>Hn)$hf%MS7QEaFnm&*&nphRg5b@ms{Dvq;g*&n;Y#>4=LnY^na(qnQ6u zyt|^9muj@L;|izJUU6A2l^+8xPQTx=q9}e9_6&HpwlNEzt|uJ$QV^e)9|A7K1()xH zJ=}0PMVKqrEQOGx7}C7_p?Jd@bJB*(7oN*CMNxBch99Q)maod=wf^D4nd8L}`NBRv zpGRNz5obU5|A)`Z&)5vkM9<|h@XE)0iE%kj?w)93s5y@AANya*hUc=scIXc;^b2{) z>09kpF;0G;LqFJOVm?;-7PIsbrw9CV>AsY)&sku0bVVUH^oJ4h zqNOuo@9%3JF_4!BGBND*F^G%bXY@~!{PP}tFXSbi$32RIyte#KT=TpR> z{i$na>JV&xFYI3M%Hy^EN5YIt8RMtP&gR$YF#*!ojhU_y-f`l{ZsSA8JFF{?gn>* zeR(?%p&!&a__?zAHF%OQ&gl2SdxP!EL|@1YGcdkG)?DyoT>3S()wmp})py~`wZ4dr zI<#6UTU=09&_7>qj7!<-gHx;DU|%(cI6dGW3i}E?*pswh$Z4)$n3=|<^uFr6aPD`p z+2>gMqA%V6?|A(-hTOcmK>EzSRG;rnR`Y>t8QxRh~h zCktmTr}_Fs*jDf=*5{^bT!Q__@5j=mR?R*7z1!V<0j9jzdX}P3xjPJpm8M(aN4&G~h zVUx2m$AxpsbMdjEPrW?Z*db7-2b{YNGi%gyM9Z>5USuxff+D`Cy_@j$V!hNgIP?29 z@G|B|ACm)u4Y`ot&EUNlKSuc81Q(Q*XixSr$EcZI*i8E6TVXeVcjFk?=Uc(680Snd zE(y*Z=H>ko>Yb-QEUf7%5_ey&9N^Dkf%zq2J1>D8>JHm`h z8RO^4p`GK2e*exnUGJh^k1WfA72K2Q{qPRs^qzg7hb|@NGLDVA-_78?78jHi?DV-* zgY~mUh6MfjV)MMIF_sboJ-&{ZlX-Qt-W!)kYA3GIU!_m$uVBt#=WOAYmvZ5`q;rfO zr#HfWk^BEu)~X)1%jZ>z-wTDGAs`)KwJXgmnP kg*k2KMSs3^#v}M7O1SX7YDbipa}urb_!TbW@PB;&0Y@@oRsaA1 literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/STAFPOST.QAV b/wadsrc/static/filter/blood/qavs/STAFPOST.QAV new file mode 100644 index 0000000000000000000000000000000000000000..7a9540fa2097a5f2f94b23fecca21af3d8f85e52 GIT binary patch literal 1668 zcmWG^43lDDN-X1GU|;}Y2OwSm#K(cSB(*3vGtYn#$b^G$JPZtf|NsC042T&RAW{$D zvO|mU73!BqNPb~pXc$_afVvjumzOAhSukY%@(bvX&nSLr7_xqO0rbaL6u)E)S-%_u i`r{#rUtET)Up4~$aRtRM3PaW}%YgnkkK&i1;}rnQKTneY literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/STAFPRE.QAV b/wadsrc/static/filter/blood/qavs/STAFPRE.QAV new file mode 100644 index 0000000000000000000000000000000000000000..c2b80613f6f517346e92ee107689703b3083234b GIT binary patch literal 1260 zcmWG^43lDDN-SezU|`??Vgn#v0K~_ExFoeGH#5(G5y*stuRIJ4%l`lWe-4Nl7*M3( zYK95}le_TTGi^NcIK8ia*ez^+t#{(3qGqUYz5)I67wC`oD1I3#u4iBX0G?Gl!TCuV>VXxITdeg?=W8G#nKo+Y3F7GQ($IUy(`B$lk_ zSa;HU^0QaV^;nuBZ3(#mEqNnjG-3fBJ0d;s>YVc*QX6tZe+u5UFX4|5@7yBQvV(IU zg6D*@;jLOK@R{^;*RqH6AZoD`gdw-|XW*kCEeALc;e1IrM=d4JWr7y(u@eObR4wYU z66f;Q(hZx0mX>;Kj;41quiW=V@0jjOt(+|dVaO8aqIYZrcYl-BU_Xz=xx6x;%NG<# BS3&>) literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/TOMIDLE.QAV b/wadsrc/static/filter/blood/qavs/TOMIDLE.QAV new file mode 100644 index 0000000000000000000000000000000000000000..893886d879fe754162ec92071203960138c3a8bf GIT binary patch literal 240 zcmWG^43lDDdij!(fq{V)iWdOs<3OC0l$4yDoRR`$!a)WP1A{t{ckloI{|pQuT|)~1 E0FVa@*8l(j literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/TOMSPRED.QAV b/wadsrc/static/filter/blood/qavs/TOMSPRED.QAV new file mode 100644 index 0000000000000000000000000000000000000000..ed18e723a893dad730de1b5f49890b6759883dfc GIT binary patch literal 2892 zcmd6pJ5Izv5JZRnpLn$r34}-l2o3-N#G8=71$JSj<#PZZg=_E=A-BLJNQ9gK^U79_ zn$ePXOXGHzH>ld08hdbb)=#r3ZKjl#SrgVh>y2f#WH|%V4#BtS zwZp&Lr?D;zj?OilrTNKmu9!#QJ^H)DBWjt0qty+ZKjHi0I9EKp1Ye}r4v(m%+ew|8 zTR7{#e|4Nq%MVy|Ux-sK<>h0FmMd^o?KDR8Wxk`?UX_GqTS?8FtAKe#mw^ClV7|L^O488*%UCXKop(`(Y|7h6-&wGpmBVt~lpG$c;Wh(cW z-Y*B>*_WVN^i5!;yqq(XdrWyb0gvv>h6$l7FBkM_zR0iWzN|Sd%FBSceDBMbWANy{ atT-*o%Rci%^Y`0Q=hz{5_J#Y1+5ZJ}h^A@) literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/TOMUP.QAV b/wadsrc/static/filter/blood/qavs/TOMUP.QAV new file mode 100644 index 0000000000000000000000000000000000000000..2c48e1a05cca243c06fc36bbac33a27f33e1e691 GIT binary patch literal 1260 zcmWG^43lDDdij!#fq{V)h~N#-(FOYD!!YrS7SJ!xhlyX*fquC+MEwE)GzS|2 literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/VDDOWN.QAV b/wadsrc/static/filter/blood/qavs/VDDOWN.QAV new file mode 100644 index 0000000000000000000000000000000000000000..a7a328de7b39e07198147dc2b75c426d491d70df GIT binary patch literal 852 zcmWG^43lDDdij!tfq{V)h(&;S0T3St;-sXc zZv%=y0*ZY_6Nf7pgba{hRs-Gj0?o}JzuW_gF@xQV@Z%u#0^CU;zwCnZ5N-zf;D0SmboCBHxKT3{ORi~zVa#N`7Oal1|c literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/VDFIRE2.QAV b/wadsrc/static/filter/blood/qavs/VDFIRE2.QAV new file mode 100644 index 0000000000000000000000000000000000000000..835120ce930c7efe25b569d1c7fe3577e1343c93 GIT binary patch literal 2484 zcmeH}Jqp4=5QW!(zjy-AVq>XjVdDXkT)+d^`cruT8^LpkTG`n8Q;7-+!A21ktN32G zPGuq?TNoG^9=o&eV}{+-OO1lEJTI@5N+ODgA!3fOZQF4i*F_roYiE@@_`ZKfD3u6Z zCyI?-cx$2XLU^O+E3}i)qww%cO-tL{f#(cWg--S=^rg_XlCh^&1UnJ@Y0_z-;t$3dh45Tr zzX=95?3*Mov)_Xxje5Ii(!O6X#$-_~)Ce^}IgaDHuIHf*k6zxGZ4d+}lrgDL??WGA zH5Yn#gTjVcj_}KpSvv4L6}q+v8Oso}? zgJBsWmn3CLBimKXpIj=?H$u0@psppCBxT`S(w_jfU{!Z>fnZ+#20e+*n S43H&mTz>t(jFDxjoXZRRh`8^?7;hJnCayeyknz#vrtL_b-}y`uVto}7mWLN?j>bKf|vAc_{q60 zzo?_BsU_A}9he8B`ysz3p_gy)&I~iXJYo3J=+|%XqtMG1yxf=Vo?KJR^Iolz!-RYC z&kZln;Kg4T9vxaxq~JxT!c|hFehFS&m6pPU-q)#cl@w`RLhrjOErlu4y0Bk(N6tE1 zHsCmK=ds{L%hXN6ep#cCvcAJ~K)K1;nSTjh-pA}+tPd}9qq|vz3=sDI7kGK+w_e^c Qeq!{DSGbYrCC}e2Pg9Ff{{R30 literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/VDFIRE5.QAV b/wadsrc/static/filter/blood/qavs/VDFIRE5.QAV new file mode 100644 index 0000000000000000000000000000000000000000..72a54fa2518638a7139b6c37c7eccff378cfb313 GIT binary patch literal 2484 zcmd^>PfEi;7{xy$T?n4QvvgA^y48&bNOFN5pj+$C19T&J7!Obq6SelAMS>s}6mb>b zqnRuo?q^CvhDjb@li!bThV-I$d16sj9h+GPqlP9ot`}kB8tY@hyh~0OoEECf7kKBwOqVk-SCT(8E?Vz%pSX8(zkGmq zCd_m>N6|uZ=c4uQc|K>lkas1_bQu7wki0-&4v~lG!tcuyc-O*Amz#fF%4UsCrQT;h a+`H+*ef%kGbQz;4m)!j>#Cg~M!~6jbyUV-) literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/VDFIRE6.QAV b/wadsrc/static/filter/blood/qavs/VDFIRE6.QAV new file mode 100644 index 0000000000000000000000000000000000000000..de9f36c4b48ccc598bce308f898020309516774f GIT binary patch literal 5748 zcmds*%SyvQ7=_16Eh>np3lSGSfID&H#`*|uT)2|9&)`nTN<`aNkiLdX5xk4K@`9J* zy^2s5-axG9{5EM4+NKRjjTx9B`8${M&6$}bot&5&P|dmApi(M=oI=hZZy?9x@kAn# zOybfp&9^IcRVWl*k(Fw4tnYV)1?XAEAp0)#kmUvKn1jMH2bOIYddLz*+cy_&{qTss z#L)4X3q4_DX~8_ayO;;Rd>KQ>7cTVBm;c7HRNUi-7G5p7h&V!$%zHnDcrWIsPbR-{ z=NtFSD8}U3YStq%iUnDo@cRMlf?RD7Va_d1sUut1lfi@zOeUxpqKhnh&}=`)0xi0N zIGyDbJf*c%p>n{(WZ4DBc}Q4xz;PK87XIf^?Rz2MOUsbQHMRv7ey4?DzpR6U-!Nfd bSpx^`L8|Zl$1pb_7hGejVCfe=lO#z~r24d~BFCaAUI>wr>K*74yseC`3p`B7 za)RHd@l2L6{4R{{A%a>W%Nc$j#xq%lST!@ce&}IBmJ9sejc2k9;CF6x4-wQ-`$t{+ zSQS!_k%e_}?Ux={)`8XK3cqjTnLXA8%f{$hP!E%Tb;$x_;rZg4W85zx^%&>a4lFnG s|G#r=X><=;OD&OQ3%{~5Gz4Fl#E z6AW}W5Zrbud z@$wSrE>ImqY`k;=opc;Uy#Z|y+Lizl7{eO? literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/blood/qavs/VDUP.QAV b/wadsrc/static/filter/blood/qavs/VDUP.QAV new file mode 100644 index 0000000000000000000000000000000000000000..7704d09bd11e1c244e309a3cf315c9bc7e2586bf GIT binary patch literal 852 zcmWG^43lDDdij!tfq{V)h(&;S0T3St;-sXcRcpFgs z`v3p`)zHM@3I-tq_7SJyOL(DI$f$n_)bT