diff --git a/grfspecial.c b/grfspecial.c --- a/grfspecial.c +++ b/grfspecial.c @@ -41,6 +41,13 @@ static uint32 _ttdpatch_flags[8]; typedef void (*SpecialSpriteHandler)(byte *buf, int len); +static const int _vehcounts[4] = { + NUM_TRAIN_ENGINES, + NUM_ROAD_ENGINES, + NUM_SHIP_ENGINES, + NUM_AIRCRAFT_ENGINES +}; + static const int _vehshifts[4] = { 0, ROAD_ENGINES_INDEX, @@ -59,13 +66,16 @@ enum grfmsg_severity { static void CDECL grfmsg(enum grfmsg_severity severity, const char *str, ...) { static const char * const severitystr[4] = { "Notice", "Warning", "Error", "Fatal" }; + int export_severity = 0; char buf[1024]; va_list va; va_start(va, str); vsprintf(buf, str, va); va_end(va); - DEBUG(grf, 2) ("[%s][%s] %s", _cur_grffile->filename, severitystr[severity], buf); + + export_severity = 2 - (severity == GMS_FATAL ? 2 : severity); + DEBUG(grf, export_severity) ("[%s][%s] %s", _cur_grffile->filename, severitystr[severity], buf); } @@ -138,7 +148,7 @@ static void dewagonize(int condition, in EngineInfo *ei = &_engine_info[engine]; RailVehicleInfo *rvi = &_rail_vehicle_info[engine]; - if (condition) { + if (condition != 0) { ei->unk2 &= ~0x80; rvi->flags &= ~2; } else { @@ -226,7 +236,7 @@ static bool RailVehicleChangeInfo(uint e FOR_EACH_ENGINE { uint8 dual = grf_load_byte(&buf); - if (dual) { + if (dual != 0) { rvi[i].flags |= 1; } else { rvi[i].flags &= ~1; @@ -571,12 +581,12 @@ static void NewSpriteSet(byte *buf, int /* TODO: No stations support. */ uint8 feature; - check_length(len, 4, "SpriteNewSet"); + check_length(len, 4, "NewSpriteSet"); feature = buf[1]; if (feature == 4) { _spriteset_start = 0; - grfmsg(GMS_WARN, "SpriteNewSet: Stations unsupported, skipping."); + grfmsg(GMS_WARN, "NewSpriteSet: Stations unsupported, skipping."); return; } @@ -610,16 +620,18 @@ static void NewSpriteGroup(byte *buf, in uint8 numloaded; uint8 numloading; struct SpriteGroup *group; + byte *loaded_ptr; + byte *loading_ptr; int i; - check_length(len, 5, "SpriteNewGroup"); + check_length(len, 5, "NewSpriteGroup"); feature = buf[1]; setid = buf[2]; numloaded = buf[3]; numloading = buf[4]; if (feature == 4) { - grfmsg(GMS_WARN, "SpriteNewGroup: Stations unsupported, skipping."); + grfmsg(GMS_WARN, "NewSpriteGroup: Stations unsupported, skipping."); return; } @@ -638,7 +650,7 @@ static void NewSpriteGroup(byte *buf, in //uint32 val; uint16 def; - grfmsg(GMS_WARN, "SpriteNewGroup(0x81): Unsupported variable %x. Using default cid.", var); + grfmsg(GMS_WARN, "NewSpriteGroup(0x81): Unsupported variable %x. Using default cid.", var); //val = (0xff << shiftnum) & andmask; @@ -653,20 +665,35 @@ static void NewSpriteGroup(byte *buf, in return; } else if (numloaded & 0x80) { - grfmsg(GMS_WARN, "SpriteNewGroup(0x%x): Unsupported special group.", numloaded); + grfmsg(GMS_WARN, "NewSpriteGroup(0x%x): Unsupported special group.", numloaded); return; } if (!_spriteset_start) { - grfmsg(GMS_WARN, "SpriteNewGroup: No sprite set to work on! Skipping."); + grfmsg(GMS_ERROR, "NewSpriteGroup: No sprite set to work on! Skipping."); return; } if (_spriteset_feature != feature) { - grfmsg(GMS_WARN, "SpriteNewGroup: Group feature %x doesn't match set feature %x! Skipping.", feature, _spriteset_feature); + grfmsg(GMS_ERROR, "NewSpriteGroup: Group feature %x doesn't match set feature %x! Skipping.", feature, _spriteset_feature); return; } + check_length(bufend - buf, 5, "NewSpriteGroup"); + buf += 5; + check_length(bufend - buf, 2 * numloaded, "NewSpriteGroup"); + loaded_ptr = buf; + loading_ptr = buf + 2 * numloaded; + + if (numloaded > 16) { + grfmsg(GMS_WARN, "NewSpriteGroup: More than 16 sprites in group %x, skipping the rest.", setid); + numloaded = 16; + } + if (numloading > 16) { + grfmsg(GMS_WARN, "NewSpriteGroup: More than 16 sprites in group %x, skipping the rest.", setid); + numloading = 16; + } + if (setid >= _spritesset_count) { _spritesset_count = setid + 1; _spritesset = realloc(_spritesset, _spritesset_count * sizeof(struct SpriteGroup)); @@ -674,28 +701,24 @@ static void NewSpriteGroup(byte *buf, in group = &_spritesset[setid]; memset(group, 0, sizeof(struct SpriteGroup)); group->sprites_per_set = _spriteset_numents; - - buf += 5; - - for (i = 0; buf < bufend && i < numloaded; i++) { - uint16 spriteset_id = grf_load_word(&buf); + group->loaded_count = numloaded; + group->loading_count = numloading; - if (_spritesset[setid].loaded_count > 16) { - grfmsg(GMS_WARN, "SpriteNewGroup: More than 16 sprites in group %x, skipping.", setid); - return; - } - group->loaded[group->loaded_count++] - = _spriteset_start + spriteset_id * _spriteset_numents; + DEBUG(grf, 7) ("NewSpriteGroup: New SpriteGroup 0x%02hhx, %u views, %u loaded, %u loading, sprites %u - %u", + setid, group->sprites_per_set, group->loaded_count, group->loading_count, + _spriteset_start - _cur_grffile->sprite_offset, + _spriteset_start + (_spriteset_numents * (numloaded + numloading)) - _cur_grffile->sprite_offset); + + for (i = 0; i < numloaded; i++) { + uint16 spriteset_id = grf_load_word(&loaded_ptr); + group->loaded[i] = _spriteset_start + spriteset_id * _spriteset_numents; + DEBUG(grf, 8) ("NewSpriteGroup: + group->loaded[%i] = %u (subset %u)", i, group->loaded[i], spriteset_id); } - for (i = 0; buf < bufend && i < numloading; i++) { - uint16 spriteset_id = grf_load_word(&buf); - - if (_spritesset[setid].loading_count > 16) { - grfmsg(GMS_WARN, "SpriteNewGroup: More than 16 sprites in group %x, skipping.", setid); - return; - } - group->loading[group->loading_count++] = _spriteset_start + spriteset_id * _spriteset_numents; + for (i = 0; i < numloading; i++) { + uint16 spriteset_id = grf_load_word(&loading_ptr); + group->loading[i] = _spriteset_start + spriteset_id * _spriteset_numents; + DEBUG(grf, 8) ("NewSpriteGroup: + group->loading[%i] = %u (subset %u)", i, group->loading[i], spriteset_id); } } @@ -731,13 +754,23 @@ static void NewVehicle_SpriteGroupMappin feature = buf[1]; idcount = buf[2] & 0x7F; wagover = buf[2] & 0x80; + check_length(len, 3 + idcount, "VehicleMapSpriteGroup"); cidcount = buf[3 + idcount]; + check_length(len, 4 + idcount + cidcount * 3, "VehicleMapSpriteGroup"); if (feature == 4) { grfmsg(GMS_WARN, "VehicleMapSpriteGroup: Stations unsupported, skipping."); return; } + /* If ``n-id'' (or ``idcount'') is zero, this is a ``feature + * callback''. I have no idea how this works, so we will ignore it for + * now. --octo */ + if (idcount == 0) { + grfmsg(GMS_NOTICE, "NewMapping: Feature callbacks not implemented yet."); + return; + } + // FIXME: Tropicset contains things like: // 03 00 01 19 01 00 00 00 00 - this is missing one 00 at the end, // what should we exactly do with that? --pasky @@ -752,10 +785,28 @@ static void NewVehicle_SpriteGroupMappin last_engines_count = idcount; } + if (wagover != 0) { + if (last_engines_count == 0) { + grfmsg(GMS_ERROR, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with."); + return; + } else { + DEBUG(grf, 4) ("VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons.", + last_engines_count, idcount); + } + } + + for (i = 0; i < idcount; i++) { - uint8 engine = buf[3 + i] + _vehshifts[feature]; + uint8 engine_id = buf[3 + i]; + uint8 engine = engine_id + _vehshifts[feature]; byte *bp = &buf[4 + idcount]; + if (engine_id > _vehcounts[feature]) { + grfmsg(GMS_ERROR, "Id %u for feature %x is out of bounds.", + engine_id, feature); + return; + } + for (c = 0; c < cidcount; c++) { uint8 ctype = grf_load_byte(&bp); uint16 groupid = grf_load_word(&bp); @@ -768,7 +819,7 @@ static void NewVehicle_SpriteGroupMappin if (ctype == 0xFF) ctype = CID_PURCHASE; - if (wagover) { + if (wagover != 0) { // TODO: No multiple cargo types per vehicle yet. --pasky SetWagonOverrideSprites(engine, &_spritesset[groupid], last_engines, last_engines_count); } else { @@ -791,7 +842,7 @@ static void NewVehicle_SpriteGroupMappin return; } - if (wagover) { + if (wagover != 0) { // TODO: No multiple cargo types per vehicle yet. --pasky SetWagonOverrideSprites(engine, &_spritesset[groupid], last_engines, last_engines_count); } else { @@ -980,7 +1031,7 @@ static void SkipIf(byte *buf, int len) return; } - if (!result) { + if (result == 0) { grfmsg(GMS_NOTICE, "Not skipping sprites, test was false."); return; } @@ -1326,7 +1377,7 @@ void DecodeSpecialSprite(const char *fil if (buf == NULL) error("DecodeSpecialSprite: Could not allocate memory"); - if (!initialized) { + if (initialized == 0) { InitializeGRFSpecial(); initialized = 1; }