changeset 5668:3d6d9bff3dd8 draft

(svn r8128) -Codechange: Split sprite and palette remap into separate 32 bit values. This lets us increase the sprite width from 14 to up to 29 bits, effectively nulling the old sprite limit. Table changes in next commit.
author peter1138 <peter1138@openttd.org>
date Sun, 14 Jan 2007 19:57:49 +0000
parents 883ea446c61c
children a3a9f3c9e83c
files src/aircraft_cmd.cpp src/aircraft_gui.cpp src/bridge.h src/bridge_gui.cpp src/build_vehicle_gui.cpp src/clear_cmd.cpp src/depot_gui.cpp src/dummy_land.cpp src/economy.cpp src/elrail.cpp src/engine.h src/engine_gui.cpp src/functions.h src/genworld.cpp src/genworld_gui.cpp src/gfx.cpp src/gfx.h src/graph_gui.cpp src/industry_cmd.cpp src/landscape.cpp src/macros.h src/main_gui.cpp src/misc.cpp src/misc_gui.cpp src/newgrf.cpp src/newgrf_gui.cpp src/newgrf_station.cpp src/news_gui.cpp src/openttd.h src/order_gui.cpp src/player_gui.cpp src/players.cpp src/rail_cmd.cpp src/rail_gui.cpp src/road_cmd.cpp src/roadveh_cmd.cpp src/roadveh_gui.cpp src/saveload.cpp src/settings_gui.cpp src/ship_cmd.cpp src/ship_gui.cpp src/sprite.h src/station_cmd.cpp src/station_gui.cpp src/table/sprites.h src/texteff.cpp src/town_cmd.cpp src/town_gui.cpp src/train_cmd.cpp src/train_gui.cpp src/tree_cmd.cpp src/tunnelbridge_cmd.cpp src/unmovable_cmd.cpp src/vehicle.cpp src/vehicle.h src/vehicle_gui.cpp src/viewport.cpp src/viewport.h src/water_cmd.cpp src/widget.cpp
diffstat 60 files changed, 673 insertions(+), 512 deletions(-) [+]
line wrap: on
line diff
--- a/src/aircraft_cmd.cpp
+++ b/src/aircraft_cmd.cpp
@@ -136,11 +136,11 @@
 	return SPR_ROTOR_STOPPED + w->u.air.state;
 }
 
-void DrawAircraftEngine(int x, int y, EngineID engine, uint32 image_ormod)
+void DrawAircraftEngine(int x, int y, EngineID engine, SpriteID pal)
 {
 	const AircraftVehicleInfo* avi = AircraftVehInfo(engine);
 	int spritenum = avi->image_index;
-	int sprite = (6 + _aircraft_sprite[spritenum]);
+	SpriteID sprite = (6 + _aircraft_sprite[spritenum]);
 
 	if (is_custom_sprite(spritenum)) {
 		sprite = GetCustomVehicleIcon(engine, DIR_W);
@@ -150,12 +150,12 @@
 		}
 	}
 
-	DrawSprite(sprite | image_ormod, x, y);
+	DrawSprite(sprite, pal, x, y);
 
 	if (!(avi->subtype & AIR_CTOL)) {
 		SpriteID rotor_sprite = GetCustomRotorIcon(engine);
 		if (rotor_sprite == 0) rotor_sprite = SPR_ROTOR_STOPPED;
-		DrawSprite(rotor_sprite, x, y - 5);
+		DrawSprite(rotor_sprite, PAL_NONE, x, y - 5);
 	}
 }
 
--- a/src/aircraft_gui.cpp
+++ b/src/aircraft_gui.cpp
@@ -266,7 +266,7 @@
 		}
 
 		/* draw the flag plus orders */
-		DrawSprite(v->vehstatus & VS_STOPPED ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, 2, w->widget[5].top + 1);
+		DrawSprite(v->vehstatus & VS_STOPPED ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, 2, w->widget[5].top + 1);
 		DrawStringCenteredTruncated(w->widget[5].left + 8, w->widget[5].right, w->widget[5].top + 1, str, 0);
 		DrawWindowViewport(w);
 	} break;
--- a/src/bridge.h
+++ b/src/bridge.h
@@ -17,7 +17,8 @@
 	byte max_length;     ///< the maximum length of the bridge (not counting start and end tile)
 	uint16 price;        ///< the relative price of the bridge
 	uint16 speed;        ///< maximum travel speed
-	PalSpriteID sprite;  ///< the sprite which is used in the GUI (possibly with a recolor sprite)
+	SpriteID sprite;     ///< the sprite which is used in the GUI
+	SpriteID pal;        ///< the palette which is used in the GUI
 	StringID material;   ///< the string that contains the bridge description
 	PalSpriteID **sprite_table; ///< table of sprites for drawing the bridge
 	byte flags;          ///< bit 0 set: disable drawing of far pillars.
--- a/src/bridge_gui.cpp
+++ b/src/bridge_gui.cpp
@@ -52,7 +52,7 @@
 			SetDParam(2, _bridgedata.costs[i + w->vscroll.pos]);
 			SetDParam(1, b->speed);
 			SetDParam(0, b->material);
-			DrawSprite(b->sprite, 3, 15 + i * 22);
+			DrawSprite(b->sprite, b->pal, 3, 15 + i * 22);
 
 			DrawString(44, 15 + i * 22 , STR_500D, 0);
 		}
--- a/src/build_vehicle_gui.cpp
+++ b/src/build_vehicle_gui.cpp
@@ -252,12 +252,12 @@
 
 void DrawAircraftImage(const Vehicle *v, int x, int y, VehicleID selection)
 {
-	PalSpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
-	DrawSprite(GetAircraftImage(v, DIR_W) | pal, x + 25, y + 10);
+	SpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
+	DrawSprite(GetAircraftImage(v, DIR_W), pal, x + 25, y + 10);
 	if (v->subtype == 0) {
 		SpriteID rotor_sprite = GetCustomRotorSprite(v, true);
 		if (rotor_sprite == 0) rotor_sprite = SPR_ROTOR_STOPPED;
-		DrawSprite(rotor_sprite, x + 25, y + 5);
+		DrawSprite(rotor_sprite, PAL_NONE, x + 25, y + 5);
 	}
 	if (v->index == selection) {
 		DrawFrameRect(x - 1, y - 1, x + 58, y + 21, 0xF, FR_BORDERONLY);
--- a/src/clear_cmd.cpp
+++ b/src/clear_cmd.cpp
@@ -483,15 +483,15 @@
 
 void DrawClearLandTile(const TileInfo *ti, byte set)
 {
-	DrawGroundSprite(SPR_FLAT_BARE_LAND + _tileh_to_sprite[ti->tileh] + set * 19);
+	DrawGroundSprite(SPR_FLAT_BARE_LAND + _tileh_to_sprite[ti->tileh] + set * 19, PAL_NONE);
 }
 
 void DrawHillyLandTile(const TileInfo *ti)
 {
 	if (ti->tileh != SLOPE_FLAT) {
-		DrawGroundSprite(SPR_FLAT_ROUGH_LAND + _tileh_to_sprite[ti->tileh]);
+		DrawGroundSprite(SPR_FLAT_ROUGH_LAND + _tileh_to_sprite[ti->tileh], PAL_NONE);
 	} else {
-		DrawGroundSprite(_landscape_clear_sprites[GB(ti->x ^ ti->y, 4, 3)]);
+		DrawGroundSprite(_landscape_clear_sprites[GB(ti->x ^ ti->y, 4, 3)], PAL_NONE);
 	}
 }
 
@@ -505,11 +505,11 @@
 	}
 
 	if (GetFenceSW(ti->tile) != 0) {
-		DrawGroundSpriteAt(_clear_land_fence_sprites_1[GetFenceSW(ti->tile) - 1] + _fence_mod_by_tileh[ti->tileh], ti->x, ti->y, z);
+		DrawGroundSpriteAt(_clear_land_fence_sprites_1[GetFenceSW(ti->tile) - 1] + _fence_mod_by_tileh[ti->tileh], PAL_NONE, ti->x, ti->y, z);
 	}
 
 	if (GetFenceSE(ti->tile) != 0) {
-		DrawGroundSpriteAt(_clear_land_fence_sprites_1[GetFenceSE(ti->tile) - 1] + _fence_mod_by_tileh_2[ti->tileh], ti->x, ti->y, z);
+		DrawGroundSpriteAt(_clear_land_fence_sprites_1[GetFenceSE(ti->tile) - 1] + _fence_mod_by_tileh_2[ti->tileh], PAL_NONE, ti->x, ti->y, z);
 	}
 }
 
@@ -525,19 +525,19 @@
 			break;
 
 		case CLEAR_ROCKS:
-			DrawGroundSprite(SPR_FLAT_ROCKY_LAND_1 + _tileh_to_sprite[ti->tileh]);
+			DrawGroundSprite(SPR_FLAT_ROCKY_LAND_1 + _tileh_to_sprite[ti->tileh], PAL_NONE);
 			break;
 
 		case CLEAR_FIELDS:
-			DrawGroundSprite(_clear_land_sprites_1[GetFieldType(ti->tile)] + _tileh_to_sprite[ti->tileh]);
+			DrawGroundSprite(_clear_land_sprites_1[GetFieldType(ti->tile)] + _tileh_to_sprite[ti->tileh], PAL_NONE);
 			break;
 
 		case CLEAR_SNOW:
-			DrawGroundSprite(_clear_land_sprites_2[GetClearDensity(ti->tile)] + _tileh_to_sprite[ti->tileh]);
+			DrawGroundSprite(_clear_land_sprites_2[GetClearDensity(ti->tile)] + _tileh_to_sprite[ti->tileh], PAL_NONE);
 			break;
 
 		case CLEAR_DESERT:
-			DrawGroundSprite(_clear_land_sprites_3[GetClearDensity(ti->tile)] + _tileh_to_sprite[ti->tileh]);
+			DrawGroundSprite(_clear_land_sprites_3[GetClearDensity(ti->tile)] + _tileh_to_sprite[ti->tileh], PAL_NONE);
 			break;
 	}
 
--- a/src/depot_gui.cpp
+++ b/src/depot_gui.cpp
@@ -184,7 +184,7 @@
 		diff_y = 12;
 	}
 
-	DrawSprite((v->vehstatus & VS_STOPPED) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, x + diff_x, y + diff_y);
+	DrawSprite((v->vehstatus & VS_STOPPED) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, x + diff_x, y + diff_y);
 
 	SetDParam(0, v->unitnumber);
 	DrawString(x, y + 2, (uint16)(v->max_age-366) >= v->age ? STR_00E2 : STR_00E3, 0);
@@ -431,7 +431,7 @@
 
 				WP(w, depot_d).sel = v->index;
 				SetWindowDirty(w);
-				SetObjectToPlaceWnd(GetVehiclePalette(v) | image, 4, w);
+				SetObjectToPlaceWnd(image, GetVehiclePalette(v), 4, w);
 			}
 			}
 			break;
@@ -757,7 +757,7 @@
 						};
 
 						_place_clicked_vehicle = NULL;
-						SetObjectToPlaceWnd(clone_icons[WP(w, depot_d).type - VEH_Train], VHM_RECT, w);
+						SetObjectToPlaceWnd(clone_icons[WP(w, depot_d).type - VEH_Train], PAL_NONE, VHM_RECT, w);
 					} else {
 						ResetObjectToPlace();
 					}
--- a/src/dummy_land.cpp
+++ b/src/dummy_land.cpp
@@ -10,7 +10,7 @@
 
 static void DrawTile_Dummy(TileInfo *ti)
 {
-	DrawGroundSpriteAt(SPR_SHADOW_CELL, ti->x, ti->y, ti->z);
+	DrawGroundSpriteAt(SPR_SHADOW_CELL, PAL_NONE, ti->x, ti->y, ti->z);
 }
 
 
--- a/src/economy.cpp
+++ b/src/economy.cpp
@@ -468,7 +468,7 @@
 
 	p = GetPlayer((PlayerID)GB(WP(w,news_d).ni->string_id, 0, 4));
 	DrawPlayerFace(p->face, p->player_color, 2, 23);
-	GfxFillRect(3, 23, 3+91, 23+118, 0x323 | USE_COLORTABLE);
+	GfxFillRect(3, 23, 3 + 91, 23 + 118, PALETTE_TO_STRUCT_GREY | (1 << USE_COLORTABLE));
 
 	SetDParam(0, p->president_name_1);
 	SetDParam(1, p->president_name_2);
--- a/src/elrail.cpp
+++ b/src/elrail.cpp
@@ -273,7 +273,7 @@
 						continue; /* No neighbour, go looking for a better position */
 					}
 
-					AddSortableSpriteToDraw(pylons_normal[temp], x, y, 1, 1, 10,
+					AddSortableSpriteToDraw(pylons_normal[temp], PAL_NONE, x, y, 1, 1, 10,
 							GetSlopeZ(ti->x + x_pcp_offsets[i], ti->y + y_pcp_offsets[i]));
 					break; /* We already have drawn a pylon, bail out */
 				}
@@ -302,7 +302,7 @@
 			assert(!IsSteepSlope(tileh[TS_HOME]));
 			sss = &CatenarySpriteData[Wires[tileh_selector][t][PCPconfig]];
 
-			AddSortableSpriteToDraw( sss->image, ti->x + sss->x_offset, ti->y + sss->y_offset,
+			AddSortableSpriteToDraw( sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset,
 				sss->x_size, sss->y_size, sss->z_size, GetSlopeZ(ti->x + min(sss->x_offset, TILE_SIZE - 1), ti->y + min(sss->y_offset, TILE_SIZE - 1)) + sss->z_offset);
 		}
 	}
@@ -334,7 +334,7 @@
 
 	height = GetBridgeHeight(end);
 
-	AddSortableSpriteToDraw( sss->image, ti->x + sss->x_offset, ti->y + sss->y_offset,
+	AddSortableSpriteToDraw( sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset,
 		sss->x_size, sss->y_size, sss->z_size, height + sss->z_offset
 	);
 
@@ -342,18 +342,18 @@
 	/* every other tile needs a pylon on the northern end */
 	if (num % 2) {
 		if (axis == AXIS_X) {
-			AddSortableSpriteToDraw(pylons_bridge[0 + HASBIT(tlg, 0)], ti->x, ti->y + 4 + 8 * HASBIT(tlg, 0), 1, 1, 10, height);
+			AddSortableSpriteToDraw(pylons_bridge[0 + HASBIT(tlg, 0)], PAL_NONE, ti->x, ti->y + 4 + 8 * HASBIT(tlg, 0), 1, 1, 10, height);
 		} else {
-			AddSortableSpriteToDraw(pylons_bridge[2 + HASBIT(tlg, 1)], ti->x + 4 + 8 * HASBIT(tlg, 1), ti->y, 1, 1, 10, height);
+			AddSortableSpriteToDraw(pylons_bridge[2 + HASBIT(tlg, 1)], PAL_NONE, ti->x + 4 + 8 * HASBIT(tlg, 1), ti->y, 1, 1, 10, height);
 		}
 	}
 
 	/* need a pylon on the southern end of the bridge */
 	if (DistanceMax(ti->tile, start) == length) {
 		if (axis == AXIS_X) {
-			AddSortableSpriteToDraw(pylons_bridge[0 + HASBIT(tlg, 0)], ti->x + 16, ti->y + 4 + 8 * HASBIT(tlg, 0), 1, 1, 10, height);
+			AddSortableSpriteToDraw(pylons_bridge[0 + HASBIT(tlg, 0)], PAL_NONE, ti->x + 16, ti->y + 4 + 8 * HASBIT(tlg, 0), 1, 1, 10, height);
 		} else {
-			AddSortableSpriteToDraw(pylons_bridge[2 + HASBIT(tlg, 1)], ti->x + 4 + 8 * HASBIT(tlg, 1), ti->y + 16, 1, 1, 10, height);
+			AddSortableSpriteToDraw(pylons_bridge[2 + HASBIT(tlg, 1)], PAL_NONE, ti->x + 4 + 8 * HASBIT(tlg, 1), ti->y + 16, 1, 1, 10, height);
 		}
 	}
 }
@@ -375,7 +375,7 @@
 				const SortableSpriteStruct* sss = &CatenarySpriteData_Depot[GetRailDepotDirection(ti->tile)];
 
 				AddSortableSpriteToDraw(
-					sss->image, ti->x + sss->x_offset, ti->y + sss->y_offset,
+					sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset,
 					sss->x_size, sss->y_size, sss->z_size,
 					GetTileMaxZ(ti->tile) + sss->z_offset
 				);
--- a/src/engine.h
+++ b/src/engine.h
@@ -131,10 +131,10 @@
 void StartupEngines(void);
 
 
-void DrawTrainEngine(int x, int y, EngineID engine, uint32 image_ormod);
-void DrawRoadVehEngine(int x, int y, EngineID engine, uint32 image_ormod);
-void DrawShipEngine(int x, int y, EngineID engine, uint32 image_ormod);
-void DrawAircraftEngine(int x, int y, EngineID engine, uint32 image_ormod);
+void DrawTrainEngine(int x, int y, EngineID engine, SpriteID pal);
+void DrawRoadVehEngine(int x, int y, EngineID engine, SpriteID pal);
+void DrawShipEngine(int x, int y, EngineID engine, SpriteID pal);
+void DrawAircraftEngine(int x, int y, EngineID engine, SpriteID pal);
 
 void LoadCustomEngineNames(void);
 void DeleteCustomEngineNames(void);
--- a/src/engine_gui.cpp
+++ b/src/engine_gui.cpp
@@ -46,7 +46,7 @@
 {   WIDGETS_END},
 };
 
-typedef void DrawEngineProc(int x, int y, EngineID engine, uint32 image_ormod);
+typedef void DrawEngineProc(int x, int y, EngineID engine, SpriteID pal);
 typedef void DrawEngineInfoProc(EngineID, int x, int y, int maxw);
 
 typedef struct DrawEngineInfo {
@@ -156,7 +156,7 @@
 	DrawStringMultiCenter(w->width >> 1, 57, STR_885A, w->width - 2);
 
 	DrawTrainEngine(w->width >> 1, 88, engine, 0);
-	GfxFillRect(25, 56, w->width - 56, 112, 0x323 | USE_COLORTABLE);
+	GfxFillRect(25, 56, w->width - 56, 112, PALETTE_TO_STRUCT_GREY | (1 << USE_COLORTABLE));
 	DrawTrainEngineInfo(engine, w->width >> 1, 129, w->width - 52);
 }
 
@@ -196,7 +196,7 @@
 	DrawStringMultiCenter(w->width >> 1, 57, STR_A02D, w->width - 2);
 
 	DrawAircraftEngine(w->width >> 1, 93, engine, 0);
-	GfxFillRect(25, 56, w->width - 56, 110, 0x323 | USE_COLORTABLE);
+	GfxFillRect(25, 56, w->width - 56, 110, PALETTE_TO_STRUCT_GREY | (1 << USE_COLORTABLE));
 	DrawAircraftEngineInfo(engine, w->width >> 1, 131, w->width - 52);
 }
 
@@ -235,7 +235,7 @@
 	DrawStringMultiCenter(w->width >> 1, 57, STR_9029, w->width - 2);
 
 	DrawRoadVehEngine(w->width >> 1, 88, engine, 0);
-	GfxFillRect(25, 56, w->width - 56, 112, 0x323 | USE_COLORTABLE);
+	GfxFillRect(25, 56, w->width - 56, 112, PALETTE_TO_STRUCT_GREY | (1 << USE_COLORTABLE));
 	DrawRoadVehEngineInfo(engine, w->width >> 1, 129, w->width - 52);
 }
 
@@ -273,7 +273,7 @@
 	DrawStringMultiCenter(w->width >> 1, 57, STR_982D, w->width - 2);
 
 	DrawShipEngine(w->width >> 1, 93, engine, 0);
-	GfxFillRect(25, 56, w->width - 56, 110, 0x323 | USE_COLORTABLE);
+	GfxFillRect(25, 56, w->width - 56, 110, PALETTE_TO_STRUCT_GREY | (1 << USE_COLORTABLE));
 	DrawShipEngineInfo(engine, w->width >> 1, 131, w->width - 52);
 }
 
--- a/src/functions.h
+++ b/src/functions.h
@@ -155,8 +155,8 @@
 void DeleteWindowById(WindowClass cls, WindowNumber number);
 void DeleteWindowByClass(WindowClass cls);
 
