# HG changeset patch # User frosch # Date 2012-03-19 22:55:29 # Node ID fb28ade150afc5f03a424f16b75fb20e361e02bf # Parent 718dec875d1137f6f1c0dda3c44637690e32540a (svn r24052) -Fix (r23883) [FS#5107]: Imported GRF sounds were inserted into the wrong slots. diff --git a/src/newgrf.cpp b/src/newgrf.cpp --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -6874,10 +6874,13 @@ static void DefineGotoLabel(ByteReader * 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 +6904,13 @@ static void ImportGRFSound() sound->priority = 0; } -static void LoadGRFSound(size_t offs) -{ - SoundEntry *sound = AllocateSound(); - +/** + * 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) +{ /* Set default volume and priority */ sound->volume = 0x80; sound->priority = 0; @@ -6925,15 +6931,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 +6956,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; } @@ -6958,6 +6976,11 @@ static void GRFSound(ByteReader *buf) 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 +6989,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); // already read @@ -6977,7 +7000,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); // already read } diff --git a/src/newgrf_sound.cpp b/src/newgrf_sound.cpp --- 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 --- 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 --- 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; } }