Move offset alteration in IOMAN's OpticalMediaDevice.

This commit is contained in:
Jean-Philip Desjardins 2023-01-12 16:28:23 -05:00
parent 081668d523
commit db50cc9370
3 changed files with 60 additions and 6 deletions

View file

@ -36,11 +36,7 @@ void CFile::Seek(int64 amount, Framework::STREAM_SEEK_DIRECTION whence)
case Framework::STREAM_SEEK_END:
//Cannot seek from end with unbounded files
assert(m_end != ULLONG_MAX);
// We need to abs the amount, as the seek end works with both
// positive and negative offsets, which do the same.
// e.g. Shadow of Ganymede uses a positive offset, while it
// should be negative.
m_position = size - std::abs(amount);
m_position = size + amount;
break;
}
m_position = std::max<int64>(m_position, 0);

View file

@ -40,7 +40,12 @@ Framework::CStream* COpticalMediaDevice::GetFile(uint32 mode, const char* device
std::transform(fixedString.begin(), fixedString.end(), fixedString.begin(), &COpticalMediaDevice::FixSlashes);
fixedString = RemoveExtraVersionSpecifiers(fixedString);
auto fileSystem = m_opticalMedia->GetFileSystem();
return fileSystem->Open(fixedString.c_str());
auto fileStream = std::unique_ptr<Framework::CStream>(fileSystem->Open(fixedString.c_str()));
if(!fileStream)
{
return nullptr;
}
return new COpticalMediaFile(std::move(fileStream));
}
DirectoryIteratorPtr COpticalMediaDevice::GetDirectory(const char* devicePath)
@ -58,3 +63,40 @@ DirectoryIteratorPtr COpticalMediaDevice::GetDirectory(const char* devicePath)
}
return std::make_unique<COpticalMediaDirectoryIterator>(directoryStream);
}
COpticalMediaFile::COpticalMediaFile(std::unique_ptr<Framework::CStream> baseStream)
: m_baseStream(std::move(baseStream))
{
}
void COpticalMediaFile::Seek(int64 offset, Framework::STREAM_SEEK_DIRECTION whence)
{
if((whence == Framework::STREAM_SEEK_END) && (offset > 0))
{
//Some games from Phoenix Games relies on a positive offset seeking backwards when using SEEK_END:
//- Shadow of Ganymede
//- Guerrilla Strike
offset = -offset;
}
m_baseStream->Seek(offset, whence);
}
uint64 COpticalMediaFile::Tell()
{
return m_baseStream->Tell();
}
uint64 COpticalMediaFile::Read(void* buffer, uint64 size)
{
return m_baseStream->Read(buffer, size);
}
uint64 COpticalMediaFile::Write(const void* buffer, uint64 size)
{
return m_baseStream->Write(buffer, size);
}
bool COpticalMediaFile::IsEOF()
{
return m_baseStream->IsEOF();
}

View file

@ -25,5 +25,21 @@ namespace Iop
OpticalMediaPtr& m_opticalMedia;
};
class COpticalMediaFile : public Framework::CStream
{
public:
COpticalMediaFile(std::unique_ptr<Framework::CStream>);
virtual ~COpticalMediaFile() = default;
void Seek(int64, Framework::STREAM_SEEK_DIRECTION) override;
uint64 Tell() override;
uint64 Read(void*, uint64) override;
uint64 Write(const void*, uint64) override;
bool IsEOF() override;
private:
std::unique_ptr<Framework::CStream> m_baseStream;
};
}
}