diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index b18b9c50ee..7bdba7deaa 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -1894,7 +1894,7 @@ static bool AircraftEventHandler(Aircraft *v, int loop) if (v->current_order.IsType(OT_LOADING) || v->current_order.IsType(OT_LEAVESTATION)) return true; - if (v->state == FLYING) { + if (v->state >= ENDTAKEOFF && v->state <= HELIENDLANDING) { /* If we are flying, unconditionally clear the 'dest too far' state. */ AircraftHandleDestTooFar(v, false); } else if (v->acache.cached_max_range_sqr != 0) { diff --git a/src/newgrf.cpp b/src/newgrf.cpp index a015fe5ade..0a07fc49ff 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -6688,13 +6688,12 @@ static void ParamSet(ByteReader *buf) break; case 0x9E: // Miscellaneous GRF features - _misc_grf_features = res; - /* Set train list engine width */ - _cur.grffile->traininfo_vehicle_width = HasGrfMiscBit(GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH; - + _cur.grffile->traininfo_vehicle_width = HasBit(res, GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH; /* Remove the local flags from the global flags */ - ClrBit(_misc_grf_features, GMB_TRAIN_WIDTH_32_PIXELS); + ClrBit(res, GMB_TRAIN_WIDTH_32_PIXELS); + + _misc_grf_features = res; break; case 0x9F: // locale-dependent settings @@ -6874,10 +6873,13 @@ static void DefineGotoLabel(ByteReader *buf) grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label); } -static void ImportGRFSound() +/** + * Process a sound import from another GRF file. + * @param sound Destination for sound. + */ +static void ImportGRFSound(SoundEntry *sound) { const GRFFile *file; - SoundEntry *sound = AllocateSound(); uint32 grfid = FioReadDword(); SoundID sound_id = FioReadWord(); @@ -6901,10 +6903,13 @@ static void ImportGRFSound() sound->priority = 0; } -static void LoadGRFSound(size_t offs) +/** + * Load a sound from a file. + * @param offs File offset to read sound from. + * @param sound Destination for sound. + */ +static void LoadGRFSound(size_t offs, SoundEntry *sound) { - SoundEntry *sound = AllocateSound(); - /* Set default volume and priority */ sound->volume = 0x80; sound->priority = 0; @@ -6925,15 +6930,24 @@ static void GRFSound(ByteReader *buf) * W num Number of sound files that follow */ uint16 num = buf->ReadWord(); + if (num == 0) return; + SoundEntry *sound; if (_cur.grffile->sound_offset == 0) { _cur.grffile->sound_offset = GetNumSounds(); _cur.grffile->num_sounds = num; + sound = AllocateSound(num); + } else { + sound = GetSound(_cur.grffile->sound_offset); } for (int i = 0; i < num; i++) { _cur.nfo_line++; + /* Check whether the index is in range. This might happen if multiple action 11 are present. + * While this is invalid, we do not check for this. But we should prevent it from causing bigger trouble */ + bool invalid = i >= _cur.grffile->num_sounds; + size_t offs = FioGetPos(); uint32 len = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord(); @@ -6941,12 +6955,15 @@ static void GRFSound(ByteReader *buf) if (_cur.grf_container_ver >= 2 && type == 0xFD) { /* Reference to sprite section. */ - if (len != 4) { + if (invalid) { + grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)"); + FioSkipBytes(len); + } else if (len != 4) { grfmsg(1, "GRFSound: Invalid sprite section import"); FioSkipBytes(len); } else { uint32 id = FioReadDword(); - if (_cur.stage == GLS_INIT) LoadGRFSound(GetGRFSpriteOffset(id)); + if (_cur.stage == GLS_INIT) LoadGRFSound(GetGRFSpriteOffset(id), sound + i); } continue; } @@ -6954,10 +6971,15 @@ static void GRFSound(ByteReader *buf) if (type != 0xFF) { grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping"); FioSkipBytes(7); - SkipSpriteData(type, num - 8); + SkipSpriteData(type, len - 8); continue; } + if (invalid) { + grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)"); + FioSkipBytes(len); + } + byte action = FioReadByte(); switch (action) { case 0xFF: @@ -6966,7 +6988,7 @@ static void GRFSound(ByteReader *buf) if (_cur.grf_container_ver >= 2) { grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2"); } else { - LoadGRFSound(offs); + LoadGRFSound(offs, sound + i); } } FioSkipBytes(len - 1); // is not included in the length for pseudo-sprites. @@ -6977,7 +6999,7 @@ static void GRFSound(ByteReader *buf) /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for * importing sounds, so this is probably all wrong... */ if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch"); - ImportGRFSound(); + ImportGRFSound(sound + i); } else { FioSkipBytes(len - 1); } diff --git a/src/newgrf_sound.cpp b/src/newgrf_sound.cpp index 5abd443c90..b82853ac6a 100644 --- a/src/newgrf_sound.cpp +++ b/src/newgrf_sound.cpp @@ -22,11 +22,15 @@ static SmallVector _sounds; -/* Allocate a new Sound */ -SoundEntry *AllocateSound() +/** + * Allocate sound slots. + * @param num Number of slots to allocate. + * @return First allocated slot. + */ +SoundEntry *AllocateSound(uint num) { - SoundEntry *sound = _sounds.Append(); - MemSetT(sound, 0); + SoundEntry *sound = _sounds.Append(num); + MemSetT(sound, 0, num); return sound; } diff --git a/src/newgrf_sound.h b/src/newgrf_sound.h index a6375cee4a..0d32953274 100644 --- a/src/newgrf_sound.h +++ b/src/newgrf_sound.h @@ -30,7 +30,7 @@ enum VehicleSoundEvent { }; -SoundEntry *AllocateSound(); +SoundEntry *AllocateSound(uint num); void InitializeSoundPool(); bool LoadNewGRFSound(SoundEntry *sound); SoundEntry *GetSound(SoundID sound_id); diff --git a/src/sound.cpp b/src/sound.cpp index f792dfdff1..4c72778526 100644 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -218,11 +218,11 @@ static const byte _sound_idx[] = { void SndCopyToPool() { + SoundEntry *sound = AllocateSound(ORIGINAL_SAMPLE_COUNT); for (uint i = 0; i < ORIGINAL_SAMPLE_COUNT; i++) { - SoundEntry *sound = AllocateSound(); - *sound = _original_sounds[_sound_idx[i]]; - sound->volume = _sound_base_vol[i]; - sound->priority = 0; + sound[i] = _original_sounds[_sound_idx[i]]; + sound[i].volume = _sound_base_vol[i]; + sound[i].priority = 0; } } diff --git a/src/timetable_cmd.cpp b/src/timetable_cmd.cpp index 5be51c37b5..166b817eb5 100644 --- a/src/timetable_cmd.cpp +++ b/src/timetable_cmd.cpp @@ -118,6 +118,7 @@ CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, u case MTF_TRAVEL_SPEED: max_speed = GB(p2, 0, 16); + if (max_speed == 0) max_speed = UINT16_MAX; // Disable speed limit. break; default: