dmusic: Set instrument stream position where the instrument begins, not at the beginning of the instruments list. Simplify CustomLoad accordingly.
This commit is contained in:
parent
cdf727ebd1
commit
f30c18f3d2
|
@ -118,7 +118,7 @@ static HRESULT WINAPI IDirectMusicCollectionImpl_IDirectMusicCollection_GetInstr
|
|||
if (patch == inst_patch) {
|
||||
*instrument = inst_entry->pInstrument;
|
||||
IDirectMusicInstrument_AddRef(inst_entry->pInstrument);
|
||||
IDirectMusicInstrumentImpl_Custom_Load(inst_entry->pInstrument, This->pStm);
|
||||
IDirectMusicInstrumentImpl_CustomLoad(inst_entry->pInstrument, This->pStm);
|
||||
TRACE(": returning instrument %p\n", *instrument);
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -665,10 +665,11 @@ static HRESULT WINAPI IDirectMusicCollectionImpl_IPersistStream_Load(LPPERSISTST
|
|||
DMUSIC_CreateDirectMusicInstrumentImpl(&IID_IDirectMusicInstrument, (LPVOID*)&new_instrument->pInstrument, NULL);
|
||||
{
|
||||
IDirectMusicInstrumentImpl *instrument = impl_from_IDirectMusicInstrument(new_instrument->pInstrument);
|
||||
/* Store offset and length, they will be needed when loading the instrument */
|
||||
liMove.QuadPart = 0;
|
||||
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, &dlibInstrumentPosition);
|
||||
/* Store offset, it'll be needed later */
|
||||
instrument->liInstrumentPosition.QuadPart = dlibInstrumentPosition.QuadPart - (2 * sizeof(FOURCC) + sizeof(DWORD));
|
||||
instrument->liInstrumentPosition.QuadPart = dlibInstrumentPosition.QuadPart;
|
||||
instrument->length = ListSize[1];
|
||||
do {
|
||||
IStream_Read(stream, &chunk, sizeof(FOURCC) + sizeof(DWORD), NULL);
|
||||
ListCount[1] += sizeof(FOURCC) + sizeof(DWORD) + chunk.dwSize;
|
||||
|
|
|
@ -230,6 +230,7 @@ struct IDirectMusicInstrumentImpl {
|
|||
|
||||
/* IDirectMusicInstrumentImpl fields */
|
||||
LARGE_INTEGER liInstrumentPosition; /* offset in a stream where instrument chunk can be found */
|
||||
ULONG length; /* Length of the instrument in the stream */
|
||||
LPGUID pInstrumentID;
|
||||
LPINSTHEADER pHeader;
|
||||
WCHAR wszName[DMUS_MAX_NAME];
|
||||
|
@ -242,7 +243,7 @@ static inline IDirectMusicInstrumentImpl *impl_from_IDirectMusicInstrument(IDire
|
|||
}
|
||||
|
||||
/* custom :) */
|
||||
extern HRESULT IDirectMusicInstrumentImpl_Custom_Load (LPDIRECTMUSICINSTRUMENT iface, LPSTREAM pStm) DECLSPEC_HIDDEN;
|
||||
extern HRESULT IDirectMusicInstrumentImpl_CustomLoad(IDirectMusicInstrument *iface, IStream *stream) DECLSPEC_HIDDEN;
|
||||
|
||||
/**********************************************************************
|
||||
* Dll lifetime tracking declaration for dmusic.dll
|
||||
|
|
|
@ -156,140 +156,68 @@ static inline DWORD subtract_bytes(DWORD len, DWORD bytes)
|
|||
return len - bytes;
|
||||
}
|
||||
|
||||
static HRESULT load_instrument(IDirectMusicInstrumentImpl *This, IStream *stream, DWORD length)
|
||||
static inline HRESULT advance_stream(IStream *stream, ULONG bytes)
|
||||
{
|
||||
HRESULT hr;
|
||||
FOURCC fourcc;
|
||||
DWORD bytes;
|
||||
LARGE_INTEGER move;
|
||||
HRESULT ret;
|
||||
|
||||
while(length){
|
||||
hr = read_from_stream(stream, &fourcc, sizeof(fourcc));
|
||||
if(FAILED(hr))
|
||||
return hr;
|
||||
move.QuadPart = bytes;
|
||||
|
||||
hr = read_from_stream(stream, &bytes, sizeof(bytes));
|
||||
if(FAILED(hr))
|
||||
return hr;
|
||||
ret = IStream_Seek(stream, move, STREAM_SEEK_CUR, NULL);
|
||||
if (FAILED(ret))
|
||||
WARN("IStream_Seek failed: %08x\n", ret);
|
||||
|
||||
length = subtract_bytes(length, sizeof(fourcc) + sizeof(bytes));
|
||||
|
||||
switch(fourcc){
|
||||
case FOURCC_INSH:
|
||||
TRACE("INSH chunk: %u bytes\n", bytes);
|
||||
hr = read_from_stream(stream, This->pHeader, sizeof(*This->pHeader));
|
||||
if(FAILED(hr))
|
||||
return hr;
|
||||
|
||||
move.QuadPart = bytes - sizeof(*This->pHeader);
|
||||
hr = IStream_Seek(stream, move, STREAM_SEEK_CUR, NULL);
|
||||
if(FAILED(hr)){
|
||||
WARN("IStream_Seek failed: %08x\n", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
length = subtract_bytes(length, bytes);
|
||||
break;
|
||||
|
||||
case FOURCC_DLID:
|
||||
TRACE("DLID chunk: %u bytes\n", bytes);
|
||||
hr = read_from_stream(stream, This->pInstrumentID, sizeof(*This->pInstrumentID));
|
||||
if(FAILED(hr))
|
||||
return hr;
|
||||
|
||||
move.QuadPart = bytes - sizeof(*This->pInstrumentID);
|
||||
hr = IStream_Seek(stream, move, STREAM_SEEK_CUR, NULL);
|
||||
if(FAILED(hr)){
|
||||
WARN("IStream_Seek failed: %08x\n", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
length = subtract_bytes(length, bytes);
|
||||
break;
|
||||
|
||||
default:
|
||||
TRACE("Unknown chunk %s: %u bytes\n", debugstr_fourcc(fourcc), bytes);
|
||||
|
||||
move.QuadPart = bytes;
|
||||
hr = IStream_Seek(stream, move, STREAM_SEEK_CUR, NULL);
|
||||
if(FAILED(hr)){
|
||||
WARN("IStream_Seek failed: %08x\n", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
length = subtract_bytes(length, bytes);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* aux. function that completely loads instrument; my tests indicate that it's
|
||||
called somewhere around IDirectMusicCollection_GetInstrument */
|
||||
HRESULT IDirectMusicInstrumentImpl_Custom_Load(LPDIRECTMUSICINSTRUMENT iface, LPSTREAM stream)
|
||||
/* Function that loads all instrument data and which is called from IDirectMusicCollection_GetInstrument as in native */
|
||||
HRESULT IDirectMusicInstrumentImpl_CustomLoad(IDirectMusicInstrument *iface, IStream *stream)
|
||||
{
|
||||
IDirectMusicInstrumentImpl *This = impl_from_IDirectMusicInstrument(iface);
|
||||
LARGE_INTEGER move;
|
||||
FOURCC fourcc;
|
||||
DWORD bytes;
|
||||
HRESULT hr;
|
||||
DMUS_PRIVATE_CHUNK chunk;
|
||||
ULONG length = This->length;
|
||||
|
||||
TRACE("(%p, %p, offset = %s)\n", This, stream, wine_dbgstr_longlong(This->liInstrumentPosition.QuadPart));
|
||||
TRACE("(%p, %p): offset = 0x%s, length = %u)\n", This, stream, wine_dbgstr_longlong(This->liInstrumentPosition.QuadPart), This->length);
|
||||
|
||||
hr = IStream_Seek(stream, This->liInstrumentPosition, STREAM_SEEK_SET, NULL);
|
||||
if(FAILED(hr)){
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WARN("IStream_Seek failed: %08x\n", hr);
|
||||
goto load_failure;
|
||||
return DMUS_E_UNSUPPORTED_STREAM;
|
||||
}
|
||||
|
||||
hr = read_from_stream(stream, &fourcc, sizeof(fourcc));
|
||||
if(FAILED(hr))
|
||||
goto load_failure;
|
||||
while (length)
|
||||
{
|
||||
hr = read_from_stream(stream, &chunk, sizeof(chunk));
|
||||
if (FAILED(hr))
|
||||
return DMUS_E_UNSUPPORTED_STREAM;
|
||||
|
||||
if(fourcc != FOURCC_LIST){
|
||||
WARN("Loading failed: Expected LIST chunk, got: %s\n", debugstr_fourcc(fourcc));
|
||||
goto load_failure;
|
||||
}
|
||||
length = subtract_bytes(length, sizeof(chunk) + chunk.dwSize);
|
||||
|
||||
hr = read_from_stream(stream, &bytes, sizeof(bytes));
|
||||
if(FAILED(hr))
|
||||
goto load_failure;
|
||||
switch (chunk.fccID)
|
||||
{
|
||||
case FOURCC_INSH:
|
||||
case FOURCC_DLID:
|
||||
TRACE("Chunk %s: %u bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize);
|
||||
|
||||
TRACE("LIST chunk: %u bytes\n", bytes);
|
||||
while(1){
|
||||
hr = read_from_stream(stream, &fourcc, sizeof(fourcc));
|
||||
if(FAILED(hr))
|
||||
goto load_failure;
|
||||
/* Instrument header and id are already set so just skip */
|
||||
hr = advance_stream(stream, chunk.dwSize);
|
||||
if (FAILED(hr))
|
||||
return DMUS_E_UNSUPPORTED_STREAM;
|
||||
|
||||
switch(fourcc){
|
||||
case FOURCC_INS:
|
||||
TRACE("INS chunk: (no byte count)\n");
|
||||
hr = load_instrument(This, stream, bytes - sizeof(FOURCC));
|
||||
if(FAILED(hr))
|
||||
goto load_failure;
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
hr = read_from_stream(stream, &bytes, sizeof(bytes));
|
||||
if(FAILED(hr))
|
||||
goto load_failure;
|
||||
default:
|
||||
TRACE("Unknown chunk %s: %u bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize);
|
||||
|
||||
TRACE("Unknown chunk %s: %u bytes\n", debugstr_fourcc(fourcc), bytes);
|
||||
hr = advance_stream(stream, chunk.dwSize);
|
||||
if (FAILED(hr))
|
||||
return DMUS_E_UNSUPPORTED_STREAM;
|
||||
|
||||
move.QuadPart = bytes;
|
||||
hr = IStream_Seek(stream, move, STREAM_SEEK_CUR, NULL);
|
||||
if(FAILED(hr)){
|
||||
WARN("IStream_Seek failed: %08x\n", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
||||
load_failure:
|
||||
return DMUS_E_UNSUPPORTED_STREAM;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue