mirror of
https://github.com/emu-russia/pureikyubu.git
synced 2025-04-02 10:42:15 -04:00
396 lines
11 KiB
C++
396 lines
11 KiB
C++
// Dolwin file utilities
|
|
#include "pch.h"
|
|
#include <shlobj.h>
|
|
|
|
namespace UI
|
|
{
|
|
|
|
bool FileExists(const TCHAR* filename)
|
|
{
|
|
FILE* f = nullptr;
|
|
_tfopen_s(&f, filename, _T("rb"));
|
|
if (f == NULL) return false;
|
|
fclose(f);
|
|
return true;
|
|
}
|
|
|
|
// Get file size
|
|
size_t FileSize(const TCHAR * filename)
|
|
{
|
|
FILE* f = nullptr;
|
|
_tfopen_s (&f, filename, _T("rb"));
|
|
if (f == NULL) return 0;
|
|
fseek(f, 0, SEEK_END);
|
|
size_t size = ftell(f);
|
|
fclose(f);
|
|
return size;
|
|
}
|
|
|
|
// Load data from file
|
|
void* FileLoad(const TCHAR * filename, size_t * size)
|
|
{
|
|
FILE* f;
|
|
uint8_t* buffer;
|
|
size_t filesize;
|
|
|
|
if (size) *size = 0;
|
|
|
|
f = nullptr;
|
|
_tfopen_s(&f, filename, _T("rb"));
|
|
if (f == NULL) return NULL;
|
|
|
|
fseek(f, 0, SEEK_END);
|
|
filesize = ftell(f);
|
|
fseek(f, 0, SEEK_SET);
|
|
|
|
buffer = (uint8_t *)malloc(filesize + 1);
|
|
if (buffer == NULL)
|
|
{
|
|
fclose(f);
|
|
return NULL;
|
|
}
|
|
|
|
fread(buffer, filesize, 1, f);
|
|
fclose(f);
|
|
|
|
buffer[filesize] = 0;
|
|
|
|
if (size) *size = filesize;
|
|
return buffer;
|
|
}
|
|
|
|
// Load data from file
|
|
void* FileLoad(const char* filename, size_t* size)
|
|
{
|
|
FILE* f;
|
|
uint8_t* buffer;
|
|
size_t filesize;
|
|
|
|
if (size) *size = 0;
|
|
|
|
f = nullptr;
|
|
fopen_s(&f, filename, "rb");
|
|
if (f == NULL) return NULL;
|
|
|
|
fseek(f, 0, SEEK_END);
|
|
filesize = ftell(f);
|
|
fseek(f, 0, SEEK_SET);
|
|
|
|
buffer = (uint8_t*)malloc(filesize + 1);
|
|
if (buffer == NULL)
|
|
{
|
|
fclose(f);
|
|
return NULL;
|
|
}
|
|
|
|
fread(buffer, filesize, 1, f);
|
|
fclose(f);
|
|
|
|
buffer[filesize] = 0;
|
|
|
|
if (size) *size = filesize;
|
|
return buffer;
|
|
}
|
|
|
|
// Save data in file
|
|
bool FileSave(const TCHAR * filename, void* data, size_t size)
|
|
{
|
|
FILE* f = nullptr;
|
|
_tfopen_s (&f, filename, _T("wb"));
|
|
if (f == NULL) return FALSE;
|
|
|
|
fwrite(data, size, 1, f);
|
|
fclose(f);
|
|
return TRUE;
|
|
}
|
|
|
|
bool FileSave(const char* filename, void* data, size_t size)
|
|
{
|
|
FILE* f = nullptr;
|
|
fopen_s(&f, filename, "wb");
|
|
if (f == NULL) return FALSE;
|
|
|
|
fwrite(data, size, 1, f);
|
|
fclose(f);
|
|
return TRUE;
|
|
}
|
|
|
|
// Open file/directory dialog
|
|
TCHAR * FileOpen(HWND hwnd, FileType type)
|
|
{
|
|
static TCHAR tempBuf[0x1000] = { 0 };
|
|
OPENFILENAME ofn;
|
|
TCHAR szFileName[1024];
|
|
TCHAR szFileTitle[1024];
|
|
TCHAR lastDir[1024], prevDir[1024];
|
|
BOOL result;
|
|
|
|
GetCurrentDirectory(sizeof(prevDir), prevDir);
|
|
|
|
switch (type)
|
|
{
|
|
case FileType::All:
|
|
_tcscpy_s(lastDir, _countof(lastDir) - 1, GetConfigString(USER_LASTDIR_ALL, USER_UI));
|
|
break;
|
|
case FileType::Dvd:
|
|
_tcscpy_s(lastDir, _countof(lastDir) - 1, GetConfigString(USER_LASTDIR_DVD, USER_UI));
|
|
break;
|
|
case FileType::Map:
|
|
_tcscpy_s(lastDir, _countof(lastDir) - 1, GetConfigString(USER_LASTDIR_MAP, USER_UI));
|
|
break;
|
|
case FileType::Patch:
|
|
_tcscpy_s(lastDir, _countof(lastDir) - 1, GetConfigString(USER_LASTDIR_PATCH, USER_UI));
|
|
break;
|
|
}
|
|
|
|
memset(szFileName, 0, sizeof(szFileName));
|
|
memset(szFileTitle, 0, sizeof(szFileTitle));
|
|
|
|
if (type == FileType::Directory)
|
|
{
|
|
BROWSEINFO bi;
|
|
LPTSTR lpBuffer = NULL;
|
|
LPITEMIDLIST pidlRoot = NULL; // PIDL for root folder
|
|
LPITEMIDLIST pidlBrowse = NULL; // PIDL selected by user
|
|
LPMALLOC g_pMalloc;
|
|
|
|
// Get the shell's allocator.
|
|
if (!SUCCEEDED(SHGetMalloc(&g_pMalloc)))
|
|
return NULL;
|
|
|
|
// Allocate a buffer to receive browse information.
|
|
lpBuffer = (LPTSTR)g_pMalloc->Alloc(MAX_PATH);
|
|
if (lpBuffer == NULL) return NULL;
|
|
|
|
// Get the PIDL for the root folder.
|
|
if (!SUCCEEDED(SHGetSpecialFolderLocation(hwnd, CSIDL_DRIVES, &pidlRoot)))
|
|
{
|
|
g_pMalloc->Free(lpBuffer);
|
|
return NULL;
|
|
}
|
|
|
|
// Fill in the BROWSEINFO structure.
|
|
bi.hwndOwner = hwnd;
|
|
bi.pidlRoot = pidlRoot;
|
|
bi.pszDisplayName = lpBuffer;
|
|
bi.lpszTitle = _T("Choose Directory");
|
|
bi.ulFlags = 0;
|
|
bi.lpfn = NULL;
|
|
bi.lParam = 0;
|
|
|
|
// Browse for a folder and return its PIDL.
|
|
pidlBrowse = SHBrowseForFolder(&bi);
|
|
result = (pidlBrowse != NULL);
|
|
if (result)
|
|
{
|
|
SHGetPathFromIDList(pidlBrowse, lpBuffer);
|
|
_tcscpy_s(szFileName, _countof(szFileName) - 1, lpBuffer);
|
|
|
|
// Free the PIDL returned by SHBrowseForFolder.
|
|
g_pMalloc->Free(pidlBrowse);
|
|
}
|
|
|
|
// Clean up.
|
|
if (pidlRoot) g_pMalloc->Free(pidlRoot);
|
|
if (lpBuffer) g_pMalloc->Free(lpBuffer);
|
|
|
|
// Release the shell's allocator.
|
|
g_pMalloc->Release();
|
|
}
|
|
else
|
|
{
|
|
ofn.lStructSize = sizeof(OPENFILENAME);
|
|
ofn.hwndOwner = hwnd;
|
|
switch (type)
|
|
{
|
|
case FileType::All:
|
|
ofn.lpstrFilter =
|
|
_T("All Supported Files (*.dol, *.elf, *.bin, *.gcm, *.iso)\0*.dol;*.elf;*.bin;*.gcm;*.iso\0")
|
|
_T("GameCube Executable Files (*.dol, *.elf)\0*.dol;*.elf\0")
|
|
_T("Binary Files (*.bin)\0*.bin\0")
|
|
_T("GameCube DVD Images (*.gcm, *.iso)\0*.gcm;*.iso\0")
|
|
_T("All Files (*.*)\0*.*\0");
|
|
break;
|
|
case FileType::Dvd:
|
|
ofn.lpstrFilter =
|
|
_T("GameCube DVD Images (*.gcm, *.iso)\0*.gcm;*.iso\0")
|
|
_T("All Files (*.*)\0*.*\0");
|
|
break;
|
|
case FileType::Map:
|
|
ofn.lpstrFilter =
|
|
_T("Symbolic information files (*.map)\0*.map\0")
|
|
_T("All Files (*.*)\0*.*\0");
|
|
break;
|
|
case FileType::Patch:
|
|
ofn.lpstrFilter =
|
|
_T("Patch files (*.patch)\0*.patch\0")
|
|
_T("All Files (*.*)\0*.*\0");
|
|
break;
|
|
}
|
|
|
|
ofn.lpstrCustomFilter = NULL;
|
|
ofn.nMaxCustFilter = 0;
|
|
ofn.nFilterIndex = 1;
|
|
ofn.lpstrFile = szFileName;
|
|
ofn.nMaxFile = sizeof(szFileName);
|
|
ofn.lpstrInitialDir = lastDir;
|
|
ofn.lpstrFileTitle = szFileTitle;
|
|
ofn.nMaxFileTitle = sizeof(szFileTitle);
|
|
ofn.lpstrTitle = _T("Open File\0");
|
|
ofn.lpstrDefExt = _T("");
|
|
ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
|
|
|
|
result = GetOpenFileName(&ofn);
|
|
}
|
|
|
|
if (result)
|
|
{
|
|
_tcscpy_s(tempBuf, _countof(tempBuf) - 1, szFileName);
|
|
|
|
// save last directory
|
|
_tcscpy_s(lastDir, _countof(lastDir) - 1, tempBuf);
|
|
int i = (int)_tcslen(lastDir) - 1;
|
|
while (lastDir[i] != _T('\\')) i--;
|
|
lastDir[i + 1] = _T('\0');
|
|
switch (type)
|
|
{
|
|
case FileType::All:
|
|
SetConfigString(USER_LASTDIR_ALL, lastDir, USER_UI);
|
|
break;
|
|
case FileType::Dvd:
|
|
SetConfigString(USER_LASTDIR_DVD, lastDir, USER_UI);
|
|
break;
|
|
case FileType::Map:
|
|
SetConfigString(USER_LASTDIR_MAP, lastDir, USER_UI);
|
|
break;
|
|
case FileType::Patch:
|
|
SetConfigString(USER_LASTDIR_PATCH, lastDir, USER_UI);
|
|
break;
|
|
}
|
|
|
|
SetCurrentDirectory(prevDir);
|
|
return tempBuf;
|
|
}
|
|
else
|
|
{
|
|
SetCurrentDirectory(prevDir);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
// make path to file shorter for "lvl" levels.
|
|
TCHAR * FileShortName(const TCHAR * filename, int lvl)
|
|
{
|
|
static TCHAR tempBuf[1024] = { 0 };
|
|
|
|
int c = 0;
|
|
size_t i = 0;
|
|
|
|
TCHAR * ptr = (TCHAR *)filename;
|
|
|
|
tempBuf[0] = ptr[0];
|
|
tempBuf[1] = ptr[1];
|
|
tempBuf[2] = ptr[2];
|
|
|
|
ptr += 3;
|
|
|
|
for (i = _tcslen(ptr) - 1; i; i--)
|
|
{
|
|
if (ptr[i] == _T('\\')) c++;
|
|
if (c == lvl) break;
|
|
}
|
|
|
|
if (c == lvl)
|
|
{
|
|
_stprintf_s(&tempBuf[3], _countof(tempBuf) - 3, _T("...%s"), &ptr[i]);
|
|
}
|
|
else return ptr - 3;
|
|
|
|
return tempBuf;
|
|
}
|
|
|
|
// nice value of KB, MB or GB, for output
|
|
TCHAR * FileSmartSize(size_t size)
|
|
{
|
|
static TCHAR tempBuf[1024] = { 0 };
|
|
|
|
if (size < 1024)
|
|
{
|
|
_stprintf_s(tempBuf, sizeof(tempBuf), _T("%zi byte"), size);
|
|
}
|
|
else if (size < 1024 * 1024)
|
|
{
|
|
_stprintf_s(tempBuf, sizeof(tempBuf), _T("%zi KB"), size / 1024);
|
|
}
|
|
else if (size < 1024 * 1024 * 1024)
|
|
{
|
|
_stprintf_s(tempBuf, sizeof(tempBuf), _T("%zi MB"), size / 1024 / 1024);
|
|
}
|
|
else _stprintf_s(tempBuf, sizeof(tempBuf), _T("%1.1f GB"), (float)size / 1024 / 1024 / 1024);
|
|
return tempBuf;
|
|
}
|
|
|
|
char* FileSmartSizeA(size_t size)
|
|
{
|
|
static char tempBuf[1024] = { 0 };
|
|
|
|
if (size < 1024)
|
|
{
|
|
sprintf_s(tempBuf, sizeof(tempBuf), "%zi byte", size);
|
|
}
|
|
else if (size < 1024 * 1024)
|
|
{
|
|
sprintf_s(tempBuf, sizeof(tempBuf), "%zi KB", size / 1024);
|
|
}
|
|
else if (size < 1024 * 1024 * 1024)
|
|
{
|
|
sprintf_s(tempBuf, sizeof(tempBuf), "%zi MB", size / 1024 / 1024);
|
|
}
|
|
else sprintf_s(tempBuf, sizeof(tempBuf), "%1.1f GB", (float)size / 1024 / 1024 / 1024);
|
|
return tempBuf;
|
|
}
|
|
|
|
void* FileLoad(std::wstring filename, size_t& size)
|
|
{
|
|
FILE* f;
|
|
uint8_t* buffer;
|
|
size_t filesize;
|
|
|
|
size = 0;
|
|
|
|
f = nullptr;
|
|
_wfopen_s(&f, filename.c_str(), L"rb");
|
|
if (f == NULL) return NULL;
|
|
|
|
fseek(f, 0, SEEK_END);
|
|
filesize = ftell(f);
|
|
fseek(f, 0, SEEK_SET);
|
|
|
|
buffer = new uint8_t[filesize + 1];
|
|
if (buffer == NULL)
|
|
{
|
|
fclose(f);
|
|
return NULL;
|
|
}
|
|
|
|
fread(buffer, filesize, 1, f);
|
|
fclose(f);
|
|
|
|
buffer[filesize] = 0;
|
|
|
|
size = filesize;
|
|
return buffer;
|
|
}
|
|
|
|
bool FileSave(std::wstring filename, void* data, size_t size)
|
|
{
|
|
FILE* f = nullptr;
|
|
_wfopen_s(&f, filename.c_str(), L"wb");
|
|
if (f == NULL) return FALSE;
|
|
|
|
fwrite(data, size, 1, f);
|
|
fclose(f);
|
|
return TRUE;
|
|
}
|
|
|
|
}
|