Files
@ r11976:ae6aa97461b7
Branch filter:
Location: cpp/openttd-patchpack/source/src/spriteloader/grf.cpp - annotation
r11976:ae6aa97461b7
4.9 KiB
text/x-c
(svn r16387) -Codechange: use Aircraft instead of Vehicle where appropriate
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 | r6872:f40beb7256a6 r6872:f40beb7256a6 r9111:983de9c5a848 r6872:f40beb7256a6 r6852:5b6b567a9e32 r8123:dde0a9a84019 r10039:727fb45b0424 r6852:5b6b567a9e32 r8130:bece2e5c7460 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 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 r10359:36d7a611e1f5 r10359:36d7a611e1f5 r10359:36d7a611e1f5 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 r6852:5b6b567a9e32 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 r10062:9a719b26b56e 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 r10062:9a719b26b56e r10062:9a719b26b56e r6852:5b6b567a9e32 r6852:5b6b567a9e32 r6889:9eefa1ce35c6 r6889:9eefa1ce35c6 r6889:9eefa1ce35c6 r6889:9eefa1ce35c6 r6852:5b6b567a9e32 r6852:5b6b567a9e32 | /* $Id$ */
/** @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 "../core/alloc_func.hpp"
#include "../strings_func.h"
#include "table/strings.h"
#include "../gui.h"
#include "grf.hpp"
/**
* 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(INVALID_STRING_ID, STR_NEWGRF_ERROR_CORRUPT_SPRITE, 0, 0);
}
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 an other 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++) {
data->m = ((sprite_type == ST_NORMAL && _palette_remap_grf[file_slot]) ? _palette_remap[*dest] : *dest);
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++) {
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 */
for (int i = 0; i < sprite->width * sprite->height; i++)
if (sprite->data[i].m != 0) sprite->data[i].a = 0xFF;
return true;
}
|