summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gfxinit.c114
-rw-r--r--newgrf.c312
-rw-r--r--newgrf.h3
-rw-r--r--spritecache.c66
4 files changed, 199 insertions, 296 deletions
diff --git a/gfxinit.c b/gfxinit.c
index c93a8b906..60c155e85 100644
--- a/gfxinit.c
+++ b/gfxinit.c
@@ -14,23 +14,6 @@
#include "variables.h"
#include <ctype.h>
-#define SPRITE_CACHE_SIZE 1024*1024
-
-#define WANT_NEW_LRU
-
-
-/* These are used in newgrf.c: */
-
-int _skip_sprites = 0; // XXX
-int _replace_sprites_count[16]; // XXX
-int _replace_sprites_offset[16]; // XXX
-
-const char* _cur_grffile; // XXX
-int _loading_stage; // XXX
-int _skip_specials; // XXX
-uint16 _custom_sprites_base; // XXX
-
-
typedef struct MD5File {
const char * const filename; // filename
const md5_byte_t hash[16]; // md5 sum of the file
@@ -58,17 +41,12 @@ static const SpriteID * const _slopes_spriteindexes[] = {
};
-static int LoadGrfFile(const char *filename, int load_index, int file_index)
+static uint LoadGrfFile(const char* filename, uint load_index, int file_index)
{
- int load_index_org = load_index;
+ uint load_index_org = load_index;
FioOpenFile(file_index, filename);
- /* Thou shalt use LoadNewGrfFile() if thou loadeth a GRF file that
- * might contain some special sprites. */
- _skip_specials = 1;
- _skip_sprites = 0;
-
DEBUG(spritecache, 2) ("Reading grf-file ``%s''", filename);
while (LoadNextSprite(load_index, file_index)) {
@@ -82,62 +60,19 @@ static int LoadGrfFile(const char *filename, int load_index, int file_index)
return load_index - load_index_org;
}
-static int LoadNewGrfFile(const char *filename, int load_index, int file_index)
-{
- int i;
-
- FioOpenFile(file_index, filename);
- _cur_grffile = filename;
- _skip_specials = 0;
- _skip_sprites = 0;
-
- DEBUG(spritecache, 2) ("Reading newgrf-file ``%s'' [offset: %u]",
- filename, load_index);
-
- /* Skip the first sprite; we don't care about how many sprites this
- * does contain; newest TTDPatches and George's longvehicles don't
- * neither, apparently. */
- {
- int length;
- byte type;
-
- length = FioReadWord();
- type = FioReadByte();
-
- if (length == 4 && type == 0xFF) {
- FioReadDword();
- } else {
- error("Custom .grf has invalid format.");
- }
- }
-
- for (i = 0; LoadNextSprite(load_index + i, file_index); i++) {
- if (load_index + i >= MAX_SPRITES)
- error("Too many sprites (0x%X). Recompile with higher MAX_SPRITES value or remove some custom GRF files.",
- load_index + i);
- }
-
- /* Clean up. */
- _skip_sprites = 0;
- memset(_replace_sprites_count, 0, sizeof(_replace_sprites_count));
- memset(_replace_sprites_offset, 0, sizeof(_replace_sprites_offset));
- return i;
-}
-
-static void LoadGrfIndexed(const char *filename, const SpriteID *index_tbl, int file_index)
+static void LoadGrfIndexed(const char* filename, const SpriteID* index_tbl, int file_index)
{
- int start;
+ uint start;
FioOpenFile(file_index, filename);
- _skip_specials = 1;
- _skip_sprites = 0;
DEBUG(spritecache, 2) ("Reading indexed grf-file ``%s''", filename);
for (; (start = *index_tbl++) != 0xffff;) {
- int end = *index_tbl++;
- if(start == 0xfffe) { // skip sprites (amount in second var)
+ uint end = *index_tbl++;
+
+ if (start == 0xfffe) { // skip sprites (amount in second var)
SkipSprites(end);
} else { // load sprites and use indexes from start to end
do {
@@ -153,8 +88,6 @@ static void LoadGrfIndexed(const char *filename, const SpriteID *index_tbl, int
}
-static byte _sprite_page_to_load = 0xFF;
-
#define OPENTTD_SPRITES_COUNT 100
static const SpriteID _openttd_grf_indexes[] = {
SPR_OPENTTD_BASE + 0, SPR_OPENTTD_BASE + 7, // icons etc
@@ -170,7 +103,6 @@ static const SpriteID _openttd_grf_indexes[] = {
0xffff,
};
-/* FUNCTIONS FOR CHECKING MD5 SUMS OF GRF FILES */
/* Check that the supplied MD5 hash matches that stored for the supplied filename */
static bool CheckMD5Digest(const MD5File file, md5_byte_t *digest, bool warn)
@@ -269,21 +201,15 @@ void CheckExternalFiles(void)
}
}
+
+static byte _sprite_page_to_load = 0xFF;
+
static void LoadSpriteTables(void)
{
- int load_index = 0;
+ uint load_index = 0;
uint i;
- uint j;
const FileList *files; // list of grf files to be loaded. Either Windows files or DOS files
- _loading_stage = 1;
-
- /*
- * TODO:
- * I think we can live entirely without Indexed GRFs, but I have to
- * invest that further. --octo
- */
-
files = _use_dos_palette? &files_dos : &files_win;
for (i = 0; files->basic[i].filename != NULL; i++) {
@@ -310,23 +236,7 @@ static void LoadSpriteTables(void)
load_index = SPR_OPENTTD_BASE + OPENTTD_SPRITES_COUNT + 1;
-
- /* Load newgrf sprites
- * in each loading stage, (try to) open each file specified in the config
- * and load information from it. */
- _custom_sprites_base = load_index;
- for (_loading_stage = 0; _loading_stage < 2; _loading_stage++) {
- load_index = _custom_sprites_base;
- for (j = 0; j != lengthof(_newgrf_files) && _newgrf_files[j]; j++) {
- if (!FiosCheckFileExists(_newgrf_files[j])) {
- // TODO: usrerror()
- error("NewGRF file missing: %s", _newgrf_files[j]);
- }
- if (_loading_stage == 0) InitNewGRFFile(_newgrf_files[j], load_index);
- load_index += LoadNewGrfFile(_newgrf_files[j], load_index, i++);
- DEBUG(spritecache, 2) ("Currently %i sprites are loaded", load_index);
- }
- }
+ LoadNewGRF(load_index, i);
}
diff --git a/newgrf.c b/newgrf.c
index e6efb6bae..74709c7f2 100644
--- a/newgrf.c
+++ b/newgrf.c
@@ -10,6 +10,7 @@
#include "fileio.h"
#include "functions.h"
#include "engine.h"
+#include "spritecache.h"
#include "station.h"
#include "sprite.h"
#include "newgrf.h"
@@ -25,9 +26,9 @@
* served as subject to the initial testing of this codec. */
-extern int _skip_sprites;
-extern int _replace_sprites_count[16];
-extern int _replace_sprites_offset[16];
+uint16 _custom_sprites_base;
+static int _skip_sprites; // XXX
+static uint _file_index; // XXX
extern int _traininfo_vehicle_pitch;
static GRFFile *_cur_grffile;
@@ -1156,14 +1157,29 @@ static void NewSpriteSet(byte *buf, int len)
* different sprites that make up a station */
/* TODO: No stations support. */
uint8 feature;
+ uint num_sets;
+ uint num_ents;
+ uint i;
check_length(len, 4, "NewSpriteSet");
feature = buf[1];
+ num_sets = buf[2];
+ num_ents = buf[3];
- _cur_grffile->spriteset_start = _cur_spriteid + 1;
+ _cur_grffile->spriteset_start = _cur_spriteid;
_cur_grffile->spriteset_feature = feature;
- _cur_grffile->spriteset_numsets = buf[2];
- _cur_grffile->spriteset_numents = buf[3];
+ _cur_grffile->spriteset_numsets = num_sets;
+ _cur_grffile->spriteset_numents = num_ents;
+
+ DEBUG(grf, 7) (
+ "New sprite set at %d of type %d, "
+ "consisting of %d sets with %d views each (total %d)",
+ _cur_spriteid, feature, num_sets, num_ents, num_sets * num_ents
+ );
+
+ for (i = 0; i < num_sets * num_ents; i++) {
+ LoadNextSprite(_cur_spriteid++, _file_index);
+ }
}
/* Action 0x02 */
@@ -1790,7 +1806,7 @@ static void SkipIf(byte *buf, int len)
}
numsprites = grf_load_byte(&buf);
- grfmsg(GMS_NOTICE, "Skipping %d->+%d sprites, test was true.", _cur_spriteid - _cur_grffile->sprite_offset, numsprites);
+ grfmsg(GMS_NOTICE, "Skipping %d sprites, test was true.", numsprites);
_skip_sprites = numsprites;
if (_skip_sprites == 0) {
/* Zero means there are no sprites to skip, so
@@ -1838,27 +1854,23 @@ static void SpriteReplace(byte *buf, int len)
* B num-sprites How many sprites are in this set
* W first-sprite First sprite number to replace */
uint8 num_sets;
- int i;
+ uint i;
buf++; /* skip action byte */
num_sets = grf_load_byte(&buf);
- if (num_sets > 16) {
- grfmsg(GMS_ERROR, "SpriteReplace: Too many sets (%d), taking only the first 16!", num_sets);
- }
+ for (i = 0; i < num_sets; i++) {
+ uint8 num_sprites = grf_load_byte(&buf);
+ uint16 first_sprite = grf_load_word(&buf);
+ uint j;
- for (i = 0; i < 16; i++) {
- if (i < num_sets) {
- uint8 num_sprites = grf_load_byte(&buf);
- uint16 first_sprite = grf_load_word(&buf);
+ grfmsg(GMS_NOTICE,
+ "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
+ i, num_sprites, first_sprite
+ );
- _replace_sprites_count[i] = num_sprites;
- _replace_sprites_offset[i] = first_sprite;
- grfmsg(GMS_NOTICE, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
- i, num_sprites, first_sprite);
- } else {
- _replace_sprites_count[i] = 0;
- _replace_sprites_offset[i] = 0;
+ for (j = 0; j < num_sprites; j++) {
+ LoadNextSprite(first_sprite + j, _file_index); // XXX
}
}
}
@@ -2090,7 +2102,7 @@ static void InitializeGRFSpecial(void)
| (1 << 0x17); /* newstartyear */
}
-void InitNewGRFFile(const char *filename, int sprite_offset)
+static void InitNewGRFFile(const char* filename, int sprite_offset)
{
GRFFile *newfile;
@@ -2126,130 +2138,170 @@ void InitNewGRFFile(const char *filename, int sprite_offset)
/* XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
* a crafted invalid GRF file. We should tell that to the user somehow, or
* better make this more robust in the future. */
-
-void DecodeSpecialSprite(const char *filename, int num, int spriteid, int stage)
+static void DecodeSpecialSprite(const char* filename, uint num, uint stage)
{
-#define NUM_ACTIONS 0xF
- static const SpecialSpriteHandler handlers[NUM_ACTIONS] = {
- /* 0x0 */ VehicleChangeInfo,
- /* 0x1 */ NewSpriteSet,
- /* 0x2 */ NewSpriteGroup,
- /* 0x3 */ NewVehicle_SpriteGroupMapping,
- /* 0x4 */ VehicleNewName,
- /* 0x5 */ GraphicsNew,
- /* 0x6 */ CfgApply,
- /* 0x7 */ SkipIf,
- /* 0x8 */ GRFInfo,
- /* 0x9 */ SkipIf,
- /* 0xa */ SpriteReplace,
- /* 0xb */ GRFError,
- /* 0xc */ GRFComment,
- /* 0xd */ ParamSet,
- /* 0xe */ GRFInhibit,
+ /* XXX: There is a difference between staged loading in TTDPatch and
+ * here. In TTDPatch, for some reason actions 1 and 2 are carried out
+ * during stage 0, whilst action 3 is carried out during stage 1 (to
+ * "resolve" cargo IDs... wtf). This is a little problem, because cargo
+ * IDs are valid only within a given set (action 1) block, and may be
+ * overwritten after action 3 associates them. But overwriting happens
+ * in an earlier stage than associating, so... We just process actions
+ * 1 and 2 in stage 1 now, let's hope that won't get us into problems.
+ * --pasky */
+ uint32 action_mask = (stage == 0) ? 0x0001FF40 : 0x0001FFBF;
+ static const SpecialSpriteHandler handlers[] = {
+ /* 0x00 */ VehicleChangeInfo,
+ /* 0x01 */ NewSpriteSet,
+ /* 0x02 */ NewSpriteGroup,
+ /* 0x03 */ NewVehicle_SpriteGroupMapping,
+ /* 0x04 */ VehicleNewName,
+ /* 0x05 */ GraphicsNew,
+ /* 0x06 */ CfgApply,
+ /* 0x07 */ SkipIf,
+ /* 0x08 */ GRFInfo,
+ /* 0x09 */ SkipIf,
+ /* 0x0A */ SpriteReplace,
+ /* 0x0B */ GRFError,
+ /* 0x0C */ GRFComment,
+ /* 0x0D */ ParamSet,
+ /* 0x0E */ GRFInhibit,
+ /* 0x0F */ NULL, // TODO implement
+ /* 0x10 */ NULL // TODO implement
};
- static bool initialized = false;
+
+ byte* buf = malloc(num);
byte action;
- byte *buf = malloc(num);
if (buf == NULL) error("DecodeSpecialSprite: Could not allocate memory");
- if (!initialized) {
- InitializeGRFSpecial();
- initialized = true;
+ FioReadBlock(buf, num);
+ action = buf[0];
+
+ if (action >= lengthof(handlers)) {
+ DEBUG(grf, 7) ("Skipping unknown action 0x%02X", action);
+ free(buf);
+ return;
}
- _cur_stage = stage;
- _cur_spriteid = spriteid;
+ if (!HASBIT(action_mask, action)) {
+ DEBUG(grf, 7) ("Skipping action 0x%02X in stage %d", action, stage);
+ free(buf);
+ return;
+ }
- FioReadBlock(buf, num);
+ if (handlers[action] == NULL) {
+ DEBUG(grf, 7) ("Skipping unsupported Action 0x%02X", action);
+ free(buf);
+ return;
+ }
- action = buf[0];
+ DEBUG(grf, 7) ("Handling action 0x%02X in stage %d", action, stage);
+ handlers[action](buf, num);
+ free(buf);
+}
- /* XXX: There is a difference between staged loading in TTDPatch and
- * here. In TTDPatch, for some reason actions 1 and 2 are carried out
- * during stage 0, whilst action 3 is carried out during stage 1 (to
- * "resolve" cargo IDs... wtf). This is a little problem, because cargo
- * IDs are valid only within a given set (action 1) block, and may be
- * overwritten after action 3 associates them. But overwriting happens
- * in an earlier stage than associating, so... We just process actions
- * 1 and 2 in stage 1 now, let's hope that won't get us into problems.
- * --pasky */
- if (stage == 0) {
- switch (action) {
- case 0x00:
- case 0x01:
- case 0x02:
- case 0x03:
- case 0x04:
- case 0x05:
- case 0x07:
- /* During initialization, these actions are ignored. */
- DEBUG (grf, 7) (
- "DecodeSpecialSprite: Action: %x, Stage 0, Skipped", action);
- break;
-
- default:
- if (action < NUM_ACTIONS) {
- DEBUG (grf, 7) ("DecodeSpecialSprite: Action: %x, Stage 0", action);
- handlers[action](buf, num);
- } else {
- grfmsg(GMS_WARN,
- "Unknown special sprite action %x, skipping.", action);
- }
- }
- } else if (stage == 1) {
- /* A .grf file is activated only if it was active when the game was
- * started. If a game is loaded, only its active .grfs will be
- * reactivated, unless "loadallgraphics on" is used. A .grf file is
- * considered active if its action 8 has been processed, i.e. its
- * action 8 hasn't been skipped using an action 7.
- *
- * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
- * carried out. All others are ignored, because they only need to be
- * processed once at initialization. */
-
- if (_cur_grffile == NULL || strcmp(_cur_grffile->filename, filename) != 0)
- _cur_grffile = GetFileByFilename(filename);
-
- if (_cur_grffile == NULL)
- error("File ``%s'' lost in cache.\n", filename);
-
- if (_cur_grffile->flags & 0x0001) {
- switch (action) {
- case 0x00:
- case 0x01:
- case 0x02:
- case 0x03:
- case 0x04:
- case 0x05:
- case 0x07:
- case 0x08:
- case 0x09:
- case 0x0A:
- case 0x0B:
- DEBUG (grf, 7) ("DecodeSpecialSprite: Action: %x, Stage 1", action);
- handlers[action](buf, num);
- break;
+static void LoadNewGRFFile(const char* filename, uint file_index, uint stage)
+{
+ uint16 num;
+
+ /* A .grf file is activated only if it was active when the game was
+ * started. If a game is loaded, only its active .grfs will be
+ * reactivated, unless "loadallgraphics on" is used. A .grf file is
+ * considered active if its action 8 has been processed, i.e. its
+ * action 8 hasn't been skipped using an action 7.
+ *
+ * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
+ * carried out. All others are ignored, because they only need to be
+ * processed once at initialization. */
+ if (stage != 0) {
+ _cur_grffile = GetFileByFilename(filename);
+ if (_cur_grffile == NULL) error("File ``%s'' lost in cache.\n", filename);
+ if (!(_cur_grffile->flags & 0x0001)) return;
+ }
+
+ FioOpenFile(file_index, filename);
+ _file_index = file_index; // XXX
+
+ DEBUG(grf, 7) ("Reading NewGRF-file '%s'", filename);
+
+ /* Skip the first sprite; we don't care about how many sprites this
+ * does contain; newest TTDPatches and George's longvehicles don't
+ * neither, apparently. */
+ if (FioReadWord() == 4 && FioReadByte() == 0xFF) {
+ FioReadDword();
+ } else {
+ error("Custom .grf has invalid format.");
+ }
+
+ _skip_sprites = 0; // XXX
+
+ while ((num = FioReadWord()) != 0) {
+ byte type = FioReadByte();
+
+ if (type == 0xFF) {
+ if (_skip_sprites == 0) {
+ DecodeSpecialSprite(filename, num, stage);
+ continue;
+ } else {
+ FioSkipBytes(num);
+ }
+ } else {
+ if (_skip_sprites == 0) DEBUG(grf, 7) ("Skipping unexpected sprite");
+
+ FioSkipBytes(7);
+ num -= 8;
- default:
- if (action < NUM_ACTIONS) {
- DEBUG (grf, 7) (
- "DecodeSpecialSprite: Action: %x, Stage 1, Skipped", action);
+ if (type & 2) {
+ FioSkipBytes(num);
+ } else {
+ while (num > 0) {
+ int8 i = FioReadByte();
+ if (i >= 0) {
+ num -= i;
+ FioSkipBytes(i);
} else {
- grfmsg(GMS_WARN,
- "Unknown special sprite action %x, skipping.", action);
+ i = -(i >> 3);
+ num -= i;
+ FioReadByte();
}
- break;
+ }
}
- } else {
- DEBUG (grf, 7) (
- "DecodeSpecialSprite: Action: %x, Stage 1, Not activated", action);
}
- } else {
- error("Invalid stage %d", stage);
+
+ if (_skip_sprites > 0) _skip_sprites--;
}
+}
- free(buf);
-#undef NUM_ACTIONS
+
+void LoadNewGRF(uint load_index, uint file_index)
+{
+ static bool initialized = false; // XXX yikes
+ uint stage;
+
+ if (!initialized) {
+ InitializeGRFSpecial();
+ initialized = true;
+ }
+
+ /* Load newgrf sprites
+ * in each loading stage, (try to) open each file specified in the config
+ * and load information from it. */
+ _custom_sprites_base = load_index;
+ for (stage = 0; stage < 2; stage++) {
+ uint j;
+
+ _cur_stage = stage;
+ _cur_spriteid = load_index;
+ for (j = 0; j != lengthof(_newgrf_files) && _newgrf_files[j] != NULL; j++) {
+ if (!FiosCheckFileExists(_newgrf_files[j])) {
+ // TODO: usrerror()
+ error("NewGRF file missing: %s", _newgrf_files[j]);
+ }
+ if (stage == 0) InitNewGRFFile(_newgrf_files[j], _cur_spriteid);
+ LoadNewGRFFile(_newgrf_files[j], file_index++, stage); // XXX different file indices in both stages?
+ DEBUG(spritecache, 2) ("Currently %i sprites are loaded", load_index);
+ }
+ }
}
diff --git a/newgrf.h b/newgrf.h
index 232223f6e..b13573de9 100644
--- a/newgrf.h
+++ b/newgrf.h
@@ -39,9 +39,8 @@ struct GRFFile {
extern int _grffile_count;
extern GRFFile *_first_grffile;
-void InitNewGRFFile(const char *filename, int sprite_offset);
-void DecodeSpecialSprite(const char *filename, int num, int spriteid, int stage);
+void LoadNewGRF(uint load_index, uint file_index);
#endif /* NEWGRF_H */
diff --git a/spritecache.c b/spritecache.c
index aa6b2cf29..967538125 100644
--- a/spritecache.c
+++ b/spritecache.c
@@ -7,25 +7,12 @@
#include "spritecache.h"
#include "table/sprites.h"
#include "fileio.h"
-#include "newgrf.h"
#define SPRITE_CACHE_SIZE 1024*1024
#define WANT_NEW_LRU
-/* These are used in newgrf.c: */
-
-extern int _skip_sprites; // XXX
-extern int _replace_sprites_count[16]; // XXX
-extern int _replace_sprites_offset[16]; // XXX
-
-extern const char* _cur_grffile; // XXX
-extern int _loading_stage; // XXX
-extern int _skip_specials; // XXX
-static Sprite _cur_sprite; // XXX
-
-
static void* _sprite_ptr[MAX_SPRITES];
static uint32 _sprite_file_pos[MAX_SPRITES];
@@ -47,33 +34,16 @@ static int _compact_cache_counter;
static void CompactSpriteCache(void);
-static bool ReadSpriteHeaderSkipData(int load_index)
+static bool ReadSpriteHeaderSkipData(void)
{
uint16 num = FioReadWord();
byte type;
- int deaf = 0;
if (num == 0) return false;
- if (_skip_sprites) {
- if (_skip_sprites > 0)
- _skip_sprites--;
- deaf = 1;
- }
-
type = FioReadByte();
- _cur_sprite.info = type;
if (type == 0xFF) {
- /* We need to really skip only special sprites in the deaf
- * mode. It won't hurt to proceed regular sprites as usual
- * because if no special sprite referencing to them is
- * processed, they themselves are never referenced and loaded
- * on their own. */
- if (_skip_specials || deaf) {
- FioSkipBytes(num);
- } else {
- DecodeSpecialSprite(_cur_grffile, num, load_index, _loading_stage);
- }
+ FioSkipBytes(num);
return true;
}
@@ -169,35 +139,7 @@ bool LoadNextSprite(int load_index, byte file_index)
{
uint32 file_pos = FioGetPos() | (file_index << 24);
- if (!ReadSpriteHeaderSkipData(load_index)) return false;
-
- if (_replace_sprites_count[0] > 0 && _cur_sprite.info != 0xFF) {
- int count = _replace_sprites_count[0];
- int offset = _replace_sprites_offset[0];
-
- _replace_sprites_offset[0]++;
- _replace_sprites_count[0]--;
-
- if ((offset + count) <= MAX_SPRITES) {
- load_index = offset;
- } else {
- DEBUG(spritecache, 1) ("Sprites to be replaced are out of range: %x+%x",
- count, offset);
- _replace_sprites_offset[0] = 0;
- _replace_sprites_count[0] = 0;
- }
-
- if (_replace_sprites_count[0] == 0) {
- int i;
-
- for (i = 0; i < 15; i++) {
- _replace_sprites_count[i] = _replace_sprites_count[i + 1];
- _replace_sprites_offset[i] = _replace_sprites_offset[i + 1];
- }
- _replace_sprites_count[i] = 0;
- _replace_sprites_offset[i] = 0;
- }
- }
+ if (!ReadSpriteHeaderSkipData()) return false;
_sprite_file_pos[load_index] = file_pos;
@@ -216,7 +158,7 @@ bool LoadNextSprite(int load_index, byte file_index)
void SkipSprites(uint count)
{
for (; count > 0; --count) {
- if (!ReadSpriteHeaderSkipData(MAX_SPRITES - 1)) return;
+ if (!ReadSpriteHeaderSkipData()) return;
}
}