-void SetObjectToPlaceWnd(CursorID icon, byte mode, Window *w);
-void SetObjectToPlace(CursorID icon, byte mode, WindowClass window_class, WindowNumber window_num);
+void SetObjectToPlaceWnd(CursorID icon, SpriteID pal, byte mode, Window *w);
+void SetObjectToPlace(CursorID icon, SpriteID pal, byte mode, WindowClass window_class, WindowNumber window_num);
 
 void ResetObjectToPlace(void);
 
@@ -164,7 +164,7 @@
 
 bool ScrollMainWindowToTile(TileIndex tile);
 bool ScrollMainWindowTo(int x, int y);
-void DrawSprite(uint32 img, int x, int y);
+void DrawSprite(SpriteID img, SpriteID pal, int x, int y);
 bool EnsureNoVehicle(TileIndex tile);
 bool EnsureNoVehicleOnGround(TileIndex tile);
 void MarkAllViewportsDirty(int left, int top, int right, int bottom);
--- a/src/genworld.cpp
+++ b/src/genworld.cpp
@@ -84,7 +84,7 @@
 	if (_patches.generation_seed == GENERATE_NEW_SEED) _patches.generation_seed = _patches_newgame.generation_seed = InteractiveRandom();
 	_random_seeds[0][0] = _random_seeds[0][1] = _patches.generation_seed;
 	SetGeneratingWorldProgress(GWP_MAP_INIT, 2);
-	SetObjectToPlace(SPR_CURSOR_ZZZ, 0, 0, 0);
+	SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, 0, 0, 0);
 
 	IncreaseGeneratingWorldProgress(GWP_MAP_INIT);
 	// Must start economy early because of the costs.
@@ -140,7 +140,7 @@
 	if (_gw.proc != NULL) _gw.proc();
 	IncreaseGeneratingWorldProgress(GWP_GAME_START);
 
-	if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE);
+	if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE, PAL_NONE);
 	/* Show all vital windows again, because we have hidden them */
 	if (_gw.threaded && _game_mode != GM_MENU) ShowVitalWindows();
 	_gw.active   = false;
@@ -213,7 +213,7 @@
 
 	if (_gw.abortp != NULL) _gw.abortp();
 
-	if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE);
+	if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE, PAL_NONE);
 	/* Show all vital windows again, because we have hidden them */
 	if (_gw.threaded && _game_mode != GM_MENU) ShowVitalWindows();
 	_gw.active   = false;
--- a/src/genworld_gui.cpp
+++ b/src/genworld_gui.cpp
@@ -727,7 +727,7 @@
 	if (confirmed) {
 		AbortGeneratingWorld();
 	} else if (IsGeneratingWorld() && !IsGeneratingWorldAborted()) {
-		SetMouseCursor(SPR_CURSOR_ZZZ);
+		SetMouseCursor(SPR_CURSOR_ZZZ, PAL_NONE);
 	}
 }
 
@@ -737,7 +737,7 @@
 	case WE_CLICK:
 		switch (e->we.click.widget) {
 		case 2:
-			if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE);
+			if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE, PAL_NONE);
 			ShowQuery(
 				STR_GENERATION_ABORT_CAPTION,
 				STR_GENERATION_ABORT_MESSAGE,
--- a/src/gfx.cpp
+++ b/src/gfx.cpp
@@ -170,15 +170,15 @@
 
 	dst = dpi->dst_ptr + top * dpi->pitch + left;
 
-	if (!(color & PALETTE_MODIFIER_GREYOUT)) {
-		if (!(color & USE_COLORTABLE)) {
+	if (!HASBIT(color, PALETTE_MODIFIER_GREYOUT)) {
+		if (!HASBIT(color, USE_COLORTABLE)) {
 			do {
 				memset(dst, color, right);
 				dst += dpi->pitch;
 			} while (--bottom);
 		} else {
 			/* use colortable mode */
-			const byte* ctab = GetNonSprite(color & COLORTABLE_MASK) + 1;
+			const byte* ctab = GetNonSprite(GB(color, 0, PALETTE_WIDTH)) + 1;
 
 			do {
 				int i;
@@ -695,16 +695,16 @@
 	return DoDrawString(buffer, x, y, color);
 }
 
-void DrawSprite(uint32 img, int x, int y)
+void DrawSprite(SpriteID img, SpriteID pal, int x, int y)
 {
-	if (img & PALETTE_MODIFIER_COLOR) {
-		_color_remap_ptr = GetNonSprite(GB(img, PALETTE_SPRITE_START, PALETTE_SPRITE_WIDTH)) + 1;
-		GfxMainBlitter(GetSprite(img & SPRITE_MASK), x, y, BM_COLOUR_REMAP);
-	} else if (img & PALETTE_MODIFIER_TRANSPARENT) {
-		_color_remap_ptr = GetNonSprite(GB(img, PALETTE_SPRITE_START, PALETTE_SPRITE_WIDTH)) + 1;
-		GfxMainBlitter(GetSprite(img & SPRITE_MASK), x, y, BM_TRANSPARENT);
+	if (HASBIT(img, PALETTE_MODIFIER_TRANSPARENT)) {
+		_color_remap_ptr = GetNonSprite(GB(pal, 0, PALETTE_WIDTH)) + 1;
+		GfxMainBlitter(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y, BM_TRANSPARENT);
+	} else if (pal != PAL_NONE) {
+		_color_remap_ptr = GetNonSprite(GB(pal, 0, PALETTE_WIDTH)) + 1;
+		GfxMainBlitter(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y, BM_COLOUR_REMAP);
 	} else {
-		GfxMainBlitter(GetSprite(img & SPRITE_MASK), x, y, BM_NORMAL);
+		GfxMainBlitter(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y, BM_NORMAL);
 	}
 }
 
@@ -1739,7 +1739,7 @@
 
 	// Draw cursor on screen
 	_cur_dpi = &_screen;
-	DrawSprite(_cursor.sprite, _cursor.pos.x, _cursor.pos.y);
+	DrawSprite(_cursor.sprite, _cursor.pal, _cursor.pos.x, _cursor.pos.y);
 
 	_video_driver->make_dirty(_cursor.draw_pos.x, _cursor.draw_pos.y, _cursor.draw_size.x, _cursor.draw_size.y);
 
@@ -1967,15 +1967,16 @@
 	return true;
 }
 
-static void SetCursorSprite(CursorID cursor)
+static void SetCursorSprite(SpriteID cursor, SpriteID pal)
 {
 	CursorVars *cv = &_cursor;
 	const Sprite *p;
 
 	if (cv->sprite == cursor) return;
 
-	p = GetSprite(cursor & SPRITE_MASK);
+	p = GetSprite(GB(cursor, 0, SPRITE_WIDTH));
 	cv->sprite = cursor;
+	cv->pal    = pal;
 	cv->size.y = p->height;
 	cv->size.x = p->width;
 	cv->offs.x = p->x_offs;
@@ -1997,7 +1998,7 @@
 	cv->animate_timeout = cur[1];
 	cv->animate_cur = cur + 2;
 
-	SetCursorSprite(sprite);
+	SetCursorSprite(sprite, cv->pal);
 }
 
 void CursorTick(void)
@@ -2006,18 +2007,19 @@
 		SwitchAnimatedCursor();
 }
 
-void SetMouseCursor(CursorID cursor)
+void SetMouseCursor(SpriteID sprite, SpriteID pal)
 {
 	// Turn off animation
 	_cursor.animate_timeout = 0;
 	// Set cursor
-	SetCursorSprite(cursor);
+	SetCursorSprite(sprite, pal);
 }
 
 void SetAnimatedMouseCursor(const CursorID *table)
 {
 	_cursor.animate_list = table;
 	_cursor.animate_cur = NULL;
+	_cursor.pal = PAL_NONE;
 	SwitchAnimatedCursor();
 }
 
--- a/src/gfx.h
+++ b/src/gfx.h
@@ -108,7 +108,8 @@
 typedef struct CursorVars {
 	Point pos, size, offs, delta; ///< position, size, offset from top-left, and movement
 	Point draw_pos, draw_size;    ///< position and size bounding-box for drawing
-	CursorID sprite; ///< current image of cursor
+	SpriteID sprite; ///< current image of cursor
+	SpriteID pal;
 
 	int wheel;       ///< mouse wheel movement
 	const CursorID *animate_list, *animate_cur; ///< in case of animated cursor, list of frames
@@ -236,6 +237,7 @@
 void DrawOverlappedWindowForAll(int left, int top, int right, int bottom);
 
 void SetMouseCursor(CursorID cursor);
+void SetMouseCursor(SpriteID sprite, SpriteID pal);
 void SetAnimatedMouseCursor(const CursorID *table);
 void CursorTick(void);
 void DrawMouseCursor(void);
--- a/src/graph_gui.cpp
+++ b/src/graph_gui.cpp
@@ -218,7 +218,7 @@
 
 void DrawPlayerIcon(PlayerID p, int x, int y)
 {
-	DrawSprite(SPRITE_PALETTE(PLAYER_SPRITE_COLOR(p) + 0x2EB), x, y);
+	DrawSprite(0x2EB, PLAYER_SPRITE_COLOR(p), x, y);
 }
 
 static void GraphLegendWndProc(Window *w, WindowEvent *e)
--- a/src/industry_cmd.cpp
+++ b/src/industry_cmd.cpp
@@ -125,14 +125,14 @@
 
 	d = &_draw_industry_spec1[GetIndustryAnimationState(ti->tile)];
 
-	AddChildSpriteScreen(SPR_IT_SUGAR_MINE_SIEVE + d->image_1, d->x, 0);
+	AddChildSpriteScreen(SPR_IT_SUGAR_MINE_SIEVE + d->image_1, PAL_NONE, d->x, 0);
 
 	image = d->image_2;
-	if (image != 0) AddChildSpriteScreen(SPR_IT_SUGAR_MINE_CLOUDS + image - 1, 8, 41);
+	if (image != 0) AddChildSpriteScreen(SPR_IT_SUGAR_MINE_CLOUDS + image - 1, PAL_NONE, 8, 41);
 
 	image = d->image_3;
 	if (image != 0) {
-		AddChildSpriteScreen(SPR_IT_SUGAR_MINE_PILE + image - 1,
+		AddChildSpriteScreen(SPR_IT_SUGAR_MINE_PILE + image - 1, PAL_NONE,
 			_drawtile_proc1_x[image - 1], _drawtile_proc1_y[image - 1]);
 	}
 }
@@ -147,16 +147,16 @@
 			x = 0;
 	}
 
-	AddChildSpriteScreen(SPR_IT_TOFFEE_QUARRY_SHOVEL, 22 - x, 24 + x);
-	AddChildSpriteScreen(SPR_IT_TOFFEE_QUARRY_TOFFEE, 6, 14);
+	AddChildSpriteScreen(SPR_IT_TOFFEE_QUARRY_SHOVEL, PAL_NONE, 22 - x, 24 + x);
+	AddChildSpriteScreen(SPR_IT_TOFFEE_QUARRY_TOFFEE, PAL_NONE, 6, 14);
 }
 
 static void IndustryDrawBubbleGenerator( const TileInfo *ti)
 {
 	if (IsIndustryCompleted(ti->tile)) {
-		AddChildSpriteScreen(SPR_IT_BUBBLE_GENERATOR_BUBBLE, 5, _industry_anim_offs_2[GetIndustryAnimationState(ti->tile)]);
+		AddChildSpriteScreen(SPR_IT_BUBBLE_GENERATOR_BUBBLE, PAL_NONE, 5, _industry_anim_offs_2[GetIndustryAnimationState(ti->tile)]);
 	} else {
-		AddChildSpriteScreen(SPR_IT_BUBBLE_GENERATOR_SPRING, 3, 67);
+		AddChildSpriteScreen(SPR_IT_BUBBLE_GENERATOR_SPRING, PAL_NONE, 3, 67);
 	}
 }
 
@@ -167,15 +167,15 @@
 	d = &_industry_anim_offs_3[GetIndustryAnimationState(ti->tile)];
 
 	if (d->image_1 != 0xFF) {
-		AddChildSpriteScreen(SPR_IT_TOY_FACTORY_CLAY, 50 - d->image_1 * 2, 96 + d->image_1);
+		AddChildSpriteScreen(SPR_IT_TOY_FACTORY_CLAY, PAL_NONE, 50 - d->image_1 * 2, 96 + d->image_1);
 	}
 
 	if (d->image_2 != 0xFF) {
-		AddChildSpriteScreen(SPR_IT_TOY_FACTORY_ROBOT, 16 - d->image_2 * 2, 100 + d->image_2);
+		AddChildSpriteScreen(SPR_IT_TOY_FACTORY_ROBOT, PAL_NONE, 16 - d->image_2 * 2, 100 + d->image_2);
 	}
 
-	AddChildSpriteScreen(SPR_IT_TOY_FACTORY_STAMP, 7, d->image_3);
-	AddChildSpriteScreen(SPR_IT_TOY_FACTORY_STAMP_HOLDER, 0, 42);
+	AddChildSpriteScreen(SPR_IT_TOY_FACTORY_STAMP, PAL_NONE, 7, d->image_3);
+	AddChildSpriteScreen(SPR_IT_TOY_FACTORY_STAMP_HOLDER, PAL_NONE, 0, 42);
 }
 
 static void IndustryDrawCoalPlantSparks(const TileInfo *ti)
@@ -185,6 +185,7 @@
 
 		if (image != 0 && image < 7) {
 			AddChildSpriteScreen(image + SPR_IT_POWER_PLANT_TRANSFORMERS,
+				PAL_NONE,
 				_coal_plant_sparks_x[image - 1],
 				_coal_plant_sparks_y[image - 1]
 			);
@@ -207,41 +208,46 @@
 	const Industry *ind;
 	const DrawBuildingsTileStruct *dits;
 	byte z;
-	uint32 image, ormod;
+	SpriteID image;
+	SpriteID pal;
 
 	/* Pointer to industry */
 	ind = GetIndustryByTile(ti->tile);
-	ormod = GENERAL_SPRITE_COLOR(ind->random_color);
 
 	/* Retrieve pointer to the draw industry tile struct */
 	dits = &_industry_draw_tile_data[gfx << 2 | (_industry_section_draw_animation_state[gfx] ?
 			GetIndustryAnimationState(ti->tile) & 3 :
 			GetIndustryConstructionStage(ti->tile))];
 
-	image = dits->ground;
-	if (image & PALETTE_MODIFIER_COLOR && (image & PALETTE_SPRITE_MASK) == 0)
-		image |= ormod;
+	image = dits->ground.sprite;
+	if (HASBIT(image, PALETTE_MODIFIER_COLOR) && dits->ground.pal == PAL_NONE) {
+		pal = GENERAL_SPRITE_COLOR(ind->random_color);
+	} else {
+		pal = dits->ground.pal;
+	}
 
 	z = ti->z;
 	/* Add bricks below the industry? */
 	if (ti->tileh != SLOPE_FLAT) {
-		AddSortableSpriteToDraw(SPR_FOUNDATION_BASE + ti->tileh, ti->x, ti->y, 16, 16, 7, z);
-		AddChildSpriteScreen(image, 31, 1);
+		AddSortableSpriteToDraw(SPR_FOUNDATION_BASE + ti->tileh, PAL_NONE, ti->x, ti->y, 16, 16, 7, z);
+		AddChildSpriteScreen(image, pal, 31, 1);
 		z += TILE_HEIGHT;
 	} else {
 		/* Else draw regular ground */
-		DrawGroundSprite(image);
+		DrawGroundSprite(image, pal);
 	}
 
 	/* Add industry on top of the ground? */
-	image = dits->building;
+	image = dits->building.sprite;
 	if (image != 0) {
-		if (image & PALETTE_MODIFIER_COLOR && (image & PALETTE_SPRITE_MASK) == 0)
-			image |= ormod;
+		if (_display_opt & DO_TRANS_BUILDINGS) {
+			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
+			pal = PALETTE_TO_TRANSPARENT;
+		} else {
+			pal = dits->building.pal;
+		}
 
-		if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
-
-		AddSortableSpriteToDraw(image,
+		AddSortableSpriteToDraw(image, pal,
 			ti->x + dits->subtile_x,
 			ti->y + dits->subtile_y,
 			dits->width  + 1,
--- a/src/landscape.cpp
+++ b/src/landscape.cpp
@@ -212,7 +212,7 @@
 
 void DrawFoundation(TileInfo *ti, uint f)
 {
-	uint32 sprite_base = SPR_SLOPES_BASE - 15;
+	SpriteID sprite_base = SPR_SLOPES_BASE - 15;
 	Slope slope;
 	uint z;
 
@@ -221,26 +221,26 @@
 	if (!HasFoundationNE(ti->tile, slope, z)) sprite_base += 44;
 
 	if (IsSteepSlope(ti->tileh)) {
-		uint32 lower_base;
+		SpriteID lower_base;
 
 		// Lower part of foundation
 		lower_base = sprite_base;
 		if (lower_base == SPR_SLOPES_BASE - 15) lower_base = SPR_FOUNDATION_BASE;
 		AddSortableSpriteToDraw(
-			lower_base + (ti->tileh & ~SLOPE_STEEP), ti->x, ti->y, 16, 16, 7, ti->z
+			lower_base + (ti->tileh & ~SLOPE_STEEP), PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z
 		);
 		ti->z += TILE_HEIGHT;
 		ti->tileh = _inclined_tileh[f - 15];
 		if (f < 15 + 8) {
 			// inclined
-			AddSortableSpriteToDraw(sprite_base + f, ti->x, ti->y, 16, 16, 1, ti->z);
+			AddSortableSpriteToDraw(sprite_base + f, PAL_NONE, ti->x, ti->y, 16, 16, 1, ti->z);
 			OffsetGroundSprite(31, 9);
 		} else if (f >= 15 + 8 + 4) {
 			// three corners raised
-			uint32 upper = sprite_base + 15 + (f - 15 - 8 - 4) * 2;
+			SpriteID upper = sprite_base + 15 + (f - 15 - 8 - 4) * 2;
 
-			AddSortableSpriteToDraw(upper, ti->x, ti->y, 16, 16, 1, ti->z);
-			AddChildSpriteScreen(upper + 1, 31, 9);
+			AddSortableSpriteToDraw(upper, PAL_NONE, ti->x, ti->y, 16, 16, 1, ti->z);
+			AddChildSpriteScreen(upper + 1, PAL_NONE, 31, 9);
 			OffsetGroundSprite(31, 9);
 		} else {
 			// one corner raised
@@ -252,13 +252,13 @@
 			// Use the original slope sprites if NW and NE borders should be visible
 			if (sprite_base  == SPR_SLOPES_BASE - 15) sprite_base = SPR_FOUNDATION_BASE;
 
-			AddSortableSpriteToDraw(sprite_base + f, ti->x, ti->y, 16, 16, 7, ti->z);
+			AddSortableSpriteToDraw(sprite_base + f, PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z);
 			ti->z += TILE_HEIGHT;
 			ti->tileh = SLOPE_FLAT;
 			OffsetGroundSprite(31, 1);
 		} else {
 			// inclined foundation
-			AddSortableSpriteToDraw(sprite_base + f, ti->x, ti->y, 16, 16, 1, ti->z);
+			AddSortableSpriteToDraw(sprite_base + f, PAL_NONE, ti->x, ti->y, 16, 16, 1, ti->z);
 			ti->tileh = _inclined_tileh[f - 15];
 			OffsetGroundSprite(31, 9);
 		}
--- a/src/macros.h
+++ b/src/macros.h
@@ -79,9 +79,8 @@
 #define SETBITS(x,y) ((x) |= (y))
 #define CLRBITS(x,y) ((x) &= ~(y))
 
-#define GENERAL_SPRITE_COLOR(color) ( ((color) + PALETTE_RECOLOR_START) << PALETTE_SPRITE_START)
-#define PLAYER_SPRITE_COLOR(owner) ( GENERAL_SPRITE_COLOR(_player_colors[owner]))
-#define SPRITE_PALETTE(x) ((x) | PALETTE_MODIFIER_COLOR)
+#define GENERAL_SPRITE_COLOR(color) ((color) + PALETTE_RECOLOR_START)
+#define PLAYER_SPRITE_COLOR(owner) (GENERAL_SPRITE_COLOR(_player_colors[owner]))
 
 extern const byte _ffb_64[128];
 /* Returns the position of the first bit that is not zero, counted from the
--- a/src/main_gui.cpp
+++ b/src/main_gui.cpp
@@ -118,7 +118,7 @@
 		return false;
 	}
 
-	SetObjectToPlace(cursor, mode, w->window_class, w->window_number);
+	SetObjectToPlace(cursor, PAL_NONE, mode, w->window_class, w->window_number);
 	LowerWindowWidget(w, widget);
 	_place_proc = placeproc;
 	return true;
@@ -340,7 +340,7 @@
 	if (_cursor.sprite == SPR_CURSOR_SIGN) {
 		ResetObjectToPlace();
 	} else {
-		SetObjectToPlace(SPR_CURSOR_SIGN, 1, 1, 0);
+		SetObjectToPlace(SPR_CURSOR_SIGN, PAL_NONE, 1, 1, 0);
 		_place_proc = PlaceProc_Sign;
 	}
 }
@@ -1256,7 +1256,7 @@
 
 			assert(n != 0);
 			do {
-				DrawSprite(SPR_WHITE_POINT, 77 + coords[0], 55 + coords[1]);
+				DrawSprite(SPR_WHITE_POINT, PAL_NONE, 77 + coords[0], 55 + coords[1]);
 				coords += 2;
 			} while (--n);
 		}
@@ -1771,7 +1771,7 @@
 	case WE_PAINT:
 		// Draw brown-red toolbar bg.
 		GfxFillRect(0, 0, w->width-1, w->height-1, 0xB2);
-		GfxFillRect(0, 0, w->width-1, w->height-1, 0xB4 | PALETTE_MODIFIER_GREYOUT);
+		GfxFillRect(0, 0, w->width-1, w->height-1, 0xB4 | (1 << PALETTE_MODIFIER_GREYOUT));
 
 		/* If spectator, disable all construction buttons
 		 * ie : Build road, rail, ships, airports and landscaping
@@ -1984,7 +1984,7 @@
 
 		// Draw brown-red toolbar bg.
 		GfxFillRect(0, 0, w->width-1, w->height-1, 0xB2);
-		GfxFillRect(0, 0, w->width-1, w->height-1, 0xB4 | PALETTE_MODIFIER_GREYOUT);
+		GfxFillRect(0, 0, w->width-1, w->height-1, 0xB4 | (1 << PALETTE_MODIFIER_GREYOUT));
 
 		DrawWindowWidgets(w);
 
@@ -2145,7 +2145,7 @@
 			}
 		}
 
-		if (WP(w, def_d).data_2 > 0) DrawSprite(SPR_BLOT | PALETTE_TO_RED, 489, 2);
+		if (WP(w, def_d).data_2 > 0) DrawSprite(SPR_BLOT, PALETTE_TO_RED, 489, 2);
 	} break;
 
 	case WE_MESSAGE:
@@ -2208,14 +2208,14 @@
 		if (_game_mode == GM_MENU) {
 			off_x = _screen.width / 2;
 
-			DrawSprite(SPR_OTTD_O, off_x - 120, 50);
-			DrawSprite(SPR_OTTD_P, off_x -  86, 50);
-			DrawSprite(SPR_OTTD_E, off_x -  53, 50);
-			DrawSprite(SPR_OTTD_N, off_x -  22, 50);
+			DrawSprite(SPR_OTTD_O, PAL_NONE, off_x - 120, 50);
+			DrawSprite(SPR_OTTD_P, PAL_NONE, off_x -  86, 50);
+			DrawSprite(SPR_OTTD_E, PAL_NONE, off_x -  53, 50);
+			DrawSprite(SPR_OTTD_N, PAL_NONE, off_x -  22, 50);
 
-			DrawSprite(SPR_OTTD_T, off_x +  34, 50);
-			DrawSprite(SPR_OTTD_T, off_x +  65, 50);
-			DrawSprite(SPR_OTTD_D, off_x +  96, 50);
+			DrawSprite(SPR_OTTD_T, PAL_NONE, off_x +  34, 50);
+			DrawSprite(SPR_OTTD_T, PAL_NONE, off_x +  65, 50);
+			DrawSprite(SPR_OTTD_D, PAL_NONE, off_x +  96, 50);
 
 			/*
 			DrawSprite(SPR_OTTD_R, off_x + 119, 50);
@@ -2434,3 +2434,4 @@
 }
 
 
+
--- a/src/misc.cpp
+++ b/src/misc.cpp
@@ -100,7 +100,7 @@
 
 	AddTypeToEngines(); // make sure all engines have a type
 
-	SetObjectToPlace(SPR_CURSOR_ZZZ, 0, 0, 0);
+	SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, 0, 0, 0);
 
 	_pause = 0;
 	_fast_forward = 0;
--- a/src/misc_gui.cpp
+++ b/src/misc_gui.cpp
@@ -193,7 +193,7 @@
 		ResetObjectToPlace();
 	} else {
 		_place_proc = Place_LandInfo;
-		SetObjectToPlace(SPR_CURSOR_QUERY, 1, 1, 0);
+		SetObjectToPlace(SPR_CURSOR_QUERY, PAL_NONE, 1, 1, 0);
 	}
 }
 
@@ -308,11 +308,17 @@
 
 static int _tree_to_plant;
 
-static const uint32 _tree_sprites[] = {
-	0x655, 0x663, 0x678, 0x62B, 0x647, 0x639, 0x64E, 0x632, 0x67F, 0x68D, 0x69B, 0x6A9,
-	0x6AF, 0x6D2, 0x6D9, 0x6C4, 0x6CB, 0x6B6, 0x6BD, 0x6E0,
-	0x72E, 0x734, 0x74A, 0x74F, 0x76B, 0x78F, 0x788, 0x77B, 0x75F, 0x774, 0x720, 0x797,
-	0x79E, 0x7A5 | PALETTE_TO_GREEN, 0x7AC | PALETTE_TO_RED, 0x7B3, 0x7BA, 0x7C1 | PALETTE_TO_RED, 0x7C8 | PALETTE_TO_PALE_GREEN, 0x7CF | PALETTE_TO_YELLOW, 0x7D6 | PALETTE_TO_RED
+static const PalSpriteID _tree_sprites[] = {
+	{ 0x655, PAL_NONE }, { 0x663, PAL_NONE }, { 0x678, PAL_NONE }, { 0x62B, PAL_NONE },
+	{ 0x647, PAL_NONE }, { 0x639, PAL_NONE }, { 0x64E, PAL_NONE }, { 0x632, PAL_NONE },
+	{ 0x67F, PAL_NONE }, { 0x68D, PAL_NONE }, { 0x69B, PAL_NONE }, { 0x6A9, PAL_NONE },
+	{ 0x6AF, PAL_NONE }, { 0x6D2, PAL_NONE }, { 0x6D9, PAL_NONE }, { 0x6C4, PAL_NONE },
+	{ 0x6CB, PAL_NONE }, { 0x6B6, PAL_NONE }, { 0x6BD, PAL_NONE }, { 0x6E0, PAL_NONE },
+	{ 0x72E, PAL_NONE }, { 0x734, PAL_NONE }, { 0x74A, PAL_NONE }, { 0x74F, PAL_NONE },
+	{ 0x76B, PAL_NONE }, { 0x78F, PAL_NONE }, { 0x788, PAL_NONE }, { 0x77B, PAL_NONE },
+	{ 0x75F, PAL_NONE }, { 0x774, PAL_NONE }, { 0x720, PAL_NONE }, { 0x797, PAL_NONE },
+	{ 0x79E, PAL_NONE }, { 0x7A5, PALETTE_TO_GREEN }, { 0x7AC, PALETTE_TO_RED }, { 0x7B3, PAL_NONE },
+	{ 0x7BA, PAL_NONE }, { 0x7C1, PALETTE_TO_RED, }, { 0x7C8, PALETTE_TO_PALE_GREEN }, { 0x7CF, PALETTE_TO_YELLOW }, { 0x7D6, PALETTE_TO_RED }
 };
 
 static void BuildTreesWndProc(Window *w, WindowEvent *e)
@@ -330,7 +336,7 @@
 		x = 18;
 		y = 54;
 		do {
-			DrawSprite(_tree_sprites[i], x, y);
+			DrawSprite(_tree_sprites[i].sprite, _tree_sprites[i].pal, x, y);
 			x += 35;
 			if (!(++i & 3)) {
 				x -= 35 * 4;
@@ -1619,7 +1625,7 @@
 	const WindowDesc *sld = &_save_dialog_desc;
 
 
-	SetObjectToPlace(SPR_CURSOR_ZZZ, 0, 0, 0);
+	SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, 0, 0, 0);
 	DeleteWindowById(WC_QUERY_STRING, 0);
 	DeleteWindowById(WC_SAVELOAD, 0);
 
@@ -1802,7 +1808,7 @@
 		for (i = 0; i != lengthof(_cheats_ui); i++) {
 			const CheatEntry *ce = &_cheats_ui[i];
 
-			DrawSprite((*ce->been_used) ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, x + 5, y + 2);
+			DrawSprite((*ce->been_used) ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, PAL_NONE, x + 5, y + 2);
 
 			switch (ce->type) {
 			case SLE_BOOL: {
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -885,8 +885,13 @@
 					uint seq_count = 0;
 
 					dts->seq = NULL;
-					dts->ground_sprite = grf_load_dword(&buf);
+					dts->ground_sprite = grf_load_word(&buf);
+					dts->ground_pal = grf_load_word(&buf);
 					if (dts->ground_sprite == 0) continue;
+					if (HASBIT(dts->ground_pal, 15)) {
+						CLRBIT(dts->ground_pal, 15);
+						SETBIT(dts->ground_sprite, SPRITE_MODIFIER_USE_OFFSET);
+					}
 
 					while (buf < *bufp + len) {
 						DrawTileSeqStruct *dtss;
@@ -902,16 +907,22 @@
 						dtss->size_x = grf_load_byte(&buf);
 						dtss->size_y = grf_load_byte(&buf);
 						dtss->size_z = grf_load_byte(&buf);
-						dtss->image = grf_load_dword(&buf);
+						dtss->image = grf_load_word(&buf);
+						dtss->pal = grf_load_word(&buf);
 
 						/* Remap flags as ours collide */
-						if (HASBIT(dtss->image, 31)) {
-							CLRBIT(dtss->image, 31);
-							SETBIT(dtss->image, 30);
+						if (HASBIT(dtss->pal, 15)) {
+							CLRBIT(dtss->pal, 15);
+							SETBIT(dtss->image, SPRITE_MODIFIER_USE_OFFSET);
+						}
+
+						if (HASBIT(dtss->image, 15)) {
+							CLRBIT(dtss->image, 15);
+							SETBIT(dtss->image, PALETTE_MODIFIER_COLOR);
 						}
 						if (HASBIT(dtss->image, 14)) {
 							CLRBIT(dtss->image, 14);
-							SETBIT(dtss->image, 31);
+							SETBIT(dtss->image, PALETTE_MODIFIER_TRANSPARENT);
 						}
 					}
 				}
@@ -1092,8 +1103,20 @@
 						bridge->sprite_table[tableid] = MallocT<PalSpriteID>(32);
 					}
 
-					for (sprite = 0; sprite < 32; sprite++)
-						bridge->sprite_table[tableid][sprite] = grf_load_dword(&buf);
+					for (sprite = 0; sprite < 32; sprite++) {
+						SpriteID image = grf_load_word(&buf);
+						SpriteID pal   = grf_load_word(&buf);
+
+						if (HASBIT(pal, 15)) {
+							SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
+						}
+
+						/* Clear old color modifer bit */
+						CLRBIT(image, 15);
+
+						bridge->sprite_table[tableid][sprite].sprite = image;
+						bridge->sprite_table[tableid][sprite].pal    = pal;
+					}
 				}
 			}
 			break;
@@ -3777,3 +3800,4 @@
 
 
 
+
--- a/src/newgrf_gui.cpp
+++ b/src/newgrf_gui.cpp
@@ -312,7 +312,7 @@
 			for (c = *WP(w, newgrf_d).list, i = 0; c != NULL; c = c->next, i++) {
 				if (i >= w->vscroll.pos && i < w->vscroll.pos + w->vscroll.cap) {
 					const char *text = (c->name != NULL && !StrEmpty(c->name)) ? c->name : c->filename;
-					PalSpriteID pal;
+					SpriteID pal;
 
 					/* Pick a colour */
 					if (HASBIT(c->flags, GCF_NOT_FOUND) || HASBIT(c->flags, GCF_DISABLED)) {
@@ -327,7 +327,7 @@
 						pal = PALETTE_TO_BLUE;
 					}
 
-					DrawSprite(SPRITE_PALETTE(SPR_SQUARE | pal), 5, y + 2);
+					DrawSprite(SPR_SQUARE, pal, 5, y + 2);
 					DoDrawString(text, 25, y + 3, WP(w, newgrf_d).sel == c ? 0xC : 0x10);
 					y += 14;
 				}
--- a/src/newgrf_station.cpp
+++ b/src/newgrf_station.cpp
@@ -676,8 +676,8 @@
 	const DrawTileSeqStruct *seq;
 	const RailtypeInfo *rti = GetRailTypeInfo(railtype);
 	SpriteID relocation;
-	PalSpriteID image;
-	PalSpriteID colourmod = SPRITE_PALETTE(PLAYER_SPRITE_COLOR(_local_player));
+	SpriteID image;
+	SpriteID pal = PLAYER_SPRITE_COLOR(_local_player);
 	uint tile = 2;
 
 	statspec = GetCustomStationSpec(sclass, station);
@@ -697,22 +697,19 @@
 	}
 
 	image = sprites->ground_sprite;
-	if (HASBIT(image, 31)) {
-		CLRBIT(image, 31);
+	if (HASBIT(image, SPRITE_MODIFIER_USE_OFFSET)) {
 		image += GetCustomStationGroundRelocation(statspec, NULL, INVALID_TILE);
 		image += rti->custom_ground_offset;
 	} else {
 		image += rti->total_offset;
 	}
 
-	if (image & PALETTE_MODIFIER_COLOR) image &= SPRITE_MASK;
-	DrawSprite(image, x, y);
+	DrawSprite(image, PAL_NONE, x, y);
 
 	foreach_draw_tile_seq(seq, sprites->seq) {
 		Point pt;
 		image = seq->image;
-		if (HASBIT(image, 30)) {
-			CLRBIT(image, 30);
+		if (HASBIT(image, SPRITE_MODIFIER_USE_OFFSET)) {
 			image += rti->total_offset;
 		} else {
 			image += relocation;
@@ -720,7 +717,7 @@
 
 		if ((byte)seq->delta_z != 0x80) {
 			pt = RemapCoords(seq->delta_x, seq->delta_y, seq->delta_z);
-			DrawSprite((image & SPRITE_MASK) | colourmod, x + pt.x, y + pt.y);
+			DrawSprite(image, pal, x + pt.x, y + pt.y);
 		}
 	}
 
--- a/src/news_gui.cpp
+++ b/src/news_gui.cpp
@@ -146,7 +146,7 @@
 					vp = w->viewport;
 					GfxFillRect(vp->left - w->left, vp->top - w->top,
 						vp->left - w->left + vp->width - 1, vp->top - w->top + vp->height - 1,
-						(ni->flags & NF_INCOLOR ? 0x322 : 0x323) | USE_COLORTABLE
+						(ni->flags & NF_INCOLOR ? PALETTE_TO_TRANSPARENT : PALETTE_TO_STRUCT_GREY) | (1 << USE_COLORTABLE)
 					);
 
 					COPY_IN_DPARAM(0, ni->params, lengthof(ni->params));
--- a/src/openttd.h
+++ b/src/openttd.h
@@ -44,7 +44,10 @@
 typedef byte CargoID;
 typedef byte LandscapeID;
 typedef uint32 SpriteID;      ///< The number of a sprite, without mapping bits and colortables
-typedef uint32 PalSpriteID;   ///< The number of a sprite plus all the mapping bits and colortables
+typedef struct PalSpriteID {
+	SpriteID sprite;
+	SpriteID pal;
+} PalSpriteID;
 typedef uint16 EngineID;
 typedef uint16 UnitID;
 typedef uint16 StringID;
--- a/src/order_gui.cpp
+++ b/src/order_gui.cpp
@@ -342,7 +342,7 @@
 	ToggleWidgetLoweredState(w, 7);
 	if (IsWindowWidgetLowered(w, 7)) {
 		_place_clicked_vehicle = NULL;
-		SetObjectToPlaceWnd(ANIMCURSOR_PICKSTATION, 1, w);
+		SetObjectToPlaceWnd(ANIMCURSOR_PICKSTATION, PAL_NONE, 1, w);
 	} else {
 		ResetObjectToPlace();
 	}
--- a/src/player_gui.cpp
+++ b/src/player_gui.cpp
@@ -353,16 +353,16 @@
 					bool sel = HASBIT(WP(w, livery_d).sel, scheme) != 0;
 
 					if (scheme != LS_DEFAULT) {
-						DrawSprite(p->livery[scheme].in_use ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, 2, y);
+						DrawSprite(p->livery[scheme].in_use ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, PAL_NONE, 2, y);
 					}
 
 					DrawString(15, y, STR_LIVERY_DEFAULT + scheme, sel ? 0xC : 0x10);
 
-					DrawSprite(SPR_SQUARE | GENERAL_SPRITE_COLOR(p->livery[scheme].colour1) | PALETTE_MODIFIER_COLOR, 152, y);
+					DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOR(p->livery[scheme].colour1), 152, y);
 					DrawString(165, y, STR_00D1_DARK_BLUE + p->livery[scheme].colour1, sel ? 0xC : 2);
 
 					if (_have_2cc) {
-						DrawSprite(SPR_SQUARE | GENERAL_SPRITE_COLOR(p->livery[scheme].colour2) | PALETTE_MODIFIER_COLOR, 277, y);
+						DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOR(p->livery[scheme].colour2), 277, y);
 						DrawString(290, y, STR_00D1_DARK_BLUE + p->livery[scheme].colour2, sel ? 0xC : 2);
 					}
 
@@ -722,7 +722,7 @@
 
 			DrawString(110,48, STR_7006_COLOR_SCHEME, 0);
 			// Draw company-colour bus
-			DrawSprite(PLAYER_SPRITE_COLOR(p->index) + SPRITE_PALETTE(SPR_VEH_BUS_SW_VIEW), 215, 49);
+			DrawSprite(SPR_VEH_BUS_SW_VIEW, PLAYER_SPRITE_COLOR(p->index), 215, 49);
 
 			DrawPlayerFace(p->face, p->player_color, 2, 16);
 
@@ -782,7 +782,7 @@
 					if (tile == 0) {
 						if ((byte)w->window_number != _local_player)
 							return;
-						SetObjectToPlaceWnd(SPR_CURSOR_HQ, 1, w);
+						SetObjectToPlaceWnd(SPR_CURSOR_HQ, PAL_NONE, 1, w);
 						SetTileSelectSize(2, 2);
 						LowerWindowWidget(w, PCW_WIDGET_BUILD_VIEW_HQ);
 						InvalidateWidget(w, PCW_WIDGET_BUILD_VIEW_HQ);
@@ -793,7 +793,7 @@
 				}
 
 				case PCW_WIDGET_RELOCATE_HQ:
-					SetObjectToPlaceWnd(SPR_CURSOR_HQ, 1, w);
+					SetObjectToPlaceWnd(SPR_CURSOR_HQ, PAL_NONE, 1, w);
 					SetTileSelectSize(2, 2);
 					LowerWindowWidget(w, PCW_WIDGET_RELOCATE_HQ);
 					InvalidateWidget(w, PCW_WIDGET_RELOCATE_HQ);
@@ -959,7 +959,7 @@
 	*x = max(0, (_screen.width  / 2) - (640 / 2));
 	*y = max(0, (_screen.height / 2) - (480 / 2));
 	for (i = 0; i < 10; i++) // the image is split into 10 50px high parts
-		DrawSprite(WP(w, highscore_d).background_img + i, *x, *y + (i * 50));
+		DrawSprite(WP(w, highscore_d).background_img + i, PAL_NONE, *x, *y + (i * 50));
 }
 
 extern StringID EndGameGetPerformanceTitleFromValue(uint value);
--- a/src/players.cpp
+++ b/src/players.cpp
@@ -80,44 +80,46 @@
 		flag |= 2;
 
 	/* draw the gradient */
-	DrawSprite(GENERAL_SPRITE_COLOR(color) + SPRITE_PALETTE(SPR_GRADIENT), x, y);
+	DrawSprite(SPR_GRADIENT, GENERAL_SPRITE_COLOR(color), x, y);
 
 	/* draw the cheeks */
-	DrawSprite(cheeks_table[flag&3], x, y);
+	DrawSprite(cheeks_table[flag&3], PAL_NONE, x, y);
 
 	/* draw the chin */
 	/* FIXME: real code uses -2 in zoomlevel 1 */
 	{
 		uint val = GB(face, 4, 2);
 		if (!(flag & 2)) {
-			DrawSprite(0x327 + (flag&1?0:val), x, y);
+			DrawSprite(0x327 + (flag&1?0:val), PAL_NONE, x, y);
 		} else {
-			DrawSprite((flag&1?0x3B1:0x391) + (val>>1), x, y);
+			DrawSprite((flag&1?0x3B1:0x391) + (val>>1), PAL_NONE, x, y);
 		}
 	}
 	/* draw the eyes */
 	{
 		uint val1 = GB(face,  6, 4);
 		uint val2 = GB(face, 20, 3);
-		uint32 high = 0x314 << PALETTE_SPRITE_START;
+		SpriteID pal;
 
-		if (val2 >= 6) {
-			high = 0x30F << PALETTE_SPRITE_START;
-			if (val2 != 6)
-				high = 0x30D << PALETTE_SPRITE_START;
+		if (val2 < 6) {
+			pal = PALETTE_TO_BROWN;
+		} else if (val2 == 6) {
+			pal = PALETTE_TO_BLUE;
+		} else {
+			pal = PALETTE_TO_GREEN;
 		}
 
 		if (!(flag & 2)) {
 			if (!(flag & 1)) {
-				DrawSprite(high+((val1 * 12 >> 4) + SPRITE_PALETTE(0x32B)), x, y);
+				DrawSprite(0x32B + (val1 * 12 >> 4), pal, x, y);
 			} else {
-				DrawSprite(high+(val1 + SPRITE_PALETTE(0x337)), x, y);
+				DrawSprite(0x337 + val1, pal, x, y);
 			}
 		} else {
 			if (!(flag & 1)) {
-				DrawSprite(high+((val1 * 11 >> 4) + SPRITE_PALETTE(0x39A)), x, y);
+				DrawSprite(0x39A + (val1 * 11 >> 4), pal, x, y);
 			} else {
-				DrawSprite(high+(val1 + SPRITE_PALETTE(0x3B8)), x, y);
+				DrawSprite(0x3B8 + val1, pal, x, y);
 			}
 		}
 	}
@@ -131,7 +133,7 @@
 			val2 = ((val&0xF) * 15 >> 4);
 
 			if (val2 < 3) {
-				DrawSprite((flag&2 ? 0x397 : 0x367) + val2, x, y);
+				DrawSprite((flag&2 ? 0x397 : 0x367) + val2, PAL_NONE, x, y);
 				/* skip the rest */
 				goto skip_mouth;
 			}
@@ -141,26 +143,26 @@
 				if (val2 > 8) val2 = 0;
 				val2 += 0x3A5 - 0x35B;
 			}
-			DrawSprite(val2 + 0x35B, x, y);
+			DrawSprite(val2 + 0x35B, PAL_NONE, x, y);
 		} else if (!(flag&2)) {
-			DrawSprite(((val&0xF) * 10 >> 4) + 0x351, x, y);
+			DrawSprite(((val&0xF) * 10 >> 4) + 0x351, PAL_NONE, x, y);
 		} else {
-			DrawSprite(((val&0xF) * 9 >> 4) + 0x3C8, x, y);
+			DrawSprite(((val&0xF) * 9 >> 4) + 0x3C8, PAL_NONE, x, y);
 		}
 
 		val >>= 3;
 
 		if (!(flag&2)) {
 			if (!(flag&1)) {
-				DrawSprite(0x349 + val, x, y);
+				DrawSprite(0x349 + val, PAL_NONE, x, y);
 			} else {
-				DrawSprite( mouth_table[(val*3>>3)], x, y);
+				DrawSprite( mouth_table[(val*3>>3)], PAL_NONE, x, y);
 			}
 		} else {
 			if (!(flag&1)) {
-				DrawSprite(0x393 + (val&3), x, y);
+				DrawSprite(0x393 + (val&3), PAL_NONE, x, y);
 			} else {
-				DrawSprite(0x3B3 + (val*5>>3), x, y);
+				DrawSprite(0x3B3 + (val*5>>3), PAL_NONE, x, y);
 			}
 		}
 
@@ -173,15 +175,15 @@
 		uint val = GB(face, 16, 4);
 		if (flag & 2) {
 			if (flag & 1) {
-				DrawSprite(0x3D9 + (val * 5 >> 4), x, y);
+				DrawSprite(0x3D9 + (val * 5 >> 4), PAL_NONE, x, y);
 			} else {
-				DrawSprite(0x3D4 + (val * 5 >> 4), x, y);
+				DrawSprite(0x3D4 + (val * 5 >> 4), PAL_NONE, x, y);
 			}
 		} else {
 			if (flag & 1) {
-				DrawSprite(0x38B + (val * 5 >> 4), x, y);
+				DrawSprite(0x38B + (val * 5 >> 4), PAL_NONE, x, y);
 			} else {
-				DrawSprite(0x382 + (val * 9 >> 4), x, y);
+				DrawSprite(0x382 + (val * 9 >> 4), PAL_NONE, x, y);
 			}
 		}
 	}
@@ -191,15 +193,15 @@
 		uint val = GB(face, 20, 8);
 
 		if (!(flag&1)) {
-			DrawSprite(0x36B + (GB(val, 0, 2) * 3 >> 2), x, y);
-			DrawSprite(0x36E + (GB(val, 2, 2) * 4 >> 2), x, y);
-			DrawSprite(0x372 + (GB(val, 4, 4) * 6 >> 4), x, y);
+			DrawSprite(0x36B + (GB(val, 0, 2) * 3 >> 2), PAL_NONE, x, y);
+			DrawSprite(0x36E + (GB(val, 2, 2) * 4 >> 2), PAL_NONE, x, y);
+			DrawSprite(0x372 + (GB(val, 4, 4) * 6 >> 4), PAL_NONE, x, y);
 		} else {
-			DrawSprite(0x378 + (GB(val, 0, 2) * 3 >> 2), x, y);
-			DrawSprite(0x37B + (GB(val, 2, 2) * 4 >> 2), x, y);
+			DrawSprite(0x378 + (GB(val, 0, 2) * 3 >> 2), PAL_NONE, x, y);
+			DrawSprite(0x37B + (GB(val, 2, 2) * 4 >> 2), PAL_NONE, x, y);
 
 			val >>= 4;
-			if (val < 3) DrawSprite((flag & 2 ? 0x3D1 : 0x37F) + val, x, y);
+			if (val < 3) DrawSprite((flag & 2 ? 0x3D1 : 0x37F) + val, PAL_NONE, x, y);
 		}
 	}
 
@@ -208,9 +210,9 @@
 		uint val = GB(face, 28, 3);
 
 		if (flag & 2) {
-			if (val <= 1) DrawSprite(0x3AE + val, x, y);
+			if (val <= 1) DrawSprite(0x3AE + val, PAL_NONE, x, y);
 		} else {
-			if (val <= 1) DrawSprite(0x347 + val, x, y);
+			if (val <= 1) DrawSprite(0x347 + val, PAL_NONE, x, y);
 		}
 	}
 }
