Changeset - r6960:e903748e34e4
[Not reviewed]
master
0 12 0
truelight - 17 years ago 2007-06-19 15:04:08
truelight@openttd.org
(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
12 files changed with 115 insertions and 28 deletions:
0 comments (0 inline, 0 general)
src/blitter/32bpp_base.cpp
Show inline comments
 
@@ -177,3 +177,13 @@ int Blitter_32bppBase::BufferSize(int wi
 
{
 
	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;
 
}
src/blitter/32bpp_base.hpp
Show inline comments
 
@@ -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))
src/blitter/8bpp_base.cpp
Show inline comments
 
@@ -182,3 +182,13 @@ int Blitter_8bppBase::BufferSize(int wid
 
{
 
	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;
 
}
src/blitter/8bpp_base.hpp
Show inline comments
 
@@ -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 */
src/blitter/base.hpp
Show inline comments
 
@@ -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() { }
 
};
 

	
src/blitter/null.hpp
Show inline comments
 
@@ -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<FBlitter_Null> {
src/gfx.cpp
Show inline comments
 
@@ -41,7 +41,7 @@ bool _networking;         ///< are we in
 
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;
 
}
 

	
 

	
src/gfx.h
Show inline comments
 
@@ -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];
src/os/macosx/splash.cpp
Show inline comments
 
@@ -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);
src/video/cocoa_v.mm
Show inline comments
 
@@ -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;
 
	}
 
}
 

	
src/video/sdl_v.cpp
Show inline comments
 
@@ -37,10 +37,6 @@ static void SdlVideoMakeDirty(int left, 
 

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

	
src/video/win32_v.cpp
Show inline comments
 
@@ -145,7 +145,7 @@ static void ClientSizeChanged(int w, int
 
	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 
 
			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);
0 comments (0 inline, 0 general)