changeset 19226:07b983e40c39 draft

(svn r24111) -Codechange: use Colour more instead of manually bitstuffing
author rubidium <rubidium@openttd.org>
date Tue, 10 Apr 2012 20:16:51 +0000
parents 6b2b85c73b6c
children 4a0cb8270570
files src/blitter/32bpp_anim.cpp src/blitter/32bpp_anim.hpp src/blitter/32bpp_base.cpp src/blitter/32bpp_base.hpp src/blitter/32bpp_optimized.cpp src/blitter/32bpp_simple.cpp src/gfx_type.h src/table/palettes.h
diffstat 8 files changed, 95 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- a/src/blitter/32bpp_anim.cpp
+++ b/src/blitter/32bpp_anim.cpp
@@ -31,13 +31,13 @@
 		src_n  = (const uint16 *)((const byte *)src_n  + *(const uint32 *)src_n);
 	}
 
-	uint32 *dst = (uint32 *)bp->dst + bp->top * bp->pitch + bp->left;
+	Colour *dst = (Colour *)bp->dst + bp->top * bp->pitch + bp->left;
 	uint16 *anim = this->anim_buf + ((uint32 *)bp->dst - (uint32 *)_screen.dst_ptr) + bp->top * this->anim_buf_width + bp->left;
 
 	const byte *remap = bp->remap; // store so we don't have to access it via bp everytime
 
 	for (int y = 0; y < bp->height; y++) {
-		uint32 *dst_ln = dst + bp->pitch;
+		Colour *dst_ln = dst + bp->pitch;
 		uint16 *anim_ln = anim + this->anim_buf_width;
 
 		const Colour *src_px_ln = (const Colour *)((const byte *)src_px + *(const uint32 *)src_px);
@@ -46,7 +46,7 @@
 		const uint16 *src_n_ln = (const uint16 *)((const byte *)src_n + *(const uint32 *)src_n);
 		src_n += 2;
 
-		uint32 *dst_end = dst + bp->skip_left;
+		Colour *dst_end = dst + bp->skip_left;
 
 		uint n;
 
@@ -219,7 +219,7 @@
 		return;
 	}
 
-	uint32 *udst = (uint32 *)dst;
+	Colour *udst = (Colour *)dst;
 	uint16 *anim;
 
 	anim = this->anim_buf + ((uint32 *)dst - (uint32 *)_screen.dst_ptr);
@@ -256,7 +256,7 @@
 
 void Blitter_32bppAnim::SetPixel(void *video, int x, int y, uint8 colour)
 {
-	*((uint32 *)video + x + y * _screen.pitch) = LookupColourInPalette(colour);
+	*((Colour *)video + x + y * _screen.pitch) = LookupColourInPalette(colour);
 
 	/* Set the colour in the anim-buffer too, if we are rendering to the screen */
 	if (_screen_disable_anim) return;
@@ -271,13 +271,13 @@
 		return;
 	}
 
