mirror of
https://github.com/isledecomp/isle.git
synced 2026-01-21 07:11:16 +00:00
MXIOINFO Progress
* MXIOINFO: 100% * ~MXIOINFO: 100% * Close: 100% * Open: 100% * SetBuffer: 80% (matching except register allocation) * Something: 96% (matching except == comparison args swapped) * Read: 59% (having trouble with the loop)
This commit is contained in:
parent
8dfacd18d8
commit
7d6fb5432c
@ -1,4 +1,5 @@
|
||||
#include "mxioinfo.h"
|
||||
#include "ddraw.h"
|
||||
|
||||
// OFFSET: LEGO1 0x100cc800
|
||||
MXIOINFO::MXIOINFO()
|
||||
@ -12,38 +13,331 @@ MXIOINFO::~MXIOINFO()
|
||||
Close(0);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100cc8e0
|
||||
unsigned short MXIOINFO::Close(long arg)
|
||||
{
|
||||
short result = 0;
|
||||
if (m_info.hmmio != NULL)
|
||||
{
|
||||
result = Flush(0);
|
||||
|
||||
_lclose((HFILE)m_info.hmmio);
|
||||
m_info.hmmio = NULL;
|
||||
|
||||
if (m_info.dwFlags & MMIO_ALLOCBUF)
|
||||
free(m_info.pchBuffer);
|
||||
|
||||
m_info.pchEndWrite = NULL;
|
||||
m_info.pchEndRead = NULL;
|
||||
m_info.pchBuffer = NULL;
|
||||
m_info.dwFlags = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100cc830
|
||||
unsigned short MXIOINFO::Open(const char *filename, DWORD fdwOpen)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100cc8e0
|
||||
void MXIOINFO::Close(long arg)
|
||||
{
|
||||
|
||||
_OFSTRUCT lpReOpenBuff;
|
||||
unsigned short result = 0;
|
||||
|
||||
m_info.lBufOffset = 0;
|
||||
m_info.lDiskOffset = 0;
|
||||
m_info.hmmio = (HMMIO)OpenFile(filename, &lpReOpenBuff, (unsigned short)fdwOpen);
|
||||
|
||||
if (m_info.hmmio != (HMMIO)HFILE_ERROR)
|
||||
{
|
||||
m_info.dwFlags = fdwOpen;
|
||||
if (m_info.dwFlags & MMIO_ALLOCBUF)
|
||||
{
|
||||
long currentLength = m_info.cchBuffer != 0 ? m_info.cchBuffer : 0x2000;
|
||||
|
||||
char* buffer = (char*)malloc(currentLength);
|
||||
if (buffer == NULL)
|
||||
{
|
||||
m_info.cchBuffer = 0;
|
||||
m_info.dwFlags &= ~MMIO_ALLOCBUF;
|
||||
m_info.pchBuffer = NULL;
|
||||
result = MMIOERR_OUTOFMEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_info.cchBuffer = currentLength;
|
||||
m_info.pchBuffer = buffer;
|
||||
}
|
||||
m_info.pchEndRead = m_info.pchBuffer;
|
||||
m_info.pchNext = m_info.pchBuffer;
|
||||
m_info.pchEndWrite = m_info.pchBuffer + m_info.cchBuffer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = MMIOERR_CANNOTOPEN;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Not close to a match yet.
|
||||
// OFFSET: LEGO1 0x100cc930
|
||||
unsigned long MXIOINFO::Read(HPSTR pch, LONG cch)
|
||||
{
|
||||
return 0;
|
||||
long result = 0;
|
||||
if (m_info.pchBuffer != NULL)
|
||||
{
|
||||
LONG toRead = m_info.pchEndRead - m_info.pchNext;
|
||||
unsigned long remaining = cch;
|
||||
do
|
||||
{
|
||||
if (toRead > 0) {
|
||||
if (toRead > remaining) {
|
||||
toRead = remaining;
|
||||
}
|
||||
remaining -= toRead;
|
||||
memcpy(pch, m_info.pchNext, toRead);
|
||||
m_info.pchNext += toRead;
|
||||
}
|
||||
} while (remaining && !Something(0) && m_info.pchEndRead - m_info.pchNext >= 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_info.hmmio != NULL && cch > 0) {
|
||||
result = _hread((HFILE)m_info.hmmio, pch, cch);
|
||||
if (result == -1) {
|
||||
result = 0;
|
||||
m_info.lDiskOffset = GetCurrentOffset();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_info.lDiskOffset += result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// First attemp, not particularly close, see some sensible logic of what the
|
||||
// function is trying to do.
|
||||
// OFFSET: LEGO1 0x100cca00
|
||||
LONG MXIOINFO::Seek(LONG lOffset, int iOrigin)
|
||||
{
|
||||
return 0;
|
||||
LONG result = -1;
|
||||
if (m_info.pchBuffer != NULL)
|
||||
{
|
||||
// Convert to SEEK_SET
|
||||
if (iOrigin == SEEK_CUR) {
|
||||
if (lOffset == 0) {
|
||||
// Nothing to do
|
||||
return (LONG)(m_info.pchNext + m_info.lBufOffset - m_info.pchBuffer);
|
||||
} else {
|
||||
iOrigin = 0;
|
||||
lOffset = (LONG)(m_info.pchNext + lOffset + m_info.lBufOffset - m_info.pchBuffer);
|
||||
}
|
||||
} else if (iOrigin == SEEK_END) {
|
||||
// Not implemented
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Seek distance is already within the buffer
|
||||
if ((m_info.lBufOffset <= lOffset) && (lOffset < m_info.cchBuffer + m_info.lBufOffset)) {
|
||||
m_info.pchNext = m_info.pchBuffer + lOffset - m_info.lBufOffset;
|
||||
return lOffset;
|
||||
}
|
||||
|
||||
// Do SEEK_CUR on the underlying file handle
|
||||
if (m_info.hmmio != NULL) {
|
||||
short result = Flush(0);
|
||||
if (result == 0) {
|
||||
LONG newOffset = _llseek((HFILE)m_info.hmmio, lOffset, iOrigin);
|
||||
m_info.lDiskOffset = newOffset;
|
||||
if (newOffset == -1) {
|
||||
m_info.lDiskOffset = GetCurrentOffset();
|
||||
return -1;
|
||||
}
|
||||
LONG wholeBlockOffset = lOffset - (int)(lOffset % m_info.cchBuffer);
|
||||
m_info.lBufOffset = wholeBlockOffset;
|
||||
if (lOffset != wholeBlockOffset) {
|
||||
LONG newOffset2 = _llseek((HFILE)m_info.hmmio, wholeBlockOffset, 0);
|
||||
m_info.lDiskOffset = newOffset2;
|
||||
if (newOffset2 == -1) {
|
||||
m_info.lDiskOffset = GetCurrentOffset();
|
||||
}
|
||||
}
|
||||
if (m_info.lDiskOffset == m_info.lBufOffset) {
|
||||
DWORD rw = m_info.dwFlags & MMIO_RWMODE;
|
||||
if (rw != MMIO_READ && rw != MMIO_READWRITE) {
|
||||
m_info.pchNext = m_info.pchBuffer + lOffset - m_info.lBufOffset;
|
||||
return lOffset;
|
||||
}
|
||||
LONG bytesRead = _hread((HFILE)m_info.hmmio, m_info.pchBuffer, m_info.cchBuffer);
|
||||
if (bytesRead == -1) {
|
||||
m_info.lDiskOffset = GetCurrentOffset();
|
||||
return -1;
|
||||
}
|
||||
m_info.lDiskOffset += bytesRead;
|
||||
m_info.pchNext = m_info.pchBuffer + lOffset - m_info.lBufOffset;
|
||||
m_info.pchEndRead = m_info.pchBuffer + bytesRead;
|
||||
if (m_info.pchNext < m_info.pchEndRead) {
|
||||
return lOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_info.hmmio != NULL) {
|
||||
if ((iOrigin == SEEK_CUR) && (lOffset == 0)) {
|
||||
return m_info.lDiskOffset;
|
||||
}
|
||||
result = _llseek((HFILE)m_info.hmmio, lOffset, iOrigin);
|
||||
m_info.lDiskOffset = result;
|
||||
if (result == HFILE_ERROR) {
|
||||
m_info.lDiskOffset = GetCurrentOffset();
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Matching except for swap of EAX and ECX
|
||||
// OFFSET: LEGO1 0x100ccbc0
|
||||
void MXIOINFO::SetBuffer(LPSTR pchBuffer, LONG cchBuffer, LONG unk)
|
||||
unsigned short MXIOINFO::SetBuffer(LPSTR pchBuffer, LONG cchBuffer, UINT fuBuffer)
|
||||
{
|
||||
|
||||
unsigned short ret = Flush(0);
|
||||
if (m_info.dwFlags & MMIO_ALLOCBUF)
|
||||
{
|
||||
m_info.dwFlags &= ~MMIO_ALLOCBUF;
|
||||
free(m_info.pchBuffer);
|
||||
}
|
||||
m_info.pchBuffer = pchBuffer;
|
||||
m_info.cchBuffer = cchBuffer;
|
||||
m_info.pchEndRead = pchBuffer;
|
||||
m_info.pchEndWrite = pchBuffer + cchBuffer;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100cce60
|
||||
unsigned short MXIOINFO::Descend(LPMMCKINFO pmmcki, const MMCKINFO *pmmckiParent, UINT fuDescend)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Not a close match, but the behavior looks reasonable.
|
||||
// OFFSET: LEGO1 0x100ccc10
|
||||
unsigned short MXIOINFO::Flush(int arg)
|
||||
{
|
||||
unsigned short result = 0;
|
||||
if (m_info.dwFlags & MMIO_DIRTY)
|
||||
{
|
||||
if (m_info.pchBuffer == NULL)
|
||||
{
|
||||
result = MMIOERR_UNBUFFERED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_info.hmmio == NULL || (m_info.dwFlags & MMIO_RWMODE) == 0)
|
||||
{
|
||||
return MMIOERR_CANNOTWRITE;
|
||||
}
|
||||
if (m_info.cchBuffer > 0)
|
||||
{
|
||||
if (m_info.lDiskOffset != m_info.lBufOffset)
|
||||
{
|
||||
m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, m_info.lBufOffset, 0);
|
||||
}
|
||||
if (m_info.lBufOffset == m_info.lDiskOffset)
|
||||
{
|
||||
long written = _hwrite((HFILE)m_info.hmmio, m_info.pchBuffer, m_info.cchBuffer);
|
||||
if (written != -1 && m_info.cchBuffer == written)
|
||||
{
|
||||
m_info.lDiskOffset += written;
|
||||
m_info.dwFlags &= ~MMIO_DIRTY;
|
||||
m_info.pchNext = m_info.pchBuffer;
|
||||
return 0;
|
||||
}
|
||||
m_info.lDiskOffset = GetCurrentOffset();
|
||||
return MMIOERR_CANNOTWRITE;
|
||||
}
|
||||
m_info.lDiskOffset = GetCurrentOffset();
|
||||
return MMIOERR_CANNOTSEEK;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// 97% Match, just two locations have the order of an == comparison swapped.
|
||||
// I suspect this isn't how the code was originally written, because I have to
|
||||
// include an empty if branch to get the code almost matching, though it is a
|
||||
// place where you logically could have an empty block.
|
||||
// OFFSET: LEGO1 0x100ccd00
|
||||
unsigned short MXIOINFO::Something(UINT flags)
|
||||
{
|
||||
short result = 0;
|
||||
DWORD rwState = m_info.dwFlags & MMIO_RWMODE;
|
||||
if (m_info.pchBuffer != NULL)
|
||||
{
|
||||
LONG cchBuffer = m_info.cchBuffer;
|
||||
if (((rwState == MMIO_WRITE) || (rwState == MMIO_READWRITE)) && (m_info.dwFlags & MMIO_DIRTY))
|
||||
{
|
||||
if (((flags & MMIO_WRITE) || (rwState == MMIO_READWRITE)) && (cchBuffer > 0))
|
||||
{
|
||||
if (m_info.lDiskOffset != m_info.lBufOffset) {
|
||||
m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, m_info.lBufOffset, 0);
|
||||
}
|
||||
if (m_info.lDiskOffset != m_info.lBufOffset)
|
||||
{
|
||||
result = MMIOERR_CANNOTSEEK;
|
||||
m_info.lDiskOffset = GetCurrentOffset();
|
||||
}
|
||||
else
|
||||
{
|
||||
LONG bytesWritten = _hwrite((HFILE)m_info.hmmio, m_info.pchBuffer, cchBuffer);
|
||||
if ((bytesWritten != -1) && (cchBuffer == bytesWritten)) {
|
||||
m_info.lDiskOffset += bytesWritten;
|
||||
m_info.dwFlags = m_info.dwFlags & ~MMIO_DIRTY;
|
||||
m_info.pchNext = m_info.pchBuffer;
|
||||
m_info.pchEndRead = m_info.pchBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = MMIOERR_CANNOTWRITE;
|
||||
m_info.lDiskOffset = GetCurrentOffset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_info.lBufOffset = m_info.lBufOffset + cchBuffer;
|
||||
if (((rwState != MMIO_READ) && (rwState != MMIO_READWRITE)) || cchBuffer <= 0) {
|
||||
// Nothing to do
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_info.lDiskOffset != m_info.lBufOffset) {
|
||||
m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, m_info.lBufOffset, 0);
|
||||
}
|
||||
if (m_info.lDiskOffset != m_info.lBufOffset) {
|
||||
result = MMIOERR_CANNOTSEEK;
|
||||
m_info.lDiskOffset = GetCurrentOffset();
|
||||
} else {
|
||||
LONG bytesRead = _hread((HFILE)m_info.hmmio, m_info.pchBuffer, cchBuffer);
|
||||
if (bytesRead == -1) {
|
||||
result = MMIOERR_CANNOTREAD;
|
||||
m_info.lDiskOffset = GetCurrentOffset();
|
||||
} else {
|
||||
m_info.lDiskOffset += bytesRead;
|
||||
m_info.pchNext = m_info.pchBuffer;
|
||||
m_info.pchEndRead = m_info.pchBuffer + bytesRead;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = MMIOERR_UNBUFFERED;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -12,11 +12,15 @@ class MXIOINFO
|
||||
__declspec(dllexport) ~MXIOINFO();
|
||||
|
||||
unsigned short Open(const char *filename, DWORD fdwOpen);
|
||||
void Close(long arg);
|
||||
unsigned short Close(long arg);
|
||||
LONG Seek(LONG lOffset, int iOrigin);
|
||||
unsigned long Read(HPSTR pch, LONG cch);
|
||||
void SetBuffer(LPSTR pchBuffer, LONG cchBuffer, LONG unk);
|
||||
unsigned short SetBuffer(LPSTR pchBuffer, LONG cchBuffer, UINT fuBuffer);
|
||||
unsigned short Descend(LPMMCKINFO pmmcki, const MMCKINFO *pmmckiParent, UINT fuDescend);
|
||||
unsigned short Flush(int arg);
|
||||
unsigned short Something(UINT flags);
|
||||
|
||||
inline LONG GetCurrentOffset() { return _llseek((HFILE)m_info.hmmio, 0, SEEK_CUR); }
|
||||
|
||||
MMIOINFO m_info;
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user