--- a/src/rail_cmd.cpp
+++ b/src/rail_cmd.cpp
@@ -1053,7 +1053,7 @@
 		sprite = _signal_base + (GetSignalType(tile) - 1) * 16 + GetSignalVariant(tile) * 64 + image + condition;
 	}
 
-	AddSortableSpriteToDraw(sprite, x, y, 1, 1, 10, GetSlopeZ(x,y));
+	AddSortableSpriteToDraw(sprite, PAL_NONE, x, y, 1, 1, 10, GetSlopeZ(x,y));
 }
 
 static uint32 _drawtile_track_palette;
@@ -1061,17 +1061,17 @@
 
 static void DrawTrackFence_NW(const TileInfo *ti)
 {
-	uint32 image = 0x515;
+	SpriteID image = 0x515;
 	if (ti->tileh != SLOPE_FLAT) image = (ti->tileh & SLOPE_S) ? 0x519 : 0x51B;
-	AddSortableSpriteToDraw(image | _drawtile_track_palette,
+	AddSortableSpriteToDraw(image, _drawtile_track_palette,
 		ti->x, ti->y + 1, 16, 1, 4, ti->z);
 }
 
 static void DrawTrackFence_SE(const TileInfo *ti)
 {
-	uint32 image = 0x515;
+	SpriteID image = 0x515;
 	if (ti->tileh != SLOPE_FLAT) image = (ti->tileh & SLOPE_S) ? 0x519 : 0x51B;
-	AddSortableSpriteToDraw(image | _drawtile_track_palette,
+	AddSortableSpriteToDraw(image, _drawtile_track_palette,
 		ti->x, ti->y + TILE_SIZE - 1, 16, 1, 4, ti->z);
 }
 
@@ -1083,17 +1083,17 @@
 
 static void DrawTrackFence_NE(const TileInfo *ti)
 {
-	uint32 image = 0x516;
+	SpriteID image = 0x516;
 	if (ti->tileh != SLOPE_FLAT) image = (ti->tileh & SLOPE_S) ? 0x51A : 0x51C;
-	AddSortableSpriteToDraw(image | _drawtile_track_palette,
+	AddSortableSpriteToDraw(image, _drawtile_track_palette,
 		ti->x + 1, ti->y, 1, 16, 4, ti->z);
 }
 
 static void DrawTrackFence_SW(const TileInfo *ti)
 {
-	uint32 image = 0x516;
+	SpriteID image = 0x516;
 	if (ti->tileh != SLOPE_FLAT) image = (ti->tileh & SLOPE_S) ? 0x51A : 0x51C;
-	AddSortableSpriteToDraw(image | _drawtile_track_palette,
+	AddSortableSpriteToDraw(image, _drawtile_track_palette,
 		ti->x + TILE_SIZE - 1, ti->y, 1, 16, 4, ti->z);
 }
 
@@ -1107,7 +1107,7 @@
 {
 	int z = ti->z;
 	if (ti->tileh & SLOPE_W) z += TILE_HEIGHT;
-	AddSortableSpriteToDraw(0x517 | _drawtile_track_palette,
+	AddSortableSpriteToDraw(0x517, _drawtile_track_palette,
 		ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z);
 }
 
@@ -1115,7 +1115,7 @@
 {
 	int z = ti->z;
 	if (ti->tileh & SLOPE_E) z += TILE_HEIGHT;
-	AddSortableSpriteToDraw(0x517 | _drawtile_track_palette,
+	AddSortableSpriteToDraw(0x517, _drawtile_track_palette,
 		ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z);
 }
 
@@ -1123,7 +1123,7 @@
 {
 	int z = ti->z;
 	if (ti->tileh & SLOPE_N) z += TILE_HEIGHT;
-	AddSortableSpriteToDraw(0x518 | _drawtile_track_palette,
+	AddSortableSpriteToDraw(0x518, _drawtile_track_palette,
 		ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z);
 }
 
@@ -1131,7 +1131,7 @@
 {
 	int z = ti->z;
 	if (ti->tileh & SLOPE_S) z += TILE_HEIGHT;
-	AddSortableSpriteToDraw(0x518 | _drawtile_track_palette,
+	AddSortableSpriteToDraw(0x518, _drawtile_track_palette,
 		ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z);
 }
 
@@ -1165,7 +1165,8 @@
 static void DrawTrackBits(TileInfo* ti, TrackBits track)
 {
 	const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
-	PalSpriteID image;
+	SpriteID image;
+	SpriteID pal = PAL_NONE;
 	bool junction = false;
 
 	// Select the sprite to use.
@@ -1199,21 +1200,21 @@
 	}
 
 	switch (GetRailGroundType(ti->tile)) {
-		case RAIL_GROUND_BARREN:     image |= PALETTE_TO_BARE_LAND; break;
+		case RAIL_GROUND_BARREN:     pal = PALETTE_TO_BARE_LAND; break;
 		case RAIL_GROUND_ICE_DESERT: image += rti->snow_offset; break;
 		default: break;
 	}
 
-	DrawGroundSprite(image);
+	DrawGroundSprite(image, pal);
 
 	// Draw track pieces individually for junction tiles
 	if (junction) {
-		if (track & TRACK_BIT_X)     DrawGroundSprite(rti->base_sprites.single_y);
-		if (track & TRACK_BIT_Y)     DrawGroundSprite(rti->base_sprites.single_x);
-		if (track & TRACK_BIT_UPPER) DrawGroundSprite(rti->base_sprites.single_n);
-		if (track & TRACK_BIT_LOWER) DrawGroundSprite(rti->base_sprites.single_s);
-		if (track & TRACK_BIT_LEFT)  DrawGroundSprite(rti->base_sprites.single_w);
-		if (track & TRACK_BIT_RIGHT) DrawGroundSprite(rti->base_sprites.single_e);
+		if (track & TRACK_BIT_X)     DrawGroundSprite(rti->base_sprites.single_y, PAL_NONE);
+		if (track & TRACK_BIT_Y)     DrawGroundSprite(rti->base_sprites.single_x, PAL_NONE);
+		if (track & TRACK_BIT_UPPER) DrawGroundSprite(rti->base_sprites.single_n, PAL_NONE);
+		if (track & TRACK_BIT_LOWER) DrawGroundSprite(rti->base_sprites.single_s, PAL_NONE);
+		if (track & TRACK_BIT_LEFT)  DrawGroundSprite(rti->base_sprites.single_w, PAL_NONE);
+		if (track & TRACK_BIT_RIGHT) DrawGroundSprite(rti->base_sprites.single_e, PAL_NONE);
 	}
 
 	if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
@@ -1255,9 +1256,9 @@
 static void DrawTile_Track(TileInfo *ti)
 {
 	const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
-	PalSpriteID image;
+	SpriteID image;
 
-	_drawtile_track_palette = SPRITE_PALETTE(PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile)));
+	_drawtile_track_palette = PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile));
 
 	if (IsPlainRailTile(ti->tile)) {
 		TrackBits rails = GetTrackBits(ti->tile);
@@ -1337,20 +1338,25 @@
 			}
 		}
 
-		DrawGroundSprite(image);
+		DrawGroundSprite(image, PAL_NONE);
 
 		if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
 
 		foreach_draw_tile_seq(dtss, dts->seq) {
-			uint32 image = dtss->image + relocation;
+			SpriteID image = dtss->image + relocation;
+			SpriteID pal;
 
 			if (_display_opt & DO_TRANS_BUILDINGS) {
-				MAKE_TRANSPARENT(image);
-			} else if (image & PALETTE_MODIFIER_COLOR) {
-				image |= _drawtile_track_palette;
+				SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
+				pal = PALETTE_TO_TRANSPARENT;
+			} else if (HASBIT(image, PALETTE_MODIFIER_COLOR)) {
+				pal = _drawtile_track_palette;
+			} else {
+				pal = dtss->pal;
 			}
+
 			AddSortableSpriteToDraw(
-				image,
+				image, pal,
 				ti->x + dtss->delta_x, ti->y + dtss->delta_y,
 				dtss->size_x, dtss->size_y,
 				dtss->size_z, ti->z + dtss->delta_z
@@ -1361,24 +1367,23 @@
 }
 
 
-static void DrawTileSequence(int x, int y, uint32 ground, const DrawTileSeqStruct* dtss, uint32 offset)
+static void DrawTileSequence(int x, int y, SpriteID ground, const DrawTileSeqStruct* dtss, uint32 offset)
 {
-	uint32 palette = PLAYER_SPRITE_COLOR(_local_player);
+	SpriteID palette = PLAYER_SPRITE_COLOR(_local_player);
 
-	DrawSprite(ground, x, y);
+	DrawSprite(ground, PAL_NONE, x, y);
 	for (; dtss->image != 0; dtss++) {
 		Point pt = RemapCoords(dtss->delta_x, dtss->delta_y, dtss->delta_z);
-		uint32 image = dtss->image + offset;
+		SpriteID image = dtss->image + offset;
 
-		if (image & PALETTE_MODIFIER_COLOR) image |= palette;
-		DrawSprite(image, x + pt.x, y + pt.y);
+		DrawSprite(image, HASBIT(image, PALETTE_MODIFIER_COLOR) ? palette : PAL_NONE, x + pt.x, y + pt.y);
 	}
 }
 
 void DrawTrainDepotSprite(int x, int y, int dir, RailType railtype)
 {
 	const DrawTileSprites* dts = &_depot_gfx_table[dir];
-	uint32 image = dts->ground_sprite;
+	SpriteID image = dts->ground_sprite;
 	uint32 offset = GetRailTypeInfo(railtype)->total_offset;
 
 	if (image != SPR_FLAT_GRASS_TILE) image += offset;
--- a/src/rail_gui.cpp
+++ b/src/rail_gui.cpp
@@ -765,7 +765,7 @@
 
 				if (statspec != NULL && statspec->name != 0) {
 					if (HASBIT(statspec->callbackmask, CBM_STATION_AVAIL) && GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE) == 0) {
-						GfxFillRect(8, y - 2, 127, y + 10, PALETTE_MODIFIER_GREYOUT);
+						GfxFillRect(8, y - 2, 127, y + 10, (1 << PALETTE_MODIFIER_GREYOUT));
 					}
 
 					DrawStringTruncated(9, y, statspec->name, i == _railstation.station_type ? 12 : 16, 118);
@@ -1087,7 +1087,7 @@
 				if (statspec != NULL &&
 						HASBIT(statspec->callbackmask, CBM_STATION_AVAIL) &&
 						GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE) == 0) {
-					GfxFillRect(4 + i * 68, 18, 67 + i * 68, 75, PALETTE_MODIFIER_GREYOUT);
+					GfxFillRect(4 + i * 68, 18, 67 + i * 68, 75, (1 << PALETTE_MODIFIER_GREYOUT));
 				}
 			}
 		}
--- a/src/road_cmd.cpp
+++ b/src/road_cmd.cpp
@@ -656,7 +656,8 @@
 {
 	RoadBits road = GetRoadBits(ti->tile);
 	const DrawRoadTileStruct *drts;
-	PalSpriteID image = 0;
+	SpriteID image = 0;
+	SpriteID pal = PAL_NONE;
 	Roadside roadside;
 
 	if (ti->tileh != SLOPE_FLAT) {
@@ -677,18 +678,18 @@
 		image += 19;
 	} else {
 		switch (roadside) {
-			case ROADSIDE_BARREN:           image |= PALETTE_TO_BARE_LAND; break;
+			case ROADSIDE_BARREN:           pal = PALETTE_TO_BARE_LAND; break;
 			case ROADSIDE_GRASS:            break;
 			case ROADSIDE_GRASS_ROAD_WORKS: break;
 			default:                        image -= 19; break; // Paved
 		}
 	}
 
-	DrawGroundSprite(image);
+	DrawGroundSprite(image, pal);
 
 	if (HasRoadWorks(ti->tile)) {
 		// Road works
-		DrawGroundSprite(road & ROAD_X ? SPR_EXCAVATION_X : SPR_EXCAVATION_Y);
+		DrawGroundSprite(road & ROAD_X ? SPR_EXCAVATION_X : SPR_EXCAVATION_Y, PAL_NONE);
 		return;
 	}
 
@@ -701,7 +702,7 @@
 		int y = ti->y | drts->subcoord_y;
 		byte z = ti->z;
 		if (ti->tileh != SLOPE_FLAT) z = GetSlopeZ(x, y);
-		AddSortableSpriteToDraw(drts->image, x, y, 2, 2, 0x10, z);
+		AddSortableSpriteToDraw(drts->image, PAL_NONE, x, y, 2, 2, 0x10, z);
 	}
 }
 
@@ -713,7 +714,8 @@
 			break;
 
 		case ROAD_TILE_CROSSING: {
-			PalSpriteID image;
+			SpriteID image;
+			SpriteID pal = PAL_NONE;
 
 			if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
 
@@ -726,13 +728,13 @@
 				image += 8;
 			} else {
 				switch (GetRoadside(ti->tile)) {
-					case ROADSIDE_BARREN: image |= PALETTE_TO_BARE_LAND; break;
+					case ROADSIDE_BARREN: pal = PALETTE_TO_BARE_LAND; break;
 					case ROADSIDE_GRASS:  break;
 					default:              image += 4; break; // Paved
 				}
 			}
 
-			DrawGroundSprite(image);
+			DrawGroundSprite(image, pal);
 			if (GetRailTypeCrossing(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
 			break;
 		}
@@ -741,26 +743,30 @@
 		case ROAD_TILE_DEPOT: {
 			const DrawTileSprites* dts;
 			const DrawTileSeqStruct* dtss;
-			uint32 palette;
+			SpriteID palette;
 
 			if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
 
 			palette = PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile));
 
 			dts =  &_road_depot[GetRoadDepotDirection(ti->tile)];
-			DrawGroundSprite(dts->ground_sprite);
+			DrawGroundSprite(dts->ground_sprite, PAL_NONE);
 
 			for (dtss = dts->seq; dtss->image != 0; dtss++) {
-				uint32 image = dtss->image;
+				SpriteID image = dtss->image;
+				SpriteID pal;
 
 				if (_display_opt & DO_TRANS_BUILDINGS) {
-					MAKE_TRANSPARENT(image);
-				} else if (image & PALETTE_MODIFIER_COLOR) {
-					image |= palette;
+					SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
+					pal = PALETTE_TO_TRANSPARENT;
+				} else if (HASBIT(image, PALETTE_MODIFIER_COLOR)) {
+					pal = palette;
+				} else {
+					pal = PAL_NONE;
 				}
 
 				AddSortableSpriteToDraw(
-					image,
+					image, pal,
 					ti->x + dtss->delta_x, ti->y + dtss->delta_y,
 					dtss->size_x, dtss->size_y,
 					dtss->size_z, ti->z
@@ -774,22 +780,20 @@
 
 void DrawRoadDepotSprite(int x, int y, DiagDirection dir)
 {
-	uint32 palette = PLAYER_SPRITE_COLOR(_local_player);
+	SpriteID palette = PLAYER_SPRITE_COLOR(_local_player);
 	const DrawTileSprites* dts =  &_road_depot[dir];
 	const DrawTileSeqStruct* dtss;
 
 	x += 33;
 	y += 17;
 
-	DrawSprite(dts->ground_sprite, x, y);
+	DrawSprite(dts->ground_sprite, PAL_NONE, x, y);
 
 	for (dtss = dts->seq; dtss->image != 0; dtss++) {
 		Point pt = RemapCoords(dtss->delta_x, dtss->delta_y, dtss->delta_z);
-		uint32 image = dtss->image;
+		SpriteID image = dtss->image;
 
-		if (image & PALETTE_MODIFIER_COLOR) image |= palette;
-
-		DrawSprite(image, x + pt.x, y + pt.y);
+		DrawSprite(image, HASBIT(image, PALETTE_MODIFIER_COLOR) ? palette : PAL_NONE, x + pt.x, y + pt.y);
 	}
 }
 
--- a/src/roadveh_cmd.cpp
+++ b/src/roadveh_cmd.cpp
@@ -82,7 +82,7 @@
 	return image;
 }
 
-void DrawRoadVehEngine(int x, int y, EngineID engine, uint32 image_ormod)
+void DrawRoadVehEngine(int x, int y, EngineID engine, SpriteID pal)
 {
 	int spritenum = RoadVehInfo(engine)->image_index;
 
@@ -90,12 +90,12 @@
 		int sprite = GetCustomVehicleIcon(engine, DIR_W);
 
 		if (sprite != 0) {
-			DrawSprite(sprite | image_ormod, x, y);
+			DrawSprite(sprite, pal, x, y);
 			return;
 		}
 		spritenum = orig_road_vehicle_info[engine - ROAD_ENGINES_INDEX].image_index;
 	}
-	DrawSprite((6 + _roadveh_images[spritenum]) | image_ormod, x, y);
+	DrawSprite(6 + _roadveh_images[spritenum], pal, x, y);
 }
 
 static int32 EstimateRoadVehCost(EngineID engine_type)
--- a/src/roadveh_gui.cpp
+++ b/src/roadveh_gui.cpp
@@ -71,8 +71,8 @@
 
 void DrawRoadVehImage(const Vehicle *v, int x, int y, VehicleID selection)
 {
-	PalSpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
-	DrawSprite(GetRoadVehImage(v, DIR_W) | pal, x + 14, y + 6);
+	SpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
+	DrawSprite(GetRoadVehImage(v, DIR_W), pal, x + 14, y + 6);
 
 	if (v->index == selection) {
 		DrawFrameRect(x - 1, y - 1, x + 28, y + 12, 15, FR_BORDERONLY);
@@ -291,7 +291,7 @@
 		}
 
 		/* draw the flag plus orders */
-		DrawSprite(v->vehstatus & VS_STOPPED ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, 2, w->widget[5].top + 1);
+		DrawSprite(v->vehstatus & VS_STOPPED ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, 2, w->widget[5].top + 1);
 		DrawStringCenteredTruncated(w->widget[5].left + 8, w->widget[5].right, w->widget[5].top + 1, str, 0);
 		DrawWindowViewport(w);
 	} break;
@@ -544,3 +544,4 @@
 }
 
 
+
--- a/src/saveload.cpp
+++ b/src/saveload.cpp
@@ -1399,7 +1399,7 @@
 {
 	_ts.ff_state = (_fast_forward != 0);
 	_fast_forward = false;
-	if (_cursor.sprite == SPR_CURSOR_MOUSE) SetMouseCursor(SPR_CURSOR_ZZZ);
+	if (_cursor.sprite == SPR_CURSOR_MOUSE) SetMouseCursor(SPR_CURSOR_ZZZ, PAL_NONE);
 
 	SendWindowMessage(WC_STATUS_BAR, 0, true, 0, 0);
 	_ts.saveinprogress = true;
@@ -1410,7 +1410,7 @@
 void SaveFileDone(void)
 {
 	_fast_forward = _ts.ff_state;
-	if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE);
+	if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE, PAL_NONE);
 
 	SendWindowMessage(WC_STATUS_BAR, 0, false, 0, 0);
 	_ts.saveinprogress = false;
--- a/src/settings_gui.cpp
+++ b/src/settings_gui.cpp
@@ -413,7 +413,7 @@
 			DrawFrameRect( 5, y,  5 + 8, y + 8, 3, GetBitAndShift(&click_a) ? FR_LOWERED : FR_NONE);
 			DrawFrameRect(15, y, 15 + 8, y + 8, 3, GetBitAndShift(&click_b) ? FR_LOWERED : FR_NONE);
 			if (GetBitAndShift(&disabled) || (_networking && !_network_server)) {
-				int color = PALETTE_MODIFIER_GREYOUT | _colour_gradient[COLOUR_YELLOW][2];
+				int color = (1 << PALETTE_MODIFIER_GREYOUT) | _colour_gradient[COLOUR_YELLOW][2];
 				GfxFillRect( 6, y + 1,  6 + 8, y + 8, color);
 				GfxFillRect(16, y + 1, 16 + 8, y + 8, color);
 			}
@@ -930,7 +930,7 @@
  */
 void DrawArrowButtons(int x, int y, int ctab, byte state, bool clickable_left, bool clickable_right)
 {
-	int color = PALETTE_MODIFIER_GREYOUT | _colour_gradient[COLOUR_YELLOW][2];
+	int color = (1 << PALETTE_MODIFIER_GREYOUT) | _colour_gradient[COLOUR_YELLOW][2];
 
 	DrawFrameRect(x,      y + 1, x +  9, y + 9, ctab, (state == 1) ? FR_LOWERED : FR_NONE);
 	DrawFrameRect(x + 10, y + 1, x + 19, y + 9, ctab, (state == 2) ? FR_LOWERED : FR_NONE);
--- a/src/ship_cmd.cpp
+++ b/src/ship_cmd.cpp
@@ -43,7 +43,7 @@
 	return TrackdirBitsToTrackBits((TrackdirBits)(TRACKDIR_BIT_MASK & (r | r >> 8)));
 }
 
-void DrawShipEngine(int x, int y, EngineID engine, uint32 image_ormod)
+void DrawShipEngine(int x, int y, EngineID engine, SpriteID pal)
 {
 	int spritenum = ShipVehInfo(engine)->image_index;
 
@@ -51,12 +51,12 @@
 		int sprite = GetCustomVehicleIcon(engine, DIR_W);
 
 		if (sprite != 0) {
-			DrawSprite(sprite | image_ormod, x, y);
+			DrawSprite(sprite, pal, x, y);
 			return;
 		}
 		spritenum = orig_ship_vehicle_info[engine - SHIP_ENGINES_INDEX].image_index;
 	}
-	DrawSprite((6 + _ship_sprites[spritenum]) | image_ormod, x, y);
+	DrawSprite(6 + _ship_sprites[spritenum], pal, x, y);
 }
 
 int GetShipImage(const Vehicle* v, Direction direction)
