author | miham |
Tue, 15 Jul 2008 23:27:28 +0000 | |
changeset 11149 | f3ff534dded8 |
parent 11134 | c40cabfe69a5 |
permissions | -rw-r--r-- |
2186 | 1 |
/* $Id$ */ |
2 |
||
10429
1b99254f9607
(svn r12971) -Documentation: add @file in files that missed them and add something more than whitespace as description of files that don't have a description.
rubidium
parents:
9237
diff
changeset
|
3 |
/** @file spritecache.cpp Caching of sprites. */ |
6916
e87d54a598ea
(svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents:
6574
diff
changeset
|
4 |
|
0 | 5 |
#include "stdafx.h" |
1891
92a3b0aa0946
(svn r2397) - CodeChange: rename all "ttd" files to "openttd" files.
Darkvater
parents:
1844
diff
changeset
|
6 |
#include "openttd.h" |
7392
a716551b0c7f
(svn r10143) -Add: store the filename of the grfs opened and allow easy access to the name
truelight
parents:
7365
diff
changeset
|
7 |
#include "variables.h" |
1299
0a6510cc889b
(svn r1803) Move debugging stuff into files of it's own
tron
parents:
1250
diff
changeset
|
8 |
#include "debug.h" |
1349
07514c2cc6d1
(svn r1853) Move spritecache function declarations into a header of their own and use SpriteID as parameter type where appropriate
tron
parents:
1348
diff
changeset
|
9 |
#include "spritecache.h" |
0 | 10 |
#include "fileio.h" |
7348
becce3f57dc7
(svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
7299
diff
changeset
|
11 |
#include "spriteloader/grf.hpp" |
8626
440dfcd14c4a
(svn r11691) -Codechange: move+rename helpers.hpp and only include it when it is really needed.
rubidium
parents:
8609
diff
changeset
|
12 |
#include "core/alloc_func.hpp" |
8627
448ebf3a8291
(svn r11692) -Codechange: move some functions from 'functions.h' to a more logical place and remove about 50% of the includes of 'functions.h'
rubidium
parents:
8626
diff
changeset
|
13 |
#include "core/math_func.hpp" |
7397
d371cc0fbb3c
(svn r10148) -Fix r10143: make --without-png to compile again
truelight
parents:
7392
diff
changeset
|
14 |
#ifdef WITH_PNG |
7392
a716551b0c7f
(svn r10143) -Add: store the filename of the grfs opened and allow easy access to the name
truelight
parents:
7365
diff
changeset
|
15 |
#include "spriteloader/png.hpp" |
7397
d371cc0fbb3c
(svn r10148) -Fix r10143: make --without-png to compile again
truelight
parents:
7392
diff
changeset
|
16 |
#endif /* WITH_PNG */ |
7433
8e410e7ec0d7
(svn r10190) -Codechange: merged renderer and blitter to one single class API: blitter
truelight
parents:
7404
diff
changeset
|
17 |
#include "blitter/factory.hpp" |
7299
74e163f03bbc
(svn r10042) -Codechange: Replace hardcoded spritecache size with a configuration
peter1138
parents:
7295
diff
changeset
|
18 |
|
8760
ce0891c412ce
(svn r11828) -Codechange: include table/* as the last includes and remove an unneeded include from openttd.h.
rubidium
parents:
8710
diff
changeset
|
19 |
#include "table/sprites.h" |
ce0891c412ce
(svn r11828) -Codechange: include table/* as the last includes and remove an unneeded include from openttd.h.
rubidium
parents:
8710
diff
changeset
|
20 |
|
7348
becce3f57dc7
(svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
7299
diff
changeset
|
21 |
/* Default of 4MB spritecache */ |
becce3f57dc7
(svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
7299
diff
changeset
|
22 |
uint _sprite_cache_size = 4; |
0 | 23 |
|
24 |
||
6574
e1d1a12faaf7
(svn r9051) -Codechange: typedef [enum|struct] Y {} X; -> [enum|struct] X {};
rubidium
parents:
6573
diff
changeset
|
25 |
struct SpriteCache { |
9237 | 26 |
void *ptr; |
11116
879c1c2d3db3
(svn r13674) -Fix [FS#2127]: crash when drawing a non-real sprite. The drawing of the non-real sprite is caused when two NewGRFs replace the same sprite and the first replaces it with a real sprite (and thus assumes it remains a real sprite) and the second replaces it with a non-real sprite. OpenTTD already looked at whether the sprite to load should be seen as a real or non-real sprite, but it failed to replace non-real sprites with a substitute real sprite when getting the sprite from the cache.
rubidium
parents:
10839
diff
changeset
|
27 |
size_t file_pos; |
7392
a716551b0c7f
(svn r10143) -Add: store the filename of the grfs opened and allow easy access to the name
truelight
parents:
7365
diff
changeset
|
28 |
uint32 id; |
8869
1e62a45d7599
(svn r11939) -Codechange: some type fixes and very initial steps into supporting NDS by default. Based on work by Dominik.
rubidium
parents:
8760
diff
changeset
|
29 |
uint16 file_slot; |
9237 | 30 |
int16 lru; |
11116
879c1c2d3db3
(svn r13674) -Fix [FS#2127]: crash when drawing a non-real sprite. The drawing of the non-real sprite is caused when two NewGRFs replace the same sprite and the first replaces it with a real sprite (and thus assumes it remains a real sprite) and the second replaces it with a non-real sprite. OpenTTD already looked at whether the sprite to load should be seen as a real or non-real sprite, but it failed to replace non-real sprites with a substitute real sprite when getting the sprite from the cache.
rubidium
parents:
10839
diff
changeset
|
31 |
bool real_sprite; ///< In some cases a single sprite is misused by two NewGRFs. Once as real sprite and once as non-real sprite. If the non-real sprite gets into the cache it might be drawn as real sprite which causes enormous trouble. |
6574
e1d1a12faaf7
(svn r9051) -Codechange: typedef [enum|struct] Y {} X; -> [enum|struct] X {};
rubidium
parents:
6573
diff
changeset
|
32 |
}; |
5755
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
33 |
|
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
34 |
|
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
35 |
static uint _spritecache_items = 0; |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
36 |
static SpriteCache *_spritecache = NULL; |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
37 |
|
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
38 |
|
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
39 |
static inline SpriteCache *GetSpriteCache(uint index) |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
40 |
{ |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
41 |
return &_spritecache[index]; |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
42 |
} |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
43 |
|
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
44 |
|
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
45 |
static SpriteCache *AllocateSpriteCache(uint index) |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
46 |
{ |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
47 |
if (index >= _spritecache_items) { |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
48 |
/* Add another 1024 items to the 'pool' */ |
8423
8453e9a0f0b5
(svn r11480) -Codechange: Rename the function ALIGN fitting to the naming style
skidd13
parents:
8072
diff
changeset
|
49 |
uint items = Align(index + 1, 1024); |
5755
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
50 |
|
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
51 |
DEBUG(sprite, 4, "Increasing sprite cache to %d items (%d bytes)", items, items * sizeof(*_spritecache)); |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
52 |
|
5860
7fdc9b423ba1
(svn r8066) - Codechange: MallocT(), CallocT(), ReallocT() now return the pointer to allocated memory instead of modifying the pointer given as parameter
KUDr
parents:
5838
diff
changeset
|
53 |
_spritecache = ReallocT(_spritecache, items); |
5755
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
54 |
|
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
55 |
/* Reset the new items and update the count */ |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
56 |
memset(_spritecache + _spritecache_items, 0, (items - _spritecache_items) * sizeof(*_spritecache)); |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
57 |
_spritecache_items = items; |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
58 |
} |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
59 |
|
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
60 |
return GetSpriteCache(index); |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
61 |
} |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
62 |
|
0 | 63 |
|
6574
e1d1a12faaf7
(svn r9051) -Codechange: typedef [enum|struct] Y {} X; -> [enum|struct] X {};
rubidium
parents:
6573
diff
changeset
|
64 |
struct MemBlock { |
10465
0c68afe3d725
(svn r13008) -Fix [FS#1997]: silence some MSVC x64 warnings
glx
parents:
10429
diff
changeset
|
65 |
size_t size; |
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
66 |
byte data[VARARRAY_SIZE]; |
6574
e1d1a12faaf7
(svn r9051) -Codechange: typedef [enum|struct] Y {} X; -> [enum|struct] X {};
rubidium
parents:
6573
diff
changeset
|
67 |
}; |
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
68 |
|
0 | 69 |
static uint _sprite_lru_counter; |
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
70 |
static MemBlock *_spritecache_ptr; |
0 | 71 |
static int _compact_cache_counter; |
72 |
||
6573 | 73 |
static void CompactSpriteCache(); |
0 | 74 |
|
6573 | 75 |
static bool ReadSpriteHeaderSkipData() |
0 | 76 |
{ |
2329
f68428464540
(svn r2855) Make ReadSpriteHeaderSkipData() responsible for detecting the end of a grf file instead of its callers - this simplifies the code a bit
tron
parents:
2321
diff
changeset
|
77 |
uint16 num = FioReadWord(); |
0 | 78 |
byte type; |
79 |
||
2329
f68428464540
(svn r2855) Make ReadSpriteHeaderSkipData() responsible for detecting the end of a grf file instead of its callers - this simplifies the code a bit
tron
parents:
2321
diff
changeset
|
80 |
if (num == 0) return false; |
f68428464540
(svn r2855) Make ReadSpriteHeaderSkipData() responsible for detecting the end of a grf file instead of its callers - this simplifies the code a bit
tron
parents:
2321
diff
changeset
|
81 |
|
0 | 82 |
type = FioReadByte(); |
83 |
if (type == 0xFF) { |
|
2342
c19fb4f2df30
(svn r2868) Change the way NewGRFs are loaded: The loading process i no longer bolted onto the normal graphics loading.
tron
parents:
2340
diff
changeset
|
84 |
FioSkipBytes(num); |
5150
247343201280
(svn r7242) -Fix: Don't load 1-byte pseudo sprites, as used in some NewGRF sets. If the sprite is ever drawn this will result in a "missing sprite" error instead of undefined misbehaviour leading to segmentation faults...
peter1138
parents:
4522
diff
changeset
|
85 |
/* Some NewGRF files have "empty" pseudo-sprites which are 1 |
247343201280
(svn r7242) -Fix: Don't load 1-byte pseudo sprites, as used in some NewGRF sets. If the sprite is ever drawn this will result in a "missing sprite" error instead of undefined misbehaviour leading to segmentation faults...
peter1138
parents:
4522
diff
changeset
|
86 |
* byte long. Catch these so the sprites won't be displayed. */ |
247343201280
(svn r7242) -Fix: Don't load 1-byte pseudo sprites, as used in some NewGRF sets. If the sprite is ever drawn this will result in a "missing sprite" error instead of undefined misbehaviour leading to segmentation faults...
peter1138
parents:
4522
diff
changeset
|
87 |
return num != 1; |
0 | 88 |
} |
184
dbeaaaf8b2bb
(svn r185) -Fix: [1016954] Cached_sprites does now work again
truelight
parents:
182
diff
changeset
|
89 |
|
0 | 90 |
FioSkipBytes(7); |
91 |
num -= 8; |
|
2329
f68428464540
(svn r2855) Make ReadSpriteHeaderSkipData() responsible for detecting the end of a grf file instead of its callers - this simplifies the code a bit
tron
parents:
2321
diff
changeset
|
92 |
if (num == 0) return true; |
0 | 93 |
|
94 |
if (type & 2) { |
|
95 |
FioSkipBytes(num); |
|
1355 | 96 |
} else { |
97 |
while (num > 0) { |
|
98 |
int8 i = FioReadByte(); |
|
99 |
if (i >= 0) { |
|
100 |
num -= i; |
|
101 |
FioSkipBytes(i); |
|
102 |
} else { |
|
103 |
i = -(i >> 3); |
|
104 |
num -= i; |
|
105 |
FioReadByte(); |
|
106 |
} |
|
0 | 107 |
} |
108 |
} |
|
2329
f68428464540
(svn r2855) Make ReadSpriteHeaderSkipData() responsible for detecting the end of a grf file instead of its callers - this simplifies the code a bit
tron
parents:
2321
diff
changeset
|
109 |
|
f68428464540
(svn r2855) Make ReadSpriteHeaderSkipData() responsible for detecting the end of a grf file instead of its callers - this simplifies the code a bit
tron
parents:
2321
diff
changeset
|
110 |
return true; |
0 | 111 |
} |
112 |
||
3565
03d870cc3dcd
(svn r4446) - Add function to determine if a Sprite ID exists.
peter1138
parents:
2548
diff
changeset
|
113 |
/* Check if the given Sprite ID exists */ |
03d870cc3dcd
(svn r4446) - Add function to determine if a Sprite ID exists.
peter1138
parents:
2548
diff
changeset
|
114 |
bool SpriteExists(SpriteID id) |
03d870cc3dcd
(svn r4446) - Add function to determine if a Sprite ID exists.
peter1138
parents:
2548
diff
changeset
|
115 |
{ |
03d870cc3dcd
(svn r4446) - Add function to determine if a Sprite ID exists.
peter1138
parents:
2548
diff
changeset
|
116 |
/* Special case for Sprite ID zero -- its position is also 0... */ |
5755
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
117 |
if (id == 0) return true; |
5953
7000c5bdd70b
(svn r8166) -Fix (r7797): Protect against out of bounds access to the sprite ptr
peter1138
parents:
5860
diff
changeset
|
118 |
if (id >= _spritecache_items) return false; |
8072
417f041eaee8
(svn r11101) -Fix r11099: the check: file_pos == 0, no longer works; adjust the check with file_slot. This solves the ? sprites with autorail (nice catch Progman)
truelight
parents:
8066
diff
changeset
|
119 |
return !(GetSpriteCache(id)->file_pos == 0 && GetSpriteCache(id)->file_slot == 0); |
3565
03d870cc3dcd
(svn r4446) - Add function to determine if a Sprite ID exists.
peter1138
parents:
2548
diff
changeset
|
120 |
} |
03d870cc3dcd
(svn r4446) - Add function to determine if a Sprite ID exists.
peter1138
parents:
2548
diff
changeset
|
121 |
|
7348
becce3f57dc7
(svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
7299
diff
changeset
|
122 |
void* AllocSprite(size_t); |
2014
0230ed9186bc
(svn r2522) Reorganize sprite load and decompression in order to remove a special case from the sprite blitter, which decompressed certain sprites every time when blitting them
tron
parents:
1891
diff
changeset
|
123 |
|
7365
d484a635f91d
(svn r10109) -Fix [FS#838]: some NewGRFs use the same (unused in the "current" climate) sprite IDs. Normally this gives some artefacts, but when one NewGRF expects it to be a sprite and another NewGRF overwrites it with a non-sprite nasty things happen (drawing a non-sprite crashes OTTD).
rubidium
parents:
7361
diff
changeset
|
124 |
static void* ReadSprite(SpriteCache *sc, SpriteID id, bool real_sprite) |
0 | 125 |
{ |
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:
7585
diff
changeset
|
126 |
uint8 file_slot = sc->file_slot; |
10751
ebd94f2d6385
(svn r13301) -Fix [FS#1997]: resolve more MSVC 9 x64 warnings.
rubidium
parents:
10465
diff
changeset
|
127 |
size_t file_pos = sc->file_pos; |
2014
0230ed9186bc
(svn r2522) Reorganize sprite load and decompression in order to remove a special case from the sprite blitter, which decompressed certain sprites every time when blitting them
tron
parents:
1891
diff
changeset
|
128 |
|
5568
75f13d7bfaed
(svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents:
5150
diff
changeset
|
129 |
DEBUG(sprite, 9, "Load sprite %d", id); |
184
dbeaaaf8b2bb
(svn r185) -Fix: [1016954] Cached_sprites does now work again
truelight
parents:
182
diff
changeset
|
130 |
|
3565
03d870cc3dcd
(svn r4446) - Add function to determine if a Sprite ID exists.
peter1138
parents:
2548
diff
changeset
|
131 |
if (!SpriteExists(id)) { |
6213
164d84e1c5b4
(svn r8634) -Codechange: replace missing sprites with a red question mark.
rubidium
parents:
5971
diff
changeset
|
132 |
DEBUG(sprite, 1, "Tried to load non-existing sprite #%d. Probable cause: Wrong/missing NewGRFs", id); |
164d84e1c5b4
(svn r8634) -Codechange: replace missing sprites with a red question mark.
rubidium
parents:
5971
diff
changeset
|
133 |
|
164d84e1c5b4
(svn r8634) -Codechange: replace missing sprites with a red question mark.
rubidium
parents:
5971
diff
changeset
|
134 |
/* SPR_IMG_QUERY is a BIG FAT RED ? */ |
164d84e1c5b4
(svn r8634) -Codechange: replace missing sprites with a red question mark.
rubidium
parents:
5971
diff
changeset
|
135 |
id = SPR_IMG_QUERY; |
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:
7585
diff
changeset
|
136 |
file_slot = GetSpriteCache(SPR_IMG_QUERY)->file_slot; |
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:
7585
diff
changeset
|
137 |
file_pos = GetSpriteCache(SPR_IMG_QUERY)->file_pos; |
1378
ebb8d52f0352
(svn r1882) Add a basic check if a non-existent sprite gets accessed.
tron
parents:
1363
diff
changeset
|
138 |
} |
ebb8d52f0352
(svn r1882) Add a basic check if a non-existent sprite gets accessed.
tron
parents:
1363
diff
changeset
|
139 |
|
7399
8e062c789dec
(svn r10150) -Fix r10148: show a message to users when using 32bpp blitter and no libpng available
truelight
parents:
7398
diff
changeset
|
140 |
if (BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth() == 32) { |
7397
d371cc0fbb3c
(svn r10148) -Fix r10143: make --without-png to compile again
truelight
parents:
7392
diff
changeset
|
141 |
#ifdef WITH_PNG |
7392
a716551b0c7f
(svn r10143) -Add: store the filename of the grfs opened and allow easy access to the name
truelight
parents:
7365
diff
changeset
|
142 |
/* Try loading 32bpp graphics in case we are 32bpp output */ |
a716551b0c7f
(svn r10143) -Add: store the filename of the grfs opened and allow easy access to the name
truelight
parents:
7365
diff
changeset
|
143 |
SpriteLoaderPNG sprite_loader; |
a716551b0c7f
(svn r10143) -Add: store the filename of the grfs opened and allow easy access to the name
truelight
parents:
7365
diff
changeset
|
144 |
SpriteLoader::Sprite sprite; |
a716551b0c7f
(svn r10143) -Add: store the filename of the grfs opened and allow easy access to the name
truelight
parents:
7365
diff
changeset
|
145 |
|
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:
8869
diff
changeset
|
146 |
if (sprite_loader.LoadSprite(&sprite, file_slot, sc->id)) { |
7392
a716551b0c7f
(svn r10143) -Add: store the filename of the grfs opened and allow easy access to the name
truelight
parents:
7365
diff
changeset
|
147 |
sc->ptr = BlitterFactoryBase::GetCurrentBlitter()->Encode(&sprite, &AllocSprite); |
a716551b0c7f
(svn r10143) -Add: store the filename of the grfs opened and allow easy access to the name
truelight
parents:
7365
diff
changeset
|
148 |
free(sprite.data); |
a716551b0c7f
(svn r10143) -Add: store the filename of the grfs opened and allow easy access to the name
truelight
parents:
7365
diff
changeset
|
149 |
|
11134
c40cabfe69a5
(svn r13692) -Fix (r13674): loading PNG sprites could very quickly fill the sprite cache.
rubidium
parents:
11116
diff
changeset
|
150 |
sc->real_sprite = true; |
c40cabfe69a5
(svn r13692) -Fix (r13674): loading PNG sprites could very quickly fill the sprite cache.
rubidium
parents:
11116
diff
changeset
|
151 |
|
7392
a716551b0c7f
(svn r10143) -Add: store the filename of the grfs opened and allow easy access to the name
truelight
parents:
7365
diff
changeset
|
152 |
return sc->ptr; |
a716551b0c7f
(svn r10143) -Add: store the filename of the grfs opened and allow easy access to the name
truelight
parents:
7365
diff
changeset
|
153 |
} |
a716551b0c7f
(svn r10143) -Add: store the filename of the grfs opened and allow easy access to the name
truelight
parents:
7365
diff
changeset
|
154 |
/* If the PNG couldn't be loaded, fall back to 8bpp grfs */ |
7399
8e062c789dec
(svn r10150) -Fix r10148: show a message to users when using 32bpp blitter and no libpng available
truelight
parents:
7398
diff
changeset
|
155 |
#else |
8e062c789dec
(svn r10150) -Fix r10148: show a message to users when using 32bpp blitter and no libpng available
truelight
parents:
7398
diff
changeset
|
156 |
static bool show_once = true; |
8e062c789dec
(svn r10150) -Fix r10148: show a message to users when using 32bpp blitter and no libpng available
truelight
parents:
7398
diff
changeset
|
157 |
if (show_once) { |
8e062c789dec
(svn r10150) -Fix r10148: show a message to users when using 32bpp blitter and no libpng available
truelight
parents:
7398
diff
changeset
|
158 |
DEBUG(misc, 0, "You are running a 32bpp blitter, but this build is without libpng support; falling back to 8bpp graphics"); |
8e062c789dec
(svn r10150) -Fix r10148: show a message to users when using 32bpp blitter and no libpng available
truelight
parents:
7398
diff
changeset
|
159 |
show_once = false; |
8e062c789dec
(svn r10150) -Fix r10148: show a message to users when using 32bpp blitter and no libpng available
truelight
parents:
7398
diff
changeset
|
160 |
} |
8e062c789dec
(svn r10150) -Fix r10148: show a message to users when using 32bpp blitter and no libpng available
truelight
parents:
7398
diff
changeset
|
161 |
#endif /* WITH_PNG */ |
7392
a716551b0c7f
(svn r10143) -Add: store the filename of the grfs opened and allow easy access to the name
truelight
parents:
7365
diff
changeset
|
162 |
} |
a716551b0c7f
(svn r10143) -Add: store the filename of the grfs opened and allow easy access to the name
truelight
parents:
7365
diff
changeset
|
163 |
|
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:
7585
diff
changeset
|
164 |
FioSeekToFile(file_slot, file_pos); |
1354
5e5c89b9b169
(svn r1858) Let ReadSprite() handle the subtleties of loading a sprite, not its caller
tron
parents:
1353
diff
changeset
|
165 |
|
7348
becce3f57dc7
(svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
7299
diff
changeset
|
166 |
/* Read the size and type */ |
becce3f57dc7
(svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
7299
diff
changeset
|
167 |
int num = FioReadWord(); |
becce3f57dc7
(svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
7299
diff
changeset
|
168 |
byte type = FioReadByte(); |
becce3f57dc7
(svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
7299
diff
changeset
|
169 |
/* Type 0xFF indicates either a colormap or some other non-sprite info */ |
2014
0230ed9186bc
(svn r2522) Reorganize sprite load and decompression in order to remove a special case from the sprite blitter, which decompressed certain sprites every time when blitting them
tron
parents:
1891
diff
changeset
|
170 |
if (type == 0xFF) { |
7365
d484a635f91d
(svn r10109) -Fix [FS#838]: some NewGRFs use the same (unused in the "current" climate) sprite IDs. Normally this gives some artefacts, but when one NewGRF expects it to be a sprite and another NewGRF overwrites it with a non-sprite nasty things happen (drawing a non-sprite crashes OTTD).
rubidium
parents:
7361
diff
changeset
|
171 |
if (real_sprite) { |
d484a635f91d
(svn r10109) -Fix [FS#838]: some NewGRFs use the same (unused in the "current" climate) sprite IDs. Normally this gives some artefacts, but when one NewGRF expects it to be a sprite and another NewGRF overwrites it with a non-sprite nasty things happen (drawing a non-sprite crashes OTTD).
rubidium
parents:
7361
diff
changeset
|
172 |
static byte warning_level = 0; |
d484a635f91d
(svn r10109) -Fix [FS#838]: some NewGRFs use the same (unused in the "current" climate) sprite IDs. Normally this gives some artefacts, but when one NewGRF expects it to be a sprite and another NewGRF overwrites it with a non-sprite nasty things happen (drawing a non-sprite crashes OTTD).
rubidium
parents:
7361
diff
changeset
|
173 |
DEBUG(sprite, warning_level, "Tried to load non sprite #%d as a real sprite. Probable cause: NewGRF interference", id); |
d484a635f91d
(svn r10109) -Fix [FS#838]: some NewGRFs use the same (unused in the "current" climate) sprite IDs. Normally this gives some artefacts, but when one NewGRF expects it to be a sprite and another NewGRF overwrites it with a non-sprite nasty things happen (drawing a non-sprite crashes OTTD).
rubidium
parents:
7361
diff
changeset
|
174 |
warning_level = 6; |
10839
a62547c31fdb
(svn r13390) -Codechange: introduce usererror() for fatal but not openttd related errors. Now all error() will 'crash' openttd after showing the message in win32 releases (MSVC), creating a crash.log and crash.dmp (like the '!' hack used before). On the other hand, usererror() will just close the game. So use error() only when it can be helpful to debugging, else use usererror().
glx
parents:
10751
diff
changeset
|
175 |
if (id == SPR_IMG_QUERY) usererror("Uhm, would you be so kind not to load a NewGRF that makes the 'query' sprite a non- sprite?"); |
7365
d484a635f91d
(svn r10109) -Fix [FS#838]: some NewGRFs use the same (unused in the "current" climate) sprite IDs. Normally this gives some artefacts, but when one NewGRF expects it to be a sprite and another NewGRF overwrites it with a non-sprite nasty things happen (drawing a non-sprite crashes OTTD).
rubidium
parents:
7361
diff
changeset
|
176 |
return (void*)GetSprite(SPR_IMG_QUERY); |
d484a635f91d
(svn r10109) -Fix [FS#838]: some NewGRFs use the same (unused in the "current" climate) sprite IDs. Normally this gives some artefacts, but when one NewGRF expects it to be a sprite and another NewGRF overwrites it with a non-sprite nasty things happen (drawing a non-sprite crashes OTTD).
rubidium
parents:
7361
diff
changeset
|
177 |
} |
d484a635f91d
(svn r10109) -Fix [FS#838]: some NewGRFs use the same (unused in the "current" climate) sprite IDs. Normally this gives some artefacts, but when one NewGRF expects it to be a sprite and another NewGRF overwrites it with a non-sprite nasty things happen (drawing a non-sprite crashes OTTD).
rubidium
parents:
7361
diff
changeset
|
178 |
|
7348
becce3f57dc7
(svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
7299
diff
changeset
|
179 |
byte *dest = (byte *)AllocSprite(num); |
2014
0230ed9186bc
(svn r2522) Reorganize sprite load and decompression in order to remove a special case from the sprite blitter, which decompressed certain sprites every time when blitting them
tron
parents:
1891
diff
changeset
|
180 |
|
5755
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
181 |
sc->ptr = dest; |
11116
879c1c2d3db3
(svn r13674) -Fix [FS#2127]: crash when drawing a non-real sprite. The drawing of the non-real sprite is caused when two NewGRFs replace the same sprite and the first replaces it with a real sprite (and thus assumes it remains a real sprite) and the second replaces it with a non-real sprite. OpenTTD already looked at whether the sprite to load should be seen as a real or non-real sprite, but it failed to replace non-real sprites with a substitute real sprite when getting the sprite from the cache.
rubidium
parents:
10839
diff
changeset
|
182 |
sc->real_sprite = false; |
2014
0230ed9186bc
(svn r2522) Reorganize sprite load and decompression in order to remove a special case from the sprite blitter, which decompressed certain sprites every time when blitting them
tron
parents:
1891
diff
changeset
|
183 |
FioReadBlock(dest, num); |
0230ed9186bc
(svn r2522) Reorganize sprite load and decompression in order to remove a special case from the sprite blitter, which decompressed certain sprites every time when blitting them
tron
parents:
1891
diff
changeset
|
184 |
|
7361
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
185 |
return sc->ptr; |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
186 |
} |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
187 |
/* Ugly hack to work around the problem that the old landscape |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
188 |
* generator assumes that those sprites are stored uncompressed in |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
189 |
* the memory, and they are only read directly by the code, never |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
190 |
* send to the blitter. So do not send it to the blitter (which will |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
191 |
* result in a data array in the format the blitter likes most), but |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
192 |
* read the data directly from disk and store that as sprite. |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
193 |
* Ugly: yes. Other solution: no. Blame the original author or |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
194 |
* something ;) The image should really have been a data-stream |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
195 |
* (so type = 0xFF basicly). */ |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
196 |
if (id >= 4845 && id <= 4881) { |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
197 |
uint height = FioReadByte(); |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
198 |
uint width = FioReadWord(); |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
199 |
Sprite *sprite; |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
200 |
byte *dest; |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
201 |
|
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
202 |
num = width * height; |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
203 |
sprite = (Sprite *)AllocSprite(sizeof(*sprite) + num); |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
204 |
sc->ptr = sprite; |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
205 |
sprite->height = height; |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
206 |
sprite->width = width; |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
207 |
sprite->x_offs = FioReadWord(); |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
208 |
sprite->y_offs = FioReadWord(); |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
209 |
|
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
210 |
dest = sprite->data; |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
211 |
while (num > 0) { |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
212 |
int8 i = FioReadByte(); |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
213 |
if (i >= 0) { |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
214 |
num -= i; |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
215 |
for (; i > 0; --i) *dest++ = FioReadByte(); |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
216 |
} else { |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
217 |
const byte* rel = dest - (((i & 7) << 8) | FioReadByte()); |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
218 |
i = -(i >> 3); |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
219 |
num -= i; |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
220 |
for (; i > 0; --i) *dest++ = *rel++; |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
221 |
} |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
222 |
} |
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
223 |
|
11116
879c1c2d3db3
(svn r13674) -Fix [FS#2127]: crash when drawing a non-real sprite. The drawing of the non-real sprite is caused when two NewGRFs replace the same sprite and the first replaces it with a real sprite (and thus assumes it remains a real sprite) and the second replaces it with a non-real sprite. OpenTTD already looked at whether the sprite to load should be seen as a real or non-real sprite, but it failed to replace non-real sprites with a substitute real sprite when getting the sprite from the cache.
rubidium
parents:
10839
diff
changeset
|
224 |
sc->real_sprite = false; |
879c1c2d3db3
(svn r13674) -Fix [FS#2127]: crash when drawing a non-real sprite. The drawing of the non-real sprite is caused when two NewGRFs replace the same sprite and the first replaces it with a real sprite (and thus assumes it remains a real sprite) and the second replaces it with a non-real sprite. OpenTTD already looked at whether the sprite to load should be seen as a real or non-real sprite, but it failed to replace non-real sprites with a substitute real sprite when getting the sprite from the cache.
rubidium
parents:
10839
diff
changeset
|
225 |
|
7361
8314452833ad
(svn r10105) -Fix r10092: fix sprite 4845 till 4881 (inclusive), so they store the data as on the disk in the memory, as the old landscape generate assumes this. Talking about ugly hacks...
truelight
parents:
7352
diff
changeset
|
226 |
return sc->ptr; |
7348
becce3f57dc7
(svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
7299
diff
changeset
|
227 |
} |
2014
0230ed9186bc
(svn r2522) Reorganize sprite load and decompression in order to remove a special case from the sprite blitter, which decompressed certain sprites every time when blitting them
tron
parents:
1891
diff
changeset
|
228 |
|
11116
879c1c2d3db3
(svn r13674) -Fix [FS#2127]: crash when drawing a non-real sprite. The drawing of the non-real sprite is caused when two NewGRFs replace the same sprite and the first replaces it with a real sprite (and thus assumes it remains a real sprite) and the second replaces it with a non-real sprite. OpenTTD already looked at whether the sprite to load should be seen as a real or non-real sprite, but it failed to replace non-real sprites with a substitute real sprite when getting the sprite from the cache.
rubidium
parents:
10839
diff
changeset
|
229 |
sc->real_sprite = true; |
879c1c2d3db3
(svn r13674) -Fix [FS#2127]: crash when drawing a non-real sprite. The drawing of the non-real sprite is caused when two NewGRFs replace the same sprite and the first replaces it with a real sprite (and thus assumes it remains a real sprite) and the second replaces it with a non-real sprite. OpenTTD already looked at whether the sprite to load should be seen as a real or non-real sprite, but it failed to replace non-real sprites with a substitute real sprite when getting the sprite from the cache.
rubidium
parents:
10839
diff
changeset
|
230 |
|
7365
d484a635f91d
(svn r10109) -Fix [FS#838]: some NewGRFs use the same (unused in the "current" climate) sprite IDs. Normally this gives some artefacts, but when one NewGRF expects it to be a sprite and another NewGRF overwrites it with a non-sprite nasty things happen (drawing a non-sprite crashes OTTD).
rubidium
parents:
7361
diff
changeset
|
231 |
if (!real_sprite) { |
d484a635f91d
(svn r10109) -Fix [FS#838]: some NewGRFs use the same (unused in the "current" climate) sprite IDs. Normally this gives some artefacts, but when one NewGRF expects it to be a sprite and another NewGRF overwrites it with a non-sprite nasty things happen (drawing a non-sprite crashes OTTD).
rubidium
parents:
7361
diff
changeset
|
232 |
static byte warning_level = 0; |
d484a635f91d
(svn r10109) -Fix [FS#838]: some NewGRFs use the same (unused in the "current" climate) sprite IDs. Normally this gives some artefacts, but when one NewGRF expects it to be a sprite and another NewGRF overwrites it with a non-sprite nasty things happen (drawing a non-sprite crashes OTTD).
rubidium
parents:
7361
diff
changeset
|
233 |
DEBUG(sprite, warning_level, "Tried to load real sprite #%d as a non sprite. Probable cause: NewGRF interference", id); |
d484a635f91d
(svn r10109) -Fix [FS#838]: some NewGRFs use the same (unused in the "current" climate) sprite IDs. Normally this gives some artefacts, but when one NewGRF expects it to be a sprite and another NewGRF overwrites it with a non-sprite nasty things happen (drawing a non-sprite crashes OTTD).
rubidium
parents:
7361
diff
changeset
|
234 |
warning_level = 6; |
d484a635f91d
(svn r10109) -Fix [FS#838]: some NewGRFs use the same (unused in the "current" climate) sprite IDs. Normally this gives some artefacts, but when one NewGRF expects it to be a sprite and another NewGRF overwrites it with a non-sprite nasty things happen (drawing a non-sprite crashes OTTD).
rubidium
parents:
7361
diff
changeset
|
235 |
} |
d484a635f91d
(svn r10109) -Fix [FS#838]: some NewGRFs use the same (unused in the "current" climate) sprite IDs. Normally this gives some artefacts, but when one NewGRF expects it to be a sprite and another NewGRF overwrites it with a non-sprite nasty things happen (drawing a non-sprite crashes OTTD).
rubidium
parents:
7361
diff
changeset
|
236 |
|
7348
becce3f57dc7
(svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
7299
diff
changeset
|
237 |
SpriteLoaderGrf sprite_loader; |
becce3f57dc7
(svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
7299
diff
changeset
|
238 |
SpriteLoader::Sprite sprite; |
0 | 239 |
|
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:
8869
diff
changeset
|
240 |
if (!sprite_loader.LoadSprite(&sprite, file_slot, file_pos)) return NULL; |
7348
becce3f57dc7
(svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
7299
diff
changeset
|
241 |
if (id == 142) sprite.height = 10; // Compensate for a TTD bug |
7352
e2e8432018f6
(svn r10096) -Fix r10092: freetype bypassed the Blitter::Encode, making fonts look weird
truelight
parents:
7348
diff
changeset
|
242 |
sc->ptr = BlitterFactoryBase::GetCurrentBlitter()->Encode(&sprite, &AllocSprite); |
7348
becce3f57dc7
(svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
7299
diff
changeset
|
243 |
free(sprite.data); |
184
dbeaaaf8b2bb
(svn r185) -Fix: [1016954] Cached_sprites does now work again
truelight
parents:
182
diff
changeset
|
244 |
|
7348
becce3f57dc7
(svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
7299
diff
changeset
|
245 |
return sc->ptr; |
0 | 246 |
} |
247 |
||
248 |
||
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:
7585
diff
changeset
|
249 |
bool LoadNextSprite(int load_index, byte file_slot, uint file_sprite_id) |
0 | 250 |
{ |
5755
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
251 |
SpriteCache *sc; |
10751
ebd94f2d6385
(svn r13301) -Fix [FS#1997]: resolve more MSVC 9 x64 warnings.
rubidium
parents:
10465
diff
changeset
|
252 |
size_t file_pos = FioGetPos(); |
0 | 253 |
|
2342
c19fb4f2df30
(svn r2868) Change the way NewGRFs are loaded: The loading process i no longer bolted onto the normal graphics loading.
tron
parents:
2340
diff
changeset
|
254 |
if (!ReadSpriteHeaderSkipData()) return false; |
361
ad7a042ee0eb
(svn r549) -newgrf: Support for action 0xd (change a parameter (sorta variable for the GRF scripts)). Based on patch by octo, heavy changes by pasky.
darkvater
parents:
184
diff
changeset
|
255 |
|
3591
05a4b88d875f
(svn r4481) - Fix: Validate the given sprite ID when loading a sprite.
peter1138
parents:
3565
diff
changeset
|
256 |
if (load_index >= MAX_SPRITES) { |
10839
a62547c31fdb
(svn r13390) -Codechange: introduce usererror() for fatal but not openttd related errors. Now all error() will 'crash' openttd after showing the message in win32 releases (MSVC), creating a crash.log and crash.dmp (like the '!' hack used before). On the other hand, usererror() will just close the game. So use error() only when it can be helpful to debugging, else use usererror().
glx
parents:
10751
diff
changeset
|
257 |
usererror("Tried to load too many sprites (#%d; max %d)", load_index, MAX_SPRITES); |
3591
05a4b88d875f
(svn r4481) - Fix: Validate the given sprite ID when loading a sprite.
peter1138
parents:
3565
diff
changeset
|
258 |
} |
05a4b88d875f
(svn r4481) - Fix: Validate the given sprite ID when loading a sprite.
peter1138
parents:
3565
diff
changeset
|
259 |
|
5755
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
260 |
sc = AllocateSpriteCache(load_index); |
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:
7585
diff
changeset
|
261 |
sc->file_slot = file_slot; |
5755
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
262 |
sc->file_pos = file_pos; |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
263 |
sc->ptr = NULL; |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
264 |
sc->lru = 0; |
7404
fc0559157f16
(svn r10157) -Fix: use as indentified for PNGs, the place of the image as it was in the grf, not the internal SpriteID
truelight
parents:
7399
diff
changeset
|
265 |
sc->id = file_sprite_id; |
11116
879c1c2d3db3
(svn r13674) -Fix [FS#2127]: crash when drawing a non-real sprite. The drawing of the non-real sprite is caused when two NewGRFs replace the same sprite and the first replaces it with a real sprite (and thus assumes it remains a real sprite) and the second replaces it with a non-real sprite. OpenTTD already looked at whether the sprite to load should be seen as a real or non-real sprite, but it failed to replace non-real sprites with a substitute real sprite when getting the sprite from the cache.
rubidium
parents:
10839
diff
changeset
|
266 |
sc->real_sprite = false; |
7392
a716551b0c7f
(svn r10143) -Add: store the filename of the grfs opened and allow easy access to the name
truelight
parents:
7365
diff
changeset
|
267 |
|
0 | 268 |
return true; |
269 |
} |
|
270 |
||
2407 | 271 |
|
5838
9c3129cb019b
(svn r8038) -Merge: the cpp branch. Effort of KUDr, Celestar, glx, Smoovius, stillunknown and pv2b.
rubidium
parents:
5835
diff
changeset
|
272 |
void DupSprite(SpriteID old_spr, SpriteID new_spr) |
2407 | 273 |
{ |
8931
d84c34673a0f
(svn r12005) -Fix [FS#1717]: possible reading from an invalid pointer. Patch by PhilSophus.
rubidium
parents:
8928
diff
changeset
|
274 |
SpriteCache *scnew = AllocateSpriteCache(new_spr); // may reallocate: so put it first |
5838
9c3129cb019b
(svn r8038) -Merge: the cpp branch. Effort of KUDr, Celestar, glx, Smoovius, stillunknown and pv2b.
rubidium
parents:
5835
diff
changeset
|
275 |
SpriteCache *scold = GetSpriteCache(old_spr); |
5755
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
276 |
|
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:
7585
diff
changeset
|
277 |
scnew->file_slot = scold->file_slot; |
5755
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
278 |
scnew->file_pos = scold->file_pos; |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
279 |
scnew->ptr = NULL; |
7392
a716551b0c7f
(svn r10143) -Add: store the filename of the grfs opened and allow easy access to the name
truelight
parents:
7365
diff
changeset
|
280 |
scnew->id = scold->id; |
11116
879c1c2d3db3
(svn r13674) -Fix [FS#2127]: crash when drawing a non-real sprite. The drawing of the non-real sprite is caused when two NewGRFs replace the same sprite and the first replaces it with a real sprite (and thus assumes it remains a real sprite) and the second replaces it with a non-real sprite. OpenTTD already looked at whether the sprite to load should be seen as a real or non-real sprite, but it failed to replace non-real sprites with a substitute real sprite when getting the sprite from the cache.
rubidium
parents:
10839
diff
changeset
|
281 |
scnew->real_sprite = scold->real_sprite; |
2407 | 282 |
} |
283 |
||
284 |
||
0 | 285 |
#define S_FREE_MASK 1 |
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
286 |
|
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
287 |
static inline MemBlock* NextBlock(MemBlock* block) |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
288 |
{ |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
289 |
return (MemBlock*)((byte*)block + (block->size & ~S_FREE_MASK)); |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
290 |
} |
0 | 291 |
|
10751
ebd94f2d6385
(svn r13301) -Fix [FS#1997]: resolve more MSVC 9 x64 warnings.
rubidium
parents:
10465
diff
changeset
|
292 |
static size_t GetSpriteCacheUsage() |
0 | 293 |
{ |
10751
ebd94f2d6385
(svn r13301) -Fix [FS#1997]: resolve more MSVC 9 x64 warnings.
rubidium
parents:
10465
diff
changeset
|
294 |
size_t tot_size = 0; |
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
295 |
MemBlock* s; |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
296 |
|
9058
b9c3fec968b8
(svn r12140) -Codechange: A bit of code style fixes(Geektoo).
belugas
parents:
8931
diff
changeset
|
297 |
for (s = _spritecache_ptr; s->size != 0; s = NextBlock(s)) { |
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
298 |
if (!(s->size & S_FREE_MASK)) tot_size += s->size; |
9058
b9c3fec968b8
(svn r12140) -Codechange: A bit of code style fixes(Geektoo).
belugas
parents:
8931
diff
changeset
|
299 |
} |
0 | 300 |
|
301 |
return tot_size; |
|
302 |
} |
|
303 |
||
304 |
||
6573 | 305 |
void IncreaseSpriteLRU() |
0 | 306 |
{ |
6916
e87d54a598ea
(svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents:
6574
diff
changeset
|
307 |
/* Increase all LRU values */ |
0 | 308 |
if (_sprite_lru_counter > 16384) { |
5755
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
309 |
SpriteID i; |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
310 |
|
5568
75f13d7bfaed
(svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents:
5150
diff
changeset
|
311 |
DEBUG(sprite, 3, "Fixing lru %d, inuse=%d", _sprite_lru_counter, GetSpriteCacheUsage()); |
0 | 312 |
|
5755
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
313 |
for (i = 0; i != _spritecache_items; i++) { |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
314 |
SpriteCache *sc = GetSpriteCache(i); |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
315 |
if (sc->ptr != NULL) { |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
316 |
if (sc->lru >= 0) { |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
317 |
sc->lru = -1; |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
318 |
} else if (sc->lru != -32768) { |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
319 |
sc->lru--; |
0 | 320 |
} |
321 |
} |
|
5755
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
322 |
} |
0 | 323 |
_sprite_lru_counter = 0; |
324 |
} |
|
325 |
||
6916
e87d54a598ea
(svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents:
6574
diff
changeset
|
326 |
/* Compact sprite cache every now and then. */ |
0 | 327 |
if (++_compact_cache_counter >= 740) { |
328 |
CompactSpriteCache(); |
|
329 |
_compact_cache_counter = 0; |
|
330 |
} |
|
331 |
} |
|
332 |
||
6916
e87d54a598ea
(svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents:
6574
diff
changeset
|
333 |
/** Called when holes in the sprite cache should be removed. |
e87d54a598ea
(svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents:
6574
diff
changeset
|
334 |
* That is accomplished by moving the cached data. */ |
6573 | 335 |
static void CompactSpriteCache() |
0 | 336 |
{ |
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
337 |
MemBlock *s; |
184
dbeaaaf8b2bb
(svn r185) -Fix: [1016954] Cached_sprites does now work again
truelight
parents:
182
diff
changeset
|
338 |
|
5568
75f13d7bfaed
(svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents:
5150
diff
changeset
|
339 |
DEBUG(sprite, 3, "Compacting sprite cache, inuse=%d", GetSpriteCacheUsage()); |
184
dbeaaaf8b2bb
(svn r185) -Fix: [1016954] Cached_sprites does now work again
truelight
parents:
182
diff
changeset
|
340 |
|
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
341 |
for (s = _spritecache_ptr; s->size != 0;) { |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
342 |
if (s->size & S_FREE_MASK) { |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
343 |
MemBlock* next = NextBlock(s); |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
344 |
MemBlock temp; |
5755
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
345 |
SpriteID i; |
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
346 |
|
6916
e87d54a598ea
(svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents:
6574
diff
changeset
|
347 |
/* Since free blocks are automatically coalesced, this should hold true. */ |
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
348 |
assert(!(next->size & S_FREE_MASK)); |
184
dbeaaaf8b2bb
(svn r185) -Fix: [1016954] Cached_sprites does now work again
truelight
parents:
182
diff
changeset
|
349 |
|
6916
e87d54a598ea
(svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents:
6574
diff
changeset
|
350 |
/* If the next block is the sentinel block, we can safely return */ |
9237 | 351 |
if (next->size == 0) break; |
0 | 352 |
|
6916
e87d54a598ea
(svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents:
6574
diff
changeset
|
353 |
/* Locate the sprite belonging to the next pointer. */ |
5755
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
354 |
for (i = 0; GetSpriteCache(i)->ptr != next->data; i++) { |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
355 |
assert(i != _spritecache_items); |
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
356 |
} |
0 | 357 |
|
5755
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
358 |
GetSpriteCache(i)->ptr = s->data; // Adjust sprite array entry |
6916
e87d54a598ea
(svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents:
6574
diff
changeset
|
359 |
/* Swap this and the next block */ |
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
360 |
temp = *s; |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
361 |
memmove(s, next, next->size); |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
362 |
s = NextBlock(s); |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
363 |
*s = temp; |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
364 |
|
6916
e87d54a598ea
(svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents:
6574
diff
changeset
|
365 |
/* Coalesce free blocks */ |
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
366 |
while (NextBlock(s)->size & S_FREE_MASK) { |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
367 |
s->size += NextBlock(s)->size & ~S_FREE_MASK; |
0 | 368 |
} |
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
369 |
} else { |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
370 |
s = NextBlock(s); |
0 | 371 |
} |
372 |
} |
|
373 |
} |
|
374 |
||
6573 | 375 |
static void DeleteEntryFromSpriteCache() |
0 | 376 |
{ |
5755
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
377 |
SpriteID i; |
5838
9c3129cb019b
(svn r8038) -Merge: the cpp branch. Effort of KUDr, Celestar, glx, Smoovius, stillunknown and pv2b.
rubidium
parents:
5835
diff
changeset
|
378 |
uint best = UINT_MAX; |
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
379 |
MemBlock* s; |
0 | 380 |
int cur_lru; |
381 |
||
5568
75f13d7bfaed
(svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents:
5150
diff
changeset
|
382 |
DEBUG(sprite, 3, "DeleteEntryFromSpriteCache, inuse=%d", GetSpriteCacheUsage()); |
0 | 383 |
|
384 |
cur_lru = 0xffff; |
|
5755
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
385 |
for (i = 0; i != _spritecache_items; i++) { |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
386 |
SpriteCache *sc = GetSpriteCache(i); |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
387 |
if (sc->ptr != NULL && sc->lru < cur_lru) { |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
388 |
cur_lru = sc->lru; |
0 | 389 |
best = i; |
390 |
} |
|
391 |
} |
|
392 |
||
6916
e87d54a598ea
(svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents:
6574
diff
changeset
|
393 |
/* Display an error message and die, in case we found no sprite at all. |
e87d54a598ea
(svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents:
6574
diff
changeset
|
394 |
* This shouldn't really happen, unless all sprites are locked. */ |
8536
95419f22b9ab
(svn r11600) -Cleanup: remove extra out-of-memory checks, since it's now done in *allocT functions.
glx
parents:
8533
diff
changeset
|
395 |
if (best == (uint)-1) error("Out of sprite memory"); |
0 | 396 |
|
6916
e87d54a598ea
(svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents:
6574
diff
changeset
|
397 |
/* Mark the block as free (the block must be in use) */ |
5755
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
398 |
s = (MemBlock*)GetSpriteCache(best)->ptr - 1; |
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
399 |
assert(!(s->size & S_FREE_MASK)); |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
400 |
s->size |= S_FREE_MASK; |
5755
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
401 |
GetSpriteCache(best)->ptr = NULL; |
0 | 402 |
|
6916
e87d54a598ea
(svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents:
6574
diff
changeset
|
403 |
/* And coalesce adjacent free blocks */ |
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
404 |
for (s = _spritecache_ptr; s->size != 0; s = NextBlock(s)) { |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
405 |
if (s->size & S_FREE_MASK) { |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
406 |
while (NextBlock(s)->size & S_FREE_MASK) { |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
407 |
s->size += NextBlock(s)->size & ~S_FREE_MASK; |
0 | 408 |
} |
409 |
} |
|
410 |
} |
|
411 |
} |
|
412 |
||
7348
becce3f57dc7
(svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code
truelight
parents:
7299
diff
changeset
|
413 |
void* AllocSprite(size_t mem_req) |
0 | 414 |
{ |
2014
0230ed9186bc
(svn r2522) Reorganize sprite load and decompression in order to remove a special case from the sprite blitter, which decompressed certain sprites every time when blitting them
tron
parents:
1891
diff
changeset
|
415 |
mem_req += sizeof(MemBlock); |
0 | 416 |
|
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
417 |
/* Align this to an uint32 boundary. This also makes sure that the 2 least |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
418 |
* bits are not used, so we could use those for other things. */ |
8423
8453e9a0f0b5
(svn r11480) -Codechange: Rename the function ALIGN fitting to the naming style
skidd13
parents:
8072
diff
changeset
|
419 |
mem_req = Align(mem_req, sizeof(uint32)); |
0 | 420 |
|
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
421 |
for (;;) { |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
422 |
MemBlock* s; |
0 | 423 |
|
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
424 |
for (s = _spritecache_ptr; s->size != 0; s = NextBlock(s)) { |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
425 |
if (s->size & S_FREE_MASK) { |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
426 |
size_t cur_size = s->size & ~S_FREE_MASK; |
0 | 427 |
|
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
428 |
/* Is the block exactly the size we need or |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
429 |
* big enough for an additional free block? */ |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
430 |
if (cur_size == mem_req || |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
431 |
cur_size >= mem_req + sizeof(MemBlock)) { |
6916
e87d54a598ea
(svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents:
6574
diff
changeset
|
432 |
/* Set size and in use */ |
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
433 |
s->size = mem_req; |
184
dbeaaaf8b2bb
(svn r185) -Fix: [1016954] Cached_sprites does now work again
truelight
parents:
182
diff
changeset
|
434 |
|
6916
e87d54a598ea
(svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents:
6574
diff
changeset
|
435 |
/* Do we need to inject a free block too? */ |
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
436 |
if (cur_size != mem_req) { |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
437 |
NextBlock(s)->size = (cur_size - mem_req) | S_FREE_MASK; |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
438 |
} |
0 | 439 |
|
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
440 |
return s->data; |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
441 |
} |
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
442 |
} |
0 | 443 |
} |
444 |
||
6916
e87d54a598ea
(svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents:
6574
diff
changeset
|
445 |
/* Reached sentinel, but no block found yet. Delete some old entry. */ |
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
446 |
DeleteEntryFromSpriteCache(); |
0 | 447 |
} |
448 |
} |
|
449 |
||
450 |
||
7365
d484a635f91d
(svn r10109) -Fix [FS#838]: some NewGRFs use the same (unused in the "current" climate) sprite IDs. Normally this gives some artefacts, but when one NewGRF expects it to be a sprite and another NewGRF overwrites it with a non-sprite nasty things happen (drawing a non-sprite crashes OTTD).
rubidium
parents:
7361
diff
changeset
|
451 |
const void *GetRawSprite(SpriteID sprite, bool real_sprite) |
0 | 452 |
{ |
5755
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
453 |
SpriteCache *sc; |
2014
0230ed9186bc
(svn r2522) Reorganize sprite load and decompression in order to remove a special case from the sprite blitter, which decompressed certain sprites every time when blitting them
tron
parents:
1891
diff
changeset
|
454 |
void* p; |
0 | 455 |
|
5953
7000c5bdd70b
(svn r8166) -Fix (r7797): Protect against out of bounds access to the sprite ptr
peter1138
parents:
5860
diff
changeset
|
456 |
assert(sprite < _spritecache_items); |
0 | 457 |
|
5755
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
458 |
sc = GetSpriteCache(sprite); |
0 | 459 |
|
6916
e87d54a598ea
(svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents:
6574
diff
changeset
|
460 |
/* Update LRU */ |
5755
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
461 |
sc->lru = ++_sprite_lru_counter; |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
462 |
|
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
463 |
p = sc->ptr; |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
464 |
|
6916
e87d54a598ea
(svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents:
6574
diff
changeset
|
465 |
/* Load the sprite, if it is not loaded, yet */ |
11116
879c1c2d3db3
(svn r13674) -Fix [FS#2127]: crash when drawing a non-real sprite. The drawing of the non-real sprite is caused when two NewGRFs replace the same sprite and the first replaces it with a real sprite (and thus assumes it remains a real sprite) and the second replaces it with a non-real sprite. OpenTTD already looked at whether the sprite to load should be seen as a real or non-real sprite, but it failed to replace non-real sprites with a substitute real sprite when getting the sprite from the cache.
rubidium
parents:
10839
diff
changeset
|
466 |
if (p == NULL || sc->real_sprite != real_sprite) p = ReadSprite(sc, sprite, real_sprite); |
9058
b9c3fec968b8
(svn r12140) -Codechange: A bit of code style fixes(Geektoo).
belugas
parents:
8931
diff
changeset
|
467 |
|
184
dbeaaaf8b2bb
(svn r185) -Fix: [1016954] Cached_sprites does now work again
truelight
parents:
182
diff
changeset
|
468 |
return p; |
0 | 469 |
} |
470 |
||
961 | 471 |
|
6573 | 472 |
void GfxInitSpriteMem() |
0 | 473 |
{ |
6916
e87d54a598ea
(svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents:
6574
diff
changeset
|
474 |
/* initialize sprite cache heap */ |
8533
a9b708fe4a00
(svn r11597) -Change: replace all remaining instances of (re|m|c)alloc with (Re|M|C)allocT and add a check for out-of-memory situations to the *allocT functions.
rubidium
parents:
8423
diff
changeset
|
475 |
if (_spritecache_ptr == NULL) _spritecache_ptr = (MemBlock*)MallocT<byte>(_sprite_cache_size * 1024 * 1024); |
0 | 476 |
|
6916
e87d54a598ea
(svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents:
6574
diff
changeset
|
477 |
/* A big free block */ |
7299
74e163f03bbc
(svn r10042) -Codechange: Replace hardcoded spritecache size with a configuration
peter1138
parents:
7295
diff
changeset
|
478 |
_spritecache_ptr->size = ((_sprite_cache_size * 1024 * 1024) - sizeof(MemBlock)) | S_FREE_MASK; |
6916
e87d54a598ea
(svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents:
6574
diff
changeset
|
479 |
/* Sentinel block (identified by size == 0) */ |
1353
48b59d472641
(svn r1857) Rewrite parts of the sprite heap. It's functionally equivalent but should be easier to read and maintain.
tron
parents:
1352
diff
changeset
|
480 |
NextBlock(_spritecache_ptr)->size = 0; |
0 | 481 |
|
5755
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
482 |
/* Reset the spritecache 'pool' */ |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
483 |
free(_spritecache); |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
484 |
_spritecache_items = 0; |
5db1cb757991
(svn r7797) -Codechange: Replace static _sprite_ptr and associated arrays with dynamic array to allow variable number of sprites. This does not change the sprite limit.
peter1138
parents:
5752
diff
changeset
|
485 |
_spritecache = NULL; |
0 | 486 |
|
2340
0a9f3eeccb96
(svn r2866) Move all functions and tables which aren't directly involved in managing the sprite heap to a new file gfxinit.c.
tron
parents:
2339
diff
changeset
|
487 |
_compact_cache_counter = 0; |
0 | 488 |
} |