diff --git a/LEGO1/mxioinfo.cpp b/LEGO1/mxioinfo.cpp index 9df2a564..c834f33d 100644 --- a/LEGO1/mxioinfo.cpp +++ b/LEGO1/mxioinfo.cpp @@ -1,14 +1,15 @@ #include "mxioinfo.h" #include "decomp.h" +// This class should be 72 bytes in size, same as the MMIOINFO struct. +// The current implementation has MMIOINFO as the only member of the class, +// but this assert will enforce the size if we decide to change that. DECOMP_SIZE_ASSERT(MXIOINFO, sizeof(MMIOINFO)); // OFFSET: LEGO1 0x100cc800 MXIOINFO::MXIOINFO() { - // This is not good practice, but shouldn't damage anything - // because MXIOINFO has no vtable. - memset(this, 0, sizeof(*this)); + memset(&m_info, 0, sizeof(m_info)); } // OFFSET: LEGO1 0x100cc820 @@ -23,33 +24,33 @@ MxU16 MXIOINFO::Open(const char *p_filename, MxULong p_flags) OFSTRUCT _unused; MxU16 result = 0; - m_lBufOffset = 0; - m_lDiskOffset = 0; + m_info.lBufOffset = 0; + m_info.lDiskOffset = 0; // Cast of p_flags to u16 forces the `movzx` instruction - m_hmmio = OpenFile(p_filename, &_unused, (MxU16)p_flags); + m_info.hmmio = (HMMIO)OpenFile(p_filename, &_unused, (MxU16)p_flags); - if (m_hmmio != HFILE_ERROR) { - m_dwFlags = p_flags; + if ((HFILE)m_info.hmmio != HFILE_ERROR) { + m_info.dwFlags = p_flags; if (p_flags & MMIO_ALLOCBUF) { // Default buffer length of 8k if none specified - int len = m_cchBuffer ? m_cchBuffer : 8192; + int len = m_info.cchBuffer ? m_info.cchBuffer : 8192; HPSTR buf = new char[len]; if (!buf) { result = MMIOERR_OUTOFMEMORY; - m_cchBuffer = 0; - m_dwFlags &= ~MMIO_ALLOCBUF; - m_pchBuffer = 0; + m_info.cchBuffer = 0; + m_info.dwFlags &= ~MMIO_ALLOCBUF; + m_info.pchBuffer = 0; } else { - m_pchBuffer = buf; - m_cchBuffer = len; + m_info.pchBuffer = buf; + m_info.cchBuffer = len; } - m_pchEndRead = m_pchBuffer; - m_pchNext = m_pchBuffer; - m_pchEndWrite = m_pchBuffer + m_cchBuffer; + 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; @@ -63,18 +64,18 @@ MxU16 MXIOINFO::Close(MxLong p_unused) { MxU16 result = 0; - if (m_hmmio) { + if (m_info.hmmio) { result = Flush(0); - _lclose(m_hmmio); - m_hmmio = NULL; + _lclose((HFILE)m_info.hmmio); + m_info.hmmio = 0; - if (m_dwFlags & MMIO_ALLOCBUF) - delete[] m_pchBuffer; + if (m_info.dwFlags & MMIO_ALLOCBUF) + delete[] m_info.pchBuffer; - m_pchEndWrite = 0; - m_pchEndRead = 0; - m_pchBuffer = 0; - m_dwFlags = 0; + m_info.pchEndWrite = 0; + m_info.pchEndRead = 0; + m_info.pchBuffer = 0; + m_info.dwFlags = 0; } return result; @@ -85,37 +86,37 @@ MxLong MXIOINFO::Read(void *p_buf, MxLong p_len) { MxLong bytes_read = 0; - if (m_pchBuffer) { + if (m_info.pchBuffer) { - int bytes_left = m_pchEndRead - m_pchNext; + int bytes_left = m_info.pchEndRead - m_info.pchNext; while (p_len > 0) { if (bytes_left > 0) { if (p_len < bytes_left) bytes_left = p_len; - memcpy(p_buf, m_pchNext, bytes_left); + memcpy(p_buf, m_info.pchNext, bytes_left); p_len -= bytes_left; - m_pchNext += bytes_left; + m_info.pchNext += bytes_left; bytes_read += bytes_left; } if (p_len <= 0 || Advance(0)) break; - bytes_left = m_pchEndRead - m_pchNext; + bytes_left = m_info.pchEndRead - m_info.pchNext; if (bytes_left <= 0) break; } - } else if (m_hmmio && p_len > 0) { - bytes_read = _hread(m_hmmio, p_buf, p_len); + } else if (m_info.hmmio && p_len > 0) { + bytes_read = _hread((HFILE)m_info.hmmio, p_buf, p_len); if (bytes_read == -1) { bytes_read = 0; - m_lDiskOffset = _llseek(m_hmmio, 0, SEEK_CUR); + m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, 0, SEEK_CUR); } else { - m_lDiskOffset += bytes_read; + m_info.lDiskOffset += bytes_read; } } @@ -128,15 +129,15 @@ MxLong MXIOINFO::Seek(MxLong p_offset, int p_origin) MxLong result = -1; // If buffered I/O - if (m_pchBuffer) { + if (m_info.pchBuffer) { if (p_origin == SEEK_CUR) { if (!p_offset) { // don't seek at all and just return where we are. - return m_lBufOffset + (m_pchNext - m_pchBuffer); + return m_info.lBufOffset + (m_info.pchNext - m_info.pchBuffer); } else { // With SEEK_CUR, p_offset is a relative offset. // Get the absolute position instead and use SEEK_SET. - p_offset += m_lBufOffset + (m_pchNext - m_pchBuffer); + p_offset += m_info.lBufOffset + (m_info.pchNext - m_info.pchBuffer); p_origin = SEEK_SET; } } else if (p_origin == SEEK_END) { @@ -148,52 +149,52 @@ MxLong MXIOINFO::Seek(MxLong p_offset, int p_origin) // is p_offset between the start and end of the buffer? // i.e. can we do the seek without reading more from disk? - if (p_offset >= m_lBufOffset && p_offset < m_lBufOffset + m_cchBuffer) { - m_pchNext = m_pchBuffer + (p_offset - m_lBufOffset); + if (p_offset >= m_info.lBufOffset && p_offset < m_info.lBufOffset + m_info.cchBuffer) { + m_info.pchNext = m_info.pchBuffer + (p_offset - m_info.lBufOffset); result = p_offset; } else { // we have to read another chunk from disk. - if (m_hmmio && !Flush(0)) { - m_lDiskOffset = _llseek(m_hmmio, p_offset, p_origin); + if (m_info.hmmio && !Flush(0)) { + m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, p_offset, p_origin); - if (m_lDiskOffset == -1) { - m_lDiskOffset = _llseek(m_hmmio, 0, SEEK_CUR); + if (m_info.lDiskOffset == -1) { + m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, 0, SEEK_CUR); } else { // align offset to buffer size - int new_offset = p_offset - (p_offset % m_cchBuffer); - m_lBufOffset = new_offset; + int new_offset = p_offset - (p_offset % m_info.cchBuffer); + m_info.lBufOffset = new_offset; // do we need to seek again? // (i.e. are we already aligned to buffer size?) if (p_offset != new_offset) { - m_lDiskOffset = _llseek(m_hmmio, new_offset, SEEK_SET); + m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, new_offset, SEEK_SET); - if (m_lDiskOffset == -1) { - m_lDiskOffset = _llseek(m_hmmio, 0, SEEK_CUR); + if (m_info.lDiskOffset == -1) { + m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, 0, SEEK_CUR); } } - if (m_lBufOffset == m_lDiskOffset) { + if (m_info.lBufOffset == m_info.lDiskOffset) { // is the file open for writing only? - if ((m_dwFlags & MMIO_RWMODE) && - ((m_dwFlags & MMIO_RWMODE) != MMIO_READWRITE)) { + if ((m_info.dwFlags & MMIO_RWMODE) && + ((m_info.dwFlags & MMIO_RWMODE) != MMIO_READWRITE)) { - m_pchNext = m_pchBuffer - m_lBufOffset + p_offset; + m_info.pchNext = m_info.pchBuffer - m_info.lBufOffset + p_offset; result = p_offset; } else { // We can read from the file. Fill the buffer. - int bytes_read = _hread(m_hmmio, m_pchBuffer, m_cchBuffer); + int bytes_read = _hread((HFILE)m_info.hmmio, m_info.pchBuffer, m_info.cchBuffer); if (bytes_read == -1) { - m_lDiskOffset = _llseek(m_hmmio, 0, SEEK_CUR); + m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, 0, SEEK_CUR); } else { - m_lDiskOffset += bytes_read; - m_pchNext = p_offset - m_lBufOffset + m_pchBuffer; - m_pchEndRead = m_pchBuffer + bytes_read; + m_info.lDiskOffset += bytes_read; + m_info.pchNext = p_offset - m_info.lBufOffset + m_info.pchBuffer; + m_info.pchEndRead = m_info.pchBuffer + bytes_read; - if (m_pchNext < m_pchEndRead) { + if (m_info.pchNext < m_info.pchEndRead) { result = p_offset; } } @@ -204,17 +205,17 @@ MxLong MXIOINFO::Seek(MxLong p_offset, int p_origin) } } else { // No buffer so just seek the file directly (if we have a valid handle) - if (m_hmmio) { + if (m_info.hmmio) { // i.e. if we just want to get the current file position if (p_origin == SEEK_CUR && p_offset == 0) { - return m_lDiskOffset; + return m_info.lDiskOffset; } else { - m_lDiskOffset = _llseek(m_hmmio, p_offset, p_origin); + m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, p_offset, p_origin); - result = m_lDiskOffset; + result = m_info.lDiskOffset; if (result == -1) { - m_lDiskOffset = _llseek(m_hmmio, 0, SEEK_CUR); + m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, 0, SEEK_CUR); } } } @@ -228,15 +229,15 @@ MxU16 MXIOINFO::SetBuffer(char *p_buf, MxLong p_len, MxLong p_unused) { MxU16 result = Flush(0); - if (m_dwFlags & MMIO_ALLOCBUF) { - m_dwFlags &= ~MMIO_ALLOCBUF; - delete[] m_pchBuffer; + if (m_info.dwFlags & MMIO_ALLOCBUF) { + m_info.dwFlags &= ~MMIO_ALLOCBUF; + delete[] m_info.pchBuffer; } - m_pchBuffer = p_buf; - m_cchBuffer = p_len; - m_pchEndWrite = m_pchBuffer + m_cchBuffer; - m_pchEndRead = m_pchBuffer; + m_info.pchBuffer = p_buf; + m_info.cchBuffer = p_len; + m_info.pchEndWrite = m_info.pchBuffer + m_info.cchBuffer; + m_info.pchEndRead = m_info.pchBuffer; return result; } @@ -247,32 +248,32 @@ MxU16 MXIOINFO::Flush(MxU16 p_unused) MxU16 result = 0; // if buffer is dirty - if (m_dwFlags & MMIO_DIRTY) { + if (m_info.dwFlags & MMIO_DIRTY) { // if we have allocated an IO buffer - if (m_pchBuffer) { + if (m_info.pchBuffer) { // if we have a file open for writing - if (m_hmmio && (m_dwFlags & MMIO_RWMODE)) { + if (m_info.hmmio && (m_info.dwFlags & MMIO_RWMODE)) { // (pulling this value out into a variable forces it into EBX) - MxLong cchBuffer = m_cchBuffer; + MxLong cchBuffer = m_info.cchBuffer; if (cchBuffer > 0) { - if (m_lBufOffset != m_lDiskOffset) { - m_lDiskOffset = _llseek(m_hmmio, m_lBufOffset, SEEK_SET); + if (m_info.lBufOffset != m_info.lDiskOffset) { + m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, m_info.lBufOffset, SEEK_SET); } // Was the previous seek (if required) successful? - if (m_lBufOffset != m_lDiskOffset) { + if (m_info.lBufOffset != m_info.lDiskOffset) { result = MMIOERR_CANNOTSEEK; - m_lDiskOffset = _llseek(m_hmmio, 0, SEEK_CUR); + m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, 0, SEEK_CUR); } else { - MxLong bytes_written = _hwrite(m_hmmio, m_pchBuffer, cchBuffer); + MxLong bytes_written = _hwrite((HFILE)m_info.hmmio, m_info.pchBuffer, cchBuffer); if (bytes_written != -1 && bytes_written == cchBuffer) { - m_lDiskOffset += bytes_written; - m_pchNext = m_pchBuffer; - m_dwFlags &= ~MMIO_DIRTY; + m_info.lDiskOffset += bytes_written; + m_info.pchNext = m_info.pchBuffer; + m_info.dwFlags &= ~MMIO_DIRTY; } else { result = MMIOERR_CANNOTWRITE; - m_lDiskOffset = _llseek(m_hmmio, 0, SEEK_CUR); + m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, 0, SEEK_CUR); } } } @@ -291,62 +292,62 @@ MxU16 MXIOINFO::Flush(MxU16 p_unused) MxU16 MXIOINFO::Advance(MxU16 p_option) { MxU16 result = 0; - MxULong rwmode = m_dwFlags & MMIO_RWMODE; + MxULong rwmode = m_info.dwFlags & MMIO_RWMODE; - if (m_pchBuffer) { - MxLong cch = m_cchBuffer; + if (m_info.pchBuffer) { + MxLong cch = m_info.cchBuffer; // If we can and should write to the file, // if we are being asked to write to the file, // and if there is a buffer *to* write: if ((rwmode == MMIO_WRITE || rwmode == MMIO_READWRITE) && - (m_dwFlags & MMIO_DIRTY) && + (m_info.dwFlags & MMIO_DIRTY) && ((p_option & MMIO_WRITE) || (rwmode == MMIO_READWRITE)) && cch > 0) { - if (m_lBufOffset != m_lDiskOffset) { - m_lDiskOffset = _llseek(m_hmmio, m_lBufOffset, SEEK_SET); + if (m_info.lBufOffset != m_info.lDiskOffset) { + m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, m_info.lBufOffset, SEEK_SET); } - if (m_lBufOffset != m_lDiskOffset) { + if (m_info.lBufOffset != m_info.lDiskOffset) { result = MMIOERR_CANNOTSEEK; } else { - MxLong bytes_written = _hwrite(m_hmmio, m_pchBuffer, cch); + MxLong bytes_written = _hwrite((HFILE)m_info.hmmio, m_info.pchBuffer, cch); if (bytes_written != -1 && bytes_written == cch) { - m_lDiskOffset += bytes_written; - m_pchNext = m_pchBuffer; - m_pchEndRead = m_pchBuffer; - m_dwFlags &= ~MMIO_DIRTY; + m_info.lDiskOffset += bytes_written; + m_info.pchNext = m_info.pchBuffer; + m_info.pchEndRead = m_info.pchBuffer; + m_info.dwFlags &= ~MMIO_DIRTY; } else { result = MMIOERR_CANNOTWRITE; } } - m_lDiskOffset = _llseek(m_hmmio, 0, SEEK_CUR); + m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, 0, SEEK_CUR); } - m_lBufOffset += cch; + m_info.lBufOffset += cch; if ((!rwmode || rwmode == MMIO_READWRITE) && cch > 0) { - if (m_lBufOffset != m_lDiskOffset) { - m_lDiskOffset = _llseek(m_hmmio, m_lBufOffset, SEEK_SET); + if (m_info.lBufOffset != m_info.lDiskOffset) { + m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, m_info.lBufOffset, SEEK_SET); } // if previous seek failed - if (m_lBufOffset != m_lDiskOffset) { + if (m_info.lBufOffset != m_info.lDiskOffset) { result = MMIOERR_CANNOTSEEK; - m_lDiskOffset = _llseek(m_hmmio, 0, SEEK_CUR); + m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, 0, SEEK_CUR); } else { - int bytes_read = _hread(m_hmmio, m_pchBuffer, cch); + int bytes_read = _hread((HFILE)m_info.hmmio, m_info.pchBuffer, cch); if (bytes_read == -1) { result = MMIOERR_CANNOTREAD; - m_lDiskOffset = _llseek(m_hmmio, 0, SEEK_CUR); + m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, 0, SEEK_CUR); } else { - m_lDiskOffset += bytes_read; - m_pchNext = m_pchBuffer; - m_pchEndRead = m_pchBuffer + bytes_read; + m_info.lDiskOffset += bytes_read; + m_info.pchNext = m_info.pchBuffer; + m_info.pchEndRead = m_info.pchBuffer + bytes_read; } } } @@ -370,10 +371,10 @@ MxU16 MXIOINFO::Descend(MMCKINFO *p_chunkInfo, const MMCKINFO *p_parentInfo, MxU if (Read(p_chunkInfo, 8) != 8) { result = MMIOERR_CANNOTREAD; } else { - if (m_pchBuffer) { - p_chunkInfo->dwDataOffset = m_pchNext - m_pchBuffer + m_lBufOffset; + if (m_info.pchBuffer) { + p_chunkInfo->dwDataOffset = m_info.pchNext - m_info.pchBuffer + m_info.lBufOffset; } else { - p_chunkInfo->dwDataOffset = m_lDiskOffset; + p_chunkInfo->dwDataOffset = m_info.lDiskOffset; } if (p_chunkInfo->ckid == FOURCC_RIFF || p_chunkInfo->ckid == FOURCC_LIST) { @@ -383,7 +384,7 @@ MxU16 MXIOINFO::Descend(MMCKINFO *p_chunkInfo, const MMCKINFO *p_parentInfo, MxU } } } else { - MxLong ofs = MAXLONG; + MxULong ofs = MAXLONG; if (p_parentInfo) ofs = p_parentInfo->cksize + p_parentInfo->dwDataOffset; @@ -401,10 +402,10 @@ MxU16 MXIOINFO::Descend(MMCKINFO *p_chunkInfo, const MMCKINFO *p_parentInfo, MxU running = FALSE; } else { read_ok = TRUE; - if (m_pchBuffer) { - tmp.dwDataOffset = m_pchNext - m_pchBuffer + m_lBufOffset; + if (m_info.pchBuffer) { + tmp.dwDataOffset = m_info.pchNext - m_info.pchBuffer + m_info.lBufOffset; } else { - tmp.dwDataOffset = m_lDiskOffset; + tmp.dwDataOffset = m_info.lDiskOffset; } if (ofs < tmp.dwDataOffset) { diff --git a/LEGO1/mxioinfo.h b/LEGO1/mxioinfo.h index a42d7a93..83da930a 100644 --- a/LEGO1/mxioinfo.h +++ b/LEGO1/mxioinfo.h @@ -21,31 +21,9 @@ class MXIOINFO MxU16 Advance(MxU16); MxU16 Descend(MMCKINFO *, const MMCKINFO *, MxU16); - // The following is the MMIOINFO struct but with h_mmio set to type HFILE. - - /* general fields */ - DWORD m_dwFlags; /* 0 general status flags */ - FOURCC m_fccIOProc; /* 4 pointer to I/O procedure */ - LPMMIOPROC m_pIOProc; /* 8 pointer to I/O procedure */ - UINT m_wErrorRet; /* c place for error to be returned */ - HTASK m_htask; /* 10 alternate local task */ - - /* fields maintained by MMIO functions during buffered I/O */ - LONG m_cchBuffer; /* 14 size of I/O buffer (or 0L) */ - HPSTR m_pchBuffer; /* 18 start of I/O buffer (or NULL) */ - HPSTR m_pchNext; /* 1c pointer to next byte to read/write */ - HPSTR m_pchEndRead; /* 20 pointer to last valid byte to read */ - HPSTR m_pchEndWrite; /* 24 pointer to last byte to write */ - LONG m_lBufOffset; /* 28 disk offset of start of buffer */ - - /* fields maintained by I/O procedure */ - LONG m_lDiskOffset; /* 2c disk offset of next read or write */ - DWORD m_adwInfo[3]; /* 30 data specific to type of MMIOPROC */ - - /* other fields maintained by MMIO */ - DWORD m_dwReserved1; /* 3c reserved for MMIO use */ - DWORD m_dwReserved2; /* 40 reserved for MMIO use */ - HFILE m_hmmio; /* 44 handle to open file */ + // NOTE: In MXIOINFO, the `hmmio` member of MMIOINFO is used like + // an HFILE (int) instead of an HMMIO (WORD). + MMIOINFO m_info; }; #endif // MXIOINFO_H