--- a/src/ship_gui.cpp
+++ b/src/ship_gui.cpp
@@ -71,7 +71,7 @@
 
 void DrawShipImage(const Vehicle *v, int x, int y, VehicleID selection)
 {
-	DrawSprite(GetShipImage(v, DIR_W) | GetVehiclePalette(v), x + 32, y + 10);
+	DrawSprite(GetShipImage(v, DIR_W), GetVehiclePalette(v), x + 32, y + 10);
 
 	if (v->index == selection) {
 		DrawFrameRect(x - 5, y - 1, x + 67, y + 21, 15, FR_BORDERONLY);
@@ -427,7 +427,7 @@
 			}
 
 		/* draw the flag plus orders */
-		DrawSprite(v->vehstatus & VS_STOPPED ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, 2, w->widget[5].top + 1);
+		DrawSprite(v->vehstatus & VS_STOPPED ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, 2, w->widget[5].top + 1);
 		DrawStringCenteredTruncated(w->widget[5].left + 8, w->widget[5].right, w->widget[5].top + 1, str, 0);
 		DrawWindowViewport(w);
 	} break;
--- a/src/sprite.h
+++ b/src/sprite.h
@@ -15,11 +15,13 @@
 	byte size_x;
 	byte size_y;
 	byte size_z;
-	uint32 image;
+	SpriteID image;
+	SpriteID pal;
 } DrawTileSeqStruct;
 
 typedef struct DrawTileSprites {
 	SpriteID ground_sprite;
+	SpriteID ground_pal;
 	const DrawTileSeqStruct* seq;
 } DrawTileSprites;
 
