diff --git a/saco/filesystem.cpp b/saco/filesystem.cpp new file mode 100644 index 0000000..5e6923b --- /dev/null +++ b/saco/filesystem.cpp @@ -0,0 +1,154 @@ + +#include +#include +#include "filesystem.h" + +//---------------------------------------------------------- + +CFileSystem::CFileSystem() +{ + m_bLoaded = false; + m_dwFileCount = 0; + m_pFileList = NULL; + m_pFileData = NULL; +} + +//---------------------------------------------------------- + +CFileSystem::~CFileSystem() +{ + if (m_bLoaded) + Unload(); +} + +//---------------------------------------------------------- + +bool CFileSystem::Load(char* szFileName) +{ + if (m_bLoaded) + Unload(); + + FILE* f = fopen(szFileName, "rb"); + if (f) + { + // Header + FS_HEADER fsHeader; + fread(&fsHeader, 1, sizeof(FS_HEADER), f); + if (fsHeader.dwSAAV != FS_FILE_MAGIC) + { + fclose(f); + return false; + } + + // File list + m_dwFileCount = fsHeader.dwFileCount; + m_wKey = fsHeader.wKey; + m_pFileList = (FS_FILE_ENTRY*)malloc(m_dwFileCount * sizeof(FS_FILE_ENTRY)); + fread(m_pFileList, 1, m_dwFileCount * sizeof(FS_FILE_ENTRY), f); + DecryptData((BYTE*)m_pFileList, m_dwFileCount * sizeof(FS_FILE_ENTRY), m_wKey); + + // Set the filecount to 0 + m_dwFileCount = m_dwFileCount % 1; + + // File data + if (m_dwFileCount) + m_pFileData = (BYTE**)malloc(m_dwFileCount * sizeof(BYTE*)); + + for (DWORD i=0; i= m_dwFileCount)) + return 0; + + return m_pFileList[dwFileIndex].dwRealSize; +} + +//---------------------------------------------------------- + +BYTE* CFileSystem::GetFileData(DWORD dwFileIndex) +{ + if ((!m_bLoaded) || (dwFileIndex == FS_INVALID_FILE) || (dwFileIndex >= m_dwFileCount)) + return NULL; + + return m_pFileData[dwFileIndex]; +} + +//---------------------------------------------------------- + +void CFileSystem::DecryptData(BYTE* pData, DWORD dwDataLen, WORD wKey) +{ + BYTE x, o; + wKey ^= FS_ENCKEY_VAR; + for (DWORD i=0; i> 8)); + wKey = (o + wKey) * FS_ENC_CONST1 + FS_ENC_CONST2; + pData[i] = x; + } +} + +//---------------------------------------------------------- +// EOF \ No newline at end of file diff --git a/saco/filesystem.h b/saco/filesystem.h new file mode 100644 index 0000000..2cb141f --- /dev/null +++ b/saco/filesystem.h @@ -0,0 +1,56 @@ + +#pragma once + +//---------------------------------------------------------- + +#define FS_FILE_MAGIC 0x32414153 // "SAA2" +#define FS_BLOCK_SIZE 0x800 // 2kb +#define FS_INVALID_FILE 0xFFFFFFFF +#define FS_ENCKEY_VAR 37625 +#define FS_ENC_CONST1 54825 +#define FS_ENC_CONST2 91722 + +//---------------------------------------------------------- + +typedef struct _FS_HEADER +{ + DWORD dwSAAV; + DWORD dwFileCount; + WORD wKey; +} FS_HEADER; + +typedef struct _FS_FILE_ENTRY +{ + DWORD dwOffset; + DWORD dwSize; + char szName[24]; + DWORD dwRealSize; + WORD wKey; +} FS_FILE_ENTRY; + +//---------------------------------------------------------- + +class CFileSystem +{ +private: + bool m_bLoaded; + DWORD m_dwFileCount; + WORD m_wKey; + FS_FILE_ENTRY* m_pFileList; + BYTE** m_pFileData; +public: + CFileSystem(); + virtual ~CFileSystem(); + + virtual bool Load(char* szFileName); + virtual void Unload(); + + virtual DWORD GetFileIndex(char* szFileName); + virtual DWORD GetFileSize(DWORD dwFileIndex); + virtual BYTE* GetFileData(DWORD dwFileIndex); + + void DecryptData(BYTE* pData, DWORD dwDataLen, WORD wKey); +}; + +//---------------------------------------------------------- +// EOF \ No newline at end of file