src/spriteloader/grf.cpp
author rubidium
Fri, 28 Mar 2008 19:01:57 +0000
branch0.6
changeset 9353 1127b484af20
parent 8870 461ed7760525
child 10429 1b99254f9607
permissions -rw-r--r--
(svn r12478) [0.6] -Backport from trunk (12477, 12453, 12448, 12443, 12439, 12417):
- Fix: Timetable times for aircraft were always doubled [FS#1883] (r12477)
- Fix: Remove broken endian-dependent code and unnecessary rgb to bgr swapping [FS#1880] (r12453)
- Change: Unify RPM spec files (r12448)
- Add: OpenTTD's version to the config file to 'ease' getting the correct version on bugreports (r12443)
- Fix: Do not 'disable' the drawing of autorail overlays when the tile is 'error'-marked (red pulsating selection) [FS#1871] (r12439)
- Fix: Plural rule for Icelandic was wrong (r12417)
7368
c8585746a177 (svn r10113) -Fix (r10092): Missing svn properties and some Id/@file comments
peter1138
parents: 7348
diff changeset
     1
/* $Id$ */
c8585746a177 (svn r10113) -Fix (r10092): Missing svn properties and some Id/@file comments
peter1138
parents: 7348
diff changeset
     2
c8585746a177 (svn r10113) -Fix (r10092): Missing svn properties and some Id/@file comments
peter1138
parents: 7348
diff changeset
     3
/** @file grf.cpp */
c8585746a177 (svn r10113) -Fix (r10092): Missing svn properties and some Id/@file comments
peter1138
parents: 7348
diff changeset
     4
7348
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
     5
#include "../stdafx.h"
8619
c2434269c3eb (svn r11684) -Codechange: split gfx.h in a type and functional header.
rubidium
parents: 8066
diff changeset
     6
#include "../gfx_func.h"
7348
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
     7
#include "../fileio.h"
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
     8
#include "../debug.h"
8626
440dfcd14c4a (svn r11691) -Codechange: move+rename helpers.hpp and only include it when it is really needed.
rubidium
parents: 8619
diff changeset
     9
#include "../core/alloc_func.hpp"
7348
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    10
#include "grf.hpp"
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    11
8870
461ed7760525 (svn r11940) -Codechange: Store short filename once per open file instead of once per sprite cache entry. Not all file types need this, but most of the time no sprite cache entry needed it either.
peter1138
parents: 8626
diff changeset
    12
bool SpriteLoaderGrf::LoadSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, uint32 file_pos)
7348
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    13
{
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    14
	/* Open the right file and go to the correct position */
8066
7acd480e05c9 (svn r11095) -Codechange: don't abuse 'file_pos' by storing the file_slot in it too, but use a nice seperate variable for it
truelight
parents: 7392
diff changeset
    15
	FioSeekToFile(file_slot, file_pos);
7348
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    16
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    17
	/* Read the size and type */
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    18
	int num = FioReadWord();
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    19
	byte type = FioReadByte();
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    20
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    21
	/* Type 0xFF indicates either a colormap or some other non-sprite info; we do not handle them here */
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    22
	if (type == 0xFF) return false;
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    23
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    24
	sprite->height = FioReadByte();
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    25
	sprite->width  = FioReadWord();
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    26
	sprite->x_offs = FioReadWord();
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    27
	sprite->y_offs = FioReadWord();
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    28
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    29
	/* 0x02 indicates it is a compressed sprite, so we can't rely on 'num' to be valid.
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    30
	 *  In case it is uncompressed, the size is 'num' - 8 (header-size). */
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    31
	num = (type & 0x02) ? sprite->width * sprite->height : num - 8;
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    32
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    33
	/* XXX -- We should use a pre-located memory segment for this, malloc/free is pretty expensive */
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    34
	byte *dest_orig = MallocT<byte>(num);
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    35
	byte *dest = dest_orig;
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    36
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    37
	/* Read the file, which has some kind of compression */
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    38
	while (num > 0) {
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    39
		int8 code = FioReadByte();
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    40
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    41
		if (code >= 0) {
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    42
			/* Plain bytes to read */
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    43
			int size = (code == 0) ? 0x80 : code;
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    44
			num -= size;
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    45
			for (; size > 0; size--) {
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    46
				*dest = FioReadByte();
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    47
				dest++;
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    48
			}
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    49
		} else {
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    50
			/* Copy bytes from earlier in the sprite */
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    51
			const uint data_offset = ((code & 7) << 8) | FioReadByte();
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    52
			int size = -(code >> 3);
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    53
			num -= size;
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    54
			for (; size > 0; size--) {
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    55
				*dest = *(dest - data_offset);
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    56
				dest++;
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    57
			}
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    58
		}
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    59
	}
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    60
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    61
	assert(num == 0);
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    62
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    63
	sprite->data = CallocT<SpriteLoader::CommonPixel>(sprite->width * sprite->height);
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    64
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    65
	/* When there are transparency pixels, this format has an other trick.. decode it */
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    66
	if (type & 0x08) {
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    67
		for (int y = 0; y < sprite->height; y++) {
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    68
			bool last_item = false;
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    69
			/* Look up in the header-table where the real data is stored for this row */
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    70
			int offset = (dest_orig[y * 2 + 1] << 8) | dest_orig[y * 2];
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    71
			/* Go to that row */
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    72
			dest = &dest_orig[offset];
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    73
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    74
			do {
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    75
				SpriteLoader::CommonPixel *data;
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    76
				/* Read the header:
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    77
				 *  0 .. 14  - length
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    78
				 *  15       - last_item
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    79
				 *  16 .. 31 - transparency bytes */
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    80
				last_item  = ((*dest) & 0x80) != 0;
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    81
				int length =  (*dest++) & 0x7F;
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    82
				int skip   =   *dest++;
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    83
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    84
				data = &sprite->data[y * sprite->width + skip];
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    85
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    86
				for (int x = 0; x < length; x++) {
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    87
					data->m = *dest;
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    88
					dest++;
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    89
					data++;
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    90
				}
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    91
			} while (!last_item);
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    92
		}
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    93
	} else {
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    94
		dest = dest_orig;
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    95
		for (int i = 0; i < sprite->width * sprite->height; i++)
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    96
			sprite->data[i].m = dest[i];
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    97
	}
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
    98
7385
dc6e404283bc (svn r10132) -Codechange: split out the last direct video-buffer read access to the blitter-layer
truelight
parents: 7368
diff changeset
    99
	/* Make sure to mark all transparent pixels transparent on the alpha channel too */
dc6e404283bc (svn r10132) -Codechange: split out the last direct video-buffer read access to the blitter-layer
truelight
parents: 7368
diff changeset
   100
	for (int i = 0; i < sprite->width * sprite->height; i++)
dc6e404283bc (svn r10132) -Codechange: split out the last direct video-buffer read access to the blitter-layer
truelight
parents: 7368
diff changeset
   101
		if (sprite->data[i].m != 0) sprite->data[i].a = 0xFF;
dc6e404283bc (svn r10132) -Codechange: split out the last direct video-buffer read access to the blitter-layer
truelight
parents: 7368
diff changeset
   102
7348
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
   103
	free(dest_orig);
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
   104
	return true;
becce3f57dc7 (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
diff changeset
   105
}