summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gfx_func.h3
-rw-r--r--src/gfxinit.cpp36
-rw-r--r--src/newgrf.cpp6
-rw-r--r--src/spritecache.cpp24
-rw-r--r--src/spriteloader/grf.cpp8
-rw-r--r--src/table/palette_convert.h75
6 files changed, 143 insertions, 9 deletions
diff --git a/src/gfx_func.h b/src/gfx_func.h
index 317f947fa..4a709bf88 100644
--- a/src/gfx_func.h
+++ b/src/gfx_func.h
@@ -180,5 +180,8 @@ extern DrawPixelInfo *_cur_dpi;
extern byte _colour_gradient[COLOUR_END][8];
extern PaletteType _use_palette;
+extern bool _palette_remap_grf[];
+extern const byte *_palette_remap;
+extern const byte *_palette_reverse_remap;
#endif /* GFX_FUNC_H */
diff --git a/src/gfxinit.cpp b/src/gfxinit.cpp
index d1195803a..86f0fa8ee 100644
--- a/src/gfxinit.cpp
+++ b/src/gfxinit.cpp
@@ -23,9 +23,17 @@
#include "ini_type.h"
#include "table/sprites.h"
+#include "table/palette_convert.h"
/** The currently used palette */
PaletteType _use_palette = PAL_AUTODETECT;
+/** Whether the given NewGRFs must get a palette remap or not. */
+bool _palette_remap_grf[MAX_FILE_SLOTS];
+/** Palette map to go from the !_use_palette to the _use_palette */
+const byte *_palette_remap = NULL;
+/** Palette map to go from the _use_palette to the !_use_palette */
+const byte *_palette_reverse_remap = NULL;
+
char _ini_graphics_set[32];
/** Structure holding filename and MD5 information about a single file */
@@ -176,7 +184,9 @@ static bool DetermineGraphicsPack()
const GraphicsSet *best = _available_graphics_sets;
for (const GraphicsSet *c = _available_graphics_sets; c != NULL; c = c->next) {
if (best->found_grfs < c->found_grfs ||
- (best->found_grfs == c->found_grfs && best->shortname == c->shortname && best->version < c->version)) {
+ (best->found_grfs == c->found_grfs && (
+ (best->shortname == c->shortname && best->version < c->version) ||
+ (best->palette != _use_palette && c->palette == _use_palette)))) {
best = c;
}
}
@@ -193,9 +203,22 @@ static bool DetermineGraphicsPack()
static void DeterminePalette()
{
assert(_used_graphics_set != NULL);
- if (_use_palette < MAX_PAL) return;
+ if (_use_palette >= MAX_PAL) _use_palette = _used_graphics_set->palette;
+
+ switch (_use_palette) {
+ case PAL_DOS:
+ _palette_remap = _palmap_w2d;
+ _palette_reverse_remap = _palmap_d2w;
+ break;
+
+ case PAL_WINDOWS:
+ _palette_remap = _palmap_d2w;
+ _palette_reverse_remap = _palmap_w2d;
+ break;
- _use_palette = _used_graphics_set->palette;
+ default:
+ NOT_REACHED();
+ }
}
/**
@@ -207,6 +230,8 @@ void CheckExternalFiles()
{
DeterminePalette();
+ DEBUG(grf, 1, "Using the %s base graphics set with the %s palette", _used_graphics_set->name, _use_palette == PAL_DOS ? "DOS" : "Windows");
+
static const size_t ERROR_MESSAGE_LENGTH = 128;
char error_msg[ERROR_MESSAGE_LENGTH * (MAX_GFT + 1)];
error_msg[0] = '\0';
@@ -233,8 +258,10 @@ void CheckExternalFiles()
static void LoadSpriteTables()
{
+ memset(_palette_remap_grf, 0, sizeof(_palette_remap_grf));
uint i = FIRST_GRF_SLOT;
+ _palette_remap_grf[i] = (_use_palette != _used_graphics_set->palette);
LoadGrfFile(_used_graphics_set->files[GFT_BASE].filename, 0, i++);
/*
@@ -243,6 +270,7 @@ static void LoadSpriteTables()
* has a few sprites less. However, we do not care about those missing
* sprites as they are not shown anyway (logos in intro game).
*/
+ _palette_remap_grf[i] = (_use_palette != _used_graphics_set->palette);
LoadGrfFile(_used_graphics_set->files[GFT_LOGOS].filename, 4793, i++);
/*
@@ -251,6 +279,7 @@ static void LoadSpriteTables()
* and the ground sprites.
*/
if (_settings_game.game_creation.landscape != LT_TEMPERATE) {
+ _palette_remap_grf[i] = (_use_palette != _used_graphics_set->palette);
LoadGrfIndexed(
_used_graphics_set->files[GFT_ARCTIC + _settings_game.game_creation.landscape - 1].filename,
_landscape_spriteindexes[_settings_game.game_creation.landscape - 1],
@@ -274,6 +303,7 @@ static void LoadSpriteTables()
master->next = top;
_grfconfig = master;
+ _palette_remap_grf[i] = (_use_palette != _used_graphics_set->palette);
LoadNewGRF(SPR_NEWGRFS_BASE, i);
/* Free and remove the top element. */
diff --git a/src/newgrf.cpp b/src/newgrf.cpp
index a701b2f37..dea96f88c 100644
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -3652,7 +3652,11 @@ bool GetGlobalVariable(byte param, uint32 *value)
}
case 0x0D: // TTD Version, 00=DOS, 01=Windows
- *value = _use_palette;
+ if (_palette_remap_grf[_file_index]) {
+ *value = !_use_palette;
+ } else {
+ *value = _use_palette;
+ }
return true;
case 0x0E: // Y-offset for train sprites
diff --git a/src/spritecache.cpp b/src/spritecache.cpp
index f7ab69b72..5d141cce3 100644
--- a/src/spritecache.cpp
+++ b/src/spritecache.cpp
@@ -11,6 +11,7 @@
#include "spriteloader/grf.hpp"
#include "core/alloc_func.hpp"
#include "core/math_func.hpp"
+#include "gfx_func.h"
#ifdef WITH_PNG
#include "spriteloader/png.hpp"
#endif /* WITH_PNG */
@@ -188,11 +189,30 @@ static void* ReadSprite(SpriteCache *sc, SpriteID id, SpriteType sprite_type)
return (void*)GetRawSprite(SPR_IMG_QUERY, ST_NORMAL);
}
- byte *dest = (byte *)AllocSprite(num);
+ /* "Normal" recolour sprites are ALWAYS 257 bytes. Then there is a small
+ * number of recolour sprites that are 17 bytes that only exist in DOS
+ * GRFs which are the same as 257 byte recolour sprites, but with the last
+ * 240 bytes zeroed. */
+ static const int RECOLOUR_SPRITE_SIZE = 257;
+ byte *dest = (byte *)AllocSprite(max(RECOLOUR_SPRITE_SIZE, num));
sc->ptr = dest;
sc->type = sprite_type;
- FioReadBlock(dest, num);
+
+ if (_palette_remap_grf[sc->file_slot]) {
+ byte *dest_tmp = AllocaM(byte, max(RECOLOUR_SPRITE_SIZE, num));
+
+ /* Only a few recolour sprites are less than 257 bytes */
+ if (num < RECOLOUR_SPRITE_SIZE) memset(dest_tmp, 0, RECOLOUR_SPRITE_SIZE);
+ FioReadBlock(dest_tmp, num);
+
+ /* The data of index 0 is never used; "literal 00" according to the (New)GRF specs. */
+ for (int i = 1; i < RECOLOUR_SPRITE_SIZE; i++) {
+ dest[i] = _palette_remap[dest_tmp[_palette_reverse_remap[i - 1] + 1]];
+ }
+ } else {
+ FioReadBlock(dest, num);
+ }
return sc->ptr;
}
diff --git a/src/spriteloader/grf.cpp b/src/spriteloader/grf.cpp
index 17510027e..1ded90b07 100644
--- a/src/spriteloader/grf.cpp
+++ b/src/spriteloader/grf.cpp
@@ -83,7 +83,7 @@ bool SpriteLoaderGrf::LoadSprite(SpriteLoader::Sprite *sprite, uint8 file_slot,
data = &sprite->data[y * sprite->width + skip];
for (int x = 0; x < length; x++) {
- data->m = *dest;
+ data->m = ((sprite_type == ST_NORMAL && _palette_remap_grf[file_slot]) ? _palette_remap[*dest] : *dest);
dest++;
data++;
}
@@ -91,8 +91,10 @@ bool SpriteLoaderGrf::LoadSprite(SpriteLoader::Sprite *sprite, uint8 file_slot,
}
} else {
dest = dest_orig;
- for (int i = 0; i < sprite->width * sprite->height; i++)
- sprite->data[i].m = dest[i];
+
+ for (int i = 0; i < sprite->width * sprite->height; i++) {
+ sprite->data[i].m = ((sprite_type == ST_NORMAL && _palette_remap_grf[file_slot]) ? _palette_remap[dest[i]] : dest[i]);
+ }
}
/* Make sure to mark all transparent pixels transparent on the alpha channel too */
diff --git a/src/table/palette_convert.h b/src/table/palette_convert.h
new file mode 100644
index 000000000..33864f82c
--- /dev/null
+++ b/src/table/palette_convert.h
@@ -0,0 +1,75 @@
+/* $Id$ */
+
+/** @file palette_convert.h Translation tables from one GRF to another GRF. */
+
+/** Converting from the Windows palette to the DOS palette */
+static const byte _palmap_w2d[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, // 0..7
+ 8, 9, 10, 11, 12, 13, 14, 15, // 8..15
+ 16, 17, 18, 19, 20, 21, 22, 23, // 16..23
+ 24, 25, 26, 27, 28, 29, 30, 31, // 24..31
+ 6, 7, 34, 35, 36, 37, 38, 39, // 32..39
+ 8, 41, 42, 43, 44, 45, 46, 47, // 40..47
+ 48, 49, 50, 51, 52, 53, 54, 55, // 48..55
+ 56, 57, 58, 59, 60, 61, 62, 63, // 56..63
+ 64, 65, 66, 67, 68, 69, 70, 71, // 64..71
+ 72, 73, 74, 75, 76, 77, 78, 79, // 72..79
+ 80, 81, 82, 83, 84, 85, 86, 87, // 80..87
+ 4, 89, 90, 91, 92, 93, 94, 95, // 88..95
+ 96, 97, 98, 99, 100, 101, 102, 103, // 96..103
+ 104, 105, 5, 107, 108, 109, 110, 111, // 104..111
+ 112, 113, 114, 115, 116, 117, 118, 119, // 112..119
+ 120, 121, 122, 123, 124, 125, 126, 127, // 120..127
+ 128, 129, 130, 131, 132, 133, 134, 135, // 128..135
+ 3, 137, 138, 139, 140, 141, 142, 143, // 136..143
+ 144, 145, 146, 147, 148, 149, 150, 151, // 144..151
+ 152, 153, 154, 155, 156, 157, 158, 159, // 152..159
+ 160, 161, 162, 163, 164, 165, 166, 167, // 160..167
+ 168, 169, 170, 171, 172, 173, 174, 175, // 168..175
+ 176, 177, 178, 179, 180, 181, 182, 183, // 176..183
+ 184, 185, 186, 187, 188, 189, 190, 191, // 184..191
+ 192, 193, 194, 195, 196, 197, 198, 199, // 192..199
+ 200, 201, 202, 203, 204, 205, 206, 207, // 200..207
+ 208, 209, 210, 211, 212, 213, 214, 1, // 208..215
+ 2, 245, 246, 247, 248, 249, 250, 251, // 216..223
+ 252, 253, 254, 229, 230, 231, 227, 228, // 224..231
+ 235, 236, 237, 238, 232, 233, 234, 239, // 232..239
+ 240, 241, 242, 244, 243, 9, 218, 219, // 240..247
+ 220, 221, 222, 223, 224, 225, 226, 255, // 248..255
+};
+
+/** Converting from the DOS palette to the Windows palette */
+static const byte _palmap_d2w[] = {
+ 0, 215, 216, 136, 88, 106, 32, 33, // 0..7
+ 40, 245, 10, 11, 12, 13, 14, 15, // 8..15
+ 16, 17, 18, 19, 20, 21, 22, 23, // 16..23
+ 24, 25, 26, 27, 28, 29, 30, 31, // 24..31
+ 53, 54, 34, 35, 36, 37, 38, 39, // 32..39
+ 178, 41, 42, 43, 44, 45, 46, 47, // 40..47
+ 48, 49, 50, 51, 52, 53, 54, 55, // 48..55
+ 56, 57, 58, 59, 60, 61, 62, 63, // 56..63
+ 64, 65, 66, 67, 68, 69, 70, 71, // 64..71
+ 72, 73, 74, 75, 76, 77, 78, 79, // 72..79
+ 80, 81, 82, 83, 84, 85, 86, 87, // 80..87
+ 96, 89, 90, 91, 92, 93, 94, 95, // 88..95
+ 96, 97, 98, 99, 100, 101, 102, 103, // 96..103
+ 104, 105, 53, 107, 108, 109, 110, 111, // 104..111
+ 112, 113, 114, 115, 116, 117, 118, 119, // 112..119
+ 120, 121, 122, 123, 124, 125, 126, 127, // 120..127
+ 128, 129, 130, 131, 132, 133, 134, 135, // 128..135
+ 170, 137, 138, 139, 140, 141, 142, 143, // 136..143
+ 144, 145, 146, 147, 148, 149, 150, 151, // 144..151
+ 152, 153, 154, 155, 156, 157, 158, 159, // 152..159
+ 160, 161, 162, 163, 164, 165, 166, 167, // 160..167
+ 168, 169, 170, 171, 172, 173, 174, 175, // 168..175
+ 176, 177, 178, 179, 180, 181, 182, 183, // 176..183
+ 184, 185, 186, 187, 188, 189, 190, 191, // 184..191
+ 192, 193, 194, 195, 196, 197, 198, 199, // 192..199
+ 200, 201, 202, 203, 204, 205, 206, 207, // 200..207
+ 208, 209, 210, 211, 212, 213, 214, 215, // 208..215
+ 216, 217, 246, 247, 248, 249, 250, 251, // 216..223
+ 252, 253, 254, 227, 228, 229, 230, 231, // 224..231
+ 232, 233, 234, 235, 236, 237, 238, 239, // 232..239
+ 240, 241, 242, 243, 244, 217, 218, 219, // 240..247
+ 220, 221, 222, 223, 224, 225, 226, 255, // 248..255
+};