mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-25 07:21:14 +01:00
updating the HLE FS and FileIO
added banner support of the savegames for wii... same games git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1031 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
dad9f74b09
commit
046ca53f8c
@ -56,11 +56,13 @@ void CFileSearch::FindFiles(const std::string& _searchString, const std::string&
|
||||
bool bkeepLooping = true;
|
||||
|
||||
while (bkeepLooping)
|
||||
{
|
||||
std::string strFilename;
|
||||
BuildCompleteFilename(strFilename, _strPath, findData.cFileName);
|
||||
|
||||
m_FileNames.push_back(strFilename);
|
||||
{
|
||||
if (findData.cFileName[0] != '.')
|
||||
{
|
||||
std::string strFilename;
|
||||
BuildCompleteFilename(strFilename, _strPath, findData.cFileName);
|
||||
m_FileNames.push_back(strFilename);
|
||||
}
|
||||
|
||||
bkeepLooping = FindNextFile(FindFirst, &findData) ? true : false;
|
||||
}
|
||||
|
@ -48,6 +48,10 @@ bool Exists(const char *filename)
|
||||
bool IsDirectory(const char *filename)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
DWORD Attribs = GetFileAttributes(filename);
|
||||
if (Attribs == INVALID_FILE_ATTRIBUTES)
|
||||
return false;
|
||||
|
||||
return (GetFileAttributes(filename) & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
#else
|
||||
struct stat file_info;
|
||||
@ -163,11 +167,15 @@ std::string GetUserDirectory()
|
||||
|
||||
u64 GetSize(const char *filename)
|
||||
{
|
||||
FILE *f = fopen(filename, "rb");
|
||||
fseek(f, 0, SEEK_END);
|
||||
u64 pos = ftell(f);
|
||||
fclose(f);
|
||||
return pos;
|
||||
FILE *pFile = fopen(filename, "rb");
|
||||
if (pFile)
|
||||
{
|
||||
fseek(pFile, 0, SEEK_END);
|
||||
u64 pos = ftell(pFile);
|
||||
fclose(pFile);
|
||||
return pos;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
@ -236,4 +244,14 @@ u32 ScanDirectoryTree(const std::string& _Directory, FSTEntry& parentEntry)
|
||||
}
|
||||
#endif
|
||||
|
||||
bool CreateEmptyFile(const char *filename)
|
||||
{
|
||||
FILE* pFile = fopen(filename, "wb");
|
||||
if (pFile == NULL)
|
||||
return false;
|
||||
|
||||
fclose(pFile);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -35,6 +35,7 @@ struct FSTEntry
|
||||
std::vector<FSTEntry> children;
|
||||
};
|
||||
|
||||
std::string SanitizePath(const char *filename);
|
||||
bool Exists(const char *filename);
|
||||
void Launch(const char *filename);
|
||||
void Explore(const char *path);
|
||||
@ -43,6 +44,7 @@ bool CreateDir(const char *filename);
|
||||
bool Delete(const char *filename);
|
||||
u64 GetSize(const char *filename);
|
||||
std::string GetUserDirectory();
|
||||
bool CreateEmptyFile(const char *filename);
|
||||
|
||||
u32 ScanDirectoryTree(const std::string& _Directory, FSTEntry& parentEntry);
|
||||
|
||||
|
@ -16,10 +16,31 @@
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include "Common.h"
|
||||
#include "FileUtil.h"
|
||||
|
||||
#include "WII_IPC_HLE_Device_FileIO.h"
|
||||
|
||||
|
||||
|
||||
std::string HLE_IPC_BuildFilename(const char* _pFilename, int _size)
|
||||
{
|
||||
char Buffer[128];
|
||||
memcpy(Buffer, _pFilename, _size);
|
||||
|
||||
std::string Filename("WII");
|
||||
if (Buffer[1] == '0')
|
||||
Filename += std::string("/title"); // this looks and feel like an hack...
|
||||
|
||||
Filename += File::SanitizePath(Buffer);
|
||||
|
||||
return Filename;
|
||||
}
|
||||
|
||||
|
||||
/// ----------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName )
|
||||
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
|
||||
, m_pFileHandle(NULL)
|
||||
@ -43,16 +64,6 @@ CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress)
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string HLE_IPC_BuildFilename(const char* _pFilename)
|
||||
{
|
||||
std::string Filename("WII");
|
||||
if (_pFilename[1] == '0')
|
||||
Filename += std::string("/title"); // this looks and feel like an hack...
|
||||
Filename += std::string (_pFilename);
|
||||
|
||||
return Filename;
|
||||
}
|
||||
|
||||
bool
|
||||
CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
|
||||
{
|
||||
@ -60,7 +71,7 @@ CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
|
||||
|
||||
LOG(WII_IPC_FILEIO, "FileIO: Open (Device=%s)", GetDeviceName().c_str());
|
||||
|
||||
m_Filename = (HLE_IPC_BuildFilename(GetDeviceName().c_str()));
|
||||
m_Filename = std::string(HLE_IPC_BuildFilename(GetDeviceName().c_str(), 64));
|
||||
|
||||
switch(_Mode)
|
||||
{
|
||||
@ -175,7 +186,7 @@ CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
|
||||
{
|
||||
case ISFS_IOCTL_GETFILESTATS:
|
||||
{
|
||||
u32 Position = ftell(m_pFileHandle);
|
||||
u32 Position = (u32)ftell(m_pFileHandle);
|
||||
|
||||
u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
|
||||
LOG(WII_IPC_FILEIO, "FileIO: ISFS_IOCTL_GETFILESTATS");
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "Common.h"
|
||||
#include "StringUtil.h"
|
||||
#include "FileSearch.h"
|
||||
#include "FileUtil.h"
|
||||
|
||||
#include "WII_IPC_HLE_Device_fs.h"
|
||||
|
||||
@ -26,12 +27,16 @@
|
||||
|
||||
|
||||
|
||||
extern std::string HLE_IPC_BuildFilename(const char* _pFilename);
|
||||
extern std::string HLE_IPC_BuildFilename(const char* _pFilename, int _size);
|
||||
|
||||
#define FS_RESULT_OK (0)
|
||||
#define FS_FILE_EXIST (-105)
|
||||
#define FS_FILE_NOT_EXIST (-106)
|
||||
#define FS_RESULT_FATAL (-128)
|
||||
|
||||
#define MAX_NAME (12)
|
||||
|
||||
|
||||
CWII_IPC_HLE_Device_fs::CWII_IPC_HLE_Device_fs(u32 _DeviceID, const std::string& _rDeviceName)
|
||||
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
|
||||
{}
|
||||
@ -85,18 +90,60 @@ bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
|
||||
{
|
||||
case IOCTL_READ_DIR:
|
||||
{
|
||||
std::string Filename(HLE_IPC_BuildFilename((const char*)Memory::GetPointer(CommandBuffer.InBuffer[0].m_Address)));
|
||||
// the wii uses this function to define the type (dir or file)
|
||||
std::string Filename(HLE_IPC_BuildFilename((const char*)Memory::GetPointer(CommandBuffer.InBuffer[0].m_Address), CommandBuffer.InBuffer[0].m_Size));
|
||||
|
||||
LOG(WII_IPC_FILEIO, "FS: IOCTL_READ_DIR %s", Filename.c_str());
|
||||
|
||||
// check if this is really a directory
|
||||
if (!File::IsDirectory(Filename.c_str()))
|
||||
{
|
||||
LOG(WII_IPC_FILEIO, " Not a directory - return -6 (dunno if this is a correct return value)", Filename.c_str());
|
||||
ReturnValue = -6;
|
||||
break;
|
||||
}
|
||||
|
||||
// make a file search
|
||||
CFileSearch::XStringVector Directories;
|
||||
Directories.push_back(Filename);
|
||||
|
||||
CFileSearch::XStringVector Extensions;
|
||||
Extensions.push_back("*.*");
|
||||
|
||||
CFileSearch FileSearch(Extensions, Directories);
|
||||
|
||||
// it is one
|
||||
if ((CommandBuffer.InBuffer.size() == 1) && (CommandBuffer.PayloadBuffer.size() == 1))
|
||||
{
|
||||
LOG(WII_IPC_FILEIO, "FS: IOCTL_READ_DIR %s (dunno what i should return, number of FiLES?)", Filename.c_str());
|
||||
size_t numFile = FileSearch.GetFileNames().size();
|
||||
LOG(WII_IPC_FILEIO, " Files in directory: %i", numFile);
|
||||
|
||||
Memory::Write_U32(0, CommandBuffer.PayloadBuffer[0].m_Address);
|
||||
Memory::Write_U32((u32)numFile, CommandBuffer.PayloadBuffer[0].m_Address);
|
||||
}
|
||||
else
|
||||
{
|
||||
PanicAlert("IOCTL_READ_DIR with a lot of parameters");
|
||||
|
||||
|
||||
memset(Memory::GetPointer(CommandBuffer.PayloadBuffer[0].m_Address), 0, CommandBuffer.PayloadBuffer[0].m_Size);
|
||||
|
||||
size_t numFile = FileSearch.GetFileNames().size();
|
||||
for (size_t i=0; i<numFile; i++)
|
||||
{
|
||||
char* pDest = (char*)Memory::GetPointer((u32)(CommandBuffer.PayloadBuffer[0].m_Address + i * MAX_NAME));
|
||||
|
||||
std::string filename, ext;
|
||||
SplitPath(FileSearch.GetFileNames()[i], NULL, &filename, &ext);
|
||||
|
||||
|
||||
memcpy(pDest, (filename + ext).c_str(), MAX_NAME);
|
||||
pDest[MAX_NAME-1] = 0x00;
|
||||
LOG(WII_IPC_FILEIO, " %s", pDest);
|
||||
}
|
||||
|
||||
Memory::Write_U32((u32)numFile, CommandBuffer.PayloadBuffer[1].m_Address);
|
||||
}
|
||||
|
||||
ReturnValue = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -106,12 +153,14 @@ bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
|
||||
// fsBlocks and inodes
|
||||
// we answer nothing is used, but if a program uses it to check
|
||||
// how much memory has been used we are doomed...
|
||||
std::string Filename(HLE_IPC_BuildFilename((const char*)Memory::GetPointer(CommandBuffer.InBuffer[0].m_Address)));
|
||||
std::string Filename(HLE_IPC_BuildFilename((const char*)Memory::GetPointer(CommandBuffer.InBuffer[0].m_Address), CommandBuffer.InBuffer[0].m_Size));
|
||||
|
||||
LOG(WII_IPC_FILEIO, "FS: IOCTL_GETUSAGE %s", Filename.c_str());
|
||||
|
||||
Memory::Write_U32(0, CommandBuffer.PayloadBuffer[0].m_Address);
|
||||
Memory::Write_U32(0, CommandBuffer.PayloadBuffer[1].m_Address);
|
||||
|
||||
ReturnValue = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -131,13 +180,64 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
|
||||
{
|
||||
switch(_Parameter)
|
||||
{
|
||||
case DELETE_FILE:
|
||||
case CREATE_DIR:
|
||||
{
|
||||
_dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0);
|
||||
u32 Addr = _BufferIn;
|
||||
|
||||
u32 OwnerID = Memory::Read_U32(Addr); Addr += 4;
|
||||
u16 GroupID = Memory::Read_U16(Addr); Addr += 2;
|
||||
std::string DirName(HLE_IPC_BuildFilename((const char*)Memory::GetPointer(Addr), 64));
|
||||
Addr += 64;
|
||||
Addr += 9; // owner attribs, permission
|
||||
u8 Attribs = Memory::Read_U8(Addr);
|
||||
|
||||
if (File::IsDirectory(DirName.c_str()))
|
||||
{
|
||||
bool Result = File::CreateDir(DirName.c_str());
|
||||
LOG(WII_IPC_FILEIO, "FS: CREATE_DIR %s (%s)", DirName.c_str(), Result ? "success" : "failed");
|
||||
|
||||
_dbg_assert_msg_(WII_IPC_FILEIO, Result, "FS: CREATE_DIR %s failed", DirName.c_str());
|
||||
}
|
||||
|
||||
return FS_RESULT_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case GET_ATTR:
|
||||
{
|
||||
_dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0);
|
||||
int Offset = 0;
|
||||
|
||||
std::string Filename = HLE_IPC_BuildFilename((const char*)Memory::GetPointer(_BufferIn+Offset));
|
||||
std::string Filename = HLE_IPC_BuildFilename((const char*)Memory::GetPointer(_BufferIn+Offset), 64);
|
||||
Offset += 64;
|
||||
if (remove(Filename.c_str()) == 0)
|
||||
|
||||
if (File::IsDirectory(Filename.c_str()))
|
||||
{
|
||||
LOG(WII_IPC_FILEIO, "FS: GET_ATTR Directory %s - ni", Filename.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (File::Exists(Filename.c_str()))
|
||||
{
|
||||
LOG(WII_IPC_FILEIO, "FS: GET_ATTR %s - ni", Filename.c_str());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return FS_RESULT_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case DELETE_FILE:
|
||||
{
|
||||
_dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0);
|
||||
int Offset = 0;
|
||||
|
||||
std::string Filename = HLE_IPC_BuildFilename((const char*)Memory::GetPointer(_BufferIn+Offset), 64);
|
||||
Offset += 64;
|
||||
if (File::Delete(Filename.c_str()))
|
||||
{
|
||||
LOG(WII_IPC_FILEIO, "FS: DeleteFile %s", Filename.c_str());
|
||||
}
|
||||
@ -152,14 +252,17 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
|
||||
|
||||
case RENAME_FILE:
|
||||
{
|
||||
_dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0);
|
||||
int Offset = 0;
|
||||
|
||||
std::string Filename = HLE_IPC_BuildFilename((const char*)Memory::GetPointer(_BufferIn+Offset));
|
||||
std::string Filename = HLE_IPC_BuildFilename((const char*)Memory::GetPointer(_BufferIn+Offset), 64);
|
||||
Offset += 64;
|
||||
|
||||
std::string FilenameRename = HLE_IPC_BuildFilename((const char*)Memory::GetPointer(_BufferIn+Offset));
|
||||
std::string FilenameRename = HLE_IPC_BuildFilename((const char*)Memory::GetPointer(_BufferIn+Offset), 64);
|
||||
Offset += 64;
|
||||
|
||||
CreateDirectoryStruct(FilenameRename);
|
||||
|
||||
if (rename(Filename.c_str(), FilenameRename.c_str()) == 0)
|
||||
{
|
||||
LOG(WII_IPC_FILEIO, "FS: Rename %s to %s", Filename.c_str(), FilenameRename.c_str());
|
||||
@ -176,40 +279,36 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
|
||||
|
||||
case CREATE_FILE:
|
||||
{
|
||||
_dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0);
|
||||
|
||||
u32 Addr = _BufferIn;
|
||||
u32 OwnerID = Memory::Read_U32(Addr); Addr += 4;
|
||||
u16 GroupID = Memory::Read_U16(Addr); Addr += 2;
|
||||
std::string Filename(HLE_IPC_BuildFilename((const char*)Memory::GetPointer(Addr)));
|
||||
std::string Filename(HLE_IPC_BuildFilename((const char*)Memory::GetPointer(Addr), 64));
|
||||
Addr += 64;
|
||||
Addr += 9; // unk memory;
|
||||
u8 Attribs = Memory::Read_U8(Addr);
|
||||
|
||||
LOG(WII_IPC_FILEIO, "FS: CreateFile %s (attrib: 0x%02x)", Filename.c_str(), Attribs);
|
||||
|
||||
FILE* pFileHandle = fopen(Filename.c_str(), "r+b");
|
||||
if (pFileHandle != NULL)
|
||||
// check if the file allready exist
|
||||
if (File::Exists(Filename.c_str()))
|
||||
{
|
||||
fclose(pFileHandle);
|
||||
pFileHandle = NULL;
|
||||
LOG(WII_IPC_FILEIO, " result = FS_RESULT_EXISTS", Filename.c_str(), Attribs);
|
||||
|
||||
LOG(WII_IPC_FILEIO, " result = FS_RESULT_EXISTS", Filename.c_str());
|
||||
return FS_FILE_EXIST;
|
||||
}
|
||||
else
|
||||
{
|
||||
CreateDirectoryStruct(Filename);
|
||||
|
||||
FILE* pFileHandle = fopen(Filename.c_str(), "w+b");
|
||||
if (!pFileHandle)
|
||||
{
|
||||
PanicAlert("CWII_IPC_HLE_Device_fs: couldn't create new file");
|
||||
return FS_RESULT_FATAL;
|
||||
}
|
||||
fclose(pFileHandle);
|
||||
LOG(WII_IPC_FILEIO, " result = FS_RESULT_OK", Filename.c_str(), Attribs);
|
||||
|
||||
return FS_RESULT_OK;
|
||||
// create the file
|
||||
CreateDirectoryStruct(Filename);
|
||||
bool Result = File::CreateEmptyFile(Filename.c_str());
|
||||
if (!Result)
|
||||
{
|
||||
PanicAlert("CWII_IPC_HLE_Device_fs: couldn't create new file");
|
||||
return FS_RESULT_FATAL;
|
||||
}
|
||||
|
||||
LOG(WII_IPC_FILEIO, " result = FS_RESULT_OK", Filename.c_str(), Attribs);
|
||||
return FS_RESULT_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -228,18 +327,31 @@ void CWII_IPC_HLE_Device_fs::CreateDirectoryStruct(const std::string& _rFullPath
|
||||
size_t Position = 0;
|
||||
while(true)
|
||||
{
|
||||
Position = _rFullPath.find('/', Position);
|
||||
if (Position == std::string::npos)
|
||||
break;
|
||||
// find next sub path
|
||||
{
|
||||
size_t nextPosition = _rFullPath.find('/', Position);
|
||||
if (nextPosition == std::string::npos)
|
||||
nextPosition = _rFullPath.find('\\', Position);
|
||||
Position = nextPosition;
|
||||
|
||||
Position++;
|
||||
if (Position == std::string::npos)
|
||||
break;
|
||||
|
||||
Position++;
|
||||
}
|
||||
|
||||
// create next sub path
|
||||
std::string SubPath = _rFullPath.substr(0, Position);
|
||||
if (!SubPath.empty())
|
||||
_mkdir(SubPath.c_str());
|
||||
|
||||
LOG(WII_IPC_FILEIO, " CreateSubDir %s", SubPath.c_str());
|
||||
{
|
||||
if (!File::IsDirectory(SubPath.c_str()))
|
||||
{
|
||||
File::CreateDir(SubPath.c_str());
|
||||
LOG(WII_IPC_FILEIO, " CreateSubDir %s", SubPath.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// just a safty check...
|
||||
PanicCounter--;
|
||||
if (PanicCounter <= 0)
|
||||
{
|
||||
@ -247,4 +359,4 @@ void CWII_IPC_HLE_Device_fs::CreateDirectoryStruct(const std::string& _rFullPath
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,9 @@ private:
|
||||
|
||||
enum
|
||||
{
|
||||
CREATE_DIR = 0x03,
|
||||
IOCTL_READ_DIR = 0x04,
|
||||
GET_ATTR = 0x06,
|
||||
DELETE_FILE = 0x07,
|
||||
RENAME_FILE = 0x08,
|
||||
CREATE_FILE = 0x09,
|
||||
@ -53,6 +55,7 @@ private:
|
||||
s32 ExecuteCommand(u32 Parameter, u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, u32 _BufferOutSize);
|
||||
|
||||
void CreateDirectoryStruct(const std::string& _rFullPath);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "BannerLoaderGC.h"
|
||||
|
||||
#include "VolumeCreator.h"
|
||||
#include "FileUtil.h"
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
|
@ -21,77 +21,110 @@
|
||||
|
||||
#include "Common.h"
|
||||
#include "BannerLoaderWii.h"
|
||||
#include "FileHandlerARC.h"
|
||||
// #include "FileHandlerLZ77.h"
|
||||
#include "FileUtil.h"
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
CBannerLoaderWii::CBannerLoaderWii(DiscIO::IFileSystem& _rFileSystem)
|
||||
: m_pBuffer(NULL)
|
||||
CBannerLoaderWii::CBannerLoaderWii(DiscIO::IFileSystem& _rFileSystem)
|
||||
: m_pBannerFile(NULL)
|
||||
, m_IsValid(false)
|
||||
{
|
||||
FILE* pFile = fopen("e:\\opening.bnr", "rb");
|
||||
InitLUTTable();
|
||||
|
||||
char Filename[260];
|
||||
char TitleID[4];
|
||||
|
||||
_rFileSystem.GetVolume()->Read(0, 4, (u8*)TitleID);
|
||||
sprintf(Filename, "Wii/title/00010000/%02x%02x%02x%02x/data/banner.bin", (u8)TitleID[0], (u8)TitleID[1], (u8)TitleID[2], (u8)TitleID[3]);
|
||||
|
||||
if (pFile)
|
||||
// load the opening.bnr
|
||||
size_t FileSize = File::GetSize(Filename);
|
||||
|
||||
if (FileSize > 0)
|
||||
{
|
||||
fseek(pFile, 0, SEEK_END);
|
||||
int insize = ftell(pFile);
|
||||
fseek(pFile, 0, SEEK_SET);
|
||||
|
||||
m_pBuffer = new u8[insize];
|
||||
|
||||
fread(m_pBuffer, 1, insize, pFile);
|
||||
|
||||
fclose(pFile);
|
||||
|
||||
CARCFile ArcFile(m_pBuffer + 0x600, insize - 0x600);
|
||||
|
||||
size_t BannerSize = ArcFile.GetFileSize("meta\\banner.bin");
|
||||
|
||||
if (BannerSize > 0)
|
||||
m_pBannerFile = new u8[FileSize];
|
||||
FILE* pFile = fopen(Filename, "rb");
|
||||
if (pFile != NULL)
|
||||
{
|
||||
u8* TempBuffer = new u8[BannerSize];
|
||||
ArcFile.ReadFile("meta\\banner.bin", TempBuffer, BannerSize);
|
||||
|
||||
// CLZ77File File(TempBuffer + 0x20 + 4, BannerSize - 0x20 - 4);
|
||||
delete[] TempBuffer;
|
||||
|
||||
// CARCFile IconFile(File.GetBuffer(), File.GetSize());
|
||||
|
||||
// IconFile.ExportFile("arc\\anim\\banner_loop.brlan", "e:\\banner_loop.brlan");
|
||||
|
||||
//IconFile.ReadFile("meta\\icon.bin", TempBuffer, BannerSize);
|
||||
fread(m_pBannerFile, FileSize, 1, pFile);
|
||||
fclose(pFile);
|
||||
m_IsValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_Name = std::string("Wii: ") + _rFileSystem.GetVolume()->GetName();
|
||||
}
|
||||
|
||||
|
||||
CBannerLoaderWii::~CBannerLoaderWii()
|
||||
{
|
||||
delete [] m_pBuffer;
|
||||
m_pBuffer = NULL;
|
||||
if (m_pBannerFile)
|
||||
{
|
||||
delete [] m_pBannerFile;
|
||||
m_pBannerFile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CBannerLoaderWii::IsValid()
|
||||
{
|
||||
return(true);
|
||||
return (m_IsValid);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CBannerLoaderWii::GetBanner(u32* _pBannerImage)
|
||||
{
|
||||
return(false);
|
||||
if (!IsValid())
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
SWiiBanner* pBanner = (SWiiBanner*)m_pBannerFile;
|
||||
|
||||
static u32 Buffer[192 * 64];
|
||||
decode5A3image(Buffer, (u16*)pBanner->m_BannerTexture, 192, 64);
|
||||
|
||||
for (int y=0; y<32; y++)
|
||||
{
|
||||
for (int x=0; x<96; x++)
|
||||
{
|
||||
_pBannerImage[y*96+x] = Buffer[(y*2)*96+(x*2)];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
std::string
|
||||
CBannerLoaderWii::StupidWideCharToString(u16* _pSrc, size_t _max)
|
||||
{
|
||||
std::string temp;
|
||||
|
||||
int offset = 0;
|
||||
while (_pSrc[offset] != 0x0000)
|
||||
{
|
||||
temp += (char)(_pSrc[offset] >> 8);
|
||||
offset ++;
|
||||
|
||||
if (offset >= _max)
|
||||
break;
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
bool
|
||||
CBannerLoaderWii::GetName(std::string& _rName, int language)
|
||||
{
|
||||
if (IsValid())
|
||||
{
|
||||
SWiiBanner* pBanner = (SWiiBanner*)m_pBannerFile;
|
||||
|
||||
// very stupid
|
||||
_rName = StupidWideCharToString(pBanner->m_Comment[0], WII_BANNER_COMMENT_SIZE);
|
||||
return true;
|
||||
}
|
||||
|
||||
_rName = m_Name;
|
||||
return(true);
|
||||
}
|
||||
@ -107,7 +140,84 @@ CBannerLoaderWii::GetCompany(std::string& _rCompany)
|
||||
bool
|
||||
CBannerLoaderWii::GetDescription(std::string& _rDescription)
|
||||
{
|
||||
if (IsValid())
|
||||
{
|
||||
SWiiBanner* pBanner = (SWiiBanner*)m_pBannerFile;
|
||||
|
||||
// very stupid
|
||||
_rDescription = StupidWideCharToString(pBanner->m_Comment[1], WII_BANNER_COMMENT_SIZE);
|
||||
return true;
|
||||
}
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CBannerLoaderWii::InitLUTTable()
|
||||
{
|
||||
// build LUT Table
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
lut3to8[i] = (i * 255) / 7;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
lut4to8[i] = (i * 255) / 15;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
lut5to8[i] = (i * 255) / 31;
|
||||
}
|
||||
}
|
||||
|
||||
u32
|
||||
CBannerLoaderWii::decode5A3(u16 val)
|
||||
{
|
||||
u32 bannerBGColor = 0x00000000;
|
||||
|
||||
int r, g, b, a;
|
||||
|
||||
if ((val & 0x8000))
|
||||
{
|
||||
r = lut5to8[(val >> 10) & 0x1f];
|
||||
g = lut5to8[(val >> 5) & 0x1f];
|
||||
b = lut5to8[(val) & 0x1f];
|
||||
a = 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
a = lut3to8[(val >> 12) & 0x7];
|
||||
r = (lut4to8[(val >> 8) & 0xf] * a + (bannerBGColor & 0xFF) * (255 - a)) / 255;
|
||||
g = (lut4to8[(val >> 4) & 0xf] * a + ((bannerBGColor >> 8) & 0xFF) * (255 - a)) / 255;
|
||||
b = (lut4to8[(val) & 0xf] * a + ((bannerBGColor >> 16) & 0xFF) * (255 - a)) / 255;
|
||||
a = 0xFF;
|
||||
}
|
||||
|
||||
return((a << 24) | (r << 16) | (g << 8) | b);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CBannerLoaderWii::decode5A3image(u32* dst, u16* src, int width, int height)
|
||||
{
|
||||
for (int y = 0; y < height; y += 4)
|
||||
{
|
||||
for (int x = 0; x < width; x += 4)
|
||||
{
|
||||
for (int iy = 0; iy < 4; iy++, src += 4)
|
||||
{
|
||||
for (int ix = 0; ix < 4; ix++)
|
||||
{
|
||||
u32 RGBA = decode5A3(Common::swap16(src[ix]));
|
||||
dst[(y + iy) * width + (x + ix)] = RGBA;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
@ -43,10 +43,40 @@ class CBannerLoaderWii
|
||||
|
||||
|
||||
private:
|
||||
|
||||
#define WII_BANNER_TEXTURE_SIZE (192 * 64 * 2)
|
||||
#define WII_BANNER_ICON_SIZE ( 48 * 48 * 2)
|
||||
#define WII_BANNER_COMMENT_SIZE 32
|
||||
|
||||
struct SWiiBanner
|
||||
{
|
||||
u32 ID;
|
||||
|
||||
u32 m_Flag;
|
||||
u16 m_Speed;
|
||||
u8 m_Unknown[22];
|
||||
|
||||
u16 m_Comment[2][WII_BANNER_COMMENT_SIZE];
|
||||
u8 m_BannerTexture[WII_BANNER_TEXTURE_SIZE];
|
||||
u8 m_IconTexture[8][WII_BANNER_ICON_SIZE];
|
||||
} ;
|
||||
|
||||
// for banner decoding
|
||||
int lut3to8[8];
|
||||
int lut4to8[16];
|
||||
int lut5to8[32];
|
||||
|
||||
std::string m_Name;
|
||||
|
||||
u8* m_pBuffer;
|
||||
u8* m_pBannerFile;
|
||||
|
||||
bool m_IsValid;
|
||||
|
||||
void InitLUTTable();
|
||||
u32 decode5A3(u16 val);
|
||||
void decode5A3image(u32* dst, u16* src, int width, int height);
|
||||
|
||||
std::string StupidWideCharToString(u16* _pSrc, size_t _max);
|
||||
};
|
||||
} // namespace
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user