@@ -28,8 +30,8 @@
  * Buildings here reference a general type of construction
  */
 typedef struct DrawBuildingsTileStruct {
-	SpriteID ground;
-	SpriteID building;
+	PalSpriteID ground;
+	PalSpriteID building;
 	byte subtile_x:4;
 	byte subtile_y:4;
 	byte width:4;
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -2036,7 +2036,6 @@
 
 static void DrawTile_Station(TileInfo *ti)
 {
-	uint32 image;
 	const DrawTileSeqStruct *dtss;
 	const DrawTileSprites *t = NULL;
 	RailType railtype = GetRailType(ti->tile);
@@ -2045,7 +2044,8 @@
 	const Station *st = NULL;
 	const StationSpec *statspec = NULL;
 	PlayerID owner = GetTileOwner(ti->tile);
-	uint32 palette;
+	SpriteID image;
+	SpriteID palette;
 
 	if (IsValidPlayer(owner)) {
 		palette = PLAYER_SPRITE_COLOR(owner);
@@ -2085,67 +2085,68 @@
 	if (t == NULL || t->seq == NULL) t = &_station_display_datas[GetStationGfx(ti->tile)];
 
 	image = t->ground_sprite;
-	if (HASBIT(image, 31)) {
-		CLRBIT(image, 31);
+	if (HASBIT(image, SPRITE_MODIFIER_USE_OFFSET)) {
 		image += GetCustomStationGroundRelocation(statspec, st, ti->tile);
 		image += rti->custom_ground_offset;
 	} else {
 		image += rti->total_offset;
 	}
-	if (image & PALETTE_MODIFIER_COLOR) image |= palette;
 
 	// station_land array has been increased from 82 elements to 114
 	// but this is something else. If AI builds station with 114 it looks all weird
-	DrawGroundSprite(image);
+	DrawGroundSprite(image, HASBIT(image, PALETTE_MODIFIER_COLOR) ? palette : PAL_NONE);
 
 	if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC && IsStationTileElectrifiable(ti->tile)) DrawCatenary(ti);
 
 	foreach_draw_tile_seq(dtss, t->seq) {
+		SpriteID pal;
+
 		image = dtss->image;
-		if (HASBIT(image, 30)) {
-			CLRBIT(image, 30);
+		if (HASBIT(image, SPRITE_MODIFIER_USE_OFFSET)) {
 			image += rti->total_offset;
 		} else {
 			image += relocation;
 		}
 
 		if (_display_opt & DO_TRANS_BUILDINGS) {
-			MAKE_TRANSPARENT(image);
-		} else if (image & PALETTE_MODIFIER_COLOR) {
-			image |= palette;
+			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
+			pal = PALETTE_TO_TRANSPARENT;
+		} else if (HASBIT(image, PALETTE_MODIFIER_COLOR)) {
+			pal = palette;
+		} else {
+			pal = dtss->pal;
 		}
 
 		if ((byte)dtss->delta_z != 0x80) {
 			AddSortableSpriteToDraw(
-				image,
+				image, pal,
 				ti->x + dtss->delta_x, ti->y + dtss->delta_y,
 				dtss->size_x, dtss->size_y,
 				dtss->size_z, ti->z + dtss->delta_z
 			);
 		} else {
-			AddChildSpriteScreen(image, dtss->delta_x, dtss->delta_y);
+			AddChildSpriteScreen(image, pal, dtss->delta_x, dtss->delta_y);
 		}
 	}
 }
 
 void StationPickerDrawSprite(int x, int y, RailType railtype, int image)
 {
-	uint32 ormod, img;
+	SpriteID pal, img;
 	const DrawTileSeqStruct *dtss;
 	const DrawTileSprites *t;
 	const RailtypeInfo *rti = GetRailTypeInfo(railtype);
 
-	ormod = PLAYER_SPRITE_COLOR(_local_player);
+	pal = PLAYER_SPRITE_COLOR(_local_player);
 
 	t = &_station_display_datas[image];
 
 	img = t->ground_sprite;
-	if (img & PALETTE_MODIFIER_COLOR) img |= ormod;
-	DrawSprite(img + rti->total_offset, x, y);
+	DrawSprite(img + rti->total_offset, HASBIT(img, PALETTE_MODIFIER_COLOR) ? pal : PAL_NONE, x, y);
 
 	foreach_draw_tile_seq(dtss, t->seq) {
 		Point pt = RemapCoords(dtss->delta_x, dtss->delta_y, dtss->delta_z);
-		DrawSprite((dtss->image | ormod) + rti->total_offset, x + pt.x, y + pt.y);
+		DrawSprite(dtss->image + rti->total_offset, pal, x + pt.x, y + pt.y);
 	}
 }
 
--- a/src/station_gui.cpp
+++ b/src/station_gui.cpp
@@ -18,6 +18,7 @@
 #include "vehicle_gui.h"
 #include "date.h"
 #include "vehicle.h"
+#include "table/sprites.h"
 #include "helpers.hpp"
 
 enum StationListWidgets {
@@ -655,7 +656,7 @@
 			int cur_x = x;
 			num = min(num, 23);
 			do {
-				DrawSprite(_cargoc.sprites[i], cur_x, y);
+				DrawSprite(_cargoc.sprites[i], PAL_NONE, cur_x, y);
 				cur_x += 10;
 			} while (--num);
 		}
--- a/src/table/sprites.h
+++ b/src/table/sprites.h
@@ -1282,10 +1282,11 @@
  */
 enum SpriteSetup {
 	TRANSPARENT_BIT = 31,       ///< toggles transparency in the sprite
-	RECOLOR_BIT = 15,           ///< toggles recoloring in the sprite
-	PALETTE_SPRITE_START = 16,  ///< number of the first bit of the sprite containing the recolor palette
-	PALETTE_SPRITE_WIDTH = 14,  ///< number of bits of the sprite containing the recolor palette
-	SPRITE_WIDTH = 14,          ///< number of bits for the sprite number
+	RECOLOR_BIT = 30,           ///< toggles recoloring in the sprite
+	OFFSET_BIT = 29,
+
+	PALETTE_WIDTH = 24,         ///< number of bits of the sprite containing the recolor palette
+	SPRITE_WIDTH = 24,          ///< number of bits for the sprite number
 };
 
 /**
@@ -1297,16 +1298,17 @@
  * @see SpriteSetup
  */
 enum Modifiers {
+	SPRITE_MODIFIER_USE_OFFSET    = OFFSET_BIT,
 	///when a sprite is to be displayed transparently, this bit needs to be set.
-	PALETTE_MODIFIER_TRANSPARENT  = 1 << TRANSPARENT_BIT,
+	PALETTE_MODIFIER_TRANSPARENT  = TRANSPARENT_BIT,
 	///this bit is set when a recoloring process is in action
-	PALETTE_MODIFIER_COLOR        = 1 << RECOLOR_BIT,
+	PALETTE_MODIFIER_COLOR        = RECOLOR_BIT,
 
 	//This is used for the GfxFillRect function
 	///Used to draw a "grey out" rectangle. @see GfxFillRect
-	PALETTE_MODIFIER_GREYOUT        = 1 << TRANSPARENT_BIT,
+	PALETTE_MODIFIER_GREYOUT        = TRANSPARENT_BIT,
 	///Set when a colortable mode is used. @see GfxFillRect
-	USE_COLORTABLE                  = 1 << RECOLOR_BIT,
+	USE_COLORTABLE                  = RECOLOR_BIT,
 };
 
 /** Masks needed for sprite operations.
@@ -1317,85 +1319,80 @@
 	MAX_SPRITES = 1 << SPRITE_WIDTH,
 	///The mask to for the main sprite
 	SPRITE_MASK = MAX_SPRITES - 1,
+
+	MAX_PALETTES = 1 << PALETTE_WIDTH,
 	///The mask for the auxiliary sprite (the one that takes care of recoloring)
-	PALETTE_SPRITE_MASK = ((1 << PALETTE_SPRITE_WIDTH) - 1) << PALETTE_SPRITE_START,
-	///Mask for the auxiliary sprites if it is locate in the LSBs
-	COLORTABLE_MASK = (1 << PALETTE_SPRITE_WIDTH) - 1
+	PALETTE_MASK = MAX_PALETTES - 1,
 };
 
 assert_compile( (1 << TRANSPARENT_BIT & SPRITE_MASK) == 0 );
 assert_compile( (1 << RECOLOR_BIT & SPRITE_MASK) == 0 );
 assert_compile( TRANSPARENT_BIT != RECOLOR_BIT );
-assert_compile( (1 << TRANSPARENT_BIT & PALETTE_SPRITE_MASK) == 0);
-assert_compile( (1 << RECOLOR_BIT & PALETTE_SPRITE_MASK) == 0 );
-assert_compile( (PALETTE_SPRITE_MASK & SPRITE_MASK) == 0 );
-assert_compile( SPRITE_WIDTH + PALETTE_SPRITE_WIDTH <= 30 );
+assert_compile( (1 << TRANSPARENT_BIT & PALETTE_MASK) == 0);
+assert_compile( (1 << RECOLOR_BIT & PALETTE_MASK) == 0 );
 
 enum Recoloring {
 	PALETTE_RECOLOR_START       = 0x307,
 };
 
-#define PALETTE_RECOLOR_SPRITE(a) (a << PALETTE_SPRITE_START | PALETTE_MODIFIER_COLOR)
 
-static const PalSpriteID PALETTE_CRASH = PALETTE_RECOLOR_SPRITE(0x324);
+static const SpriteID PALETTE_CRASH = 0x324;
+static const SpriteID PAL_NONE = 0;
 
-enum PaletteSprites {
 	//note: these numbers are already the modified once the renderer needs.
 	//the actual sprite number is the upper 16 bits of the number
 
 	///Here a puslating red tile is drawn if you try to build a wrong tunnel or raise/lower land where it is not possible
-	PALETTE_TILE_RED_PULSATING  = PALETTE_RECOLOR_SPRITE(0x303),
+static const SpriteID PALETTE_TILE_RED_PULSATING  = 0x303;
 	///makes a square red. is used when removing rails or other stuff
-	PALETTE_SEL_TILE_RED        = PALETTE_RECOLOR_SPRITE(0x304),
+static const SpriteID PALETTE_SEL_TILE_RED        = 0x304;
 	///This draws a blueish square (catchment areas for example)
-	PALETTE_SEL_TILE_BLUE       = PALETTE_RECOLOR_SPRITE(0x305),
+static const SpriteID PALETTE_SEL_TILE_BLUE       = 0x305;
 	//0x306 is a real sprite (the little dot you get when you try to raise/lower a corner of the map
 	//here the color switches begin
 	//use this if you add stuff to the value, so that the resulting color
 	//is not a fixed value.
 	//NOTE THAT THE SWITCH 0x8000 is NOT present in _TO_COLORS yet!
-	PALETTE_TO_COLORS           = PALETTE_RECOLOR_START << PALETTE_SPRITE_START,
-	PALETTE_TO_DARK_BLUE        = PALETTE_RECOLOR_SPRITE(PALETTE_RECOLOR_START),
-	PALETTE_TO_PALE_GREEN       = PALETTE_RECOLOR_SPRITE(0x308),
-	PALETTE_TO_PINK             = PALETTE_RECOLOR_SPRITE(0x309),
-	PALETTE_TO_YELLOW           = PALETTE_RECOLOR_SPRITE(0x30A),
-	PALETTE_TO_RED              = PALETTE_RECOLOR_SPRITE(0x30B),
-	PALETTE_TO_LIGHT_BLUE       = PALETTE_RECOLOR_SPRITE(0x30C),
-	PALETTE_TO_GREEN            = PALETTE_RECOLOR_SPRITE(0x30D),
-	PALETTE_TO_DARK_GREEN       = PALETTE_RECOLOR_SPRITE(0x30E),
-	PALETTE_TO_BLUE             = PALETTE_RECOLOR_SPRITE(0x30F),
-	PALETTE_TO_CREAM            = PALETTE_RECOLOR_SPRITE(0x310),
+enum PaletteSprites {
+	PALETTE_TO_DARK_BLUE        = 0x307,
+	PALETTE_TO_PALE_GREEN       = 0x308,
+	PALETTE_TO_PINK             = 0x309,
+	PALETTE_TO_YELLOW           = 0x30A,
+	PALETTE_TO_RED              = 0x30B,
+	PALETTE_TO_LIGHT_BLUE       = 0x30C,
+	PALETTE_TO_GREEN            = 0x30D,
+	PALETTE_TO_DARK_GREEN       = 0x30E,
+	PALETTE_TO_BLUE             = 0x30F,
+	PALETTE_TO_CREAM            = 0x310,
 	//maybe don't use as player color because it doesn't display in the graphs?
-	PALETTE_TO_MAUVE            = PALETTE_RECOLOR_SPRITE(0x311),
-	PALETTE_TO_PURPLE           = PALETTE_RECOLOR_SPRITE(0x312),
-	PALETTE_TO_ORANGE           = PALETTE_RECOLOR_SPRITE(0x313),
-	PALETTE_TO_BROWN            = PALETTE_RECOLOR_SPRITE(0x314),
-	PALETTE_TO_GREY             = PALETTE_RECOLOR_SPRITE(0x315),
-	PALETTE_TO_WHITE            = PALETTE_RECOLOR_SPRITE(0x316),
+	PALETTE_TO_MAUVE            = 0x311,
+	PALETTE_TO_PURPLE           = 0x312,
+	PALETTE_TO_ORANGE           = 0x313,
+	PALETTE_TO_BROWN            = 0x314,
+	PALETTE_TO_GREY             = 0x315,
+	PALETTE_TO_WHITE            = 0x316,
 	//sets color to bare land stuff, for rail and road (and crossings)
-	PALETTE_TO_BARE_LAND        = PALETTE_RECOLOR_SPRITE(0x317),
+	PALETTE_TO_BARE_LAND        = 0x317,
 	//XXX is 318-31A really not used?
-	PALETTE_TO_STRUCT_BLUE      = PALETTE_RECOLOR_SPRITE(0x31B),
+	PALETTE_TO_STRUCT_BLUE      = 0x31B,
 	//structure color to something brownish (for the cantilever bridges for example)
-	PALETTE_TO_STRUCT_BROWN     = PALETTE_RECOLOR_SPRITE(0x31C),
-	PALETTE_TO_STRUCT_WHITE     = PALETTE_RECOLOR_SPRITE(0x31D),
+	PALETTE_TO_STRUCT_BROWN     = 0x31C,
+	PALETTE_TO_STRUCT_WHITE     = 0x31D,
 	//sets bridge or structure to red, little concrete one and cantilever use this one for example
-	PALETTE_TO_STRUCT_RED       = PALETTE_RECOLOR_SPRITE(0x31E),
-	PALETTE_TO_STRUCT_GREEN     = PALETTE_RECOLOR_SPRITE(0x31F),
-	PALETTE_TO_STRUCT_CONCRETE  = PALETTE_RECOLOR_SPRITE(0x320),  //Sets the suspension bridge to concrete, also other strucutures use it
-	PALETTE_TO_STRUCT_YELLOW    = PALETTE_RECOLOR_SPRITE(0x321),    //Sets the bridge color to yellow (suspension and tubular)
-	PALETTE_TO_TRANSPARENT      = 0x322 << PALETTE_SPRITE_START | PALETTE_MODIFIER_TRANSPARENT, //This sets the sprite to transparent
+	PALETTE_TO_STRUCT_RED       = 0x31E,
+	PALETTE_TO_STRUCT_GREEN     = 0x31F,
+	PALETTE_TO_STRUCT_CONCRETE  = 0x320, //Sets the suspension bridge to concrete, also other strucutures use it
+	PALETTE_TO_STRUCT_YELLOW    = 0x321, //Sets the bridge color to yellow (suspension and tubular)
+	PALETTE_TO_TRANSPARENT      = 0x322, //This sets the sprite to transparent
 	//This is used for changing the tubular bridges to the silicon display, or some grayish color
-	PALETTE_TO_STRUCT_GREY      = PALETTE_RECOLOR_SPRITE(0x323),
+	PALETTE_TO_STRUCT_GREY      = 0x323,
 
-	//XXX - const - PALETTE_CRASH               = PALETTE_RECOLOR_SPRITE(0x324),  //this changes stuff to the "crash color"
+	//XXX - const - PALETTE_CRASH               = 0x324,  //this changes stuff to the "crash color"
 	//XXX another place where structures are colored.
 	//I'm not sure which colors these are
-	PALETTE_59E                 = PALETTE_RECOLOR_SPRITE(0x59E),
-	PALETTE_59F                 = PALETTE_RECOLOR_SPRITE(0x59F),
+	PALETTE_59E                 = 0x59E,
+	PALETTE_59F                 = 0x59F,
 };
 #undef PALETTE_RECOLOR_SPRITE
 
-#define MAKE_TRANSPARENT(img) (img = (img & SPRITE_MASK) | PALETTE_TO_TRANSPARENT)
-
 #endif /* SPRITES_H */
--- a/src/texteff.cpp
+++ b/src/texteff.cpp
@@ -210,7 +210,7 @@
 			_screen.height - _textmsg_box.y - count * 13 - 2,
 			_textmsg_box.x + _textmsg_box.width - 1,
 			_screen.height - _textmsg_box.y - 2,
-			0x322 | USE_COLORTABLE // black, but with some alpha for background
+			PALETTE_TO_TRANSPARENT | (1 << USE_COLORTABLE) // black, but with some alpha for background
 		);
 
 	/* Paint the messages starting with the lowest at the bottom */
--- a/src/town_cmd.cpp
+++ b/src/town_cmd.cpp
@@ -94,7 +94,7 @@
 
 static void TownDrawHouseLift(const TileInfo *ti)
 {
-	AddChildSpriteScreen(SPR_LIFT, 14, 60 - GetLiftPosition(ti->tile));
+	AddChildSpriteScreen(SPR_LIFT, PAL_NONE, 14, 60 - GetLiftPosition(ti->tile));
 }
 
 typedef void TownDrawTileProc(const TileInfo *ti);
@@ -106,7 +106,8 @@
 static void DrawTile_Town(TileInfo *ti)
 {
 	const DrawBuildingsTileStruct *dcts;
-	uint32 image;
+	SpriteID image;
+	SpriteID pal;
 
 	/* Retrieve pointer to the draw town tile struct */
 	{
@@ -121,14 +122,22 @@
 	}
 
 	if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
-	DrawGroundSprite(dcts->ground);
+
+	image = dcts->ground.sprite;
+	pal   = dcts->ground.pal;
+	DrawGroundSprite(image, pal);
 
 	/* Add a house on top of the ground? */
-	image = dcts->building;
+	image = dcts->building.sprite;
 	if (image != 0) {
-		if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
+		if (_display_opt & DO_TRANS_BUILDINGS) {
+			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
+			pal = PALETTE_TO_TRANSPARENT;
+		} else {
+			pal = dcts->building.pal;
+		}
 
-		AddSortableSpriteToDraw(image,
+		AddSortableSpriteToDraw(image, pal,
 			ti->x + dcts->subtile_x,
 			ti->y + dcts->subtile_y,
 			dcts->width + 1,
--- a/src/town_gui.cpp
+++ b/src/town_gui.cpp
@@ -141,8 +141,9 @@
 					(str++,                    true);                    // Outstanding
 
 					SetDParam(4, str);
-					if (t->exclusivity == p->index) // red icon for player with exclusive rights
-						DrawSprite(SPR_BLOT | PALETTE_TO_RED, 18, y);
+					if (t->exclusivity == p->index) { // red icon for player with exclusive rights
+						DrawSprite(SPR_BLOT, PALETTE_TO_RED, 18, y);
+					}
 
 					DrawString(28, y, STR_2024, 0);
 					y += 10;
--- a/src/train_cmd.cpp
+++ b/src/train_cmd.cpp
@@ -479,12 +479,12 @@
 	return base;
 }
 
-void DrawTrainEngine(int x, int y, EngineID engine, uint32 image_ormod)
+void DrawTrainEngine(int x, int y, EngineID engine, SpriteID pal)
 {
 	const RailVehicleInfo *rvi = RailVehInfo(engine);
 
 	int img = rvi->image_index;
-	uint32 image = 0;
+	SpriteID image = 0;
 
 	if (is_custom_sprite(img)) {
 		image = GetCustomVehicleIcon(engine, DIR_W);
@@ -499,7 +499,7 @@
 	}
 
 	if (rvi->flags & RVI_MULTIHEAD) {
-		DrawSprite(image | image_ormod, x - 14, y);
+		DrawSprite(image, pal, x - 14, y);
 		x += 15;
 		image = 0;
 		if (is_custom_sprite(img)) {
@@ -512,7 +512,7 @@
 				_engine_sprite_base[img + 1];
 		}
 	}
-	DrawSprite(image | image_ormod, x, y);
+	DrawSprite(image, pal, x, y);
 }
 
 uint CountArticulatedParts(EngineID engine_type)
@@ -3045,7 +3045,7 @@
 				} else {
 					/* is not inside depot */
 
-					if (!TrainCheckIfLineEnds(v)) return;
+					if (IsFrontEngine(v) && !TrainCheckIfLineEnds(v)) return;
 
 					r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
 					if (r & 0x8) {
--- a/src/train_gui.cpp
+++ b/src/train_gui.cpp
@@ -608,8 +608,8 @@
 
 		if (dx + width > 0) {
 			if (dx <= count) {
-				PalSpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
-				DrawSprite(GetTrainImage(v, DIR_W) | pal, 16 + WagonLengthToPixels(dx), 7 + (is_custom_sprite(RailVehInfo(v->engine_type)->image_index) ? _traininfo_vehicle_pitch : 0));
+				SpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
+				DrawSprite(GetTrainImage(v, DIR_W), pal, 16 + WagonLengthToPixels(dx), 7 + (is_custom_sprite(RailVehInfo(v->engine_type)->image_index) ? _traininfo_vehicle_pitch : 0));
 				if (v->index == selection) {
 					/* Set the highlight position */
 					highlight_l = WagonLengthToPixels(dx) + 1;
@@ -747,7 +747,7 @@
 		}
 
 		/* draw the flag plus orders */
-		DrawSprite(v->vehstatus & VS_STOPPED ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, 2, w->widget[5].top + 1);
+		DrawSprite(v->vehstatus & VS_STOPPED ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, 2, w->widget[5].top + 1);
 		DrawStringCenteredTruncated(w->widget[5].left + 8, w->widget[5].right, w->widget[5].top + 1, str, 0);
 		DrawWindowViewport(w);
 	}	break;
@@ -977,8 +977,8 @@
 
 				u = v;
 				do {
-					PalSpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
-					DrawSprite(GetTrainImage(u, DIR_W) | pal, x + WagonLengthToPixels(4 + dx), y + 6 + (is_custom_sprite(RailVehInfo(u->engine_type)->image_index) ? _traininfo_vehicle_pitch : 0));
+					SpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
+					DrawSprite(GetTrainImage(u, DIR_W), pal, x + WagonLengthToPixels(4 + dx), y + 6 + (is_custom_sprite(RailVehInfo(u->engine_type)->image_index) ? _traininfo_vehicle_pitch : 0));
 					dx += u->u.rail.cached_veh_length;
 					u = u->next;
 				} while (u != NULL && IsArticulatedPart(u) && u->cargo_cap == 0);
--- a/src/tree_cmd.cpp
+++ b/src/tree_cmd.cpp
@@ -313,20 +313,21 @@
 }
 
 typedef struct TreeListEnt {
-	uint32 image;
+	SpriteID image;
+	SpriteID pal;
 	byte x,y;
 } TreeListEnt;
 
 static void DrawTile_Trees(TileInfo *ti)
 {
-	const uint32 *s;
+	const PalSpriteID *s;
 	const TreePos* d;
 	byte z;
 
 	switch (GetTreeGround(ti->tile)) {
 		case TREE_GROUND_GRASS: DrawClearLandTile(ti, 3); break;
 		case TREE_GROUND_ROUGH: DrawHillyLandTile(ti); break;
-		default: DrawGroundSprite(_tree_sprites_1[GetTreeDensity(ti->tile)] + _tileh_to_sprite[ti->tileh]); break;
+		default: DrawGroundSprite(_tree_sprites_1[GetTreeDensity(ti->tile)] + _tileh_to_sprite[ti->tileh], PAL_NONE); break;
 	}
 
 	DrawClearLandFence(ti);
@@ -372,9 +373,16 @@
 		/* put the trees to draw in a list */
 		i = GetTreeCount(ti->tile) + 1;
 		do {
-			uint32 image = s[0] + (--i == 0 ? GetTreeGrowth(ti->tile) : 3);
-			if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
+			SpriteID image = s[0].sprite + (--i == 0 ? GetTreeGrowth(ti->tile) : 3);
+			SpriteID pal;
+			if (_display_opt & DO_TRANS_BUILDINGS) {
+				SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
+				pal = PALETTE_TO_TRANSPARENT;
+			} else {
+				pal = s[0].pal;
+			}
 			te[i].image = image;
+			te[i].pal   = pal;
 			te[i].x = d->x;
 			te[i].y = d->y;
 			s++;
@@ -396,7 +404,7 @@
 
 			if (tep == NULL) break;
 
-			AddSortableSpriteToDraw(tep->image, ti->x + tep->x, ti->y + tep->y, 5, 5, 0x10, z);
+			AddSortableSpriteToDraw(tep->image, tep->pal, ti->x + tep->x, ti->y + tep->y, 5, 5, 0x10, z);
 			tep->image = 0;
 		}
 	}
--- a/src/tunnelbridge_cmd.cpp
+++ b/src/tunnelbridge_cmd.cpp
@@ -42,19 +42,19 @@
 	     |  |   |    |    maximum speed
 	     |  |   |    |    |  sprite to use in GUI                string with description
 	     |  |   |    |    |  |                                   |                            */
-	{    0, 0, 16,  80,  32, 0xA24                             , STR_5012_WOODEN             , NULL, 0 },
-	{    0, 0,  2, 112,  48, 0xA26 | PALETTE_TO_STRUCT_RED     , STR_5013_CONCRETE           , NULL, 0 },
-	{ 1930, 0,  5, 144,  64, 0xA25                             , STR_500F_GIRDER_STEEL       , NULL, 0 },
-	{    0, 2, 10, 168,  80, 0xA22 | PALETTE_TO_STRUCT_CONCRETE, STR_5011_SUSPENSION_CONCRETE, NULL, 0 },
-	{ 1930, 3, 16, 185,  96, 0xA22                             , STR_500E_SUSPENSION_STEEL   , NULL, 0 },
-	{ 1930, 3, 16, 192, 112, 0xA22 | PALETTE_TO_STRUCT_YELLOW  , STR_500E_SUSPENSION_STEEL   , NULL, 0 },
-	{ 1930, 3,  7, 224, 160, 0xA23                             , STR_5010_CANTILEVER_STEEL   , NULL, 0 },
-	{ 1930, 3,  8, 232, 208, 0xA23 | PALETTE_TO_STRUCT_BROWN   , STR_5010_CANTILEVER_STEEL   , NULL, 0 },
-	{ 1930, 3,  9, 248, 240, 0xA23 | PALETTE_TO_STRUCT_RED     , STR_5010_CANTILEVER_STEEL   , NULL, 0 },
-	{ 1930, 0,  2, 240, 256, 0xA27                             , STR_500F_GIRDER_STEEL       , NULL, 0 },
-	{ 1995, 2, 16, 255, 320, 0xA28                             , STR_5014_TUBULAR_STEEL      , NULL, 0 },
-	{ 2005, 2, 32, 380, 512, 0xA28 | PALETTE_TO_STRUCT_YELLOW  , STR_5014_TUBULAR_STEEL      , NULL, 0 },
-	{ 2010, 2, 32, 510, 608, 0xA28 | PALETTE_TO_STRUCT_GREY    , STR_BRIDGE_TUBULAR_SILICON  , NULL, 0 }
+	{    0, 0, 16,  80,  32, 0xA24, PAL_NONE                  , STR_5012_WOODEN             , NULL, 0 },
+	{    0, 0,  2, 112,  48, 0xA26, PALETTE_TO_STRUCT_RED     , STR_5013_CONCRETE           , NULL, 0 },
+	{ 1930, 0,  5, 144,  64, 0xA25, PAL_NONE                  , STR_500F_GIRDER_STEEL       , NULL, 0 },
+	{    0, 2, 10, 168,  80, 0xA22, PALETTE_TO_STRUCT_CONCRETE, STR_5011_SUSPENSION_CONCRETE, NULL, 0 },
+	{ 1930, 3, 16, 185,  96, 0xA22, PAL_NONE                  , STR_500E_SUSPENSION_STEEL   , NULL, 0 },
+	{ 1930, 3, 16, 192, 112, 0xA22, PALETTE_TO_STRUCT_YELLOW  , STR_500E_SUSPENSION_STEEL   , NULL, 0 },
+	{ 1930, 3,  7, 224, 160, 0xA23, PAL_NONE                  , STR_5010_CANTILEVER_STEEL   , NULL, 0 },
+	{ 1930, 3,  8, 232, 208, 0xA23, PALETTE_TO_STRUCT_BROWN   , STR_5010_CANTILEVER_STEEL   , NULL, 0 },
+	{ 1930, 3,  9, 248, 240, 0xA23, PALETTE_TO_STRUCT_RED     , STR_5010_CANTILEVER_STEEL   , NULL, 0 },
+	{ 1930, 0,  2, 240, 256, 0xA27, PAL_NONE                  , STR_500F_GIRDER_STEEL       , NULL, 0 },
+	{ 1995, 2, 16, 255, 320, 0xA28, PAL_NONE                  , STR_5014_TUBULAR_STEEL      , NULL, 0 },
+	{ 2005, 2, 32, 380, 512, 0xA28, PALETTE_TO_STRUCT_YELLOW  , STR_5014_TUBULAR_STEEL      , NULL, 0 },
+	{ 2010, 2, 32, 510, 608, 0xA28, PALETTE_TO_STRUCT_GREY    , STR_BRIDGE_TUBULAR_SILICON  , NULL, 0 }
 };
 
 Bridge _bridge[MAX_BRIDGES];
@@ -723,13 +723,15 @@
 }
 
 
-static void DrawBridgePillars(PalSpriteID image, const TileInfo* ti, Axis axis, uint type, int x, int y, int z)
+static void DrawBridgePillars(const PalSpriteID *psid, const TileInfo* ti, Axis axis, uint type, int x, int y, int z)
 {
+	SpriteID image = psid->sprite;
 	if (image != 0) {
 		bool drawfarpillar = !HASBIT(GetBridgeFlags(type), 0);
 		int back_height, front_height;
 		int i = z;
 		const byte *p;
+		SpriteID pal;
 
 		static const byte _tileh_bits[4][8] = {
 			{ 2, 1, 8, 4,  16,  2, 0, 9 },
@@ -738,7 +740,12 @@
 			{ 2, 4, 8, 1,   2, 16, 9, 0 }
 		};
 
-		if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
+		if (_display_opt & DO_TRANS_BUILDINGS) {
+			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
+			pal = PALETTE_TO_TRANSPARENT;
+		} else {
+			pal = psid->pal;
+		}
 
 		p = _tileh_bits[(image & 1) * 2 + (axis == AXIS_X ? 0 : 1)];
 		front_height = ti->z + (ti->tileh & p[0] ? TILE_HEIGHT : 0);
@@ -754,11 +761,11 @@
 			 * sprites is at the top
 			 */
 			if (z >= front_height) { // front facing pillar
-				AddSortableSpriteToDraw(image, x, y, p[4], p[5], 1, z);
+				AddSortableSpriteToDraw(image, pal, x, y, p[4], p[5], 1, z);
 			}
 
 			if (drawfarpillar && z >= back_height && z < i - TILE_HEIGHT) { // back facing pillar
-				AddSortableSpriteToDraw(image, x - p[6], y - p[7], p[4], p[5], 1, z);
+				AddSortableSpriteToDraw(image, pal, x - p[6], y - p[7], p[4], p[5], 1, z);
 			}
 		}
 	}
@@ -800,7 +807,8 @@
  */
 static void DrawTile_TunnelBridge(TileInfo *ti)
 {
-	uint32 image;
+	SpriteID image;
+	SpriteID pal;
 
 	if (IsTunnel(ti->tile)) {
 		if (GetTunnelTransportType(ti->tile) == TRANSPORT_RAIL) {
@@ -812,12 +820,13 @@
 		if (HasTunnelSnowOrDesert(ti->tile)) image += 32;
 
 		image += GetTunnelDirection(ti->tile) * 2;
-		DrawGroundSprite(image);
+		DrawGroundSprite(image, PAL_NONE);
 		if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
 
-		AddSortableSpriteToDraw(image+1, ti->x + TILE_SIZE - 1, ti->y + TILE_SIZE - 1, 1, 1, 8, (byte)ti->z);
+		AddSortableSpriteToDraw(image+1, PAL_NONE, ti->x + TILE_SIZE - 1, ti->y + TILE_SIZE - 1, 1, 1, 8, (byte)ti->z);
 		DrawBridgeMiddle(ti);
 	} else if (IsBridge(ti->tile)) { // XXX is this necessary?
+		const PalSpriteID *psid;
 		int base_offset;
 		bool ice = HasBridgeSnowOrDesert(ti->tile);
 
@@ -842,23 +851,31 @@
 		if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head
 
 		/* Table number 6 always refers to the bridge heads for any bridge type */
-		image = GetBridgeSpriteTable(GetBridgeType(ti->tile), 6)[base_offset];
+		psid = &GetBridgeSpriteTable(GetBridgeType(ti->tile), 6)[base_offset];
 
 		if (!ice) {
 			DrawClearLandTile(ti, 3);
 		} else {
-			DrawGroundSprite(SPR_FLAT_SNOWY_TILE + _tileh_to_sprite[ti->tileh]);
+			DrawGroundSprite(SPR_FLAT_SNOWY_TILE + _tileh_to_sprite[ti->tileh], PAL_NONE);
 		}
 
 		if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
 
+		image = psid->sprite;
+
 		// draw ramp
-		if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
+		if (_display_opt & DO_TRANS_BUILDINGS) {
+			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
+			pal = PALETTE_TO_TRANSPARENT;
+		} else {
+			pal = psid->pal;
+		}
+
 		/* HACK set the height of the BB of a sloped ramp to 1 so a vehicle on
 		 * it doesn't disappear behind it
 		 */
 		AddSortableSpriteToDraw(
-			image, ti->x, ti->y, 16, 16, ti->tileh == SLOPE_FLAT ? 1 : 8, ti->z
+			image, pal, ti->x, ti->y, 16, 16, ti->tileh == SLOPE_FLAT ? 1 : 8, ti->z
 		);
 
 		DrawBridgeMiddle(ti);
@@ -900,8 +917,9 @@
 
 void DrawBridgeMiddle(const TileInfo* ti)
 {
-	const PalSpriteID* b;
-	PalSpriteID image;
+	const PalSpriteID* psid;
+	SpriteID image;
+	SpriteID pal;
 	uint base_offset;
 	TileIndex rampnorth;
 	TileIndex rampsouth;
@@ -930,45 +948,64 @@
 		base_offset = 8;
 	}
 
-	b = base_offset + GetBridgeSpriteTable(type, piece);
-	if (axis != AXIS_X) b += 4;
+	psid = base_offset + GetBridgeSpriteTable(type, piece);
+	if (axis != AXIS_X) psid += 4;
 
 	x = ti->x;
 	y = ti->y;
 	z = GetBridgeHeight(rampsouth) - 3;
 
-	image = b[0];
-	if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
-	if (axis == AXIS_X) {
-		AddSortableSpriteToDraw(image, x, y, 16, 11, 1, z);
+	image = psid->sprite;
+	if (_display_opt & DO_TRANS_BUILDINGS) {
+		SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
+		pal = PALETTE_TO_TRANSPARENT;
 	} else {
-		AddSortableSpriteToDraw(image, x, y, 11, 16, 1, z);
+		pal = psid->pal;
 	}
 
-	image = b[1];
-	if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
+	if (axis == AXIS_X) {
+		AddSortableSpriteToDraw(image, pal, x, y, 16, 11, 1, z);
+	} else {
+		AddSortableSpriteToDraw(image, pal, x, y, 11, 16, 1, z);
+	}
+
+	psid++;
+	image = psid->sprite;
+	if (_display_opt & DO_TRANS_BUILDINGS) {
+		SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
+		pal = PALETTE_TO_TRANSPARENT;
+	} else {
+		pal = psid->pal;
+	}
 
 	// draw roof, the component of the bridge which is logically between the vehicle and the camera
 	if (axis == AXIS_X) {
 		y += 12;
-		if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, x, y, 16, 1, 0x28, z);
+		if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, pal, x, y, 16, 1, 0x28, z);
 	} else {
 		x += 12;
-		if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, x, y, 1, 16, 0x28, z);
+		if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, pal, x, y, 1, 16, 0x28, z);
 	}
 
 	if (GetRailType(rampsouth) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
 
+	psid++;
 	if (ti->z + 5 == z) {
 		// draw poles below for small bridges
-		image = b[2];
-		if (image != 0) {
-			if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
-			DrawGroundSpriteAt(image, x, y, z);
+		if (psid->sprite != 0) {
+			image = psid->sprite;
+			if (_display_opt & DO_TRANS_BUILDINGS) {
+				SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
+				pal = PALETTE_TO_TRANSPARENT;
+			} else {
+				pal = psid->pal;
+			}
+
+			DrawGroundSpriteAt(image, pal, x, y, z);
 		}
 	} else if (_patches.bridge_pillars) {
 		// draw pillars below for high bridges
-		DrawBridgePillars(b[2], ti, axis, type, x, y, z);
+		DrawBridgePillars(psid, ti, axis, type, x, y, z);
 	}
 }
 
--- a/src/unmovable_cmd.cpp
+++ b/src/unmovable_cmd.cpp
@@ -107,7 +107,8 @@
 
 static void DrawTile_Unmovable(TileInfo *ti)
 {
-	uint32 image, ormod;
+	SpriteID image;
+	SpriteID pal;
 
 	switch (GetUnmovableType(ti->tile)) {
 		case UNMOVABLE_TRANSMITTER:
@@ -120,29 +121,45 @@
 			dtus = &_draw_tile_unmovable_data[GetUnmovableType(ti->tile)];
 
 			image = dtus->image;
-			if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
+			if (_display_opt & DO_TRANS_BUILDINGS) {
+				SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
+				pal = PALETTE_TO_TRANSPARENT;
+			} else {
+				pal = PAL_NONE;
+			}
 
 			AddSortableSpriteToDraw(
-				image, ti->x | dtus->subcoord_x, ti->y | dtus->subcoord_y,
+				image, pal, ti->x | dtus->subcoord_x, ti->y | dtus->subcoord_y,
 				dtus->width, dtus->height, dtus->z_size, ti->z
 			);
 			break;
 		}
 
 		case UNMOVABLE_STATUE:
-			DrawGroundSprite(SPR_CONCRETE_GROUND);
+			DrawGroundSprite(SPR_CONCRETE_GROUND, PAL_NONE);
 
-			image = PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile));
-			image += PALETTE_MODIFIER_COLOR | SPR_STATUE_COMPANY;
-			if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
-			AddSortableSpriteToDraw(image, ti->x, ti->y, 16, 16, 25, ti->z);
+			image = SPR_STATUE_COMPANY;
+			if (_display_opt & DO_TRANS_BUILDINGS) {
+				SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
+				pal = PALETTE_TO_TRANSPARENT;
+			} else {
+				pal = PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile));
+			}
+			AddSortableSpriteToDraw(image, pal, ti->x, ti->y, 16, 16, 25, ti->z);
 			break;
 
 		case UNMOVABLE_OWNED_LAND:
 			DrawClearLandTile(ti, 0);
 
+			image = SPR_BOUGHT_LAND;
+			if (_display_opt & DO_TRANS_BUILDINGS) {
+				SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
+				pal = PALETTE_TO_TRANSPARENT;
+			} else {
+				pal = PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile));
+			}
 			AddSortableSpriteToDraw(
-				PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile)) + PALETTE_MODIFIER_COLOR + SPR_BOUGHT_LAND,
+				image, pal,
 				ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 10, GetSlopeZ(ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2)
 			);
 			DrawBridgeMiddle(ti);
