changeset 18601:ee97e25c43a7 draft

(svn r23448) -Fix: keep a local copy of the palette in the 32bpp animated blitter so changes of the palette data during the game don't influence drawing (with SDL)
author rubidium <rubidium@openttd.org>
date Thu, 08 Dec 2011 19:37:33 +0000
parents 284eaca34cf1
children ca4eba47a01f
files src/blitter/32bpp_anim.cpp src/blitter/32bpp_anim.hpp src/blitter/32bpp_base.cpp src/blitter/32bpp_base.hpp src/blitter/8bpp_base.cpp src/blitter/8bpp_base.hpp src/blitter/base.hpp src/blitter/null.hpp src/video/allegro_v.cpp src/video/cocoa/event.mm src/video/sdl_v.cpp src/video/win32_v.cpp
diffstat 12 files changed, 36 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/src/blitter/32bpp_anim.cpp
+++ b/src/blitter/32bpp_anim.cpp
@@ -410,14 +410,15 @@
 	return width * height * (sizeof(uint32) + sizeof(uint8));
 }
 
-void Blitter_32bppAnim::PaletteAnimate(uint start, uint count)
+void Blitter_32bppAnim::PaletteAnimate(const Palette &palette)
 {
 	assert(!_screen_disable_anim);
 
+	this->palette = palette;
 	/* Never repaint the transparency pixel */
-	if (start == 0) {
-		start++;
-		count--;
+	if (this->palette.first_dirty == 0) {
+		this->palette.first_dirty++;
+		this->palette.count_dirty--;
 	}
 
 	const uint8 *anim = this->anim_buf;
@@ -427,7 +428,7 @@
 	for (int y = this->anim_buf_height; y != 0 ; y--) {
 		for (int x = this->anim_buf_width; x != 0 ; x--) {
 			uint colour = *anim;
-			if (IsInsideBS(colour, start, count)) {
+			if (IsInsideBS(colour, this->palette.first_dirty, this->palette.count_dirty)) {
 				/* Update this pixel */
 				*dst = LookupColourInPalette(colour);
 			}
--- a/src/blitter/32bpp_anim.hpp
+++ b/src/blitter/32bpp_anim.hpp
@@ -20,6 +20,7 @@
 	uint8 *anim_buf;     ///< In this buffer we keep track of the 8bpp indexes so we can do palette animation
 	int anim_buf_width;  ///< The width of the animation buffer.
 	int anim_buf_height; ///< The height of the animation buffer.
+	Palette palette;     ///< The current palette.
 
 public:
 	Blitter_32bppAnim() :
@@ -36,13 +37,21 @@
 	/* virtual */ void CopyToBuffer(const void *video, void *dst, 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 */ void PaletteAnimate(const Palette &palette);
 	/* virtual */ Blitter::PaletteAnimation UsePaletteAnimation();
 
 	/* virtual */ const char *GetName() { return "32bpp-anim"; }
 	/* virtual */ int GetBytesPerPixel() { return 5; }
 	/* virtual */ void PostResize();
 
+	/**
+	 * Look up the colour in the current palette.
+	 */
+	inline uint32 LookupColourInPalette(uint index)
+	{
+		return this->palette.palette[index].data;
+	}
+
 	template <BlitterMode mode> void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom);
 };
 
--- a/src/blitter/32bpp_base.cpp
+++ b/src/blitter/32bpp_base.cpp
@@ -136,7 +136,7 @@
 	return width * height * sizeof(uint32);
 }
 
-void Blitter_32bppBase::PaletteAnimate(uint start, uint count)
+void Blitter_32bppBase::PaletteAnimate(const Palette &palette)
 {
 	/* By default, 32bpp doesn't have palette animation */
 }
--- a/src/blitter/32bpp_base.hpp
+++ b/src/blitter/32bpp_base.hpp
@@ -28,7 +28,7 @@
 	/* virtual */ void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch);
 	/* 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 */ void PaletteAnimate(const Palette &palette);
 	/* virtual */ Blitter::PaletteAnimation UsePaletteAnimation();
 	/* virtual */ int GetBytesPerPixel() { return 4; }
 
--- a/src/blitter/8bpp_base.cpp
+++ b/src/blitter/8bpp_base.cpp
@@ -141,7 +141,7 @@
 	return width * height;
 }
 
-void Blitter_8bppBase::PaletteAnimate(uint start, uint count)
+void Blitter_8bppBase::PaletteAnimate(const Palette &palette)
 {
 	/* Video backend takes care of the palette animation */
 }
--- a/src/blitter/8bpp_base.hpp
+++ b/src/blitter/8bpp_base.hpp
@@ -27,7 +27,7 @@
 	/* virtual */ void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch);
 	/* 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 */ void PaletteAnimate(const Palette &palette);
 	/* virtual */ Blitter::PaletteAnimation UsePaletteAnimation();
 	/* virtual */ int GetBytesPerPixel() { return 1; }
 };
--- a/src/blitter/base.hpp
+++ b/src/blitter/base.hpp
@@ -173,11 +173,10 @@
 
 	/**
 	 * 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.
+	 *  are equal to the 8bpp palette indexes 'first_dirty' to 'first_dirty + count_dirty'.
+	 * @param palette The new palette.
 	 */
-	virtual void PaletteAnimate(uint start, uint count) = 0;
+	virtual void PaletteAnimate(const Palette &palette) = 0;
 
 	/**
 	 * Check if the blitter uses palette animation at all.
--- a/src/blitter/null.hpp
+++ b/src/blitter/null.hpp
@@ -30,7 +30,7 @@
 	/* virtual */ void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) {};
 	/* 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 */ void PaletteAnimate(const Palette &palette) { };
 	/* virtual */ Blitter::PaletteAnimation UsePaletteAnimation() { return Blitter::PALETTE_ANIMATION_NONE; };
 
 	/* virtual */ const char *GetName() { return "null"; }
--- a/src/video/allegro_v.cpp
+++ b/src/video/allegro_v.cpp
@@ -100,7 +100,7 @@
 				break;
 
 			case Blitter::PALETTE_ANIMATION_BLITTER:
-				blitter->PaletteAnimate(_cur_palette.first_dirty, _cur_palette.count_dirty);
+				blitter->PaletteAnimate(_cur_palette);
 				break;
 
 			case Blitter::PALETTE_ANIMATION_NONE:
@@ -487,7 +487,8 @@
 	uint32 cur_ticks = GetTime();
 	uint32 last_cur_ticks = cur_ticks;
 	uint32 next_tick = cur_ticks + MILLISECONDS_PER_TICK;
-	uint32 pal_tick = 0;
+
+	CheckPaletteAnim();
 
 	for (;;) {
 		uint32 prev_cur_ticks = cur_ticks; // to check for wrapping
@@ -532,10 +533,7 @@
 			GameLoop();
 
 			UpdateWindows();
-			if (++pal_tick > 4) {
-				CheckPaletteAnim();
-				pal_tick = 1;
-			}
+			CheckPaletteAnim();
 			DrawSurfaceToScreen();
 		} else {
 			CSleep(1);
--- a/src/video/cocoa/event.mm
+++ b/src/video/cocoa/event.mm
@@ -99,7 +99,7 @@
 				break;
 
 			case Blitter::PALETTE_ANIMATION_BLITTER:
-				blitter->PaletteAnimate(_cur_palette.first_dirty, _cur_palette.count_dirty);
+				blitter->PaletteAnimate(_cur_palette);
 				break;
 
 			case Blitter::PALETTE_ANIMATION_NONE:
@@ -555,7 +555,6 @@
 	uint32 cur_ticks = GetTick();
 	uint32 last_cur_ticks = cur_ticks;
 	uint32 next_tick = cur_ticks + MILLISECONDS_PER_TICK;
-	uint32 pal_tick = 0;
 
 #ifdef _DEBUG
 	uint32 et0 = GetTick();
@@ -615,10 +614,7 @@
 			GameLoop();
 
 			UpdateWindows();
-			if (++pal_tick > 4) {
-				QZ_CheckPaletteAnim();
-				pal_tick = 1;
-			}
+			QZ_CheckPaletteAnim();
 			_cocoa_subdriver->Draw();
 		} else {
 #ifdef _DEBUG
--- a/src/video/sdl_v.cpp
+++ b/src/video/sdl_v.cpp
@@ -85,7 +85,7 @@
 				break;
 
 			case Blitter::PALETTE_ANIMATION_BLITTER:
-				blitter->PaletteAnimate(_cur_palette.first_dirty, _cur_palette.count_dirty);
+				blitter->PaletteAnimate(_cur_palette);
 				break;
 
 			case Blitter::PALETTE_ANIMATION_NONE:
@@ -503,11 +503,12 @@
 	uint32 cur_ticks = SDL_CALL SDL_GetTicks();
 	uint32 last_cur_ticks = cur_ticks;
 	uint32 next_tick = cur_ticks + MILLISECONDS_PER_TICK;
-	uint32 pal_tick = 0;
 	uint32 mod;
 	int numkeys;
 	Uint8 *keys;
 
+	CheckPaletteAnim();
+
 	if (_draw_threaded) {
 		/* Initialise the mutex first, because that's the thing we *need*
 		 * directly in the newly created thread. */
@@ -584,10 +585,7 @@
 			if (_draw_threaded) _draw_mutex->BeginCritical();
 
 			UpdateWindows();
-			if (++pal_tick > 4) {
-				CheckPaletteAnim();
-				pal_tick = 1;
-			}
+			CheckPaletteAnim();
 		} else {
 			/* Release the thread while sleeping */
 			if (_draw_threaded) _draw_mutex->EndCritical();
--- a/src/video/win32_v.cpp
+++ b/src/video/win32_v.cpp
@@ -359,7 +359,7 @@
 						break;
 
 					case Blitter::PALETTE_ANIMATION_BLITTER:
-						blitter->PaletteAnimate(_cur_palette.first_dirty, _cur_palette.count_dirty);
+						blitter->PaletteAnimate(_cur_palette);
 						break;
 
 					case Blitter::PALETTE_ANIMATION_NONE:
@@ -853,6 +853,7 @@
 
 	_wnd.running = true;
 
+	CheckPaletteAnim();
 	for (;;) {
 		uint32 prev_cur_ticks = cur_ticks; // to check for wrapping