diff --git a/source/games/blood/src/d_menu.cpp b/source/games/blood/src/d_menu.cpp index ec381848971..be4292249d0 100644 --- a/source/games/blood/src/d_menu.cpp +++ b/source/games/blood/src/d_menu.cpp @@ -47,6 +47,7 @@ class CGameMenuItemQAV int lastTick; bool bWideScreen; bool bClearBackground; + const char* filename; CGameMenuItemQAV(int, int, const char*, bool widescreen = false, bool clearbackground = false); void Draw(void); }; @@ -57,6 +58,7 @@ CGameMenuItemQAV::CGameMenuItemQAV(int a3, int a4, const char* name, bool widesc m_nX = a3; bWideScreen = widescreen; bClearBackground = clearbackground; + filename = name; if (name) { @@ -70,7 +72,7 @@ CGameMenuItemQAV::CGameMenuItemQAV(int a3, int a4, const char* name, bool widesc data->y = m_nY; //data->Preload(); duration = data->duration; - lastTick = I_GetBuildTime(); + lastTick = I_GetTime(); } } } @@ -83,17 +85,26 @@ void CGameMenuItemQAV::Draw(void) if (raw.Size() > 0) { auto data = (QAV*)raw.Data(); - int backFC = PlayClock; - int currentclock = I_GetBuildTime(); - PlayClock = currentclock; - int nTicks = currentclock - lastTick; - lastTick = currentclock; - duration -= nTicks; + + auto thisTick = I_GetTime(); + if (!lastTick) + { + lastTick = thisTick; + } + if (lastTick < thisTick) + { + lastTick = thisTick; + duration -= 4; + } + if (duration <= 0 || duration > data->duration) { duration = data->duration; } - data->Play(data->duration - duration - nTicks, data->duration - duration, -1, NULL); + auto currentDuration = data->duration - duration; + auto smoothratio = I_GetTimeFrac() * MaxSmoothRatio; + + data->Play(currentDuration - 4, currentDuration, -1, NULL); if (bWideScreen) { @@ -102,15 +113,13 @@ void CGameMenuItemQAV::Draw(void) int backX = data->x; for (int i = 0; i < nCount; i++) { - data->Draw(data->duration - duration, 10 + kQavOrientationLeft, 0, 0, false); + data->Draw(currentDuration, 10 + kQavOrientationLeft, 0, 0, false, smoothratio, filename == "BDRIP.QAV"); data->x += 320; } data->x = backX; } else - data->Draw(data->duration - duration, 10, 0, 0, false); - - PlayClock = backFC; + data->Draw(currentDuration, 10, 0, 0, false, smoothratio, filename == "BDRIP.QAV"); } } diff --git a/source/games/blood/src/qav.cpp b/source/games/blood/src/qav.cpp index 55d013cbf0c..43ef1a8e3aa 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) +void QAV::Draw(double x, double y, int ticks, int stat, int shade, int palnum, bool to3dview, double const smoothratio, bool const menudrip) { assert(ticksPerFrame > 0); @@ -93,45 +93,64 @@ void QAV::Draw(double x, double y, int ticks, int stat, int shade, int palnum, b assert(oFrame >= 0 && oFrame < nFrames); FRAMEINFO *prevFrame = &frames[oFrame]; - for (int i = 0; i < 8; i++) + auto drawTile = [&](TILE_FRAME *thisTile, TILE_FRAME *prevTile, bool const interpolate = true) { - auto* thisTile = &thisFrame->tiles[i]; + double tileX = x; + double tileY = y; + double tileZ; + double tileA; - if (thisTile->picnum > 0) + if (prevTile && cl_hudinterpolation && (nFrames > 1) && (nFrame != oFrame) && (smoothratio != MaxSmoothRatio) && interpolate) { - TILE_FRAME *prevTile = nullptr; + 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; + } - if (thisTile->picnum == prevFrame->tiles[i].picnum) - { - prevTile = &prevFrame->tiles[i]; - } - else for (int j = 0; j < 8; j++) if (thisTile->picnum == prevFrame->tiles[j].picnum) - { - prevTile = &prevFrame->tiles[j]; - break; - } + DrawFrame(tileX, tileY, tileZ, tileA, thisTile, stat, shade, palnum, to3dview); + }; - double tileX = x; - double tileY = y; - double tileZ; - double tileA; + for (int i = 0; i < 8; i++) + { + TILE_FRAME *thisTile = &thisFrame->tiles[i]; + TILE_FRAME *prevTile = nullptr; - if ((nFrames > 1) && (nFrame != oFrame) && (prevTile && (thisTile->picnum == prevTile->picnum)) && (smoothratio != MaxSmoothRatio)) + if (thisTile->picnum > 0) + { + // Menu's blood drip requires special treatment. + if (menudrip) { - 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(); + 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; + } + + drawTile(thisTile, prevTile, true); + } + else + { + // First index is always the dripping bar at the top. + drawTile(thisTile, prevTile, false); + } } else { - tileX += thisTile->x; - tileY += thisTile->y; - tileZ = thisTile->z; - tileA = thisTile->angle; + prevTile = &prevFrame->tiles[i]; + drawTile(thisTile, prevTile, thisTile->picnum == prevTile->picnum); } - - DrawFrame(tileX, tileY, tileZ, tileA, thisTile, stat, shade, palnum, to3dview); } } } diff --git a/source/games/blood/src/qav.h b/source/games/blood/src/qav.h index 9bea3d3d4fd..63c0c98bb11 100644 --- a/source/games/blood/src/qav.h +++ b/source/games/blood/src/qav.h @@ -80,8 +80,8 @@ struct QAV char pad3[3]; // 20 char lastframetic; FRAMEINFO frames[1]; // 24 - 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 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 Play(int, int, int, void *); void Precache(int palette = 0); };