@@ -151,24 +168,26 @@
 		default: {
 			const DrawTileSeqStruct* dtss;
 			const DrawTileSprites* t;
+			SpriteID palette;
 
 			assert(IsCompanyHQ(ti->tile));
 			if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
 
-			ormod = PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile));
+			palette = PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile));
 
 			t = &_unmovable_display_datas[GetCompanyHQSection(ti->tile)];
-			DrawGroundSprite(t->ground_sprite | ormod);
+			DrawGroundSprite(t->ground_sprite, palette);
 
 			foreach_draw_tile_seq(dtss, t->seq) {
 				image = dtss->image;
 				if (_display_opt & DO_TRANS_BUILDINGS) {
-					MAKE_TRANSPARENT(image);
+					SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
+					pal = PALETTE_TO_TRANSPARENT;
 				} else {
-					image |= ormod;
+					pal = palette;
 				}
 				AddSortableSpriteToDraw(
-					image,
+					image, pal,
 					ti->x + dtss->delta_x, ti->y + dtss->delta_y,
 					dtss->size_x, dtss->size_y,
 					dtss->size_z, ti->z + dtss->delta_z
--- a/src/vehicle.cpp
+++ b/src/vehicle.cpp
@@ -796,15 +796,19 @@
 
 static void DoDrawVehicle(const Vehicle *v)
 {
-	uint32 image = v->cur_image;
+	SpriteID image = v->cur_image;
+	SpriteID pal;
 
 	if (v->vehstatus & VS_SHADOW) {
-		MAKE_TRANSPARENT(image);
+		SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
+		pal = PALETTE_TO_TRANSPARENT;
 	} else if (v->vehstatus & VS_DEFPAL) {
-		image |= (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
+		pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
+	} else {
+		pal = PAL_NONE;
 	}
 
-	AddSortableSpriteToDraw(image, v->x_pos + v->x_offs, v->y_pos + v->y_offs,
+	AddSortableSpriteToDraw(image, pal, v->x_pos + v->x_offs, v->y_pos + v->y_offs,
 		v->sprite_width, v->sprite_height, v->z_height, v->z_pos);
 }
 
@@ -2801,7 +2805,7 @@
 	return unit;
 }
 
-static PalSpriteID GetEngineColourMap(EngineID engine_type, PlayerID player, EngineID parent_engine_type, CargoID cargo_type)
+static SpriteID GetEngineColourMap(EngineID engine_type, PlayerID player, EngineID parent_engine_type, CargoID cargo_type)
 {
 	SpriteID map;
 	const Player *p = GetPlayer(player);
@@ -2886,15 +2890,15 @@
 		(SPR_2CCMAP_BASE + p->livery[scheme].colour1 + p->livery[scheme].colour2 * 16) :
 		(PALETTE_RECOLOR_START + p->livery[scheme].colour1);
 
-	return SPRITE_PALETTE(map << PALETTE_SPRITE_START);
+	return map;
 }
 
-PalSpriteID GetEnginePalette(EngineID engine_type, PlayerID player)
+SpriteID GetEnginePalette(EngineID engine_type, PlayerID player)
 {
 	return GetEngineColourMap(engine_type, player, INVALID_ENGINE, CT_INVALID);
 }
 
-PalSpriteID GetVehiclePalette(const Vehicle *v)
+SpriteID GetVehiclePalette(const Vehicle *v)
 {
 	if (v->type == VEH_Train) {
 		return GetEngineColourMap(
--- a/src/vehicle.h
+++ b/src/vehicle.h
@@ -466,14 +466,14 @@
  * @param player ID of player
  * @return A ready-to-use palette modifier
  */
-PalSpriteID GetEnginePalette(EngineID engine_type, PlayerID player);
+SpriteID GetEnginePalette(EngineID engine_type, PlayerID player);
 
 /**
  * Get the colour map for a vehicle.
  * @param v Vehicle to get colour map for
  * @return A ready-to-use palette modifier
  */
-PalSpriteID GetVehiclePalette(const Vehicle *v);
+SpriteID GetVehiclePalette(const Vehicle *v);
 
 /* A lot of code calls for the invalidation of the status bar, which is widget 5.
  * Best is to have a virtual value for it when it needs to change again */
--- a/src/vehicle_gui.cpp
+++ b/src/vehicle_gui.cpp
@@ -177,19 +177,19 @@
 // draw the vehicle profit button in the vehicle list window.
 void DrawVehicleProfitButton(const Vehicle *v, int x, int y)
 {
-	uint32 ormod;
+	SpriteID pal;
 
 	// draw profit-based colored icons
 	if (v->age <= 365 * 2) {
-		ormod = PALETTE_TO_GREY;
+		pal = PALETTE_TO_GREY;
 	} else if (v->profit_last_year < 0) {
-		ormod = PALETTE_TO_RED;
+		pal = PALETTE_TO_RED;
 	} else if (v->profit_last_year < 10000) {
-		ormod = PALETTE_TO_YELLOW;
+		pal = PALETTE_TO_YELLOW;
 	} else {
-		ormod = PALETTE_TO_GREEN;
+		pal = PALETTE_TO_GREEN;
 	}
-	DrawSprite(SPR_BLOT | ormod, x, y);
+	DrawSprite(SPR_BLOT, pal, x, y);
 }
 
 typedef struct RefitOption {
--- a/src/viewport.cpp
+++ b/src/viewport.cpp
@@ -57,7 +57,8 @@
 } StringSpriteToDraw;
 
 typedef struct TileSpriteToDraw {
-	uint32 image;
+	SpriteID image;
+	SpriteID pal;
 	struct TileSpriteToDraw *next;
 	int32 x;
 	int32 y;
@@ -65,14 +66,16 @@
 } TileSpriteToDraw;
 
 typedef struct ChildScreenSpriteToDraw {
-	uint32 image;
+	SpriteID image;
+	SpriteID pal;
 	int32 x;
 	int32 y;
 	struct ChildScreenSpriteToDraw *next;
 } ChildScreenSpriteToDraw;
 
 typedef struct ParentSpriteToDraw {
-	uint32 image;
+	SpriteID image;
+	SpriteID pal;
 	int32 left;
 	int32 top;
 	int32 right;
@@ -406,7 +409,7 @@
 	InvalidateWidget(w, widget_zoom_out);
 }
 
-void DrawGroundSpriteAt(uint32 image, int32 x, int32 y, byte z)
+void DrawGroundSpriteAt(SpriteID image, SpriteID pal, int32 x, int32 y, byte z)
 {
 	ViewportDrawer *vd = _cur_vd;
 	TileSpriteToDraw *ts;
@@ -422,6 +425,7 @@
 	vd->spritelist_mem += sizeof(TileSpriteToDraw);
 
 	ts->image = image;
+	ts->pal = pal;
 	ts->next = NULL;
 	ts->x = x;
 	ts->y = y;
@@ -430,14 +434,14 @@
 	vd->last_tile = &ts->next;
 }
 
-void DrawGroundSprite(uint32 image)
+void DrawGroundSprite(SpriteID image, SpriteID pal)
 {
 	if (_offset_ground_sprites) {
 		// offset ground sprite because of foundation?
-		AddChildSpriteScreen(image, _cur_vd->offs_x, _cur_vd->offs_y);
+		AddChildSpriteScreen(image, pal, _cur_vd->offs_x, _cur_vd->offs_y);
 	} else {
 		_added_tile_sprite = true;
-		DrawGroundSpriteAt(image, _cur_ti->x, _cur_ti->y, _cur_ti->z);
+		DrawGroundSpriteAt(image, pal, _cur_ti->x, _cur_ti->y, _cur_ti->z);
 	}
 }
 
@@ -449,7 +453,7 @@
 	_offset_ground_sprites = true;
 }
 
-static void AddCombinedSprite(uint32 image, int x, int y, byte z)
+static void AddCombinedSprite(SpriteID image, SpriteID pal, int x, int y, byte z)
 {
 	const ViewportDrawer *vd = _cur_vd;
 	Point pt = RemapCoords(x, y, z);
@@ -461,11 +465,11 @@
 			pt.y + spr->y_offs + spr->height <= vd->dpi.top)
 		return;
 
-	AddChildSpriteScreen(image, pt.x - vd->parent_list[-1]->left, pt.y - vd->parent_list[-1]->top);
+	AddChildSpriteScreen(image, pal, pt.x - vd->parent_list[-1]->left, pt.y - vd->parent_list[-1]->top);
 }
 
 
-void AddSortableSpriteToDraw(uint32 image, int x, int y, int w, int h, byte dz, byte z)
+void AddSortableSpriteToDraw(SpriteID image, SpriteID pal, int x, int y, int w, int h, byte dz, byte z)
 {
 	ViewportDrawer *vd = _cur_vd;
 	ParentSpriteToDraw *ps;
@@ -475,7 +479,7 @@
 	assert((image & SPRITE_MASK) < MAX_SPRITES);
 
 	if (vd->combine_sprites == 2) {
-		AddCombinedSprite(image, x, y, z);
+		AddCombinedSprite(image, pal, x, y, z);
 		return;
 	}
 
@@ -510,6 +514,7 @@
 	vd->spritelist_mem += sizeof(ParentSpriteToDraw);
 
 	ps->image = image;
+	ps->pal = pal;
 	ps->xmin = x;
 	ps->xmax = x + w - 1;
 
@@ -538,7 +543,7 @@
 	_cur_vd->combine_sprites = 0;
 }
 
-void AddChildSpriteScreen(uint32 image, int x, int y)
+void AddChildSpriteScreen(SpriteID image, SpriteID pal, int x, int y)
 {
 	ViewportDrawer *vd = _cur_vd;
 	ChildScreenSpriteToDraw *cs;
@@ -559,6 +564,7 @@
 	vd->last_child = &cs->next;
 
 	cs->image = image;
+	cs->pal = pal;
 	cs->x = x;
 	cs->y = y;
 	cs->next = NULL;
@@ -593,12 +599,12 @@
 }
 
 
-static void DrawSelectionSprite(uint32 image, const TileInfo *ti)
+static void DrawSelectionSprite(SpriteID image, SpriteID pal, const TileInfo *ti)
 {
 	if (_added_tile_sprite && !(_thd.drawstyle & HT_LINE)) { // draw on real ground
-		DrawGroundSpriteAt(image, ti->x, ti->y, ti->z + 7);
+		DrawGroundSpriteAt(image, pal, ti->x, ti->y, ti->z + 7);
 	} else { // draw on top of foundation
-		AddSortableSpriteToDraw(image, ti->x, ti->y, 0x10, 0x10, 1, ti->z + 7);
+		AddSortableSpriteToDraw(image, pal, ti->x, ti->y, 0x10, 0x10, 1, ti->z + 7);
 	}
 }
 
@@ -636,11 +642,12 @@
 
 static void DrawTileSelection(const TileInfo *ti)
 {
-	uint32 image;
+	SpriteID image;
+	SpriteID pal;
 
 	// Draw a red error square?
 	if (_thd.redsq != 0 && _thd.redsq == ti->tile) {
-		DrawSelectionSprite(PALETTE_TILE_RED_PULSATING | (SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh]), ti);
+		DrawSelectionSprite(SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh], PALETTE_TILE_RED_PULSATING, ti);
 		return;
 	}
 
@@ -652,8 +659,7 @@
 			IS_INSIDE_1D(ti->y, _thd.pos.y, _thd.size.y)) {
 		if (_thd.drawstyle & HT_RECT) {
 			image = SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh];
-			if (_thd.make_square_red) image |= PALETTE_SEL_TILE_RED;
-			DrawSelectionSprite(image, ti);
+			DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : PAL_NONE, ti);
 		} else if (_thd.drawstyle & HT_POINT) {
 			// Figure out the Z coordinate for the single dot.
 			byte z = ti->z;
@@ -661,19 +667,29 @@
 				z += TILE_HEIGHT;
 				if (ti->tileh == SLOPE_STEEP_N) z += TILE_HEIGHT;
 			}
-			DrawGroundSpriteAt(_cur_dpi->zoom != 2 ? SPR_DOT : SPR_DOT_SMALL, ti->x, ti->y, z);
+			DrawGroundSpriteAt(_cur_dpi->zoom != 2 ? SPR_DOT : SPR_DOT_SMALL, PAL_NONE, ti->x, ti->y, z);
 		} else if (_thd.drawstyle & HT_RAIL /*&& _thd.place_mode == VHM_RAIL*/) {
 			// autorail highlight piece under cursor
 			uint type = _thd.drawstyle & 0xF;
+			int offset;
+
 			assert(type <= 5);
-			image = SPR_AUTORAIL_BASE + _AutorailTilehSprite[ti->tileh][_AutorailType[type][0]];
-
-			if (_thd.make_square_red) image |= PALETTE_SEL_TILE_RED;
-			DrawSelectionSprite(image, ti);
+
+			offset = _AutorailTilehSprite[ti->tileh][_AutorailType[type][0]];
+			if (offset >= 0) {
+				image = SPR_AUTORAIL_BASE + offset;
+				pal = PAL_NONE;
+			} else {
+				image = SPR_AUTORAIL_BASE - offset;
+				pal = PALETTE_TO_RED;
+			}
+
+			DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : pal, ti);
 
 		} else if (IsPartOfAutoLine(ti->x, ti->y)) {
 			// autorail highlighting long line
 			int dir = _thd.drawstyle & ~0xF0;
+			int offset;
 			uint side;
 
 			if (dir < 2) {
@@ -683,10 +699,16 @@
 				side = delta(delta(TileX(start), TileX(ti->tile)), delta(TileY(start), TileY(ti->tile)));
 			}
 
-			image = SPR_AUTORAIL_BASE + _AutorailTilehSprite[ti->tileh][_AutorailType[dir][side]];
-
-			if (_thd.make_square_red) image |= PALETTE_SEL_TILE_RED;
-			DrawSelectionSprite(image, ti);
+			offset = _AutorailTilehSprite[ti->tileh][_AutorailType[dir][side]];
+			if (offset >= 0) {
+				image = SPR_AUTORAIL_BASE + offset;
+				pal = PAL_NONE;
+			} else {
+				image = SPR_AUTORAIL_BASE - offset;
+				pal = PALETTE_TO_RED;
+			}
+
+			DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : pal, ti);
 		}
 		return;
 	}
@@ -697,7 +719,7 @@
 			IS_INSIDE_1D(ti->x, _thd.pos.x + _thd.offs.x, _thd.size.x + _thd.outersize.x) &&
 			IS_INSIDE_1D(ti->y, _thd.pos.y + _thd.offs.y, _thd.size.y + _thd.outersize.y)) {
 		// Draw a blue rect.
-		DrawSelectionSprite(PALETTE_SEL_TILE_BLUE | (SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh]), ti);
+		DrawSelectionSprite(SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh], PALETTE_SEL_TILE_BLUE, ti);
 		return;
 	}
 }
@@ -1056,7 +1078,7 @@
 {
 	do {
 		Point pt = RemapCoords(ts->x, ts->y, ts->z);
-		DrawSprite(ts->image, pt.x, pt.y);
+		DrawSprite(ts->image, ts->pal, pt.x, pt.y);
 		ts = ts->next;
 	} while (ts != NULL);
 }
@@ -1128,10 +1150,10 @@
 		Point pt = RemapCoords(ps->xmin, ps->ymin, ps->zmin);
 		const ChildScreenSpriteToDraw* cs;
 
-		DrawSprite(ps->image, pt.x, pt.y);
+		DrawSprite(ps->image, ps->pal, pt.x, pt.y);
 
 		for (cs = ps->child; cs != NULL; cs = cs->next) {
-			DrawSprite(cs->image, ps->left + cs->x, ps->top + cs->y);
+			DrawSprite(cs->image, cs->pal, ps->left + cs->x, ps->top + cs->y);
 		}
 	}
 }
@@ -2412,14 +2434,14 @@
 	return false;
 }
 
-void SetObjectToPlaceWnd(CursorID icon, byte mode, Window *w)
+void SetObjectToPlaceWnd(CursorID icon, SpriteID pal, byte mode, Window *w)
 {
-	SetObjectToPlace(icon, mode, w->window_class, w->window_number);
+	SetObjectToPlace(icon, pal, mode, w->window_class, w->window_number);
 }
 
 #include "table/animcursors.h"
 
-void SetObjectToPlace(CursorID icon, byte mode, WindowClass window_class, WindowNumber window_num)
+void SetObjectToPlace(CursorID icon, SpriteID pal, byte mode, WindowClass window_class, WindowNumber window_num)
 {
 	Window *w;
 
@@ -2451,10 +2473,10 @@
 	if ( (int)icon < 0)
 		SetAnimatedMouseCursor(_animcursors[~icon]);
 	else
-		SetMouseCursor(icon);
+		SetMouseCursor(icon, pal);
 }
 
 void ResetObjectToPlace(void)
 {
-	SetObjectToPlace(SPR_CURSOR_MOUSE, VHM_NONE, 0, 0);
+	SetObjectToPlace(SPR_CURSOR_MOUSE, PAL_NONE, VHM_NONE, 0, 0);
 }
--- a/src/viewport.h
+++ b/src/viewport.h
@@ -42,11 +42,11 @@
 
 void OffsetGroundSprite(int x, int y);
 
-void DrawGroundSprite(uint32 image);
-void DrawGroundSpriteAt(uint32 image, int32 x, int32 y, byte z);
-void AddSortableSpriteToDraw(uint32 image, int x, int y, int w, int h, byte dz, byte z);
+void DrawGroundSprite(SpriteID image, SpriteID pal);
+void DrawGroundSpriteAt(SpriteID image, SpriteID pal, int32 x, int32 y, byte z);
+void AddSortableSpriteToDraw(SpriteID image, SpriteID pal, int x, int y, int w, int h, byte dz, byte z);
 void *AddStringToDraw(int x, int y, StringID string, uint32 params_1, uint32 params_2);
-void AddChildSpriteScreen(uint32 image, int x, int y);
+void AddChildSpriteScreen(SpriteID image, SpriteID pal, int x, int y);
 
 
 void StartSpriteCombine(void);
--- a/src/water_cmd.cpp
+++ b/src/water_cmd.cpp
@@ -370,33 +370,33 @@
 	wa += IsWateredTile(TILE_ADDXY(tile, 1, 0)) << 2;
 	wa += IsWateredTile(TILE_ADDXY(tile, 0, -1)) << 3;
 
-	if (!(wa & 1)) DrawGroundSprite(SPR_CANALS_BASE + 57);
-	if (!(wa & 2)) DrawGroundSprite(SPR_CANALS_BASE + 58);
-	if (!(wa & 4)) DrawGroundSprite(SPR_CANALS_BASE + 59);
-	if (!(wa & 8)) DrawGroundSprite(SPR_CANALS_BASE + 60);
+	if (!(wa & 1)) DrawGroundSprite(SPR_CANALS_BASE + 57, PAL_NONE);
+	if (!(wa & 2)) DrawGroundSprite(SPR_CANALS_BASE + 58, PAL_NONE);
+	if (!(wa & 4)) DrawGroundSprite(SPR_CANALS_BASE + 59, PAL_NONE);
+	if (!(wa & 8)) DrawGroundSprite(SPR_CANALS_BASE + 60, PAL_NONE);
 
 	// right corner
 	switch (wa & 0x03) {
-		case 0: DrawGroundSprite(SPR_CANALS_BASE + 57 + 4); break;
-		case 3: if (!IsWateredTile(TILE_ADDXY(tile, -1, 1))) DrawGroundSprite(SPR_CANALS_BASE + 57 + 8); break;
+		case 0: DrawGroundSprite(SPR_CANALS_BASE + 57 + 4, PAL_NONE); break;
+		case 3: if (!IsWateredTile(TILE_ADDXY(tile, -1, 1))) DrawGroundSprite(SPR_CANALS_BASE + 57 + 8, PAL_NONE); break;
 	}
 
 	// bottom corner
 	switch (wa & 0x06) {
-		case 0: DrawGroundSprite(SPR_CANALS_BASE + 57 + 5); break;
-		case 6: if (!IsWateredTile(TILE_ADDXY(tile, 1, 1))) DrawGroundSprite(SPR_CANALS_BASE + 57 + 9); break;
+		case 0: DrawGroundSprite(SPR_CANALS_BASE + 57 + 5, PAL_NONE); break;
+		case 6: if (!IsWateredTile(TILE_ADDXY(tile, 1, 1))) DrawGroundSprite(SPR_CANALS_BASE + 57 + 9, PAL_NONE); break;
 	}
 
 	// left corner
 	switch (wa & 0x0C) {
-		case  0: DrawGroundSprite(SPR_CANALS_BASE + 57 + 6); break;
-		case 12: if (!IsWateredTile(TILE_ADDXY(tile, 1, -1))) DrawGroundSprite(SPR_CANALS_BASE + 57 + 10); break;
+		case  0: DrawGroundSprite(SPR_CANALS_BASE + 57 + 6, PAL_NONE); break;
+		case 12: if (!IsWateredTile(TILE_ADDXY(tile, 1, -1))) DrawGroundSprite(SPR_CANALS_BASE + 57 + 10, PAL_NONE); break;
 	}
 
 	// upper corner
 	switch (wa & 0x09) {
-		case 0: DrawGroundSprite(SPR_CANALS_BASE + 57 + 7); break;
-		case 9: if (!IsWateredTile(TILE_ADDXY(tile, -1, -1))) DrawGroundSprite(SPR_CANALS_BASE + 57 + 11); break;
+		case 0: DrawGroundSprite(SPR_CANALS_BASE + 57 + 7, PAL_NONE); break;
+		case 9: if (!IsWateredTile(TILE_ADDXY(tile, -1, -1))) DrawGroundSprite(SPR_CANALS_BASE + 57 + 11, PAL_NONE); break;
 	}
 }
 
@@ -409,19 +409,26 @@
 #include "table/water_land.h"
 
 static void DrawWaterStuff(const TileInfo *ti, const WaterDrawTileStruct *wdts,
-	uint32 palette, uint base
+	SpriteID palette, uint base
 )
 {
-	DrawGroundSprite(wdts++->image);
+	DrawGroundSprite(wdts++->image, PAL_NONE);
 
 	for (; wdts->delta_x != 0x80; wdts++) {
-		uint32 image = wdts->image + base;
+		SpriteID image = wdts->image + base;
+		SpriteID pal;
+
 		if (_display_opt & DO_TRANS_BUILDINGS) {
-			MAKE_TRANSPARENT(image);
+			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
+			pal = PALETTE_TO_TRANSPARENT;
 		} else {
-			image |= palette;
+			pal = palette;
 		}
-		AddSortableSpriteToDraw(image, ti->x + wdts->delta_x, ti->y + wdts->delta_y, wdts->width, wdts->height, wdts->unk, ti->z + wdts->delta_z);
+
+		AddSortableSpriteToDraw(image, pal,
+			ti->x + wdts->delta_x, ti->y + wdts->delta_y,
+			wdts->width, wdts->height,
+			wdts->unk, ti->z + wdts->delta_z);
 	}
 }
 
@@ -429,7 +436,7 @@
 {
 	switch (GetWaterTileType(ti->tile)) {
 		case WATER_CLEAR:
-			DrawGroundSprite(SPR_FLAT_WATER_TILE);
+			DrawGroundSprite(SPR_FLAT_WATER_TILE, PAL_NONE);
 			if (ti->z != 0 || !IsTileOwner(ti->tile, OWNER_WATER)) DrawCanalWater(ti->tile);
 			DrawBridgeMiddle(ti);
 			break;
@@ -437,9 +444,9 @@
 		case WATER_COAST:
 			assert(!IsSteepSlope(ti->tileh));
 			if (_coast_base != 0) {
-				DrawGroundSprite(_coast_base + ti->tileh);
+				DrawGroundSprite(_coast_base + ti->tileh, PAL_NONE);
 			} else {
-				DrawGroundSprite(_water_shore_sprites[ti->tileh]);
+				DrawGroundSprite(_water_shore_sprites[ti->tileh], PAL_NONE);
 			}
 			DrawBridgeMiddle(ti);
 			break;
@@ -459,11 +466,11 @@
 {
 	const WaterDrawTileStruct *wdts = _shipdepot_display_seq[image];
 
-	DrawSprite(wdts++->image, x, y);
+	DrawSprite(wdts++->image, PAL_NONE, x, y);
 
 	for (; wdts->delta_x != 0x80; wdts++) {
 		Point pt = RemapCoords(wdts->delta_x, wdts->delta_y, wdts->delta_z);
-		DrawSprite(wdts->image + PLAYER_SPRITE_COLOR(_local_player), x + pt.x, y + pt.y);
+		DrawSprite(wdts->image, PLAYER_SPRITE_COLOR(_local_player), x + pt.x, y + pt.y);
 	}
 }
 
--- a/src/widget.cpp
+++ b/src/widget.cpp
@@ -159,7 +159,7 @@
 	uint light        = _colour_gradient[ctab][7];
 
 	if (flags & FR_TRANSPARENT) {
-		GfxFillRect(left, top, right, bottom, 0x322 | USE_COLORTABLE);
+		GfxFillRect(left, top, right, bottom, PALETTE_TO_TRANSPARENT | (1 << USE_COLORTABLE));
 	} else {
 		uint interior;
 
@@ -210,7 +210,7 @@
 
 			/* show different image when clicked for WWT_IMGBTN_2 */
 			if ((wi->type & WWT_MASK) == WWT_IMGBTN_2 && clicked) img++;
-			DrawSprite(img, r.left + 1 + clicked, r.top + 1 + clicked);
+			DrawSprite(img, PAL_NONE, r.left + 1 + clicked, r.top + 1 + clicked);
 			goto draw_default;
 		}
 
@@ -308,7 +308,7 @@
 
 			// draw "shaded" background
 			GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c2);
-			GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c1 | PALETTE_MODIFIER_GREYOUT);
+			GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c1 | (1 << PALETTE_MODIFIER_GREYOUT));
 
 			// draw shaded lines
 			GfxFillRect(r.left+2, r.top+10, r.left+2, r.bottom-10, c1);
@@ -340,7 +340,7 @@
 
 			// draw "shaded" background
 			GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c2);
-			GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c1 | PALETTE_MODIFIER_GREYOUT);
+			GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c1 | (1 << PALETTE_MODIFIER_GREYOUT));
 
 			// draw shaded lines
 			GfxFillRect(r.left+2, r.top+10, r.left+2, r.bottom-10, c1);
@@ -362,18 +362,18 @@
 
 			clicked = ((w->flags4 & (WF_SCROLL_UP | WF_HSCROLL)) == (WF_SCROLL_UP | WF_HSCROLL));
 			DrawFrameRect(r.left, r.top, r.left + 9, r.bottom, wi->color, (clicked) ? FR_LOWERED : FR_NONE);
-			DrawSprite(SPR_ARROW_LEFT, r.left + 1 + clicked, r.top + 1 + clicked);
+			DrawSprite(SPR_ARROW_LEFT, PAL_NONE, r.left + 1 + clicked, r.top + 1 + clicked);
 
 			clicked = ((w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL)) == (WF_SCROLL_DOWN | WF_HSCROLL));
 			DrawFrameRect(r.right-9, r.top, r.right, r.bottom, wi->color, (clicked) ? FR_LOWERED : FR_NONE);
-			DrawSprite(SPR_ARROW_RIGHT, r.right - 8 + clicked, r.top + 1 + clicked);
+			DrawSprite(SPR_ARROW_RIGHT, PAL_NONE, r.right - 8 + clicked, r.top + 1 + clicked);
 
 			c1 = _colour_gradient[wi->color&0xF][3];
 			c2 = _colour_gradient[wi->color&0xF][7];
 
 			// draw "shaded" background
 			GfxFillRect(r.left+10, r.top, r.right-10, r.bottom, c2);
-			GfxFillRect(r.left+10, r.top, r.right-10, r.bottom, c1 | PALETTE_MODIFIER_GREYOUT);
+			GfxFillRect(r.left+10, r.top, r.right-10, r.bottom, c1 | (1 << PALETTE_MODIFIER_GREYOUT));
 
 			// draw shaded lines
 			GfxFillRect(r.left+10, r.top+2, r.right-10, r.top+2, c1);
@@ -424,7 +424,7 @@
 
 			clicked = !!(w->flags4 & WF_STICKY);
 			DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color, (clicked) ? FR_LOWERED : FR_NONE);
-			DrawSprite((clicked) ? SPR_PIN_UP : SPR_PIN_DOWN, r.left + 2 + clicked, r.top + 3 + clicked);
+			DrawSprite((clicked) ? SPR_PIN_UP : SPR_PIN_DOWN, PAL_NONE, r.left + 2 + clicked, r.top + 3 + clicked);
 			break;
 		}
 
@@ -433,7 +433,7 @@
 
 			clicked = !!(w->flags4 & WF_SIZING);
 			DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color, (clicked) ? FR_LOWERED : FR_NONE);
-			DrawSprite(SPR_WINDOW_RESIZE, r.left + 3 + clicked, r.top + 3 + clicked);
+			DrawSprite(SPR_WINDOW_RESIZE, PAL_NONE, r.left + 3 + clicked, r.top + 3 + clicked);
 			break;
 		}
 
@@ -457,7 +457,7 @@
 			DrawStringCenteredTruncated(r.left + 2, r.right - 2, r.top+2, wi->data, 0x84);
 draw_default:;
 			if (IsWindowWidgetDisabled(w, i)) {
-				GfxFillRect(r.left+1, r.top+1, r.right-1, r.bottom-1, _colour_gradient[wi->color&0xF][2] | PALETTE_MODIFIER_GREYOUT);
+				GfxFillRect(r.left+1, r.top+1, r.right-1, r.bottom-1, _colour_gradient[wi->color&0xF][2] | (1 << PALETTE_MODIFIER_GREYOUT));
 			}
 		}
 		}
@@ -529,7 +529,7 @@
 
 						if (HASBIT(WP(w,dropdown_d).disabled_state, i)) {
 							GfxFillRect(x, y, x + width, y + 9,
-								PALETTE_MODIFIER_GREYOUT | _colour_gradient[_dropdown_menu_widgets[0].color][5]
+								(1 << PALETTE_MODIFIER_GREYOUT) | _colour_gradient[_dropdown_menu_widgets[0].color][5]
 							);
 						}
 					} else {