Files @ r9583:b6e25a00b908
Branch filter:

Location: cpp/openttd-patchpack/source/src/spriteloader/grf.cpp - annotation

rubidium
(svn r13621) -Fix: building roadbits in the wrong direction on bridges or building roadbits from underneath the bridge to the bridgehead is impossible, so don't silently ignore that error when building over houses and industries is not ignored.
r6872:f40beb7256a6
r6872:f40beb7256a6
r9111:983de9c5a848
r6872:f40beb7256a6
r6852:5b6b567a9e32
r8123:dde0a9a84019
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r8130:bece2e5c7460
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r9390:aab57f0a7820
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r7570:d6777a99c723
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6889:9eefa1ce35c6
r6889:9eefa1ce35c6
r6889:9eefa1ce35c6
r6889:9eefa1ce35c6
r6852:5b6b567a9e32
r6852:5b6b567a9e32
r6852:5b6b567a9e32
/* $Id$ */

/** @file grf.cpp Reading graphics data from (New)GRF files. */

#include "../stdafx.h"
#include "../gfx_func.h"
#include "../fileio.h"
#include "../debug.h"
#include "../core/alloc_func.hpp"
#include "grf.hpp"

bool SpriteLoaderGrf::LoadSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, size_t file_pos)
{
	/* 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 colormap 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;

	/* XXX -- We should use a pre-located memory segment for this, malloc/free is pretty expensive */
	byte *dest_orig = MallocT<byte>(num);
	byte *dest = dest_orig;

	/* 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;
			for (; size > 0; size--) {
				*dest = FioReadByte();
				dest++;
			}
		} else {
			/* Copy bytes from earlier in the sprite */
			const uint data_offset = ((code & 7) << 8) | FioReadByte();
			int size = -(code >> 3);
			num -= size;
			for (; size > 0; size--) {
				*dest = *(dest - data_offset);
				dest++;
			}
		}
	}

	assert(num == 0);

	sprite->data = CallocT<SpriteLoader::CommonPixel>(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 {
				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];

				for (int x = 0; x < length; x++) {
					data->m = *dest;
					dest++;
					data++;
				}
			} while (!last_item);
		}
	} else {
		dest = dest_orig;
		for (int i = 0; i < sprite->width * sprite->height; i++)
			sprite->data[i].m = 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;

	free(dest_orig);
	return true;
}