For https://bugs.winehq.org/show_bug.cgi?id=58493 \ But other games like `Chicken Tournament` and `No One Lives Forever` use the DX7 version too.
For the include file tagging: Native is inconsistent in marking DMUS_IO_* structs that changed between versions. And so was Wine which makes it confusing.
From: Michael Stefaniuc mstefani@winehq.org
--- include/dmusicf.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/include/dmusicf.h b/include/dmusicf.h index da8363c4b04..90fcb7cd4b8 100644 --- a/include/dmusicf.h +++ b/include/dmusicf.h @@ -429,7 +429,7 @@ struct _DMUS_IO_SEQ_ITEM { MUSIC_TIME mtTime; MUSIC_TIME mtDuration; DWORD dwPChannel; - short nOffset; + short nOffset; BYTE bStatus; BYTE bByte1; BYTE bByte2; @@ -489,7 +489,7 @@ struct _DMUS_IO_TIMESIG {
struct _DMUS_IO_STYLE { DMUS_IO_TIMESIG timeSig; - double dblTempo; + double dblTempo; };
struct _DMUS_IO_VERSION { @@ -503,6 +503,7 @@ struct _DMUS_IO_PATTERN { BYTE bGrooveTop; WORD wEmbellishment; WORD wNbrMeasures; + /* DX8 */ BYTE bDestGrooveBottom; BYTE bDestGrooveTop; DWORD dwFlags; @@ -516,6 +517,7 @@ struct _DMUS_IO_STYLEPART { BYTE bPlayModeFlags; BYTE bInvertUpper; BYTE bInvertLower; + /* DX8 */ BYTE bPad[3]; DWORD dwFlags; }; @@ -527,8 +529,9 @@ struct _DMUS_IO_PARTREF { BYTE bSubChordLevel; BYTE bPriority; BYTE bRandomVariation; + /* DX8 */ WORD wPad; - DWORD dwPChannel; + DWORD dwPChannel; /* Replaces wLogicalPartID */ };
@@ -600,6 +603,7 @@ struct _DMUS_IO_CHORD { MUSIC_TIME mtTime; WORD wMeasure; BYTE bBeat; + /* DX8 */ BYTE bFlags; };
@@ -619,6 +623,7 @@ struct _DMUS_IO_COMMAND { BYTE bCommand; BYTE bGrooveLevel; BYTE bGrooveRange; + /* DX8 */ BYTE bRepeatMode; };
@@ -673,6 +678,7 @@ struct _DMUS_IO_INSTRUMENT { BYTE bVolume; short nTranspose; DWORD dwChannelPriority; + /* DX8 */ short nPitchBendRange; };
@@ -707,6 +713,7 @@ struct _DMUS_IO_WAVE_ITEM_HEADER { DWORD dwLoopStart; DWORD dwLoopEnd; DWORD dwFlags; + /* DX9 */ WORD wVolumeRange; WORD wPitchRange; };
From: Michael Stefaniuc mstefani@winehq.org
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58493 --- dlls/dmstyle/style.c | 8 ++++---- dlls/dmusic/dmobject.c | 30 ++++++++++++++++++++++-------- dlls/dmusic/dmobject.h | 2 ++ 3 files changed, 28 insertions(+), 12 deletions(-)
diff --git a/dlls/dmstyle/style.c b/dlls/dmstyle/style.c index c64e7e3d525..759c47340f4 100644 --- a/dlls/dmstyle/style.c +++ b/dlls/dmstyle/style.c @@ -490,13 +490,13 @@ static HRESULT parse_part_list(struct style *This, IStream *stream, struct chunk break;
case DMUS_FOURCC_NOTE_CHUNK: - hr = stream_chunk_get_array(stream, &chunk, (void **)&part->notes, - &part->notes_count, sizeof(*part->notes)); + hr = stream_chunk_get_array_alt(stream, &chunk, (void **)&part->notes, + &part->notes_count, sizeof(*part->notes), offsetof(DMUS_IO_STYLENOTE, bNoteFlags)); break;
case DMUS_FOURCC_CURVE_CHUNK: - hr = stream_chunk_get_array(stream, &chunk, (void **)&part->curves, - &part->curves_count, sizeof(*part->curves)); + hr = stream_chunk_get_array_alt(stream, &chunk, (void **)&part->curves, + &part->curves_count, sizeof(*part->curves), offsetof(DMUS_IO_STYLECURVE, wParamType)); break;
case DMUS_FOURCC_MARKER_CHUNK: diff --git a/dlls/dmusic/dmobject.c b/dlls/dmusic/dmobject.c index 9ba1f239167..03ee9bd41bf 100644 --- a/dlls/dmusic/dmobject.c +++ b/dlls/dmusic/dmobject.c @@ -375,10 +375,12 @@ HRESULT stream_next_chunk(IStream *stream, struct chunk_entry *chunk) element[] - Array of elements The caller needs to free() the array. */ -HRESULT stream_chunk_get_array(IStream *stream, const struct chunk_entry *chunk, void **array, - unsigned int *count, DWORD elem_size) +HRESULT stream_chunk_get_array_alt(IStream *stream, const struct chunk_entry *chunk, void **array, + unsigned int *count, DWORD elem_size, DWORD alt_size) { DWORD size; + unsigned int i; + void *p; HRESULT hr;
*array = NULL; @@ -390,23 +392,29 @@ HRESULT stream_chunk_get_array(IStream *stream, const struct chunk_entry *chunk, } if (FAILED(hr = stream_read(stream, &size, sizeof(DWORD)))) return hr; - if (size != elem_size) { + if (!(size == elem_size || (alt_size && size == alt_size))) { WARN_(dmfile)("%s: Array element size mismatch: got %lu, expected %lu\n", debugstr_chunk(chunk), size, elem_size); return DMUS_E_UNSUPPORTED_STREAM; }
- *count = (chunk->size - sizeof(DWORD)) / elem_size; - size = *count * elem_size; - if (!(*array = malloc(size))) + *count = (chunk->size - sizeof(DWORD)) / size; + if (!(*array = calloc(*count, elem_size))) return E_OUTOFMEMORY; - if (FAILED(hr = stream_read(stream, *array, size))) { + if (size == elem_size) + hr = stream_read(stream, *array, *count * elem_size); + else + for (i = 0, p = *array; i < *count; i++, p = (char *)p + elem_size) + if (FAILED(hr = stream_read(stream, p, size))) + break; + + if (FAILED(hr)) { free(*array); *array = NULL; return hr; }
- if (chunk->size > size + sizeof(DWORD)) { + if (chunk->size > *count * size + sizeof(DWORD)) { WARN_(dmfile)("%s: Extraneous data at end of array\n", debugstr_chunk(chunk)); stream_skip_chunk(stream, chunk); return S_FALSE; @@ -414,6 +422,12 @@ HRESULT stream_chunk_get_array(IStream *stream, const struct chunk_entry *chunk, return S_OK; }
+HRESULT stream_chunk_get_array(IStream *stream, const struct chunk_entry *chunk, void **array, + unsigned int *count, DWORD elem_size) +{ + return stream_chunk_get_array_alt(stream, chunk, array, count, elem_size, 0); +} + HRESULT stream_chunk_get_data(IStream *stream, const struct chunk_entry *chunk, void *data, ULONG size) { diff --git a/dlls/dmusic/dmobject.h b/dlls/dmusic/dmobject.h index bab96c77724..f2f3ab5215d 100644 --- a/dlls/dmusic/dmobject.h +++ b/dlls/dmusic/dmobject.h @@ -39,6 +39,8 @@ HRESULT stream_skip_chunk(IStream *stream, const struct chunk_entry *chunk);
HRESULT stream_chunk_get_array(IStream *stream, const struct chunk_entry *chunk, void **array, unsigned int *count, DWORD elem_size); +HRESULT stream_chunk_get_array_alt(IStream *stream, const struct chunk_entry *chunk, void **array, + unsigned int *count, DWORD elem_size, DWORD alt_size); HRESULT stream_chunk_get_data(IStream *stream, const struct chunk_entry *chunk, void *data, ULONG size); HRESULT stream_chunk_get_wstr(IStream *stream, const struct chunk_entry *chunk, WCHAR *str,
From: Michael Stefaniuc mstefani@winehq.org
--- dlls/dmusic/dmobject.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/dlls/dmusic/dmobject.c b/dlls/dmusic/dmobject.c index 03ee9bd41bf..b1aa91d849f 100644 --- a/dlls/dmusic/dmobject.c +++ b/dlls/dmusic/dmobject.c @@ -428,13 +428,10 @@ HRESULT stream_chunk_get_array(IStream *stream, const struct chunk_entry *chunk, return stream_chunk_get_array_alt(stream, chunk, array, count, elem_size, 0); }
-HRESULT stream_chunk_get_data(IStream *stream, const struct chunk_entry *chunk, void *data, - ULONG size) +HRESULT stream_chunk_get_data(IStream *stream, const struct chunk_entry *chunk, void *data, ULONG size) { if (chunk->size != size) { - WARN_(dmfile)("Chunk %s (size %lu, offset %s) doesn't contains the expected data size %lu\n", - debugstr_fourcc(chunk->id), chunk->size, - wine_dbgstr_longlong(chunk->offset.QuadPart), size); + WARN_(dmfile)("%s: doesn't contains the expected data size %lu\n", debugstr_chunk(chunk), size); return E_FAIL; } return stream_read(stream, data, size);
From: Michael Stefaniuc mstefani@winehq.org
--- dlls/dmusic/band.c | 7 ++----- dlls/dmusic/dmobject.c | 11 +++++++++++ dlls/dmusic/dmobject.h | 2 ++ 3 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/dlls/dmusic/band.c b/dlls/dmusic/band.c index cfced6692a8..d6cc4aab440 100644 --- a/dlls/dmusic/band.c +++ b/dlls/dmusic/band.c @@ -239,12 +239,9 @@ static HRESULT parse_lbin_list(struct band *This, IStream *stream, struct chunk_ switch (MAKE_IDTYPE(chunk.id, chunk.type)) { case DMUS_FOURCC_INSTRUMENT_CHUNK: - { - UINT size = sizeof(inst); - if (chunk.size == offsetof(DMUS_IO_INSTRUMENT, nPitchBendRange)) size = chunk.size; - if (FAILED(hr = stream_chunk_get_data(stream, &chunk, &inst, size))) break; + hr = stream_chunk_get_data_alt(stream, &chunk, &inst, sizeof(inst), + offsetof(DMUS_IO_INSTRUMENT, nPitchBendRange)); break; - }
case MAKE_IDTYPE(FOURCC_LIST, DMUS_FOURCC_REF_LIST): { diff --git a/dlls/dmusic/dmobject.c b/dlls/dmusic/dmobject.c index b1aa91d849f..8b83ba41fc8 100644 --- a/dlls/dmusic/dmobject.c +++ b/dlls/dmusic/dmobject.c @@ -437,6 +437,17 @@ HRESULT stream_chunk_get_data(IStream *stream, const struct chunk_entry *chunk, return stream_read(stream, data, size); }
+HRESULT stream_chunk_get_data_alt(IStream *stream, const struct chunk_entry *chunk, void *data, + ULONG size, ULONG alt_size) +{ + if (chunk->size != size && chunk->size != alt_size) { + WARN_(dmfile)("%s: doesn't contains the expected data size %lu or %lu\n", debugstr_chunk(chunk), + size, alt_size); + return E_FAIL; + } + return stream_read(stream, data, chunk->size); +} + HRESULT stream_chunk_get_wstr(IStream *stream, const struct chunk_entry *chunk, WCHAR *str, ULONG size) { diff --git a/dlls/dmusic/dmobject.h b/dlls/dmusic/dmobject.h index f2f3ab5215d..183f866ba71 100644 --- a/dlls/dmusic/dmobject.h +++ b/dlls/dmusic/dmobject.h @@ -43,6 +43,8 @@ HRESULT stream_chunk_get_array_alt(IStream *stream, const struct chunk_entry *ch unsigned int *count, DWORD elem_size, DWORD alt_size); HRESULT stream_chunk_get_data(IStream *stream, const struct chunk_entry *chunk, void *data, ULONG size); +HRESULT stream_chunk_get_data_alt(IStream *stream, const struct chunk_entry *chunk, void *data, + ULONG size, ULONG alt_size); HRESULT stream_chunk_get_wstr(IStream *stream, const struct chunk_entry *chunk, WCHAR *str, ULONG size);
From: Michael Stefaniuc mstefani@winehq.org
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58493 --- dlls/dmstyle/style.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/dlls/dmstyle/style.c b/dlls/dmstyle/style.c index 759c47340f4..bb44d63a2e0 100644 --- a/dlls/dmstyle/style.c +++ b/dlls/dmstyle/style.c @@ -442,7 +442,8 @@ static HRESULT parse_pref_list(struct style *This, IStream *stream, struct chunk switch (MAKE_IDTYPE(chunk.id, chunk.type)) { case DMUS_FOURCC_PARTREF_CHUNK: - hr = stream_chunk_get_data(stream, &chunk, &part_ref->header, sizeof(part_ref->header)); + hr = stream_chunk_get_data_alt(stream, &chunk, &part_ref->header, sizeof(part_ref->header), + offsetof(DMUS_IO_PARTREF, wPad)); break;
case MAKE_IDTYPE(FOURCC_LIST, DMUS_FOURCC_UNFO_LIST): @@ -482,7 +483,8 @@ static HRESULT parse_part_list(struct style *This, IStream *stream, struct chunk switch (MAKE_IDTYPE(chunk.id, chunk.type)) { case DMUS_FOURCC_PART_CHUNK: - hr = stream_chunk_get_data(stream, &chunk, &part->header, sizeof(part->header)); + hr = stream_chunk_get_data_alt(stream, &chunk, &part->header, sizeof(part->header), + offsetof(DMUS_IO_STYLEPART, bPad[1])); break;
case MAKE_IDTYPE(FOURCC_LIST, DMUS_FOURCC_UNFO_LIST): @@ -552,7 +554,8 @@ static HRESULT parse_pttn_list(struct style *This, IStream *stream, struct chunk break;
case DMUS_FOURCC_PATTERN_CHUNK: - hr = stream_chunk_get_data(stream, &chunk, &pattern->pattern, sizeof(pattern->pattern)); + hr = stream_chunk_get_data_alt(stream, &chunk, &pattern->pattern, sizeof(pattern->pattern), + offsetof(DMUS_IO_PATTERN, bDestGrooveBottom)); break;
case DMUS_FOURCC_RHYTHM_CHUNK:
None of the failed tests are DMusic related