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(); }