From fda4293013b76883406eae147cd57c65ec193d65 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 12 Apr 2020 07:46:53 +0200 Subject: [PATCH] - draw the movie franes outside of the tile system to reduce the palette maintenance. The movie code has always been the part causing the most issues because it alters the palettes - the rest treats them as static data. --- source/CMakeLists.txt | 1 + source/blood/src/blood.cpp | 1 + source/blood/src/credits.cpp | 43 ++------- source/blood/src/screen.cpp | 1 + source/build/include/build.h | 10 +- source/build/src/engine.cpp | 20 ++-- source/common/textures/animtexture.cpp | 117 ++++++++++++++++++++++ source/common/textures/animtexture.h | 28 ++++++ source/core/2d/v_2ddrawer.cpp | 20 ++-- source/core/2d/v_2ddrawer.h | 2 +- source/duke3d/src/anim.cpp | 129 ++++++++++++------------- source/exhumed/src/movie.cpp | 29 +++--- source/rr/src/anim.cpp | 127 ++++++++++++------------ source/sw/src/anim.cpp | 96 +++++++++--------- 14 files changed, 374 insertions(+), 250 deletions(-) create mode 100644 source/common/textures/animtexture.cpp create mode 100644 source/common/textures/animtexture.h diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index b2584bb3c..10f927038 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -716,6 +716,7 @@ set (PCH_SOURCES core/console/d_event.cpp common/thirdparty/sfmt/SFMT.cpp + common/textures/animtexture.cpp common/textures/bitmap.cpp common/textures/m_png.cpp common/console/c_commandline.cpp diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index 786463aad..07c46d190 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -1093,6 +1093,7 @@ static const char* actions[] = { int GameInterface::app_main() { + buttonMap.SetButtons(actions, NUM_ACTIONS); memcpy(&gGameOptions, &gSingleGameOptions, sizeof(GAMEOPTIONS)); gGameOptions.nMonsterSettings = !userConfig.nomonsters; diff --git a/source/blood/src/credits.cpp b/source/blood/src/credits.cpp index 7100dd348..9ff031ada 100644 --- a/source/blood/src/credits.cpp +++ b/source/blood/src/credits.cpp @@ -35,6 +35,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "screen.h" #include "sound.h" #include "view.h" +#include "animtexture.h" #include "../glbackend/glbackend.h" #include "sound/s_soundinternal.h" @@ -149,24 +150,8 @@ bool credKOpen4Load(FString &pzFile) return nHandle; } -#define kSMKPal 5 -#define kSMKTile (MAXTILES-1) - void credPlaySmk(const char *_pzSMK, const char *_pzWAV, int nWav) { -#if 0 - CSMKPlayer smkPlayer; - if (dword_148E14 >= 0) - { - if (toupper(*pzSMK) == 'A'+dword_148E14) - { - if (Redbook.sub_82258() == 0 || Redbook.sub_82258() > 20) - return; - } - Redbook.sub_82554(); - } - smkPlayer.sub_82E6C(pzSMK, pzWAV); -#endif if (!_pzSMK || !*_pzSMK) return; FString pzSMK = _pzSMK; @@ -184,19 +169,13 @@ void credPlaySmk(const char *_pzSMK, const char *_pzWAV, int nWav) uint32_t nWidth, nHeight; Smacker_GetFrameSize(hSMK, nWidth, nHeight); uint8_t palette[768]; - tileDelete(kSMKTile); - auto pFrame = TileFiles.tileCreate(kSMKTile, nHeight, nWidth); - if (!pFrame) - { - Smacker_Close(hSMK); - return; - } + AnimTextures animtex; + TArray pFrame(nWidth * nHeight + std::max(nWidth, nHeight), true); + animtex.SetSize(nWidth, nHeight); int nFrameRate = Smacker_GetFrameRate(hSMK); int nFrames = Smacker_GetNumFrames(hSMK); Smacker_GetPalette(hSMK, palette); - paletteSetColorTable(kSMKPal, palette, true); - videoSetPalette(0, kSMKPal, Pal_Fullscreen); Mus_Stop(); int nScale; @@ -208,13 +187,13 @@ void credPlaySmk(const char *_pzSMK, const char *_pzWAV, int nWav) nScale = divscale16(320 * xdim * 3, nWidth * ydim * 4); else nScale = divscale16(200, nHeight); - nStat = 2 | 4 | 8 | 64; + nStat = 2 | 8 | 64; } else { // DOS Blood v1.11: 320x240, 320x320, 640x400, and 640x480 SMKs all display 1:1 and centered in a 640x480 viewport nScale = tabledivide32(scale(65536, ydim << 2, xdim * 3), ((max(nHeight, 240 + 1u) + 239) / 240)); - nStat = 2 | 4 | 8 | 64 | 1024; + nStat = 2 | 8 | 64 | 1024; renderSetAspect(viewingrange, 65536); } @@ -250,11 +229,9 @@ void credPlaySmk(const char *_pzSMK, const char *_pzWAV, int nWav) videoClearScreen(0); Smacker_GetPalette(hSMK, palette); - paletteSetColorTable(kSMKPal, palette, true); - videoSetPalette(0, kSMKPal, Pal_Fullscreen); - tileInvalidate(kSMKTile, 0, 1 << 4); // JBF 20031228 - Smacker_GetFrame(hSMK, pFrame); - rotatesprite_fs(160<<16, 100<<16, nScale, 512, kSMKTile, 0, 0, nStat); + Smacker_GetFrame(hSMK, pFrame.Data()); + animtex.SetFrame(palette, pFrame.Data()); + rotatesprite_fs(160<<16, 100<<16, nScale, 0, -1, 0, 0, nStat, animtex.GetFrame()); videoNextPage(); @@ -266,8 +243,6 @@ void credPlaySmk(const char *_pzSMK, const char *_pzWAV, int nWav) Smacker_Close(hSMK); inputState.ClearAllInput(); soundEngine->StopAllChannels(); - videoSetPalette(0, 0, 0); - tileDelete(kSMKTile); } END_BLD_NS diff --git a/source/blood/src/screen.cpp b/source/blood/src/screen.cpp index 0c9c20efd..8e0b70238 100644 --- a/source/blood/src/screen.cpp +++ b/source/blood/src/screen.cpp @@ -138,6 +138,7 @@ void scrLoadPalette(void) paletteloaded |= PALETTE_TRANSLUC; palettePostLoadTables(); + } void scrSetPalette(int palId) diff --git a/source/build/include/build.h b/source/build/include/build.h index 236f51303..685ea0eb7 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -859,7 +859,7 @@ void videoClearScreen(int32_t dacol); void renderDrawMapView(int32_t dax, int32_t day, int32_t zoome, int16_t ang); void rotatesprite_(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum, int8_t dashade, uint8_t dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend, - int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2); + int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2, FTexture *pic = nullptr); void renderDrawLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint8_t col); void drawlinergb(int32_t x1, int32_t y1, int32_t x2, int32_t y2, palette_t p); void drawlinergb(int32_t x1, int32_t y1, int32_t x2, int32_t y2, PalEntry p); @@ -867,15 +867,15 @@ void drawlinergb(int32_t x1, int32_t y1, int32_t x2, int32_t y2, PalEntry p); ////////// specialized rotatesprite wrappers for (very) often used cases ////////// static FORCE_INLINE void rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum, int8_t dashade, uint8_t dapalnum, int32_t dastat, - int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2) + int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2, FTexture* pic = nullptr) { - rotatesprite_(sx, sy, z, a, picnum, dashade, dapalnum, dastat, 0, 0, cx1, cy1, cx2, cy2); + rotatesprite_(sx, sy, z, a, picnum, dashade, dapalnum, dastat, 0, 0, cx1, cy1, cx2, cy2, pic); } // Don't clip at all, i.e. the whole screen real estate is available: static FORCE_INLINE void rotatesprite_fs(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum, - int8_t dashade, uint8_t dapalnum, int32_t dastat) + int8_t dashade, uint8_t dapalnum, int32_t dastat, FTexture* pic = nullptr) { - rotatesprite_(sx, sy, z, a, picnum, dashade, dapalnum, dastat, 0, 0, 0,0,xdim-1,ydim-1); + rotatesprite_(sx, sy, z, a, picnum, dashade, dapalnum, dastat, 0, 0, 0,0,xdim-1,ydim-1, pic); } static FORCE_INLINE void rotatesprite_fs_alpha(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum, diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index b6ec47d1a..0248c3076 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -4996,15 +4996,13 @@ void renderSetAspect(int32_t daxrange, int32_t daaspect) // void rotatesprite_(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum, int8_t dashade, uint8_t dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend, - int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2) + int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2, FTexture *tex) { - if ((unsigned)picnum >= MAXTILES) + if (!tex && (unsigned)picnum >= MAXTILES) return; if ((cx1 > cx2) || (cy1 > cy2)) return; if (z <= 16) return; - tileUpdatePicnum(&picnum, (int16_t)0xc000); - if ((tilesiz[picnum].x <= 0) || (tilesiz[picnum].y <= 0)) return; if (r_rotatespritenowidescreen) { @@ -5012,13 +5010,19 @@ void rotatesprite_(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum, dastat &= ~RS_ALIGN_MASK; } - if (hw_models && tile2model[picnum].hudmem[(dastat & 4) >> 2]) + if (!tex) { - polymost_dorotatespritemodel(sx, sy, z, a, picnum, dashade, dapalnum, dastat, daalpha, dablend, guniqhudid); - return; + tileUpdatePicnum(&picnum, (int16_t)0xc000); + if ((tilesiz[picnum].x <= 0) || (tilesiz[picnum].y <= 0)) return; + if (hw_models && tile2model[picnum].hudmem[(dastat & 4) >> 2]) + { + polymost_dorotatespritemodel(sx, sy, z, a, picnum, dashade, dapalnum, dastat, daalpha, dablend, guniqhudid); + return; + } } + // We must store all calls in the 2D drawer so that the backend can operate on a clean 3D view. - twod->rotatesprite(sx, sy, z, a, picnum, dashade, dapalnum, dastat, daalpha, dablend, cx1, cy1, cx2, cy2); + twod->rotatesprite(sx, sy, z, a, picnum, dashade, dapalnum, dastat, daalpha, dablend, cx1, cy1, cx2, cy2, tex); // RS_PERM code was removed because the current backend supports only one page that needs to be redrawn each frame in which case the perm list was skipped anyway. } diff --git a/source/common/textures/animtexture.cpp b/source/common/textures/animtexture.cpp new file mode 100644 index 000000000..93dcdeda0 --- /dev/null +++ b/source/common/textures/animtexture.cpp @@ -0,0 +1,117 @@ +/* +** animtexture.cpp +** +**--------------------------------------------------------------------------- +** Copyright 2020 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +** +*/ +#include "animtexture.h" +#include "bitmap.h" + +//========================================================================== +// +// +// +//========================================================================== + +void AnimTexture::SetSize(int width, int height) +{ + Size.x = width; + Size.y = height; + Image.Resize(width*height); +} + +void AnimTexture::SetFrame(const uint8_t *palette, const void *data_) +{ + memcpy(Palette, palette, 768); + memcpy(Image.Data(), data_, Size.x * Size.y); + DeleteHardwareTextures(); +} + +//=========================================================================== +// +// FPNGTexture::CopyPixels +// +//=========================================================================== + +FBitmap AnimTexture::GetBgraBitmap(const PalEntry* remap, int* trans) +{ + FBitmap bmp; + + bmp.Create(Size.x, Size.y); + + auto spix = Image.Data(); + auto dpix = bmp.GetPixels(); + for (int i = 0; i < Size.x * Size.y; i++) + { + int p = i * 4; + int index = spix[i]; + dpix[p + 0] = Palette[index*3+2]; + dpix[p + 1] = Palette[index*3+1]; + dpix[p + 2] = Palette[index*3]; + dpix[p + 3] = 255; + } + return bmp; +} + +//========================================================================== +// +// +// +//========================================================================== + +AnimTextures::AnimTextures() +{ + active = 1; + tex[0] = new AnimTexture; + tex[1] = new AnimTexture; +} + +AnimTextures::~AnimTextures() +{ + delete tex[0]; + delete tex[1]; +} + +void AnimTextures::SetSize(int width, int height) +{ + tex[0]->SetSize(width, height); + tex[1]->SetSize(width, height); +} + +void AnimTextures::SetFrame(const uint8_t *palette, const void* data) +{ + active ^= 1; + tex[active]->SetFrame(palette, data); +} + +FTexture * AnimTextures::GetFrame() +{ + return tex[active]; +} diff --git a/source/common/textures/animtexture.h b/source/common/textures/animtexture.h new file mode 100644 index 000000000..e568a3cd2 --- /dev/null +++ b/source/common/textures/animtexture.h @@ -0,0 +1,28 @@ +#pragma once + +#include "textures.h" + + +class AnimTexture : public FTexture +{ + uint8_t Palette[768]; + TArray Image; +public: + AnimTexture() = default; + void SetSize(int width, int height); + void SetFrame(const uint8_t *palette, const void* data); + virtual FBitmap GetBgraBitmap(const PalEntry* remap, int* trans) override; +}; + +class AnimTextures +{ + int active; + AnimTexture *tex[2]; + +public: + AnimTextures(); + ~AnimTextures(); + void SetSize(int width, int height); + void SetFrame(const uint8_t *palette, const void* data); + FTexture *GetFrame(); +}; diff --git a/source/core/2d/v_2ddrawer.cpp b/source/core/2d/v_2ddrawer.cpp index a656e2925..0fc4b62e8 100644 --- a/source/core/2d/v_2ddrawer.cpp +++ b/source/core/2d/v_2ddrawer.cpp @@ -627,12 +627,12 @@ static int32_t dorotspr_handle_bit2(int32_t* sxptr, int32_t* syptr, int32_t* z, void F2DDrawer::rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum, int8_t dashade, uint8_t dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend, - int32_t clipx1, int32_t clipy1, int32_t clipx2, int32_t clipy2) + int32_t clipx1, int32_t clipy1, int32_t clipx2, int32_t clipy2, FTexture *pic) { RenderCommand dg = {}; int method = 0; - dg.mType = DrawTypeRotateSprite; + dg.mType = pic? DrawTypeTriangles : DrawTypeRotateSprite; if (clipx1 > 0 || clipy1 > 0 || clipx2 < screen->GetWidth() - 1 || clipy2 < screen->GetHeight() - 1) { dg.mScissor[0] = clipx1; @@ -657,7 +657,7 @@ void F2DDrawer::rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16 } PalEntry p = 0xffffffff; - dg.mTexture = TileFiles.tiles[picnum]; + dg.mTexture = pic? pic : TileFiles.tiles[picnum]; dg.mRemapIndex = dapalnum | (dashade << 16); dg.mVertCount = 4; dg.mVertIndex = (int)mVertices.Reserve(4); @@ -666,13 +666,21 @@ void F2DDrawer::rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16 float alpha = float_trans(method, dablend) * (1.f - drawpoly_alpha); // Hmmm... p.a = (uint8_t)(alpha * 255); - vec2_16_t const siz = tilesiz[picnum]; + vec2_16_t const siz = dg.mTexture->GetSize(); vec2_16_t ofs = { 0, 0 }; if (!(dastat & RS_TOPLEFT)) { - ofs = { int16_t(picanm[picnum].xofs + (siz.x >> 1)), - int16_t(picanm[picnum].yofs + (siz.y >> 1)) }; + if (!pic) + { + ofs = { int16_t(picanm[picnum].xofs + (siz.x >> 1)), + int16_t(picanm[picnum].yofs + (siz.y >> 1)) }; + } + else + { + ofs = { int16_t((siz.x >> 1)), + int16_t((siz.y >> 1)) }; + } } if (dastat & RS_YFLIP) diff --git a/source/core/2d/v_2ddrawer.h b/source/core/2d/v_2ddrawer.h index 8c282fa71..f0368857b 100644 --- a/source/core/2d/v_2ddrawer.h +++ b/source/core/2d/v_2ddrawer.h @@ -142,7 +142,7 @@ public: void rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum, int8_t dashade, uint8_t dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend, - int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2); + int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2, FTexture *pic); void Clear(); diff --git a/source/duke3d/src/anim.cpp b/source/duke3d/src/anim.cpp index 6c002f0a5..fcb292727 100644 --- a/source/duke3d/src/anim.cpp +++ b/source/duke3d/src/anim.cpp @@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "cmdlib.h" #include "compat.h" #include "build.h" +#include "animtexture.h" #include "v_2ddrawer.h" #include "../glbackend/glbackend.h" @@ -434,97 +435,91 @@ int32_t Anim_Play(const char *fn) goto end_anim; } - paletteSetColorTable(ANIMPAL, ANIM_GetPalette(), true); - - P_SetGamePalette(g_player[myconnectindex].ps, ANIMPAL, Pal_Fullscreen); - -#ifdef USE_OPENGL if ((anim->frameflags & CUTSCENE_TEXTUREFILTER && hw_texfilter == TEXFILTER_ON) || anim->frameflags & CUTSCENE_FORCEFILTER) hw_texfilter = TEXFILTER_ON; -#endif ototalclock = totalclock; i = 1; int32_t frametime; frametime = 0; - do { - if (i > 4 && totalclock > frametime + 60) + AnimTextures animtex; + animtex.SetSize(320, 200); + + do { - Printf("WARNING: slowdown in %s, skipping playback\n", fn); - goto end_anim_restore_gl; - } + if (i > 4 && totalclock > frametime + 60) + { + Printf("WARNING: slowdown in %s, skipping playback\n", fn); + goto end_anim_restore_gl; + } - gameHandleEvents(); + gameHandleEvents(); - if (totalclock < ototalclock - 1) - continue; + if (totalclock < ototalclock - 1) + continue; - i = VM_OnEventWithReturn(EVENT_PRECUTSCENE, g_player[screenpeek].ps->i, screenpeek, i); + i = VM_OnEventWithReturn(EVENT_PRECUTSCENE, g_player[screenpeek].ps->i, screenpeek, i); - TileFiles.tileSetExternal(TILE_ANIM, 200, 320, ANIM_DrawFrame(i)); - tileInvalidate(TILE_ANIM, 0, 1 << 4); // JBF 20031228 + animtex.SetFrame(ANIM_GetPalette(), ANIM_DrawFrame(i)); - if (VM_OnEventWithReturn(EVENT_SKIPCUTSCENE, g_player[screenpeek].ps->i, screenpeek, inputState.CheckAllInput())) - { - running = 0; - goto end_anim_restore_gl; - } + if (VM_OnEventWithReturn(EVENT_SKIPCUTSCENE, g_player[screenpeek].ps->i, screenpeek, inputState.CheckAllInput())) + { + running = 0; + goto end_anim_restore_gl; + } - if (g_restorePalette == 1) - { - P_SetGamePalette(g_player[myconnectindex].ps, ANIMPAL, 0); - g_restorePalette = 0; - } + frametime = (int32_t)totalclock; - frametime = (int32_t) totalclock; + videoClearScreen(0); - videoClearScreen(0); - - int32_t z; - if (anim->frameaspect1 > 0 && anim->frameaspect2 > 0 && ((anim->frameaspect1 / anim->frameaspect2) != (tilesiz[TILE_ANIM].y / (tilesiz[TILE_ANIM].x * 1.2)))) - { - int32_t const oyxaspect = yxaspect; - if ((anim->frameaspect1 / anim->frameaspect2) >= ((decltype(anim->frameaspect1))xdim / ydim)) - z = divscale16(320, tilesiz[TILE_ANIM].y); + int32_t z; +#if 0 // fixme: The math here doesn't look right - this better use a more robust fullscreen scaler later. + if (anim->frameaspect1 > 0 && anim->frameaspect2 > 0 && ((anim->frameaspect1 / anim->frameaspect2) != (tilesiz[TILE_ANIM].y / (tilesiz[TILE_ANIM].x * 1.2)))) + { + int32_t const oyxaspect = yxaspect; + if ((anim->frameaspect1 / anim->frameaspect2) >= ((decltype(anim->frameaspect1))xdim / ydim)) + z = divscale16(320, tilesiz[TILE_ANIM].y); + else + z = divscale16(lrint(320 * ydim * anim->frameaspect1), lrint(tilesiz[TILE_ANIM].y * xdim * anim->frameaspect2)); + int32_t aspect = divscale16(lrint(tilesiz[TILE_ANIM].y * anim->frameaspect2), lrint(tilesiz[TILE_ANIM].x * anim->frameaspect1)); + renderSetAspect(viewingrange, aspect); + rotatesprite_fs(160 << 16, 100 << 16, z, 512, TILE_ANIM, 0, 0, 2 | 4 | 8 | 64 | 1024); + renderSetAspect(viewingrange, oyxaspect); + } else - z = divscale16(lrint(320 * ydim * anim->frameaspect1), lrint(tilesiz[TILE_ANIM].y * xdim * anim->frameaspect2)); - int32_t aspect = divscale16(lrint(tilesiz[TILE_ANIM].y * anim->frameaspect2), lrint(tilesiz[TILE_ANIM].x * anim->frameaspect1)); - renderSetAspect(viewingrange, aspect); - rotatesprite_fs(160<<16, 100<<16, z, 512, TILE_ANIM, 0, 0, 2|4|8|64|1024); - renderSetAspect(viewingrange, oyxaspect); - } - else - { - if ((tilesiz[TILE_ANIM].y / (tilesiz[TILE_ANIM].x * 1.2f)) > (1.f * xdim / ydim)) - z = divscale16(320 * xdim * 3, tilesiz[TILE_ANIM].y * ydim * 4); - else - z = divscale16(200, tilesiz[TILE_ANIM].x); - rotatesprite_fs(160<<16, 100<<16, z, 512, TILE_ANIM, 0, 0, 2|4|8|64); - } - g_animPtr = anim; - i = VM_OnEventWithReturn(EVENT_CUTSCENE, g_player[screenpeek].ps->i, screenpeek, i); - g_animPtr = NULL; +#endif + { + if ((320 / (200 * 1.2f)) > (1.f * xdim / ydim)) + z = divscale16(320 * xdim * 3, 320 * ydim * 4); + else + z = divscale16(200, 200); + rotatesprite_fs(160 << 16, 100 << 16, z, 0, -1, 0, 0,2 | 8 | 64, animtex.GetFrame() ); + } + g_animPtr = anim; + i = VM_OnEventWithReturn(EVENT_CUTSCENE, g_player[screenpeek].ps->i, screenpeek, i); + g_animPtr = NULL; - videoNextPage(); + videoNextPage(); - inputState.ClearAllInput(); + inputState.ClearAllInput(); - ototalclock += anim->framedelay; + ototalclock += anim->framedelay; - while (soundidx < anim->Sounds.Size() && anim->Sounds[soundidx].frame <= (uint16_t)i) - { - int16_t sound = anim->Sounds[soundidx].sound; - if (sound == -1) - FX_StopAllSounds(); - else - S_PlaySound(sound, CHAN_AUTO, CHANF_UI); + while (soundidx < anim->Sounds.Size() && anim->Sounds[soundidx].frame <= (uint16_t)i) + { + int16_t sound = anim->Sounds[soundidx].sound; + if (sound == -1) + FX_StopAllSounds(); + else + S_PlaySound(sound, CHAN_AUTO, CHANF_UI); - soundidx++; - } - ++i; - } while (i < numframes); + soundidx++; + } + ++i; + } while (i < numframes); + } end_anim_restore_gl: hw_texfilter = ogltexfiltermode; diff --git a/source/exhumed/src/movie.cpp b/source/exhumed/src/movie.cpp index 45e1b43f6..5938bbb71 100644 --- a/source/exhumed/src/movie.cpp +++ b/source/exhumed/src/movie.cpp @@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "c_bind.h" #include "sound.h" #include "v_2ddrawer.h" +#include "animtexture.h" BEGIN_PS_NS @@ -55,7 +56,7 @@ static uint8_t* CurFrame = NULL; bool bServedSample = false; palette_t moviepal[256]; -int ReadFrame(FileReader &fp) +int ReadFrame(FileReader &fp, uint8_t *palette) { static int nFrame = 0; Printf("Reading frame %d...\n", nFrame); @@ -67,7 +68,6 @@ int ReadFrame(FileReader &fp) uint16_t yOffset; uint8_t xOffset; uint8_t nPixels; - uint8_t palette[768]; while (1) { @@ -86,14 +86,11 @@ int ReadFrame(FileReader &fp) { case kFramePalette: { - fp.Read(palette, sizeof(palette)); + fp.Read(palette, 768); fp.Read(&var_1C, sizeof(var_1C)); - for (auto &c : palette) - c <<= 2; - - paletteSetColorTable(ANIMPAL, palette); - videoSetPalette(0, ANIMPAL, Pal_Fullscreen); + for (unsigned i = 0; i < 768;i++) + palette[i] <<= 2; memset(CurFrame, overscanindex, 4); //sizeof(CurFrame)); continue; @@ -189,6 +186,7 @@ static void ServeSample(const char** ptr, uint32_t* length) void PlayMovie(const char* fileName) { + uint8_t palette[768]; TArray f(64000, true); CurFrame = f.Data(); @@ -217,10 +215,11 @@ void PlayMovie(const char* fileName) int angle = 1536; int z = 0; - videoSetPalette(0, ANIMPAL, Pal_Fullscreen); + AnimTextures animtex; + animtex.SetSize(200, 320); // Read a frame in first - if (ReadFrame(fp)) + if (ReadFrame(fp, palette)) { // start audio playback (fixme) #if 0 @@ -254,10 +253,8 @@ void PlayMovie(const char* fileName) // I have no idea why this needs double buffering now. fn ^= 1; - TileFiles.tileSetExternal(10000 + fn, 320, 200, CurFrame); - tileInvalidate(10000 + fn, -1, -1); - twod->ClearScreen(); - rotatesprite(160 << 16, 100 << 16, z, angle, 10000+fn, 0, 1, 2, 0, 0, xdim - 1, ydim - 1); + animtex.SetFrame(palette, CurFrame); + rotatesprite(160 << 16, 100 << 16, z, angle+512, -1, 0, 1, RS_AUTO | RS_YFLIP, 0, 0, xdim - 1, ydim - 1, animtex.GetFrame()); if (bDoFade) { bDoFade = DoFadeIn(); @@ -265,14 +262,12 @@ void PlayMovie(const char* fileName) videoNextPage(); - if (ReadFrame(fp) == 0) { + if (ReadFrame(fp, palette) == 0) { break; } } } - tileInvalidate(10000, -1, -1); - tileInvalidate(10001, -1, -1); if (hFx > 0) { //FX_StopSound(hFx); } diff --git a/source/rr/src/anim.cpp b/source/rr/src/anim.cpp index f7b5bcaf5..4fef90685 100644 --- a/source/rr/src/anim.cpp +++ b/source/rr/src/anim.cpp @@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "compat.h" #include "cmdlib.h" #include "v_2ddrawer.h" +#include "animtexture.h" #include "../glbackend/glbackend.h" @@ -452,8 +453,6 @@ int32_t Anim_Play(const char *fn) anim->animbuf = buffer.Data(); - TileFiles.tileCreate(TILE_ANIM, 200, 320); - uint32_t firstfour; Bmemcpy(&firstfour, anim->animbuf, 4); @@ -474,90 +473,92 @@ int32_t Anim_Play(const char *fn) goto end_anim; } - paletteSetColorTable(ANIMPAL, ANIM_GetPalette(), true); - - P_SetGamePalette(g_player[myconnectindex].ps, ANIMPAL, Pal_Fullscreen); - ototalclock = totalclock; i = 1; int32_t frametime; frametime = 0; - do { - if (i > 4 && totalclock > frametime + 60) + AnimTextures animtex; + animtex.SetSize(320, 200); + + do { - Printf("WARNING: slowdown in %s, skipping playback\n", fn); - goto end_anim_restore_gl; - } + if (i > 4 && totalclock > frametime + 60) + { + Printf("WARNING: slowdown in %s, skipping playback\n", fn); + goto end_anim_restore_gl; + } - G_HandleAsync(); + G_HandleAsync(); - if (totalclock < ototalclock - 1) - continue; + if (totalclock < ototalclock - 1) + continue; - TileFiles.tileSetExternal(TILE_ANIM, 200, 320, ANIM_DrawFrame(i)); - tileInvalidate(TILE_ANIM, 0, 1 << 4); // JBF 20031228 + animtex.SetFrame(ANIM_GetPalette(), ANIM_DrawFrame(i)); - if (inputState.CheckAllInput()) - { - running = 0; - goto end_anim_restore_gl; - } + if (inputState.CheckAllInput()) + { + running = 0; + goto end_anim_restore_gl; + } - if (g_restorePalette == 1) - { - P_SetGamePalette(g_player[myconnectindex].ps, ANIMPAL, 0); - g_restorePalette = 0; - } + if (g_restorePalette == 1) + { + P_SetGamePalette(g_player[myconnectindex].ps, ANIMPAL, 0); + g_restorePalette = 0; + } - frametime = (int32_t) totalclock; + frametime = (int32_t)totalclock; - videoClearScreen(0); + videoClearScreen(0); - int32_t z; - if (anim->frameaspect1 > 0 && anim->frameaspect2 > 0 && ((anim->frameaspect1 / anim->frameaspect2) != (tilesiz[TILE_ANIM].y / (tilesiz[TILE_ANIM].x * 1.2)))) - { - int32_t const oyxaspect = yxaspect; - if ((anim->frameaspect1 / anim->frameaspect2) >= ((decltype(anim->frameaspect1))xdim / ydim)) - z = divscale16(320, tilesiz[TILE_ANIM].y); + int32_t z; +#if 0 + if (anim->frameaspect1 > 0 && anim->frameaspect2 > 0 && ((anim->frameaspect1 / anim->frameaspect2) != (tilesiz[TILE_ANIM].y / (tilesiz[TILE_ANIM].x * 1.2)))) + { + int32_t const oyxaspect = yxaspect; + if ((anim->frameaspect1 / anim->frameaspect2) >= ((decltype(anim->frameaspect1))xdim / ydim)) + z = divscale16(320, tilesiz[TILE_ANIM].y); + else + z = divscale16(lrint(320 * ydim * anim->frameaspect1), lrint(tilesiz[TILE_ANIM].y * xdim * anim->frameaspect2)); + int32_t aspect = divscale16(lrint(tilesiz[TILE_ANIM].y * anim->frameaspect2), lrint(tilesiz[TILE_ANIM].x * anim->frameaspect1)); + renderSetAspect(viewingrange, aspect); + rotatesprite_fs(160 << 16, 100 << 16, z, 512, TILE_ANIM, 0, 0, 2 | 4 | 8 | 64 | 1024); + renderSetAspect(viewingrange, oyxaspect); + } else - z = divscale16(lrint(320 * ydim * anim->frameaspect1), lrint(tilesiz[TILE_ANIM].y * xdim * anim->frameaspect2)); - int32_t aspect = divscale16(lrint(tilesiz[TILE_ANIM].y * anim->frameaspect2), lrint(tilesiz[TILE_ANIM].x * anim->frameaspect1)); - renderSetAspect(viewingrange, aspect); - rotatesprite_fs(160<<16, 100<<16, z, 512, TILE_ANIM, 0, 0, 2|4|8|64|1024); - renderSetAspect(viewingrange, oyxaspect); - } - else - { - if ((tilesiz[TILE_ANIM].y / (tilesiz[TILE_ANIM].x * 1.2f)) > (1.f * xdim / ydim)) - z = divscale16(320 * xdim * 3, tilesiz[TILE_ANIM].y * ydim * 4); - else - z = divscale16(200, tilesiz[TILE_ANIM].x); - rotatesprite_fs(160<<16, 100<<16, z, 512, TILE_ANIM, 0, 0, 2|4|8|64); - } +#endif + { + if ((320 / (200 * 1.2f)) > (1.f * xdim / ydim)) + z = divscale16(320 * xdim * 3, 320 * ydim * 4); + else + z = divscale16(200, 200); + rotatesprite_fs(160 << 16, 100 << 16, z, 0, -1, 0, 0, 2 | 8 | 64, animtex.GetFrame()); + } - g_animPtr = NULL; + g_animPtr = NULL; - videoNextPage(); + videoNextPage(); - inputState.ClearAllInput(); + inputState.ClearAllInput(); - ototalclock += anim->framedelay; + ototalclock += anim->framedelay; - while (soundidx < anim->Sounds.Size() && anim->Sounds[soundidx].frame <= (uint16_t)i) - { - int16_t sound = anim->Sounds[soundidx].sound; - if (sound == -1) - FX_StopAllSounds(); - else - S_PlaySound(sound, CHAN_AUTO, CHANF_UI); + while (soundidx < anim->Sounds.Size() && anim->Sounds[soundidx].frame <= (uint16_t)i) + { + int16_t sound = anim->Sounds[soundidx].sound; + if (sound == -1) + FX_StopAllSounds(); + else + S_PlaySound(sound, CHAN_AUTO, CHANF_UI); - soundidx++; - } + soundidx++; + } - ++i; - } while (i < numframes); + ++i; + } while (i < numframes); + } end_anim_restore_gl: hw_texfilter = ogltexfiltermode; diff --git a/source/sw/src/anim.cpp b/source/sw/src/anim.cpp index 2d12cc923..a8548547e 100644 --- a/source/sw/src/anim.cpp +++ b/source/sw/src/anim.cpp @@ -44,6 +44,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "anim.h" #include "../glbackend/glbackend.h" #include "v_2ddrawer.h" +#include "animtexture.h" #include "common_game.h" @@ -259,63 +260,62 @@ playanm(short anim_num) videoClearViewableArea(0L); - paletteSetColorTable(ANIMPAL, ANIM_GetPalette()); - videoSetPalette(0, ANIMPAL, Pal_Fullscreen); - if (ANIMnum == 1) { - // draw the first frame - TileFiles.tileSetExternal(ANIM_TILE(ANIMnum), 200, 320, ANIM_DrawFrame(1)); - tileInvalidate(ANIM_TILE(ANIMnum), 0, 1<<4); - rotatesprite(0 << 16, 0 << 16, 65536L, 512, ANIM_TILE(ANIMnum), 0, 0, 2 + 4 + 8 + 16 + 64, 0, 0, xdim - 1, ydim - 1); - } - - SoundState = 0; - //ototalclock = totalclock + 120*2; - ototalclock = (int32_t) totalclock; - - for (i = 1; i < numframes; i++) - { - while (totalclock < ototalclock) + AnimTextures animtex; + animtex.SetSize(320, 200); + if (ANIMnum == 1) { - handleevents(); + // draw the first frame + animtex.SetFrame(ANIM_GetPalette(), ANIM_DrawFrame(1)); + rotatesprite_fs(160 << 16, 100 << 16, 65536, 0, -1, 0, 0, 2 | 8 | 64, animtex.GetFrame()); + } + + SoundState = 0; + //ototalclock = totalclock + 120*2; + ototalclock = (int32_t)totalclock; + + for (i = 1; i < numframes; i++) + { + while (totalclock < ototalclock) + { + handleevents(); + switch (ANIMnum) + { + case ANIM_INTRO: + case ANIM_SERP: + if (inputState.CheckAllInput()) + { + goto ENDOFANIMLOOP; + } + break; + } + + getpackets(); + } + switch (ANIMnum) { case ANIM_INTRO: + AnimShareIntro(i, numframes); + break; case ANIM_SERP: - if (inputState.CheckAllInput()) - { - goto ENDOFANIMLOOP; - } + AnimSerp(i, numframes); + break; + case ANIM_SUMO: + AnimSumo(i, numframes); + break; + case ANIM_ZILLA: + AnimZilla(i, numframes); break; } - getpackets(); + animtex.SetFrame(ANIM_GetPalette(), ANIM_DrawFrame(i)); + rotatesprite_fs(160 << 16, 100 << 16, 65536, 0, -1, 0, 0, 2 | 8 | 64, animtex.GetFrame()); + videoNextPage(); + handleevents(); + if (inputState.CheckAllInput()) + break; } - - switch (ANIMnum) - { - case ANIM_INTRO: - AnimShareIntro(i,numframes); - break; - case ANIM_SERP: - AnimSerp(i,numframes); - break; - case ANIM_SUMO: - AnimSumo(i,numframes); - break; - case ANIM_ZILLA: - AnimZilla(i,numframes); - break; - } - - TileFiles.tileSetExternal(ANIM_TILE(ANIMnum), 200, 320, ANIM_DrawFrame(i)); - tileInvalidate(ANIM_TILE(ANIMnum), 0, 1<<4); - - rotatesprite(0 << 16, 0 << 16, 65536L, 512, ANIM_TILE(ANIMnum), 0, 0, 2 + 4 + 8 + 16 + 64, 0, 0, xdim - 1, ydim - 1); - videoNextPage(); - handleevents(); - if (inputState.CheckAllInput()) - break; } // pause on final frame @@ -330,8 +330,6 @@ ENDOFANIMLOOP: twod->ClearScreen(); videoNextPage(); - videoSetPalette(0, BASEPAL, 0); - inputState.ClearAllInput(); ANIM_FreeAnim(); }