9 #include "table/sprites.h" |
9 #include "table/sprites.h" |
10 #include "fileio.h" |
10 #include "fileio.h" |
11 |
11 |
12 #define SPRITE_CACHE_SIZE 1024*1024 |
12 #define SPRITE_CACHE_SIZE 1024*1024 |
13 |
13 |
14 #define WANT_NEW_LRU |
|
15 |
|
16 |
14 |
17 static void* _sprite_ptr[MAX_SPRITES]; |
15 static void* _sprite_ptr[MAX_SPRITES]; |
18 static uint32 _sprite_file_pos[MAX_SPRITES]; |
16 static uint32 _sprite_file_pos[MAX_SPRITES]; |
19 |
|
20 #if defined(WANT_NEW_LRU) |
|
21 static int16 _sprite_lru_new[MAX_SPRITES]; |
17 static int16 _sprite_lru_new[MAX_SPRITES]; |
22 #else |
|
23 static uint16 _sprite_lru[MAX_SPRITES]; |
|
24 static uint16 _sprite_lru_cur[MAX_SPRITES]; |
|
25 #endif |
|
26 |
18 |
27 typedef struct MemBlock { |
19 typedef struct MemBlock { |
28 uint32 size; |
20 uint32 size; |
29 byte data[VARARRAY_SIZE]; |
21 byte data[VARARRAY_SIZE]; |
30 } MemBlock; |
22 } MemBlock; |
207 void IncreaseSpriteLRU(void) |
194 void IncreaseSpriteLRU(void) |
208 { |
195 { |
209 int i; |
196 int i; |
210 |
197 |
211 // Increase all LRU values |
198 // Increase all LRU values |
212 #if defined(WANT_NEW_LRU) |
|
213 if (_sprite_lru_counter > 16384) { |
199 if (_sprite_lru_counter > 16384) { |
214 DEBUG(sprite, 3, "Fixing lru %d, inuse=%d", _sprite_lru_counter, GetSpriteCacheUsage()); |
200 DEBUG(sprite, 3, "Fixing lru %d, inuse=%d", _sprite_lru_counter, GetSpriteCacheUsage()); |
215 |
201 |
216 for (i = 0; i != MAX_SPRITES; i++) |
202 for (i = 0; i != MAX_SPRITES; i++) |
217 if (_sprite_ptr[i] != NULL) { |
203 if (_sprite_ptr[i] != NULL) { |
221 _sprite_lru_new[i]--; |
207 _sprite_lru_new[i]--; |
222 } |
208 } |
223 } |
209 } |
224 _sprite_lru_counter = 0; |
210 _sprite_lru_counter = 0; |
225 } |
211 } |
226 #else |
|
227 for (i = 0; i != MAX_SPRITES; i++) |
|
228 if (_sprite_ptr[i] != NULL && _sprite_lru[i] != 65535) |
|
229 _sprite_lru[i]++; |
|
230 // Reset the lru counter. |
|
231 _sprite_lru_counter = 0; |
|
232 #endif |
|
233 |
212 |
234 // Compact sprite cache every now and then. |
213 // Compact sprite cache every now and then. |
235 if (++_compact_cache_counter >= 740) { |
214 if (++_compact_cache_counter >= 740) { |
236 CompactSpriteCache(); |
215 CompactSpriteCache(); |
237 _compact_cache_counter = 0; |
216 _compact_cache_counter = 0; |
288 MemBlock* s; |
267 MemBlock* s; |
289 int cur_lru; |
268 int cur_lru; |
290 |
269 |
291 DEBUG(sprite, 3, "DeleteEntryFromSpriteCache, inuse=%d", GetSpriteCacheUsage()); |
270 DEBUG(sprite, 3, "DeleteEntryFromSpriteCache, inuse=%d", GetSpriteCacheUsage()); |
292 |
271 |
293 #if defined(WANT_NEW_LRU) |
|
294 cur_lru = 0xffff; |
272 cur_lru = 0xffff; |
295 for (i = 0; i != MAX_SPRITES; i++) { |
273 for (i = 0; i != MAX_SPRITES; i++) { |
296 if (_sprite_ptr[i] != NULL && _sprite_lru_new[i] < cur_lru) { |
274 if (_sprite_ptr[i] != NULL && _sprite_lru_new[i] < cur_lru) { |
297 cur_lru = _sprite_lru_new[i]; |
275 cur_lru = _sprite_lru_new[i]; |
298 best = i; |
276 best = i; |
299 } |
277 } |
300 } |
278 } |
301 #else |
|
302 { |
|
303 uint16 cur_lru = 0, cur_lru_cur = 0xffff; |
|
304 for (i = 0; i != MAX_SPRITES; i++) { |
|
305 if (_sprite_ptr[i] == NULL || _sprite_lru[i] < cur_lru) continue; |
|
306 |
|
307 // Found a sprite with a higher LRU value, then remember it. |
|
308 if (_sprite_lru[i] != cur_lru) { |
|
309 cur_lru = _sprite_lru[i]; |
|
310 best = i; |
|
311 |
|
312 // Else if both sprites were very recently referenced, compare by the cur value instead. |
|
313 } else if (cur_lru == 0 && _sprite_lru_cur[i] <= cur_lru_cur) { |
|
314 cur_lru_cur = _sprite_lru_cur[i]; |
|
315 cur_lru = _sprite_lru[i]; |
|
316 best = i; |
|
317 } |
|
318 } |
|
319 } |
|
320 #endif |
|
321 |
279 |
322 // Display an error message and die, in case we found no sprite at all. |
280 // Display an error message and die, in case we found no sprite at all. |
323 // This shouldn't really happen, unless all sprites are locked. |
281 // This shouldn't really happen, unless all sprites are locked. |
324 if (best == -1) |
282 if (best == -1) |
325 error("Out of sprite memory"); |
283 error("Out of sprite memory"); |
429 #if defined(NEW_ROTATION) |
387 #if defined(NEW_ROTATION) |
430 sprite = RotateSprite(sprite); |
388 sprite = RotateSprite(sprite); |
431 #endif |
389 #endif |
432 |
390 |
433 // Update LRU |
391 // Update LRU |
434 #if defined(WANT_NEW_LRU) |
|
435 _sprite_lru_new[sprite] = ++_sprite_lru_counter; |
392 _sprite_lru_new[sprite] = ++_sprite_lru_counter; |
436 #else |
|
437 _sprite_lru_cur[sprite] = ++_sprite_lru_counter; |
|
438 _sprite_lru[sprite] = 0; |
|
439 #endif |
|
440 |
393 |
441 p = _sprite_ptr[sprite]; |
394 p = _sprite_ptr[sprite]; |
442 // Load the sprite, if it is not loaded, yet |
395 // Load the sprite, if it is not loaded, yet |
443 if (p == NULL) p = ReadSprite(sprite); |
396 if (p == NULL) p = ReadSprite(sprite); |
444 return p; |
397 return p; |