Files
@ r18087:1bd0e337907f
Branch filter:
Location: cpp/openttd-patchpack/source/src/spriteloader/grf.cpp - annotation
r18087:1bd0e337907f
5.8 KiB
text/x-c
(svn r22918) -Fix: [NewGRF] Properties for feature 0x05 were not zeroed for each NewGRF, thus waterfeatures could glitch when the properties were set by a previous NewGRF and the NewGRF assumed the properties to be unmodified
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | r6872:f40beb7256a6 r6872:f40beb7256a6 r12768:980ae0491352 r12768:980ae0491352 r12768:980ae0491352 r12768:980ae0491352 r12768:980ae0491352 r12768:980ae0491352 r12768:980ae0491352 r9111:983de9c5a848 r6872:f40beb7256a6 r6852:5b6b567a9e32 r8123:dde0a9a84019 r10039:727fb45b0424 r6852:5b6b567a9e32 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r17142:9f8921b5eb4f r6852:5b6b567a9e32 r6852:5b6b567a9e32 r17637:0d7e49507a12 r17637:0d7e49507a12 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r14635:a75264d517b7 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10056:7a18efcd8edb r6852:5b6b567a9e32 r6852:5b6b567a9e32 r7570:d6777a99c723 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r11085:c87a330fb4c2 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r10031:f42fea05eb07 r6852:5b6b567a9e32 r10359:36d7a611e1f5 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r10359:36d7a611e1f5 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r10359:36d7a611e1f5 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r10359:36d7a611e1f5 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r10359:36d7a611e1f5 r6852:5b6b567a9e32 r11202:ec3713bd39fb r6852:5b6b567a9e32 r14126:f23988064e74 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r10359:36d7a611e1f5 r6852:5b6b567a9e32 r10359:36d7a611e1f5 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r6852:5b6b567a9e32 r13852:7154cc003043 r17637:0d7e49507a12 r13852:7154cc003043 r13852:7154cc003043 r13852:7154cc003043 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6852:5b6b567a9e32 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r6852:5b6b567a9e32 r10062:9a719b26b56e r10062:9a719b26b56e r13852:7154cc003043 r17637:0d7e49507a12 r13852:7154cc003043 r13852:7154cc003043 r13852:7154cc003043 r10062:9a719b26b56e r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6889:9eefa1ce35c6 r15542:f6c6d0f8689e r6889:9eefa1ce35c6 r15542:f6c6d0f8689e r6889:9eefa1ce35c6 r6852:5b6b567a9e32 r6852:5b6b567a9e32 | /* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file grf.cpp Reading graphics data from (New)GRF files. */
#include "../stdafx.h"
#include "../gfx_func.h"
#include "../fileio_func.h"
#include "../debug.h"
#include "../strings_func.h"
#include "table/strings.h"
#include "../gui.h"
#include "../core/math_func.hpp"
#include "grf.hpp"
extern const byte _palmap_w2d[];
/**
* We found a corrupted sprite. This means that the sprite itself
* contains invalid data or is too small for the given dimensions.
* @param file_slot the file the errored sprite is in
* @param file_pos the location in the file of the errored sprite
* @param line the line where the error occurs.
* @return always false (to tell loading the sprite failed)
*/
static bool WarnCorruptSprite(uint8 file_slot, size_t file_pos, int line)
{
static byte warning_level = 0;
if (warning_level == 0) {
SetDParamStr(0, FioGetFilename(file_slot));
ShowErrorMessage(STR_NEWGRF_ERROR_CORRUPT_SPRITE, INVALID_STRING_ID, WL_ERROR);
}
DEBUG(sprite, warning_level, "[%i] Loading corrupted sprite from %s at position %i", line, FioGetFilename(file_slot), (int)file_pos);
warning_level = 6;
return false;
}
bool SpriteLoaderGrf::LoadSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, size_t file_pos, SpriteType sprite_type)
{
/* Open the right file and go to the correct position */
FioSeekToFile(file_slot, file_pos);
/* Read the size and type */
int num = FioReadWord();
byte type = FioReadByte();
/* Type 0xFF indicates either a colourmap or some other non-sprite info; we do not handle them here */
if (type == 0xFF) return false;
sprite->height = FioReadByte();
sprite->width = FioReadWord();
sprite->x_offs = FioReadWord();
sprite->y_offs = FioReadWord();
/* 0x02 indicates it is a compressed sprite, so we can't rely on 'num' to be valid.
* In case it is uncompressed, the size is 'num' - 8 (header-size). */
num = (type & 0x02) ? sprite->width * sprite->height : num - 8;
byte *dest_orig = AllocaM(byte, num);
byte *dest = dest_orig;
const int dest_size = num;
/* Read the file, which has some kind of compression */
while (num > 0) {
int8 code = FioReadByte();
if (code >= 0) {
/* Plain bytes to read */
int size = (code == 0) ? 0x80 : code;
num -= size;
if (num < 0) return WarnCorruptSprite(file_slot, file_pos, __LINE__);
for (; size > 0; size--) {
*dest = FioReadByte();
dest++;
}
} else {
/* Copy bytes from earlier in the sprite */
const uint data_offset = ((code & 7) << 8) | FioReadByte();
if (dest - data_offset < dest_orig) return WarnCorruptSprite(file_slot, file_pos, __LINE__);
int size = -(code >> 3);
num -= size;
if (num < 0) return WarnCorruptSprite(file_slot, file_pos, __LINE__);
for (; size > 0; size--) {
*dest = *(dest - data_offset);
dest++;
}
}
}
if (num != 0) return WarnCorruptSprite(file_slot, file_pos, __LINE__);
sprite->AllocateData(sprite->width * sprite->height);
/* When there are transparency pixels, this format has another trick.. decode it */
if (type & 0x08) {
for (int y = 0; y < sprite->height; y++) {
bool last_item = false;
/* Look up in the header-table where the real data is stored for this row */
int offset = (dest_orig[y * 2 + 1] << 8) | dest_orig[y * 2];
/* Go to that row */
dest = dest_orig + offset;
do {
if (dest + 2 > dest_orig + dest_size) {
free(sprite->data);
return WarnCorruptSprite(file_slot, file_pos, __LINE__);
}
SpriteLoader::CommonPixel *data;
/* Read the header:
* 0 .. 14 - length
* 15 - last_item
* 16 .. 31 - transparency bytes */
last_item = ((*dest) & 0x80) != 0;
int length = (*dest++) & 0x7F;
int skip = *dest++;
data = &sprite->data[y * sprite->width + skip];
if (skip + length > sprite->width || dest + length > dest_orig + dest_size) {
free(sprite->data);
return WarnCorruptSprite(file_slot, file_pos, __LINE__);
}
for (int x = 0; x < length; x++) {
switch (sprite_type) {
case ST_NORMAL: data->m = _palette_remap_grf[file_slot] ? _palmap_w2d[*dest] : *dest; break;
case ST_FONT: data->m = min(*dest, 2u); break;
default: data->m = *dest; break;
}
dest++;
data++;
}
} while (!last_item);
}
} else {
if (dest_size < sprite->width * sprite->height) {
free(sprite->data);
return WarnCorruptSprite(file_slot, file_pos, __LINE__);
}
if (dest_size > sprite->width * sprite->height) {
static byte warning_level = 0;
DEBUG(sprite, warning_level, "Ignoring %i unused extra bytes from the sprite from %s at position %i", dest_size - sprite->width * sprite->height, FioGetFilename(file_slot), (int)file_pos);
warning_level = 6;
}
dest = dest_orig;
for (int i = 0; i < sprite->width * sprite->height; i++) {
switch (sprite_type) {
case ST_NORMAL: sprite->data[i].m = _palette_remap_grf[file_slot] ? _palmap_w2d[dest[i]] : dest[i]; break;
case ST_FONT: sprite->data[i].m = min(dest[i], 2u); break;
default: sprite->data[i].m = dest[i]; break;
}
}
}
/* Make sure to mark all transparent pixels transparent on the alpha channel too */
for (int i = 0; i < sprite->width * sprite->height; i++) {
if (sprite->data[i].m != 0) sprite->data[i].a = 0xFF;
}
return true;
}
|