From 1c4760ee06fb632d27648175f7bab433b32c1892 Mon Sep 17 00:00:00 2001 From: truelight Date: Tue, 19 Jun 2007 15:04:08 +0000 Subject: (svn r10216) -Fix: palette animation always redid all palette entries, where in fact only a few indexes were needed -Codechange: allow blitters to handle palette animation internally or even disable it; 8bpp uses video-backend for palette animation --- src/blitter/32bpp_base.cpp | 10 ++++++++++ src/blitter/32bpp_base.hpp | 2 ++ src/blitter/8bpp_base.cpp | 10 ++++++++++ src/blitter/8bpp_base.hpp | 2 ++ src/blitter/base.hpp | 20 ++++++++++++++++++++ src/blitter/null.hpp | 2 ++ src/gfx.cpp | 25 +++++++++++++------------ src/gfx.h | 2 +- src/os/macosx/splash.cpp | 2 +- src/video/cocoa_v.mm | 20 +++++++++++++++++--- src/video/sdl_v.cpp | 26 +++++++++++++++++++------- src/video/win32_v.cpp | 22 ++++++++++++++++++---- 12 files changed, 115 insertions(+), 28 deletions(-) diff --git a/src/blitter/32bpp_base.cpp b/src/blitter/32bpp_base.cpp index f788b56a7..a4e24cae9 100644 --- a/src/blitter/32bpp_base.cpp +++ b/src/blitter/32bpp_base.cpp @@ -177,3 +177,13 @@ int Blitter_32bppBase::BufferSize(int width, int height) { return width * height * sizeof(uint32); } + +void Blitter_32bppBase::PaletteAnimate(uint start, uint count) +{ + /* By default, 32bpp doesn't have palette animation */ +} + +Blitter::PaletteAnimation Blitter_32bppBase::UsePaletteAnimation() +{ + return Blitter::PALETTE_ANIMATION_NONE; +} diff --git a/src/blitter/32bpp_base.hpp b/src/blitter/32bpp_base.hpp index 0149330d8..66d7e7529 100644 --- a/src/blitter/32bpp_base.hpp +++ b/src/blitter/32bpp_base.hpp @@ -23,6 +23,8 @@ public: /* virtual */ void MoveBuffer(void *video_dst, const void *video_src, int width, int height); /* virtual */ void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y); /* virtual */ int BufferSize(int width, int height); + /* virtual */ void PaletteAnimate(uint start, uint count); + /* virtual */ Blitter::PaletteAnimation UsePaletteAnimation(); static inline uint32 LookupColourInPalette(uint8 index) { #define ARGB(a, r, g, b) ((((a) << 24) & 0xFF000000) | (((r) << 16) & 0x00FF0000) | (((g) << 8) & 0x0000FF00) | ((b) & 0x000000FF)) diff --git a/src/blitter/8bpp_base.cpp b/src/blitter/8bpp_base.cpp index 42da38937..6fe60ea18 100644 --- a/src/blitter/8bpp_base.cpp +++ b/src/blitter/8bpp_base.cpp @@ -182,3 +182,13 @@ int Blitter_8bppBase::BufferSize(int width, int height) { return width * height; } + +void Blitter_8bppBase::PaletteAnimate(uint start, uint count) +{ + /* Video backend takes care of the palette animation */ +} + +Blitter::PaletteAnimation Blitter_8bppBase::UsePaletteAnimation() +{ + return Blitter::PALETTE_ANIMATION_VIDEO_BACKEND; +} diff --git a/src/blitter/8bpp_base.hpp b/src/blitter/8bpp_base.hpp index 3b313bb30..f189ffdcf 100644 --- a/src/blitter/8bpp_base.hpp +++ b/src/blitter/8bpp_base.hpp @@ -23,6 +23,8 @@ public: /* virtual */ void MoveBuffer(void *video_dst, const void *video_src, int width, int height); /* virtual */ void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y); /* virtual */ int BufferSize(int width, int height); + /* virtual */ void PaletteAnimate(uint start, uint count); + /* virtual */ Blitter::PaletteAnimation UsePaletteAnimation(); }; #endif /* BLITTER_8BPP_BASE_HPP */ diff --git a/src/blitter/base.hpp b/src/blitter/base.hpp index 90e1dde03..268e13b17 100644 --- a/src/blitter/base.hpp +++ b/src/blitter/base.hpp @@ -31,6 +31,12 @@ public: int pitch; ///< The pitch of the destination buffer }; + enum PaletteAnimation { + PALETTE_ANIMATION_NONE, ///< No palette animation + PALETTE_ANIMATION_VIDEO_BACKEND, ///< Palette animation should be done by video backend (8bpp only!) + PALETTE_ANIMATION_BLITTER, ///< The blitter takes care of the palette animation + }; + typedef void *AllocatorProc(size_t size); /** @@ -158,6 +164,20 @@ public: */ virtual int BufferSize(int width, int height) = 0; + /** + * Called when the 8bpp palette is changed; you should redraw all pixels on the screen that + * are equal to the 8bpp palette indexes 'start' to 'start + count'. + * @param start The start index in the 8bpp palette. + * @param count The amount of indexes that are (possible) changed. + */ + virtual void PaletteAnimate(uint start, uint count) = 0; + + /** + * Check if the blitter uses palette animation at all. + * @return True if it uses palette animation. + */ + virtual Blitter::PaletteAnimation UsePaletteAnimation() = 0; + virtual ~Blitter() { } }; diff --git a/src/blitter/null.hpp b/src/blitter/null.hpp index 6c519b023..356385726 100644 --- a/src/blitter/null.hpp +++ b/src/blitter/null.hpp @@ -24,6 +24,8 @@ public: /* virtual */ void MoveBuffer(void *video_dst, const void *video_src, int width, int height) {}; /* virtual */ void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) {}; /* virtual */ int BufferSize(int width, int height) { return 0; }; + /* virtual */ void PaletteAnimate(uint start, uint count) { }; + /* virtual */ Blitter::PaletteAnimation UsePaletteAnimation() { return Blitter::PALETTE_ANIMATION_NONE; }; }; class FBlitter_Null: public BlitterFactory { diff --git a/src/gfx.cpp b/src/gfx.cpp index 6125797bf..c17316885 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -41,7 +41,7 @@ bool _networking; ///< are we in networking mode? byte _game_mode; byte _pause_game; int _pal_first_dirty; -int _pal_last_dirty; +int _pal_count_dirty; Colour _cur_palette[256]; byte _stringwidth_table[FS_END][224]; @@ -664,7 +664,7 @@ void GfxInitPalettes() memcpy(_cur_palette, _palettes[_use_dos_palette ? 1 : 0], sizeof(_cur_palette)); _pal_first_dirty = 0; - _pal_last_dirty = 255; + _pal_count_dirty = 255; DoPaletteAnimations(); } @@ -673,6 +673,7 @@ void GfxInitPalettes() void DoPaletteAnimations() { + Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter(); const Colour *s; Colour *d; /* Amount of colors to be rotated. @@ -680,14 +681,12 @@ void DoPaletteAnimations() * 245-254 for DOS and 217-226 for Windows. */ const ExtraPaletteValues *ev = &_extra_palette_values; int c = _use_dos_palette ? 38 : 28; - Colour old_val[38]; // max(38, 28) + Colour old_val[38]; uint i; uint j; - int old_tc = _timer_counter; + uint old_tc = _timer_counter; - /* We can only update the palette in 8bpp for now */ - /* TODO -- We need support for other bpps too! */ - if (BlitterFactoryBase::GetCurrentBlitter() != NULL && BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth() != 8) { + if (blitter != NULL && blitter->UsePaletteAnimation() == Blitter::PALETTE_ANIMATION_NONE) { _timer_counter = 0; } @@ -782,12 +781,14 @@ void DoPaletteAnimations() } } - if (memcmp(old_val, &_cur_palette[217], c * sizeof(*old_val)) != 0) { - if (_pal_first_dirty > 217) _pal_first_dirty = 217; - if (_pal_last_dirty < 217 + c) _pal_last_dirty = 217 + c; + if (blitter != NULL && blitter->UsePaletteAnimation() == Blitter::PALETTE_ANIMATION_NONE) { + _timer_counter = old_tc; + } else { + if (memcmp(old_val, &_cur_palette[217], c * sizeof(*old_val)) != 0) { + _pal_first_dirty = 217; + _pal_count_dirty = c; + } } - - if (old_tc != _timer_counter) _timer_counter = old_tc; } diff --git a/src/gfx.h b/src/gfx.h index ef369d953..edc19ab07 100644 --- a/src/gfx.h +++ b/src/gfx.h @@ -166,7 +166,7 @@ extern byte _game_mode; extern byte _pause_game; extern int _pal_first_dirty; -extern int _pal_last_dirty; +extern int _pal_count_dirty; extern int _num_resolutions; extern uint16 _resolutions[32][2]; extern uint16 _cur_resolution[2]; diff --git a/src/os/macosx/splash.cpp b/src/os/macosx/splash.cpp index 5933b808d..927f8d5ea 100644 --- a/src/os/macosx/splash.cpp +++ b/src/os/macosx/splash.cpp @@ -128,7 +128,7 @@ void DisplaySplashImage() _cur_palette[0xff].b = 0; _pal_first_dirty = 0; - _pal_last_dirty = 0xff; + _pal_count_dirty = 255; png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(f); diff --git a/src/video/cocoa_v.mm b/src/video/cocoa_v.mm index 3af09da18..eb0b5919b 100644 --- a/src/video/cocoa_v.mm +++ b/src/video/cocoa_v.mm @@ -205,9 +205,23 @@ static uint32 GetTick() static void QZ_CheckPaletteAnim() { - if (_pal_last_dirty != -1) { - QZ_UpdatePalette(_pal_first_dirty, _pal_last_dirty - _pal_first_dirty + 1); - _pal_last_dirty = -1; + if (_pal_count_dirty != 0) { + switch (blitter->UsePaletteAnimation()) { + case Blitter::PALETTE_ANIMATION_VIDEO_BACKEND: + QZ_UpdatePalette(_pal_first_dirty, _pal_count_dirty); + break; + + case Blitter::PALETTE_ANIMATION_BLITTER: + blitter->PaletteAnimate(_pal_first_dirty, _pal_count_dirty); + break; + + case Blitter::PALETTE_ANIMATION_NONE: + break; + + default: + NOT_REACHED(); + } + _pal_count_dirty = 0; } } diff --git a/src/video/sdl_v.cpp b/src/video/sdl_v.cpp index 3a1f2229e..087a3464c 100644 --- a/src/video/sdl_v.cpp +++ b/src/video/sdl_v.cpp @@ -37,10 +37,6 @@ static void SdlVideoMakeDirty(int left, int top, int width, int height) static void UpdatePalette(uint start, uint count) { - /* We can only update the palette in 8bpp for now */ - /* TODO -- We need support for other bpps too! */ - if (BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth() != 8) return; - SDL_Color pal[256]; uint i; @@ -61,9 +57,25 @@ static void InitPalette() static void CheckPaletteAnim() { - if (_pal_last_dirty != -1) { - UpdatePalette(_pal_first_dirty, _pal_last_dirty - _pal_first_dirty + 1); - _pal_last_dirty = -1; + Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter(); + + if (_pal_count_dirty != 0) { + switch (blitter->UsePaletteAnimation()) { + case Blitter::PALETTE_ANIMATION_VIDEO_BACKEND: + UpdatePalette(_pal_first_dirty, _pal_count_dirty); + break; + + case Blitter::PALETTE_ANIMATION_BLITTER: + blitter->PaletteAnimate(_pal_first_dirty, _pal_count_dirty); + break; + + case Blitter::PALETTE_ANIMATION_NONE: + break; + + default: + NOT_REACHED(); + } + _pal_count_dirty = 0; } } diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp index b67674627..79517843f 100644 --- a/src/video/win32_v.cpp +++ b/src/video/win32_v.cpp @@ -145,7 +145,7 @@ static void ClientSizeChanged(int w, int h) if (AllocateDibSection(w, h)) { // mark all palette colors dirty _pal_first_dirty = 0; - _pal_last_dirty = 255; + _pal_count_dirty = 255; GameSizeChanged(); // redraw screen @@ -231,9 +231,23 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP old_bmp = (HBITMAP)SelectObject(dc2, _wnd.dib_sect); old_palette = SelectPalette(dc, _wnd.gdi_palette, FALSE); - if (_pal_last_dirty != -1) { - UpdatePalette(dc2, _pal_first_dirty, _pal_last_dirty - _pal_first_dirty + 1); - _pal_last_dirty = -1; + if (_pal_count_dirty != 0) { + switch (blitter->UsePaletteAnimation()) { + case Blitter::PALETTE_ANIMATION_VIDEO_BACKEND: + UpdatePalette(_pal_first_dirty, _pal_count_dirty); + break; + + case Blitter::PALETTE_ANIMATION_BLITTER: + blitter->PaletteAnimate(_pal_first_dirty, _pal_count_dirty); + break; + + case Blitter::PALETTE_ANIMATION_NONE: + break; + + default: + NOT_REACHED(); + } + _pal_count_dirty = 0; } BitBlt(dc, 0, 0, _wnd.width, _wnd.height, dc2, 0, 0, SRCCOPY); -- cgit v1.2.3-54-g00ecf