-	uint32 colour32 = LookupColourInPalette(colour);
+	Colour colour32 = LookupColourInPalette(colour);
 	uint16 *anim_line;
 
 	anim_line = ((uint32 *)video - (uint32 *)_screen.dst_ptr) + this->anim_buf;
 
 	do {
-		uint32 *dst = (uint32 *)video;
+		Colour *dst = (Colour *)video;
 		uint16 *anim = anim_line;
 
 		for (int i = width; i > 0; i--) {
@@ -296,13 +296,13 @@
 {
 	assert(!_screen_disable_anim);
 	assert(video >= _screen.dst_ptr && video <= (uint32 *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch);
-	uint32 *dst = (uint32 *)video;
+	Colour *dst = (Colour *)video;
 	const uint32 *usrc = (const uint32 *)src;
 	uint16 *anim_line = ((uint32 *)video - (uint32 *)_screen.dst_ptr) + this->anim_buf;
 
 	for (; height > 0; height--) {
 		/* We need to keep those for palette animation. */
-		uint32 *dst_pal = dst;
+		Colour *dst_pal = dst;
 		uint16 *anim_pal = anim_line;
 
 		memcpy(dst, usrc, width * sizeof(uint32));
@@ -422,7 +422,7 @@
 	assert(this->palette.first_dirty == PALETTE_ANIM_START || this->palette.first_dirty == 0);
 
 	const uint16 *anim = this->anim_buf;
-	uint32 *dst = (uint32 *)_screen.dst_ptr;
+	Colour *dst = (Colour *)_screen.dst_ptr;
 
 	/* Let's walk the anim buffer and try to find the pixels */
 	for (int y = this->anim_buf_height; y != 0 ; y--) {
--- a/src/blitter/32bpp_anim.hpp
+++ b/src/blitter/32bpp_anim.hpp
@@ -47,9 +47,9 @@
 	/**
 	 * Look up the colour in the current palette.
 	 */
-	inline uint32 LookupColourInPalette(uint index)
+	inline Colour LookupColourInPalette(uint index)
 	{
-		return this->palette.palette[index].data;
+		return this->palette.palette[index];
 	}
 
 	template <BlitterMode mode> void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom);
--- a/src/blitter/32bpp_base.cpp
+++ b/src/blitter/32bpp_base.cpp
@@ -19,15 +19,15 @@
 
 void Blitter_32bppBase::SetPixel(void *video, int x, int y, uint8 colour)
 {
-	*((uint32 *)video + x + y * _screen.pitch) = LookupColourInPalette(colour);
+	*((Colour *)video + x + y * _screen.pitch) = LookupColourInPalette(colour);
 }
 
 void Blitter_32bppBase::DrawRect(void *video, int width, int height, uint8 colour)
 {
-	uint32 colour32 = LookupColourInPalette(colour);
+	Colour colour32 = LookupColourInPalette(colour);
 
 	do {
-		uint32 *dst = (uint32 *)video;
+		Colour *dst = (Colour *)video;
 		for (int i = width; i > 0; i--) {
 			*dst = colour32;
 			dst++;
--- a/src/blitter/32bpp_base.hpp
+++ b/src/blitter/32bpp_base.hpp
@@ -34,32 +34,24 @@
 	/* virtual */ int GetBytesPerPixel() { return 4; }
 
 	/**
-	 * Compose a colour based on RGB values.
-	 */
-	static inline uint32 ComposeColour(uint a, uint r, uint g, uint b)
-	{
-		return (((a) << 24) & 0xFF000000) | (((r) << 16) & 0x00FF0000) | (((g) << 8) & 0x0000FF00) | ((b) & 0x000000FF);
-	}
-
-	/**
 	 * Look up the colour in the current palette.
 	 */
-	static inline uint32 LookupColourInPalette(uint index)
+	static inline Colour LookupColourInPalette(uint index)
 	{
-		return _cur_palette.palette[index].data;
+		return _cur_palette.palette[index];
 	}
 
 	/**
 	 * Compose a colour based on RGBA values and the current pixel value.
 	 */
-	static inline uint32 ComposeColourRGBANoCheck(uint r, uint g, uint b, uint a, uint32 current)
+	static inline Colour ComposeColourRGBANoCheck(uint r, uint g, uint b, uint a, Colour current)
 	{
-		uint cr = GB(current, 16, 8);
-		uint cg = GB(current, 8,  8);
-		uint cb = GB(current, 0,  8);
+		uint cr = current.r;
+		uint cg = current.g;
+		uint cb = current.b;
 
 		/* The 256 is wrong, it should be 255, but 256 is much faster... */
-		return ComposeColour(0xFF,
+		return Colour(
 							((int)(r - cr) * a) / 256 + cr,
 							((int)(g - cg) * a) / 256 + cg,
 							((int)(b - cb) * a) / 256 + cb);
@@ -69,10 +61,10 @@
 	 * Compose a colour based on RGBA values and the current pixel value.
 	 * Handles fully transparent and solid pixels in a special (faster) way.
 	 */
-	static inline uint32 ComposeColourRGBA(uint r, uint g, uint b, uint a, uint32 current)
+	static inline Colour ComposeColourRGBA(uint r, uint g, uint b, uint a, Colour current)
 	{
 		if (a == 0) return current;
-		if (a >= 255) return ComposeColour(0xFF, r, g, b);
+		if (a >= 255) return Colour(r, g, b);
 
 		return ComposeColourRGBANoCheck(r, g, b, a, current);
 	}
@@ -80,11 +72,11 @@
 	/**
 	 * Compose a colour based on Pixel value, alpha value, and the current pixel value.
 	 */
-	static inline uint32 ComposeColourPANoCheck(uint32 colour, uint a, uint32 current)
+	static inline Colour ComposeColourPANoCheck(Colour colour, uint a, Colour current)
 	{
-		uint r  = GB(colour,  16, 8);
-		uint g  = GB(colour,  8,  8);
-		uint b  = GB(colour,  0,  8);
+		uint r  = colour.r;
+		uint g  = colour.g;
+		uint b  = colour.b;
 
 		return ComposeColourRGBANoCheck(r, g, b, a, current);
 	}
@@ -93,10 +85,13 @@
 	 * Compose a colour based on Pixel value, alpha value, and the current pixel value.
 	 * Handles fully transparent and solid pixels in a special (faster) way.
 	 */
-	static inline uint32 ComposeColourPA(uint32 colour, uint a, uint32 current)
+	static inline Colour ComposeColourPA(Colour colour, uint a, Colour current)
 	{
 		if (a == 0) return current;
-		if (a >= 255) return (colour | 0xFF000000);
+		if (a >= 255) {
+			colour.a = 255;
+			return colour;
+		}
 
 		return ComposeColourPANoCheck(colour, a, current);
 	}
@@ -108,13 +103,13 @@
 	 * @param denom denominator, makes colour darker.
 	 * @return the new colour for the screen.
 	 */
-	static inline uint32 MakeTransparent(uint32 colour, uint nom, uint denom = 256)
+	static inline Colour MakeTransparent(Colour colour, uint nom, uint denom = 256)
 	{
-		uint r = GB(colour, 16, 8);
-		uint g = GB(colour, 8,  8);
-		uint b = GB(colour, 0,  8);
+		uint r = colour.r;
+		uint g = colour.g;
+		uint b = colour.b;
 
-		return ComposeColour(0xFF, r * nom / denom, g * nom / denom, b * nom / denom);
+		return Colour(r * nom / denom, g * nom / denom, b * nom / denom);
 	}
 
 	/**
@@ -122,45 +117,46 @@
 	 * @param colour the colour to make grey.
 	 * @return the new colour, now grey.
 	 */
-	static inline uint32 MakeGrey(uint32 colour)
+	static inline Colour MakeGrey(Colour colour)
 	{
-		uint r = GB(colour, 16, 8);
-		uint g = GB(colour, 8,  8);
-		uint b = GB(colour, 0,  8);
+		uint r = colour.r;
+		uint g = colour.g;
+		uint b = colour.b;
 
 		/* To avoid doubles and stuff, multiple it with a total of 65536 (16bits), then
 		 *  divide by it to normalize the value to a byte again. See heightmap.cpp for
 		 *  information about the formula. */
-		colour = ((r * 19595) + (g * 38470) + (b * 7471)) / 65536;
+		uint grey = ((r * 19595) + (g * 38470) + (b * 7471)) / 65536;
 
-		return ComposeColour(0xFF, colour, colour, colour);
+		return Colour(grey, grey, grey);
 	}
 
 	static const int DEFAULT_BRIGHTNESS = 64;
 
-	static inline uint32 AdjustBrightness(uint32 colour, uint8 brightness)
+	static inline Colour AdjustBrightness(Colour colour, uint8 brightness)
 	{
 		/* Shortcut for normal brightness */
 		if (brightness == DEFAULT_BRIGHTNESS) return colour;
 
 		uint16 ob = 0;
-		uint16 r = GB(colour, 16, 8) * brightness / DEFAULT_BRIGHTNESS;
-		uint16 g = GB(colour, 8,  8) * brightness / DEFAULT_BRIGHTNESS;
-		uint16 b = GB(colour, 0,  8) * brightness / DEFAULT_BRIGHTNESS;
+		uint16 r = colour.r * brightness / DEFAULT_BRIGHTNESS;
+		uint16 g = colour.g * brightness / DEFAULT_BRIGHTNESS;
+		uint16 b = colour.b * brightness / DEFAULT_BRIGHTNESS;
 
 		/* Sum overbright */
 		if (r > 255) ob += r - 255;
 		if (g > 255) ob += g - 255;
 		if (b > 255) ob += b - 255;
 
-		if (ob == 0) return ComposeColour(GB(colour, 24, 8), r, g, b);
+		if (ob == 0) return Colour(r, g, b, colour.a);
 
 		/* Reduce overbright strength */
 		ob /= 2;
-		return ComposeColour(GB(colour, 24, 8),
+		return Colour(
 		                     r >= 255 ? 255 : min(r + ob * (255 - r) / 256, 255),
 		                     g >= 255 ? 255 : min(g + ob * (255 - g) / 256, 255),
-		                     b >= 255 ? 255 : min(b + ob * (255 - b) / 256, 255));
+		                     b >= 255 ? 255 : min(b + ob * (255 - b) / 256, 255),
+		                     colour.a);
 	}
 };
 
--- a/src/blitter/32bpp_optimized.cpp
+++ b/src/blitter/32bpp_optimized.cpp
@@ -44,14 +44,14 @@
 	}
 
 	/* skip lines in dst */
-	uint32 *dst = (uint32 *)bp->dst + bp->top * bp->pitch + bp->left;
+	Colour *dst = (Colour *)bp->dst + bp->top * bp->pitch + bp->left;
 
 	/* store so we don't have to access it via bp everytime (compiler assumes pointer aliasing) */
 	const byte *remap = bp->remap;
 
 	for (int y = 0; y < bp->height; y++) {
 		/* next dst line begins here */
-		uint32 *dst_ln = dst + bp->pitch;
+		Colour *dst_ln = dst + bp->pitch;
 
 		/* next src line begins here */
 		const Colour *src_px_ln = (const Colour *)((const byte *)src_px + *(const uint32 *)src_px);
@@ -62,7 +62,7 @@
 		src_n += 2;
 
 		/* we will end this line when we reach this point */
-		uint32 *dst_end = dst + bp->skip_left;
+		Colour *dst_end = dst + bp->skip_left;
 
 		/* number of pixels with the same aplha channel class */
 		uint n;
@@ -286,10 +286,10 @@
 						*dst_n |= rgb_max << 8;
 
 						/* Pre-convert the mapping channel to a RGB value */
-						uint32 colour = this->AdjustBrightness(this->LookupColourInPalette(src->m), rgb_max);
-						dst_px->r = GB(colour, 16, 8);
-						dst_px->g = GB(colour, 8,  8);
-						dst_px->b = GB(colour, 0,  8);
+						Colour colour = this->AdjustBrightness(this->LookupColourInPalette(src->m), rgb_max);
+						dst_px->r = colour.r;
+						dst_px->g = colour.g;
+						dst_px->b = colour.b;
 					} else {
 						dst_px->r = src->r;
 						dst_px->g = src->g;
--- a/src/blitter/32bpp_simple.cpp
+++ b/src/blitter/32bpp_simple.cpp
@@ -21,11 +21,11 @@
 void Blitter_32bppSimple::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom)
 {
 	const Blitter_32bppSimple::Pixel *src, *src_line;
-	uint32 *dst, *dst_line;
+	Colour *dst, *dst_line;
 
 	/* Find where to start reading in the source sprite */
 	src_line = (const Blitter_32bppSimple::Pixel *)bp->sprite + (bp->skip_top * bp->sprite_width + bp->skip_left) * ScaleByZoom(1, zoom);
-	dst_line = (uint32 *)bp->dst + bp->top * bp->pitch + bp->left;
+	dst_line = (Colour *)bp->dst + bp->top * bp->pitch + bp->left;
 
 	for (int y = 0; y < bp->height; y++) {
 		dst = dst_line;
@@ -66,7 +66,7 @@
 
 void Blitter_32bppSimple::DrawColourMappingRect(void *dst, int width, int height, PaletteID pal)
 {
-	uint32 *udst = (uint32 *)dst;
+	Colour *udst = (Colour *)dst;
 
 	if (pal == PALETTE_TO_TRANSPARENT) {
 		do {
@@ -122,10 +122,10 @@
 			dst[i].v = rgb_max;
 
 			/* Pre-convert the mapping channel to a RGB value */
-			uint colour = this->AdjustBrightness(this->LookupColourInPalette(src->m), dst[i].v);
-			dst[i].r = GB(colour, 16, 8);
-			dst[i].g = GB(colour, 8,  8);
-			dst[i].b = GB(colour, 0,  8);
+			Colour colour = this->AdjustBrightness(this->LookupColourInPalette(src->m), dst[i].v);
+			dst[i].r = colour.r;
+			dst[i].g = colour.g;
+			dst[i].b = colour.b;
 			dst[i].a = src->a;
 			dst[i].m = src->m;
 		}
--- a/src/gfx_type.h
+++ b/src/gfx_type.h
@@ -158,8 +158,35 @@
 		uint8 b, g, r, a; ///< colour channels in LE order
 #endif /* TTD_ENDIAN == TTD_BIG_ENDIAN */
 	};
+
+	/**
+	 * Create a new colour.
+	 * @param r The channel for the red colour.
+	 * @param g The channel for the green colour.
+	 * @param b The channel for the blue colour.
+	 * @param a The channel for the alpha/transparency.
+	 */
+	Colour(uint8 r, uint8 g, uint8 b, uint8 a = 0xFF) :
+#if TTD_ENDIAN == TTD_BIG_ENDIAN
+		a(a), r(r), g(g), b(b)
+#else
+		b(b), g(g), r(r), a(a)
+#endif /* TTD_ENDIAN == TTD_BIG_ENDIAN */
+	{
+	}
+
+	/**
+	 * Create a new colour.
+	 * @param The colour in the correct packed format.
+	 */
+	Colour(uint data = 0) : data(data)
+	{
+	}
 };
 
+assert_compile(sizeof(Colour) == sizeof(uint32));
+
+
 /** Available font sizes */
 enum FontSize {
 	FS_NORMAL, ///< Index of the normal font in the font tables.
--- a/src/table/palettes.h
+++ b/src/table/palettes.h
@@ -11,13 +11,13 @@
 
 #include "../core/endian_type.hpp"
 
-#define M(r, g, b) { 0xFF000000U | (r) << 16 | (g) << 8 | (b) }
+#define M(r, g, b) Colour(r, g, b)
 
 /** Colour palette (DOS) */
 static const Palette _palette = {
 	{
 		/* transparent */
-		{             0},
+		Colour(0, 0, 0, 0),
 		/* grey scale */
 		                  M( 16,  16,  16), M( 32,  32,  32), M( 48,  48,  48),
 		M( 65,  64,  65), M( 82,  80,  82), M( 98, 101,  98), M(115, 117, 115),