diff --git a/src/files.h b/src/files.h index 89e6a091d..4b281438f 100644 --- a/src/files.h +++ b/src/files.h @@ -184,6 +184,14 @@ public: return mReader->Read(buffer, (long)len); } + TArray Read() + { + TArray buffer(mReader->Length, true); + Size length = mReader->Read(&buffer[0], mReader->Length); + if (length < mReader->Length) buffer.Clear(); + return buffer; + } + char *Gets(char *strbuf, Size len) { return mReader->Gets(strbuf, (int)len); diff --git a/src/sound/midisources/midisource.h b/src/sound/midisources/midisource.h index 12e0188b4..01c0c2808 100644 --- a/src/sound/midisources/midisource.h +++ b/src/sound/midisources/midisource.h @@ -121,8 +121,7 @@ private: uint32_t *SendCommand (uint32_t *event, TrackInfo *track, uint32_t delay, ptrdiff_t room, bool &sysex_noroom); TrackInfo *FindNextDue (); - uint8_t *MusHeader; - int SongLen; + TArray MusHeader; TrackInfo *Tracks; TrackInfo *TrackDue; int NumTracks; @@ -181,8 +180,7 @@ private: static uint32_t ReadVarLenHMI(TrackInfo *); static uint32_t ReadVarLenHMP(TrackInfo *); - uint8_t *MusHeader; - int SongLen; + TArray MusHeader; int NumTracks; TrackInfo *Tracks; TrackInfo *TrackDue; @@ -218,8 +216,7 @@ private: uint32_t *SendCommand (uint32_t *event, EventSource track, uint32_t delay, ptrdiff_t room, bool &sysex_noroom); EventSource FindNextDue(); - uint8_t *MusHeader; - int SongLen; // length of the entire file + TArray MusHeader; int NumSongs; TrackInfo *Songs; TrackInfo *CurrSong; diff --git a/src/sound/midisources/midisource_hmi.cpp b/src/sound/midisources/midisource_hmi.cpp index 03516236a..b5e57c929 100644 --- a/src/sound/midisources/midisource_hmi.cpp +++ b/src/sound/midisources/midisource_hmi.cpp @@ -133,19 +133,17 @@ HMISong::HMISong (FileReader &reader) { // Way too small to be HMI. return; } - MusHeader = new uint8_t[len]; - SongLen = len; + MusHeader = reader.Read(); NumTracks = 0; - if (reader.Read(MusHeader, len) != len) + if (MusHeader.Size() == 0) return; // Do some validation of the MIDI file - if (memcmp(MusHeader, HMI_SONG_MAGIC, sizeof(HMI_SONG_MAGIC)) == 0) + if (memcmp(&MusHeader[0], HMI_SONG_MAGIC, sizeof(HMI_SONG_MAGIC)) == 0) { SetupForHMI(len); } - else if (((uint32_t *)MusHeader)[0] == MAKE_ID('H','M','I','M') && - ((uint32_t *)MusHeader)[1] == MAKE_ID('I','D','I','P')) + else if (memcmp(&MusHeader[0], "HMIMIDIP", 8) == 0) { SetupForHMP(len); } @@ -159,14 +157,10 @@ HMISong::HMISong (FileReader &reader) HMISong::~HMISong() { - if (Tracks != NULL) + if (Tracks != nullptr) { delete[] Tracks; } - if (MusHeader != NULL) - { - delete[] MusHeader; - } } //========================================================================== @@ -179,8 +173,10 @@ void HMISong::SetupForHMI(int len) { int i, p; + auto MusPtr = &MusHeader[0]; + ReadVarLen = ReadVarLenHMI; - NumTracks = GetShort(MusHeader + HMI_TRACK_COUNT_OFFSET); + NumTracks = GetShort(MusPtr + HMI_TRACK_COUNT_OFFSET); if (NumTracks <= 0) { @@ -191,16 +187,16 @@ void HMISong::SetupForHMI(int len) // HMI files have two values here, a full value and a quarter value. Some games, // notably Quarantines, have identical values for some reason, so it's safer to // use the quarter value and multiply it by four than to trust the full value. - Division = GetShort(MusHeader + HMI_DIVISION_OFFSET) << 2; + Division = GetShort(MusPtr + HMI_DIVISION_OFFSET) << 2; Tempo = InitialTempo = 4000000; Tracks = new TrackInfo[NumTracks + 1]; - int track_dir = GetInt(MusHeader + HMI_TRACK_DIR_PTR_OFFSET); + int track_dir = GetInt(MusPtr + HMI_TRACK_DIR_PTR_OFFSET); // Gather information about each track for (i = 0, p = 0; i < NumTracks; ++i) { - int start = GetInt(MusHeader + track_dir + i*4); + int start = GetInt(MusPtr + track_dir + i*4); int tracklen, datastart; if (start > len - HMITRACK_DESIGNATION_OFFSET - 4) @@ -209,7 +205,7 @@ void HMISong::SetupForHMI(int len) } // BTW, HMI does not actually check the track header. - if (memcmp(MusHeader + start, TRACK_MAGIC, 13) != 0) + if (memcmp(MusPtr + start, TRACK_MAGIC, 13) != 0) { continue; } @@ -222,7 +218,7 @@ void HMISong::SetupForHMI(int len) } else { - tracklen = GetInt(MusHeader + track_dir + i*4 + 4) - start; + tracklen = GetInt(MusPtr + track_dir + i*4 + 4) - start; } // Clamp incomplete tracks to the end of the file. tracklen = MIN(tracklen, len - start); @@ -232,7 +228,7 @@ void HMISong::SetupForHMI(int len) } // Offset to actual MIDI events. - datastart = GetInt(MusHeader + start + HMITRACK_DATA_PTR_OFFSET); + datastart = GetInt(MusPtr + start + HMITRACK_DATA_PTR_OFFSET); tracklen -= datastart; if (tracklen <= 0) { @@ -240,7 +236,7 @@ void HMISong::SetupForHMI(int len) } // Store track information - Tracks[p].TrackBegin = MusHeader + start + datastart; + Tracks[p].TrackBegin = MusPtr + start + datastart; Tracks[p].TrackP = 0; Tracks[p].MaxTrackP = tracklen; @@ -248,7 +244,7 @@ void HMISong::SetupForHMI(int len) // connected to the MIDI device. for (int ii = 0; ii < NUM_HMI_DESIGNATIONS; ++ii) { - Tracks[p].Designation[ii] = GetShort(MusHeader + start + HMITRACK_DESIGNATION_OFFSET + ii*2); + Tracks[p].Designation[ii] = GetShort(MusPtr + start + HMITRACK_DESIGNATION_OFFSET + ii*2); } p++; @@ -270,12 +266,14 @@ void HMISong::SetupForHMP(int len) int track_data; int i, p; + auto MusPtr = &MusHeader[0]; + ReadVarLen = ReadVarLenHMP; - if (MusHeader[8] == 0) + if (MusPtr[8] == 0) { track_data = HMP_TRACK_OFFSET_0; } - else if (memcmp(MusHeader + 8, HMP_NEW_DATE, sizeof(HMP_NEW_DATE)) == 0) + else if (memcmp(MusPtr + 8, HMP_NEW_DATE, sizeof(HMP_NEW_DATE)) == 0) { track_data = HMP_TRACK_OFFSET_1; } @@ -284,7 +282,7 @@ void HMISong::SetupForHMP(int len) return; } - NumTracks = GetInt(MusHeader + HMP_TRACK_COUNT_OFFSET); + NumTracks = GetInt(MusPtr + HMP_TRACK_COUNT_OFFSET); if (NumTracks <= 0) { @@ -292,7 +290,7 @@ void HMISong::SetupForHMP(int len) } // The division is the number of pulses per quarter note (PPQN). - Division = GetInt(MusHeader + HMP_DIVISION_OFFSET); + Division = GetInt(MusPtr + HMP_DIVISION_OFFSET); Tempo = InitialTempo = 1000000; Tracks = new TrackInfo[NumTracks + 1]; @@ -308,7 +306,7 @@ void HMISong::SetupForHMP(int len) break; } - tracklen = GetInt(MusHeader + start + HMPTRACK_LEN_OFFSET); + tracklen = GetInt(MusPtr + start + HMPTRACK_LEN_OFFSET); track_data += tracklen; // Clamp incomplete tracks to the end of the file. @@ -326,7 +324,7 @@ void HMISong::SetupForHMP(int len) } // Store track information - Tracks[p].TrackBegin = MusHeader + start + HMPTRACK_MIDI_DATA_OFFSET; + Tracks[p].TrackBegin = MusPtr + start + HMPTRACK_MIDI_DATA_OFFSET; Tracks[p].TrackP = 0; Tracks[p].MaxTrackP = tracklen; @@ -337,14 +335,14 @@ void HMISong::SetupForHMP(int len) // HMI files. Some songs contain nothing but zeroes for this data, so I'd rather // not go around using it without confirmation. - Printf("Track %d: %d %08x %d: \034I", i, GetInt(MusHeader + start), - GetInt(MusHeader + start + 4), GetInt(MusHeader + start + 8)); + Printf("Track %d: %d %08x %d: \034I", i, GetInt(MusPtr + start), + GetInt(MusPtr + start + 4), GetInt(MusPtr + start + 8)); int designations = HMP_DESIGNATIONS_OFFSET + - GetInt(MusHeader + start + HMPTRACK_DESIGNATION_OFFSET) * 4 * NUM_HMP_DESIGNATIONS; + GetInt(MusPtr + start + HMPTRACK_DESIGNATION_OFFSET) * 4 * NUM_HMP_DESIGNATIONS; for (int ii = 0; ii < NUM_HMP_DESIGNATIONS; ++ii) { - Printf(" %04x", GetInt(MusHeader + designations + ii*4)); + Printf(" %04x", GetInt(MusPtr + designations + ii*4)); } Printf("\n"); #endif @@ -478,7 +476,7 @@ void HMISong :: DoRestart() bool HMISong::CheckDone() { - return TrackDue == NULL; + return TrackDue == nullptr; } //========================================================================== @@ -968,7 +966,7 @@ void NoteOffQueue::Heapify() // // HMISong :: FindNextDue // -// Scans every track for the next event to play. Returns NULL if all events +// Scans every track for the next event to play. Returns nullptr if all events // have been consumed. // //========================================================================== @@ -991,7 +989,7 @@ HMISong::TrackInfo *HMISong::FindNextDue () } // Check regular tracks. - track = NULL; + track = nullptr; best = 0xFFFFFFFF; for (i = 0; i < NumTracks; ++i) { diff --git a/src/sound/midisources/midisource_smf.cpp b/src/sound/midisources/midisource_smf.cpp index 2f7f29d29..31af4d830 100644 --- a/src/sound/midisources/midisource_smf.cpp +++ b/src/sound/midisources/midisource_smf.cpp @@ -102,13 +102,11 @@ struct MIDISong2::TrackInfo MIDISong2::MIDISong2 (FileReader &reader) : MusHeader(0), Tracks(0) { - int p; + unsigned p; int i; - SongLen = (int)reader.GetLength(); - MusHeader = new uint8_t[SongLen]; - if (reader.Read(MusHeader, SongLen) != SongLen) - return; + MusHeader = reader.Read(); + if (MusHeader.Size() == 0) return; // Do some validation of the MIDI file if (MusHeader[4] != 0 || MusHeader[5] != 0 || MusHeader[6] != 0 || MusHeader[7] != 6) @@ -138,7 +136,7 @@ MIDISong2::MIDISong2 (FileReader &reader) Tracks = new TrackInfo[NumTracks]; // Gather information about each track - for (i = 0, p = 14; i < NumTracks && p < SongLen + 8; ++i) + for (i = 0, p = 14; i < NumTracks && p < MusHeader.Size() + 8; ++i) { uint32_t chunkLen = (MusHeader[p+4]<<24) | @@ -146,9 +144,9 @@ MIDISong2::MIDISong2 (FileReader &reader) (MusHeader[p+6]<<8) | (MusHeader[p+7]); - if (chunkLen + p + 8 > (uint32_t)SongLen) + if (chunkLen + p + 8 > MusHeader.Size()) { // Track too long, so truncate it - chunkLen = SongLen - p - 8; + chunkLen = MusHeader.Size() - p - 8; } if (MusHeader[p+0] == 'M' && @@ -156,7 +154,7 @@ MIDISong2::MIDISong2 (FileReader &reader) MusHeader[p+2] == 'r' && MusHeader[p+3] == 'k') { - Tracks[i].TrackBegin = MusHeader + p + 8; + Tracks[i].TrackBegin = &MusHeader[p + 8]; Tracks[i].TrackP = 0; Tracks[i].MaxTrackP = chunkLen; } @@ -182,14 +180,10 @@ MIDISong2::MIDISong2 (FileReader &reader) MIDISong2::~MIDISong2 () { - if (Tracks != NULL) + if (Tracks != nullptr) { delete[] Tracks; } - if (MusHeader != NULL) - { - delete[] MusHeader; - } } //========================================================================== @@ -277,7 +271,7 @@ void MIDISong2 :: DoRestart() bool MIDISong2::CheckDone() { - return TrackDue == NULL; + return TrackDue == nullptr; } //========================================================================== @@ -754,7 +748,7 @@ uint32_t MIDISong2::TrackInfo::ReadVarLen () // // MIDISong2 :: FindNextDue // -// Scans every track for the next event to play. Returns NULL if all events +// Scans every track for the next event to play. Returns nullptr if all events // have been consumed. // //========================================================================== @@ -774,10 +768,10 @@ MIDISong2::TrackInfo *MIDISong2::FindNextDue () switch (Format) { case 0: - return Tracks[0].Finished ? NULL : Tracks; + return Tracks[0].Finished ? nullptr : Tracks; case 1: - track = NULL; + track = nullptr; best = 0xFFFFFFFF; for (i = 0; i < NumTracks; ++i) { @@ -798,9 +792,9 @@ MIDISong2::TrackInfo *MIDISong2::FindNextDue () { track++; } - return track < &Tracks[NumTracks] ? track : NULL; + return track < &Tracks[NumTracks] ? track : nullptr; } - return NULL; + return nullptr; } diff --git a/src/sound/midisources/midisource_xmi.cpp b/src/sound/midisources/midisource_xmi.cpp index 84f860a48..2cb824a15 100644 --- a/src/sound/midisources/midisource_xmi.cpp +++ b/src/sound/midisources/midisource_xmi.cpp @@ -108,13 +108,11 @@ struct XMISong::TrackInfo XMISong::XMISong (FileReader &reader) : MusHeader(0), Songs(0) { - SongLen = (int)reader.GetLength(); - MusHeader = new uint8_t[SongLen]; - if (reader.Read(MusHeader, SongLen) != SongLen) - return; + MusHeader = reader.Read(); + if (MusHeader.Size() == 0) return; // Find all the songs in this file. - NumSongs = FindXMIDforms(MusHeader, SongLen, NULL); + NumSongs = FindXMIDforms(&MusHeader[0], MusHeader.Size(), nullptr); if (NumSongs == 0) { return; @@ -132,7 +130,7 @@ XMISong::XMISong (FileReader &reader) Songs = new TrackInfo[NumSongs]; memset(Songs, 0, sizeof(*Songs) * NumSongs); - FindXMIDforms(MusHeader, SongLen, Songs); + FindXMIDforms(&MusHeader[0], MusHeader.Size(), Songs); CurrSong = Songs; DPrintf(DMSG_SPAMMY, "XMI song count: %d\n", NumSongs); } @@ -145,14 +143,10 @@ XMISong::XMISong (FileReader &reader) XMISong::~XMISong () { - if (Songs != NULL) + if (Songs != nullptr) { delete[] Songs; } - if (MusHeader != NULL) - { - delete[] MusHeader; - } } //========================================================================== @@ -176,7 +170,7 @@ int XMISong::FindXMIDforms(const uint8_t *chunk, int len, TrackInfo *songs) cons { if (GetNativeInt(chunk + p + 8) == MAKE_ID('X','M','I','D')) { - if (songs != NULL) + if (songs != nullptr) { FoundXMID(chunk + p + 12, chunklen - 4, songs + count); }