[Project64] Separate rom list management from Rom Browser
This commit is contained in:
parent
a1787f7448
commit
46e345f99e
|
@ -67,6 +67,7 @@
|
|||
<ClCompile Include="UserInterface\NotificationClass.cpp" />
|
||||
<ClCompile Include="UserInterface\RomBrowserClass.cpp" />
|
||||
<ClCompile Include="UserInterface\RomInformationClass.cpp" />
|
||||
<ClCompile Include="UserInterface\RomList.cpp" />
|
||||
<ClCompile Include="UserInterface\SettingsConfig.cpp" />
|
||||
<ClCompile Include="UserInterface\Settings\SettingsPage-AdvancedOptions.cpp" />
|
||||
<ClCompile Include="UserInterface\Settings\SettingsPage-Directories.cpp" />
|
||||
|
@ -108,6 +109,7 @@
|
|||
<ClInclude Include="UserInterface\resource.h" />
|
||||
<ClInclude Include="UserInterface\RomBrowser.h" />
|
||||
<ClInclude Include="UserInterface\RomInformationClass.h" />
|
||||
<ClInclude Include="UserInterface\RomList.h" />
|
||||
<ClInclude Include="UserInterface\SettingsConfig.h" />
|
||||
<ClInclude Include="UserInterface\Settings\SettingsPage-AdvancedOptions.h" />
|
||||
<ClInclude Include="UserInterface\Settings\SettingsPage-Directories.h" />
|
||||
|
|
|
@ -162,6 +162,9 @@
|
|||
<ClCompile Include="Settings\UISettings.cpp">
|
||||
<Filter>Source Files\Settings Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UserInterface\RomList.cpp">
|
||||
<Filter>Source Files\User Interface Source</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="UserInterface\resource.h">
|
||||
|
@ -293,6 +296,9 @@
|
|||
<ClInclude Include="Settings\UISettings.h">
|
||||
<Filter>Header Files\Settings</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="UserInterface\RomList.h">
|
||||
<Filter>Header Files\User Interface Headers</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="res\divider.cur">
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include <vector>
|
||||
#include <Project64/Settings/UISettings.h>
|
||||
#include "RomList.h"
|
||||
|
||||
class CMainGui;
|
||||
class CPlugins;
|
||||
|
@ -80,14 +81,14 @@ struct SORT_FIELD
|
|||
};
|
||||
|
||||
class C7zip;
|
||||
class CRomBrowser
|
||||
class CRomBrowser :
|
||||
public CRomList
|
||||
{
|
||||
public:
|
||||
CRomBrowser(HWND & hMainWindow, HWND & StatusWindow);
|
||||
~CRomBrowser(void);
|
||||
void HighLightLastRom(void);
|
||||
void HideRomList(void);
|
||||
void RefreshRomBrowser(void);
|
||||
void ResetRomBrowserColomuns(void);
|
||||
void ResizeRomList(WORD nWidth, WORD nHeight);
|
||||
void RomBrowserToTop(void);
|
||||
|
@ -116,85 +117,29 @@ private:
|
|||
RB_ForceFeedback = 18, RB_FileFormat = 19
|
||||
};
|
||||
|
||||
enum FILE_FORMAT
|
||||
{
|
||||
Format_Uncompressed,
|
||||
Format_Zip,
|
||||
Format_7zip,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
NoOfSortKeys = 3
|
||||
};
|
||||
|
||||
struct ROM_INFO
|
||||
{
|
||||
char szFullFileName[300];
|
||||
FILE_FORMAT FileFormat;
|
||||
wchar_t Status[60];
|
||||
char FileName[200];
|
||||
wchar_t InternalName[22];
|
||||
wchar_t GoodName[200];
|
||||
wchar_t CartID[3];
|
||||
wchar_t PluginNotes[250];
|
||||
wchar_t CoreNotes[250];
|
||||
wchar_t UserNotes[250];
|
||||
wchar_t Developer[30];
|
||||
wchar_t ReleaseDate[30];
|
||||
wchar_t Genre[15];
|
||||
int32_t Players;
|
||||
uint32_t TextColor;
|
||||
int32_t SelColor;
|
||||
uint32_t SelTextColor;
|
||||
uint32_t SelColorBrush;
|
||||
int32_t RomSize;
|
||||
uint8_t Manufacturer;
|
||||
uint8_t Country;
|
||||
uint32_t CRC1;
|
||||
uint32_t CRC2;
|
||||
int32_t CicChip;
|
||||
wchar_t ForceFeedback[15];
|
||||
};
|
||||
|
||||
typedef std::vector<ROM_INFO> ROMINFO_LIST;
|
||||
|
||||
void AddFileNameToList(strlist & FileList, const stdstr & Directory, CPath & File);
|
||||
void AddRomToList(const char * RomLocation, const char * lpLastRom);
|
||||
void AddRomInfoToList(ROM_INFO &RomInfo, const char * lpLastRom);
|
||||
void AllocateBrushs(void);
|
||||
static void ByteSwapRomData(uint8_t * Data, int DataLen);
|
||||
void RomListReset(void);
|
||||
void RomListLoaded(void);
|
||||
void RomAddedToList(int32_t ListPos);
|
||||
int CalcSortPosition(uint32_t lParam);
|
||||
void CreateRomListControl(void);
|
||||
void DeallocateBrushs(void);
|
||||
void FillRomExtensionInfo(ROM_INFO * pRomInfo);
|
||||
bool FillRomInfo(ROM_INFO * pRomInfo);
|
||||
void FillRomList(strlist & FileList, const CPath & BaseDirectory, const char * Directory, const char * lpLastRom);
|
||||
void FixRomListWindow(void);
|
||||
static int32_t GetCicChipID(uint8_t * RomData);
|
||||
bool LoadDataFromRomFile(const char * FileName, uint8_t * Data, int32_t DataLen, int32_t * RomSize, FILE_FORMAT & FileFormat);
|
||||
void LoadRomList(void);
|
||||
void MenuSetText(HMENU hMenu, int32_t MenuPos, const wchar_t * Title, char * ShortCut);
|
||||
void SaveRomList(strlist & FileList);
|
||||
void RomList_ColoumnSortList(uint32_t pnmh);
|
||||
void RomList_GetDispInfo(uint32_t pnmh);
|
||||
void RomList_OpenRom(uint32_t pnmh);
|
||||
void RomList_PopupMenu(uint32_t pnmh);
|
||||
void RomList_SortList(void);
|
||||
bool GetRomFileNames(strlist & FileList, const CPath & BaseDirectory, const std::string & Directory, bool InWatchThread);
|
||||
MD5 RomListHash(strlist & FileList);
|
||||
|
||||
static void NotificationCB(const char * Status, CRomBrowser * _this);
|
||||
void RomDirChanged(void);
|
||||
|
||||
//Watch Directory Changed function
|
||||
HANDLE m_WatchThread, m_WatchStopEvent;
|
||||
DWORD m_WatchThreadID;
|
||||
stdstr m_WatchRomDir;
|
||||
void WatchThreadStart(void);
|
||||
void WatchThreadStop(void);
|
||||
bool RomDirNeedsRefresh(void); // Called from watch thread
|
||||
static void WatchRomDirChanged(CRomBrowser * _this);
|
||||
static void RefreshRomBrowserStatic(CRomBrowser * _this);
|
||||
static void AddField(ROMBROWSER_FIELDS_LIST & Fields, const char * Name, int32_t Pos, int32_t ID, int32_t Width, LanguageStringID LangID, bool UseDefault);
|
||||
|
||||
//Callback
|
||||
|
@ -206,16 +151,10 @@ private:
|
|||
HWND m_hRomList;
|
||||
ROMBROWSER_FIELDS_LIST m_Fields;
|
||||
FIELD_TYPE_LIST m_FieldType;
|
||||
ROMINFO_LIST m_RomInfo;
|
||||
std::string m_SelectedRom;
|
||||
bool m_Visible;
|
||||
bool m_ShowingRomBrowser;
|
||||
HANDLE m_RefreshThread;
|
||||
bool m_StopRefresh;
|
||||
CIniFile * m_RomIniFile;
|
||||
CIniFile * m_NotesIniFile;
|
||||
CIniFile * m_ExtIniFile;
|
||||
CIniFile * m_ZipIniFile;
|
||||
bool m_AllowSelectionLastRom;
|
||||
static std::wstring m_UnknownGoodName;
|
||||
std::string m_LastRom;
|
||||
};
|
||||
|
|
|
@ -20,26 +20,10 @@ CRomBrowser::CRomBrowser(HWND & MainWindow, HWND & StatusWindow) :
|
|||
m_MainWindow(MainWindow),
|
||||
m_StatusWindow(StatusWindow),
|
||||
m_ShowingRomBrowser(false),
|
||||
m_RefreshThread(NULL),
|
||||
m_RomIniFile(NULL),
|
||||
m_NotesIniFile(NULL),
|
||||
m_ExtIniFile(NULL),
|
||||
m_ZipIniFile(NULL),
|
||||
m_AllowSelectionLastRom(true),
|
||||
m_WatchThreadID(0)
|
||||
m_AllowSelectionLastRom(true)
|
||||
{
|
||||
if (g_Settings)
|
||||
{
|
||||
m_RomIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_RomDatabase).c_str());
|
||||
m_NotesIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_Notes).c_str());
|
||||
m_ExtIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_ExtInfo).c_str());
|
||||
m_ZipIniFile = new CIniFile(g_Settings->LoadStringVal(RomList_7zipCache).c_str());
|
||||
}
|
||||
|
||||
m_hRomList = 0;
|
||||
m_Visible = false;
|
||||
m_WatchThread = NULL;
|
||||
m_WatchStopEvent = NULL;
|
||||
|
||||
GetFieldInfo(m_Fields);
|
||||
m_FieldType.resize(m_Fields.size());
|
||||
|
@ -47,30 +31,7 @@ CRomBrowser::CRomBrowser(HWND & MainWindow, HWND & StatusWindow) :
|
|||
|
||||
CRomBrowser::~CRomBrowser(void)
|
||||
{
|
||||
m_StopRefresh = true;
|
||||
WatchThreadStop();
|
||||
DeallocateBrushs();
|
||||
|
||||
if (m_RomIniFile)
|
||||
{
|
||||
delete m_RomIniFile;
|
||||
m_RomIniFile = NULL;
|
||||
}
|
||||
if (m_NotesIniFile)
|
||||
{
|
||||
delete m_NotesIniFile;
|
||||
m_NotesIniFile = NULL;
|
||||
}
|
||||
if (m_ExtIniFile)
|
||||
{
|
||||
delete m_ExtIniFile;
|
||||
m_ExtIniFile = NULL;
|
||||
}
|
||||
if (m_ZipIniFile)
|
||||
{
|
||||
delete m_ZipIniFile;
|
||||
m_ZipIniFile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CRomBrowser::AddField(ROMBROWSER_FIELDS_LIST & Fields, LPCSTR Name, int32_t Pos, int32_t ID, int32_t Width, LanguageStringID LangID, bool UseDefault)
|
||||
|
@ -290,33 +251,22 @@ int32_t CRomBrowser::CalcSortPosition(uint32_t lParam)
|
|||
return End + 1;
|
||||
}
|
||||
|
||||
void CRomBrowser::AddRomToList(const char * RomLocation, const char * lpLastRom)
|
||||
void CRomBrowser::RomAddedToList(int32_t ListPos)
|
||||
{
|
||||
ROM_INFO RomInfo;
|
||||
|
||||
memset(&RomInfo, 0, sizeof(ROM_INFO));
|
||||
strncpy(RomInfo.szFullFileName, RomLocation, (sizeof(RomInfo.szFullFileName) / sizeof(RomInfo.szFullFileName[0])) - 1);
|
||||
if (!FillRomInfo(&RomInfo)) { return; }
|
||||
AddRomInfoToList(RomInfo, lpLastRom);
|
||||
}
|
||||
|
||||
void CRomBrowser::AddRomInfoToList(ROM_INFO &RomInfo, const char * lpLastRom)
|
||||
{
|
||||
int32_t ListPos = m_RomInfo.size();
|
||||
m_RomInfo.push_back(RomInfo);
|
||||
m_RomInfo[ListPos].SelColorBrush = NULL;
|
||||
|
||||
LVITEMW lvItem;
|
||||
memset(&lvItem, 0, sizeof(lvItem));
|
||||
lvItem.mask = LVIF_TEXT | LVIF_PARAM;
|
||||
lvItem.iItem = CalcSortPosition(ListPos);
|
||||
lvItem.iItem = ListView_GetItemCount(m_hRomList);
|
||||
lvItem.lParam = (LPARAM)ListPos;
|
||||
lvItem.pszText = LPSTR_TEXTCALLBACKW;
|
||||
|
||||
int32_t index = ListView_InsertItem(m_hRomList, &lvItem);
|
||||
int32_t index = SendMessageW(m_hRomList, LVM_INSERTITEMW, 0, (LPARAM)&lvItem);
|
||||
int32_t iItem = ListView_GetNextItem(m_hRomList, -1, LVNI_SELECTED);
|
||||
|
||||
//if the last rom then highlight the item
|
||||
if (iItem < 0 && _stricmp(RomInfo.szFullFileName, lpLastRom) == 0)
|
||||
if (iItem < 0 && _stricmp(m_RomInfo[ListPos].szFullFileName, m_LastRom.c_str()) == 0)
|
||||
{
|
||||
ListView_SetItemState(m_hRomList, index, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
|
||||
}
|
||||
|
@ -342,6 +292,18 @@ void CRomBrowser::AllocateBrushs(void)
|
|||
}
|
||||
}
|
||||
|
||||
void CRomBrowser::RomListReset(void)
|
||||
{
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "1");
|
||||
ListView_DeleteAllItems((HWND)m_hRomList);
|
||||
DeallocateBrushs();
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "2");
|
||||
InvalidateRect((HWND)m_hRomList, NULL, TRUE);
|
||||
Sleep(100);
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "3");
|
||||
m_LastRom = UISettingsLoadStringIndex(File_RecentGameFileIndex, 0);
|
||||
}
|
||||
|
||||
void CRomBrowser::CreateRomListControl(void)
|
||||
{
|
||||
m_hRomList = CreateWindowW(WC_LISTVIEWW, NULL, WS_TABSTOP | WS_VISIBLE | WS_CHILD | LVS_OWNERDRAWFIXED | LVS_SINGLESEL | LVS_REPORT, 0, 0, 0, 0, m_MainWindow, (HMENU)IDC_ROMLIST, GetModuleHandle(NULL), NULL);
|
||||
|
@ -365,438 +327,15 @@ void CRomBrowser::DeallocateBrushs(void)
|
|||
}
|
||||
}
|
||||
|
||||
void CRomBrowser::FillRomExtensionInfo(ROM_INFO * pRomInfo)
|
||||
void CRomBrowser::RomListLoaded(void)
|
||||
{
|
||||
//Initialize the structure
|
||||
pRomInfo->UserNotes[0] = 0;
|
||||
pRomInfo->Developer[0] = 0;
|
||||
pRomInfo->ReleaseDate[0] = 0;
|
||||
pRomInfo->Genre[0] = 0;
|
||||
pRomInfo->Players = 1;
|
||||
pRomInfo->CoreNotes[0] = 0;
|
||||
pRomInfo->PluginNotes[0] = 0;
|
||||
wcscpy(pRomInfo->GoodName, L"#340#");
|
||||
wcscpy(pRomInfo->Status, L"Unknown");
|
||||
|
||||
//Get File Identifier
|
||||
char Identifier[100];
|
||||
sprintf(Identifier, "%08X-%08X-C:%X", pRomInfo->CRC1, pRomInfo->CRC2, pRomInfo->Country);
|
||||
|
||||
//Rom Notes
|
||||
if (m_Fields[RB_UserNotes].Pos() >= 0)
|
||||
{
|
||||
wcsncpy(pRomInfo->UserNotes, m_NotesIniFile->GetString(Identifier, "Note", "").ToUTF16().c_str(), sizeof(pRomInfo->UserNotes) / sizeof(wchar_t));
|
||||
}
|
||||
|
||||
//Rom Extension info
|
||||
if (m_Fields[RB_Developer].Pos() >= 0)
|
||||
{
|
||||
wcsncpy(pRomInfo->Developer, m_ExtIniFile->GetString(Identifier, "Developer", "").ToUTF16().c_str(), sizeof(pRomInfo->Developer) / sizeof(wchar_t));
|
||||
}
|
||||
if (m_Fields[RB_ReleaseDate].Pos() >= 0)
|
||||
{
|
||||
wcsncpy(pRomInfo->ReleaseDate, m_ExtIniFile->GetString(Identifier, "ReleaseDate", "").ToUTF16().c_str(), sizeof(pRomInfo->ReleaseDate) / sizeof(wchar_t));
|
||||
}
|
||||
if (m_Fields[RB_Genre].Pos() >= 0)
|
||||
{
|
||||
wcsncpy(pRomInfo->Genre, m_ExtIniFile->GetString(Identifier, "Genre", "").ToUTF16().c_str(), sizeof(pRomInfo->Genre) / sizeof(wchar_t));
|
||||
}
|
||||
if (m_Fields[RB_Players].Pos() >= 0)
|
||||
{
|
||||
m_ExtIniFile->GetNumber(Identifier, "Players", 1, (uint32_t &)pRomInfo->Players);
|
||||
}
|
||||
if (m_Fields[RB_ForceFeedback].Pos() >= 0)
|
||||
{
|
||||
wcsncpy(pRomInfo->ForceFeedback, m_ExtIniFile->GetString(Identifier, "ForceFeedback", "unknown").ToUTF16().c_str(), sizeof(pRomInfo->ForceFeedback) / sizeof(wchar_t));
|
||||
}
|
||||
|
||||
//Rom Settings
|
||||
if (m_Fields[RB_GoodName].Pos() >= 0)
|
||||
{
|
||||
wcsncpy(pRomInfo->GoodName, m_RomIniFile->GetString(Identifier, "Good Name", stdstr().FromUTF16(pRomInfo->GoodName).c_str()).ToUTF16().c_str(), sizeof(pRomInfo->GoodName) / sizeof(wchar_t));
|
||||
}
|
||||
wcsncpy(pRomInfo->Status, m_RomIniFile->GetString(Identifier, "Status", stdstr().FromUTF16(pRomInfo->Status).c_str()).ToUTF16().c_str(), sizeof(pRomInfo->Status) / sizeof(wchar_t));
|
||||
if (m_Fields[RB_CoreNotes].Pos() >= 0)
|
||||
{
|
||||
wcsncpy(pRomInfo->CoreNotes, m_RomIniFile->GetString(Identifier, "Core Note", "").ToUTF16().c_str(), sizeof(pRomInfo->CoreNotes) / sizeof(wchar_t));
|
||||
}
|
||||
if (m_Fields[RB_PluginNotes].Pos() >= 0)
|
||||
{
|
||||
wcsncpy(pRomInfo->PluginNotes, m_RomIniFile->GetString(Identifier, "Plugin Note", "").ToUTF16().c_str(), sizeof(pRomInfo->PluginNotes) / sizeof(wchar_t));
|
||||
}
|
||||
|
||||
//Get the text color
|
||||
stdstr String = m_RomIniFile->GetString("Rom Status", stdstr().FromUTF16(pRomInfo->Status).c_str(), "000000");
|
||||
pRomInfo->TextColor = (std::strtoul(String.c_str(), 0, 16) & 0xFFFFFF);
|
||||
pRomInfo->TextColor = (pRomInfo->TextColor & 0x00FF00) | ((pRomInfo->TextColor >> 0x10) & 0xFF) | ((pRomInfo->TextColor & 0xFF) << 0x10);
|
||||
|
||||
//Get the selected color
|
||||
String.Format("%ws.Sel", pRomInfo->Status);
|
||||
String = m_RomIniFile->GetString("Rom Status", String.c_str(), "FFFFFFFF");
|
||||
uint32_t selcol = std::strtoul(String.c_str(), NULL, 16);
|
||||
if (selcol & 0x80000000)
|
||||
{
|
||||
pRomInfo->SelColor = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
selcol = (selcol & 0x00FF00) | ((selcol >> 0x10) & 0xFF) | ((selcol & 0xFF) << 0x10);
|
||||
pRomInfo->SelColor = selcol;
|
||||
}
|
||||
|
||||
//Get the selected text color
|
||||
String.Format("%ws.Seltext", pRomInfo->Status);
|
||||
String = m_RomIniFile->GetString("Rom Status", String.c_str(), "FFFFFF");
|
||||
pRomInfo->SelTextColor = (std::strtoul(String.c_str(), 0, 16) & 0xFFFFFF);
|
||||
pRomInfo->SelTextColor = (pRomInfo->SelTextColor & 0x00FF00) | ((pRomInfo->SelTextColor >> 0x10) & 0xFF) | ((pRomInfo->SelTextColor & 0xFF) << 0x10);
|
||||
AllocateBrushs();
|
||||
RomList_SortList();
|
||||
}
|
||||
|
||||
bool CRomBrowser::FillRomInfo(ROM_INFO * pRomInfo)
|
||||
void CRomBrowser::RomDirChanged(void)
|
||||
{
|
||||
int32_t count;
|
||||
uint8_t RomData[0x1000];
|
||||
|
||||
if (!LoadDataFromRomFile(pRomInfo->szFullFileName, RomData, sizeof(RomData), &pRomInfo->RomSize, pRomInfo->FileFormat))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strstr(pRomInfo->szFullFileName, "?") != NULL)
|
||||
{
|
||||
strcpy(pRomInfo->FileName, strstr(pRomInfo->szFullFileName, "?") + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(pRomInfo->FileName, CPath(pRomInfo->szFullFileName).GetNameExtension().c_str(), sizeof(pRomInfo->FileName) / sizeof(pRomInfo->FileName[0]));
|
||||
}
|
||||
if (m_Fields[RB_InternalName].Pos() >= 0)
|
||||
{
|
||||
char InternalName[22];
|
||||
memcpy(InternalName, (void *)(RomData + 0x20), 20);
|
||||
for (count = 0; count < 20; count += 4)
|
||||
{
|
||||
InternalName[count] ^= InternalName[count + 3];
|
||||
InternalName[count + 3] ^= InternalName[count];
|
||||
InternalName[count] ^= InternalName[count + 3];
|
||||
InternalName[count + 1] ^= InternalName[count + 2];
|
||||
InternalName[count + 2] ^= InternalName[count + 1];
|
||||
InternalName[count + 1] ^= InternalName[count + 2];
|
||||
}
|
||||
InternalName[20] = '\0';
|
||||
wcscpy(pRomInfo->InternalName, stdstr(InternalName).ToUTF16(stdstr::CODEPAGE_932).c_str());
|
||||
}
|
||||
pRomInfo->CartID[0] = *(RomData + 0x3F);
|
||||
pRomInfo->CartID[1] = *(RomData + 0x3E);
|
||||
pRomInfo->CartID[2] = '\0';
|
||||
pRomInfo->Manufacturer = *(RomData + 0x38);
|
||||
pRomInfo->Country = *(RomData + 0x3D);
|
||||
pRomInfo->CRC1 = *(uint32_t *)(RomData + 0x10);
|
||||
pRomInfo->CRC2 = *(uint32_t *)(RomData + 0x14);
|
||||
pRomInfo->CicChip = GetCicChipID(RomData);
|
||||
|
||||
FillRomExtensionInfo(pRomInfo);
|
||||
|
||||
if (pRomInfo->SelColor == -1)
|
||||
{
|
||||
pRomInfo->SelColorBrush = (uint32_t)((HBRUSH)(COLOR_HIGHLIGHT + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
pRomInfo->SelColorBrush = (uint32_t)CreateSolidBrush(pRomInfo->SelColor);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool CRomBrowser::GetRomFileNames(strlist & FileList, const CPath & BaseDirectory, const std::string & Directory, bool InWatchThread)
|
||||
{
|
||||
if (!BaseDirectory.DirectoryExists())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
CPath SearchPath(BaseDirectory, "*.*");
|
||||
SearchPath.AppendDirectory(Directory.c_str());
|
||||
|
||||
if (!SearchPath.FindFirst(CPath::FIND_ATTRIBUTE_ALLFILES))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (InWatchThread && WaitForSingleObject(m_WatchStopEvent, 0) != WAIT_TIMEOUT)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SearchPath.IsDirectory())
|
||||
{
|
||||
if (g_Settings->LoadBool(RomList_GameDirRecursive))
|
||||
{
|
||||
CPath CurrentDir(Directory);
|
||||
CurrentDir.AppendDirectory(SearchPath.GetLastDirectory().c_str());
|
||||
GetRomFileNames(FileList, BaseDirectory, CurrentDir, InWatchThread);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddFileNameToList(FileList, Directory, SearchPath);
|
||||
}
|
||||
} while (SearchPath.FindNext());
|
||||
return true;
|
||||
}
|
||||
|
||||
void CRomBrowser::NotificationCB(const char * Status, CRomBrowser * /*_this*/)
|
||||
{
|
||||
g_Notify->DisplayMessage(5, Status);
|
||||
}
|
||||
|
||||
static const char* ROM_extensions[] =
|
||||
{
|
||||
"zip", "7z", "v64", "z64", "n64", "rom", "jap", "pal", "usa", "eur", "bin",
|
||||
};
|
||||
|
||||
void CRomBrowser::AddFileNameToList(strlist & FileList, const stdstr & Directory, CPath & File)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
if (FileList.size() > 3000)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
stdstr Drive, Dir, Name, Extension;
|
||||
File.GetComponents(NULL, &Dir, &Name, &Extension);
|
||||
Extension.ToLower();
|
||||
for (i = 0; i < sizeof(ROM_extensions) / sizeof(ROM_extensions[0]); i++)
|
||||
{
|
||||
if (Extension == ROM_extensions[i])
|
||||
{
|
||||
stdstr FileName = Directory + Name + Extension;
|
||||
FileName.ToLower();
|
||||
FileList.push_back(FileName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CRomBrowser::FillRomList(strlist & FileList, const CPath & BaseDirectory, const char * Directory, const char * lpLastRom)
|
||||
{
|
||||
CPath SearchPath(BaseDirectory, "*");
|
||||
SearchPath.AppendDirectory(Directory);
|
||||
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "1 %s", (const char *)SearchPath);
|
||||
if (!SearchPath.FindFirst(CPath::FIND_ATTRIBUTE_ALLFILES))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
uint8_t ext_ID;
|
||||
int8_t new_list_entry = 0;
|
||||
const uint8_t exts = sizeof(ROM_extensions) / sizeof(ROM_extensions[0]);
|
||||
|
||||
WriteTrace(TraceUserInterface, TraceDebug, ": 2 %s m_StopRefresh = %d", (const char *)SearchPath, m_StopRefresh);
|
||||
if (m_StopRefresh) { break; }
|
||||
|
||||
if (SearchPath.IsDirectory())
|
||||
{
|
||||
if (g_Settings->LoadBool(RomList_GameDirRecursive))
|
||||
{
|
||||
CPath CurrentDir(Directory);
|
||||
CurrentDir.AppendDirectory(SearchPath.GetLastDirectory().c_str());
|
||||
FillRomList(FileList, BaseDirectory, CurrentDir, lpLastRom);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
AddFileNameToList(FileList, Directory, SearchPath);
|
||||
|
||||
stdstr Extension = stdstr(SearchPath.GetExtension()).ToLower();
|
||||
|
||||
for (ext_ID = 0; ext_ID < exts; ext_ID++)
|
||||
{
|
||||
if (Extension == ROM_extensions[ext_ID] && Extension != "7z")
|
||||
{
|
||||
new_list_entry = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (new_list_entry)
|
||||
{
|
||||
AddRomToList(SearchPath, lpLastRom);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Extension == "7z")
|
||||
{
|
||||
try
|
||||
{
|
||||
C7zip ZipFile(SearchPath);
|
||||
if (!ZipFile.OpenSuccess())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
char ZipFileName[260];
|
||||
stdstr_f SectionName("%s-%d", ZipFile.FileName(ZipFileName, sizeof(ZipFileName)), ZipFile.FileSize());
|
||||
SectionName.ToLower();
|
||||
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "4 %s", SectionName.c_str());
|
||||
for (int32_t i = 0; i < ZipFile.NumFiles(); i++)
|
||||
{
|
||||
CSzFileItem * f = ZipFile.FileItem(i);
|
||||
if (f->IsDir)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ROM_INFO RomInfo;
|
||||
|
||||
std::wstring FileNameW = ZipFile.FileNameIndex(i);
|
||||
if (FileNameW.length() == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
stdstr FileName;
|
||||
FileName.FromUTF16(FileNameW.c_str());
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "5");
|
||||
char drive2[_MAX_DRIVE], dir2[_MAX_DIR], FileName2[MAX_PATH], ext2[_MAX_EXT];
|
||||
_splitpath(FileName.c_str(), drive2, dir2, FileName2, ext2);
|
||||
|
||||
WriteTrace(TraceUserInterface, TraceDebug, ": 6 %s", ext2);
|
||||
if (_stricmp(ext2, ".bin") == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "7");
|
||||
memset(&RomInfo, 0, sizeof(ROM_INFO));
|
||||
stdstr_f zipFileName("%s?%s", (LPCSTR)SearchPath, FileName.c_str());
|
||||
ZipFile.SetNotificationCallback((C7zip::LP7ZNOTIFICATION)NotificationCB, this);
|
||||
|
||||
strncpy(RomInfo.szFullFileName, zipFileName.c_str(), sizeof(RomInfo.szFullFileName) - 1);
|
||||
RomInfo.szFullFileName[sizeof(RomInfo.szFullFileName) - 1] = 0;
|
||||
strcpy(RomInfo.FileName, strstr(RomInfo.szFullFileName, "?") + 1);
|
||||
RomInfo.FileFormat = Format_7zip;
|
||||
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "8");
|
||||
char szHeader[0x90];
|
||||
if (m_ZipIniFile->GetString(SectionName.c_str(), FileName.c_str(), "", szHeader, sizeof(szHeader)) == 0)
|
||||
{
|
||||
uint8_t RomData[0x1000];
|
||||
if (!ZipFile.GetFile(i, RomData, sizeof(RomData)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "9");
|
||||
if (!CN64Rom::IsValidRomImage(RomData)) { continue; }
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "10");
|
||||
ByteSwapRomData(RomData, sizeof(RomData));
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "11");
|
||||
|
||||
stdstr RomHeader;
|
||||
for (int32_t x = 0; x < 0x40; x += 4)
|
||||
{
|
||||
RomHeader += stdstr_f("%08X", *((uint32_t *)&RomData[x]));
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "11a %s", RomHeader.c_str());
|
||||
int32_t CicChip = GetCicChipID(RomData);
|
||||
|
||||
//save this info
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "12");
|
||||
m_ZipIniFile->SaveString(SectionName.c_str(), FileName.c_str(), RomHeader.c_str());
|
||||
m_ZipIniFile->SaveNumber(SectionName.c_str(), stdstr_f("%s-Cic", FileName.c_str()).c_str(), CicChip);
|
||||
strcpy(szHeader, RomHeader.c_str());
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "13");
|
||||
uint8_t RomData[0x40];
|
||||
|
||||
for (int32_t x = 0; x < 0x40; x += 4)
|
||||
{
|
||||
const size_t delimit_offset = sizeof("FFFFFFFF") - 1;
|
||||
const char backup_character = szHeader[2 * x + delimit_offset];
|
||||
|
||||
szHeader[2 * x + delimit_offset] = '\0';
|
||||
*(uint32_t *)&RomData[x] = strtoul(&szHeader[2 * x], NULL, 16);
|
||||
szHeader[2 * x + delimit_offset] = backup_character;
|
||||
}
|
||||
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "14");
|
||||
{
|
||||
char InternalName[22];
|
||||
memcpy(InternalName, (void *)(RomData + 0x20), 20);
|
||||
for (int32_t count = 0; count < 20; count += 4)
|
||||
{
|
||||
InternalName[count] ^= InternalName[count + 3];
|
||||
InternalName[count + 3] ^= InternalName[count];
|
||||
InternalName[count] ^= InternalName[count + 3];
|
||||
InternalName[count + 1] ^= InternalName[count + 2];
|
||||
InternalName[count + 2] ^= InternalName[count + 1];
|
||||
InternalName[count + 1] ^= InternalName[count + 2];
|
||||
}
|
||||
InternalName[20] = '\0';
|
||||
wcscpy(RomInfo.InternalName, stdstr(InternalName).ToUTF16(stdstr::CODEPAGE_932).c_str());
|
||||
}
|
||||
RomInfo.RomSize = (int32_t)f->Size;
|
||||
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "15");
|
||||
RomInfo.CartID[0] = *(RomData + 0x3F);
|
||||
RomInfo.CartID[1] = *(RomData + 0x3E);
|
||||
RomInfo.CartID[2] = '\0';
|
||||
RomInfo.Manufacturer = *(RomData + 0x38);
|
||||
RomInfo.Country = *(RomData + 0x3D);
|
||||
RomInfo.CRC1 = *(uint32_t *)(RomData + 0x10);
|
||||
RomInfo.CRC2 = *(uint32_t *)(RomData + 0x14);
|
||||
m_ZipIniFile->GetNumber(SectionName.c_str(), stdstr_f("%s-Cic", FileName.c_str()).c_str(), (ULONG)-1, (uint32_t &)RomInfo.CicChip);
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "16");
|
||||
FillRomExtensionInfo(&RomInfo);
|
||||
|
||||
if (RomInfo.SelColor == -1)
|
||||
{
|
||||
RomInfo.SelColorBrush = (uint32_t)((HBRUSH)(COLOR_HIGHLIGHT + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
RomInfo.SelColorBrush = (uint32_t)CreateSolidBrush(RomInfo.SelColor);
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "17");
|
||||
AddRomInfoToList(RomInfo, lpLastRom);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
WriteTrace(TraceUserInterface, TraceError, "execpetion processing %s", (LPCSTR)SearchPath);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
} while (SearchPath.FindNext());
|
||||
m_ZipIniFile->FlushChanges();
|
||||
}
|
||||
|
||||
int32_t CRomBrowser::GetCicChipID(uint8_t * RomData)
|
||||
{
|
||||
__int64 CRC = 0;
|
||||
int32_t count;
|
||||
|
||||
for (count = 0x40; count < 0x1000; count += 4)
|
||||
{
|
||||
CRC += *(uint32_t *)(RomData + count);
|
||||
}
|
||||
switch (CRC)
|
||||
{
|
||||
case 0x000000D0027FDF31: return CIC_NUS_6101;
|
||||
case 0x000000CFFB631223: return CIC_NUS_6101;
|
||||
case 0x000000D057C85244: return CIC_NUS_6102;
|
||||
case 0x000000D6497E414B: return CIC_NUS_6103;
|
||||
case 0x0000011A49F60E96: return CIC_NUS_6105;
|
||||
case 0x000000D6D5BE5580: return CIC_NUS_6106;
|
||||
case 0x000001053BC19870: return CIC_NUS_5167; //64DD CONVERSION CIC
|
||||
case 0x000000D2E53EF008: return CIC_NUS_8303; //64DD IPL
|
||||
default:
|
||||
return CIC_UNKNOWN;
|
||||
}
|
||||
PostMessage(m_MainWindow, WM_COMMAND, ID_FILE_REFRESHROMLIST, 0);
|
||||
}
|
||||
|
||||
void CRomBrowser::HighLightLastRom(void)
|
||||
|
@ -844,174 +383,6 @@ void CRomBrowser::HighLightLastRom(void)
|
|||
}
|
||||
}
|
||||
|
||||
bool CRomBrowser::LoadDataFromRomFile(const char * FileName, uint8_t * Data, int32_t DataLen, int32_t * RomSize, FILE_FORMAT & FileFormat)
|
||||
{
|
||||
uint8_t Test[4];
|
||||
|
||||
if (_strnicmp(&FileName[strlen(FileName) - 4], ".ZIP", 4) == 0)
|
||||
{
|
||||
int32_t len, port = 0, FoundRom;
|
||||
unz_file_info info;
|
||||
char zname[132];
|
||||
unzFile file;
|
||||
file = unzOpen(FileName);
|
||||
if (file == NULL) { return false; }
|
||||
|
||||
port = unzGoToFirstFile(file);
|
||||
FoundRom = false;
|
||||
while (port == UNZ_OK && FoundRom == false)
|
||||
{
|
||||
unzGetCurrentFileInfo(file, &info, zname, 128, NULL, 0, NULL, 0);
|
||||
if (unzLocateFile(file, zname, 1) != UNZ_OK)
|
||||
{
|
||||
unzClose(file);
|
||||
return true;
|
||||
}
|
||||
if (unzOpenCurrentFile(file) != UNZ_OK)
|
||||
{
|
||||
unzClose(file);
|
||||
return true;
|
||||
}
|
||||
unzReadCurrentFile(file, Test, 4);
|
||||
if (CN64Rom::IsValidRomImage(Test))
|
||||
{
|
||||
FoundRom = true;
|
||||
memcpy(Data, Test, 4);
|
||||
len = unzReadCurrentFile(file, &Data[4], DataLen - 4) + 4;
|
||||
|
||||
if ((int32_t)DataLen != len)
|
||||
{
|
||||
unzCloseCurrentFile(file);
|
||||
unzClose(file);
|
||||
return false;
|
||||
}
|
||||
*RomSize = info.uncompressed_size;
|
||||
if (unzCloseCurrentFile(file) == UNZ_CRCERROR)
|
||||
{
|
||||
unzClose(file);
|
||||
return false;
|
||||
}
|
||||
unzClose(file);
|
||||
}
|
||||
if (FoundRom == false)
|
||||
{
|
||||
unzCloseCurrentFile(file);
|
||||
port = unzGoToNextFile(file);
|
||||
}
|
||||
}
|
||||
if (FoundRom == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
FileFormat = Format_Zip;
|
||||
}
|
||||
else
|
||||
{
|
||||
HANDLE hFile = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE) { return false; }
|
||||
SetFilePointer(hFile, 0, 0, FILE_BEGIN);
|
||||
|
||||
DWORD dwRead;
|
||||
ReadFile(hFile, Test, 4, &dwRead, NULL);
|
||||
if (!CN64Rom::IsValidRomImage(Test)) { CloseHandle(hFile); return false; }
|
||||
SetFilePointer(hFile, 0, 0, FILE_BEGIN);
|
||||
if (!ReadFile(hFile, Data, DataLen, &dwRead, NULL)) { CloseHandle(hFile); return false; }
|
||||
*RomSize = GetFileSize(hFile, NULL);
|
||||
CloseHandle(hFile);
|
||||
FileFormat = Format_Uncompressed;
|
||||
}
|
||||
ByteSwapRomData(Data, DataLen);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CRomBrowser::ByteSwapRomData(uint8_t * Data, int32_t DataLen)
|
||||
{
|
||||
int32_t count;
|
||||
|
||||
switch (*((uint32_t *)&Data[0]))
|
||||
{
|
||||
case 0x12408037:
|
||||
for (count = 0; count < DataLen; count += 4)
|
||||
{
|
||||
Data[count] ^= Data[count + 2];
|
||||
Data[count + 2] ^= Data[count];
|
||||
Data[count] ^= Data[count + 2];
|
||||
Data[count + 1] ^= Data[count + 3];
|
||||
Data[count + 3] ^= Data[count + 1];
|
||||
Data[count + 1] ^= Data[count + 3];
|
||||
}
|
||||
break;
|
||||
case 0x40072780: //64DD IPL
|
||||
case 0x40123780:
|
||||
for (count = 0; count < DataLen; count += 4)
|
||||
{
|
||||
Data[count] ^= Data[count + 3];
|
||||
Data[count + 3] ^= Data[count];
|
||||
Data[count] ^= Data[count + 3];
|
||||
Data[count + 1] ^= Data[count + 2];
|
||||
Data[count + 2] ^= Data[count + 1];
|
||||
Data[count + 1] ^= Data[count + 2];
|
||||
}
|
||||
break;
|
||||
case 0x80371240: break;
|
||||
}
|
||||
}
|
||||
|
||||
void CRomBrowser::LoadRomList(void)
|
||||
{
|
||||
CPath FileName(g_Settings->LoadStringVal(RomList_RomListCache));
|
||||
CFile file(FileName, CFileBase::modeRead | CFileBase::modeNoTruncate);
|
||||
|
||||
if (!file.IsOpen())
|
||||
{
|
||||
//if file does not exist then refresh the data
|
||||
RefreshRomBrowser();
|
||||
return;
|
||||
}
|
||||
unsigned char md5[16];
|
||||
if (!file.Read(md5, sizeof(md5)))
|
||||
{
|
||||
file.Close();
|
||||
RefreshRomBrowser();
|
||||
return;
|
||||
}
|
||||
|
||||
//Read the size of ROM_INFO
|
||||
int32_t RomInfoSize = 0;
|
||||
if (!file.Read(&RomInfoSize, sizeof(RomInfoSize)) || RomInfoSize != sizeof(ROM_INFO))
|
||||
{
|
||||
file.Close();
|
||||
RefreshRomBrowser();
|
||||
return;
|
||||
}
|
||||
|
||||
//Read the Number of entries
|
||||
int32_t Entries = 0;
|
||||
file.Read(&Entries, sizeof(Entries));
|
||||
|
||||
//Read Every Entry
|
||||
DeallocateBrushs();
|
||||
m_RomInfo.clear();
|
||||
for (int32_t count = 0; count < Entries; count++)
|
||||
{
|
||||
ROM_INFO RomInfo;
|
||||
file.Read(&RomInfo, RomInfoSize);
|
||||
RomInfo.SelColorBrush = NULL;
|
||||
|
||||
LVITEMW lvItem;
|
||||
memset(&lvItem, 0, sizeof(lvItem));
|
||||
lvItem.mask = LVIF_TEXT | LVIF_PARAM;
|
||||
lvItem.iItem = ListView_GetItemCount(m_hRomList);
|
||||
lvItem.lParam = (LPARAM)m_RomInfo.size();
|
||||
lvItem.pszText = LPSTR_TEXTCALLBACKW;
|
||||
|
||||
SendMessageW(m_hRomList, LVM_INSERTITEMW, 0, (LPARAM)&lvItem);
|
||||
m_RomInfo.push_back(RomInfo);
|
||||
}
|
||||
AllocateBrushs();
|
||||
RomList_SortList();
|
||||
}
|
||||
|
||||
void CRomBrowser::MenuSetText(HMENU hMenu, int32_t MenuPos, const wchar_t * Title, char * ShortCut)
|
||||
{
|
||||
MENUITEMINFOW MenuInfo;
|
||||
|
@ -1034,68 +405,6 @@ void CRomBrowser::MenuSetText(HMENU hMenu, int32_t MenuPos, const wchar_t * Titl
|
|||
SetMenuItemInfoW(hMenu, MenuPos, TRUE, &MenuInfo);
|
||||
}
|
||||
|
||||
void CRomBrowser::RefreshRomBrowser(void)
|
||||
{
|
||||
DWORD ThreadID;
|
||||
|
||||
if (m_RefreshThread)
|
||||
{
|
||||
return;
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "1");
|
||||
m_StopRefresh = false;
|
||||
m_RefreshThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)RefreshRomBrowserStatic, (LPVOID)this, 0, &ThreadID);
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "2");
|
||||
}
|
||||
|
||||
void CRomBrowser::RefreshRomBrowserStatic(CRomBrowser * _this)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_this->m_hRomList == NULL) { return; }
|
||||
|
||||
//delete cache
|
||||
CPath(g_Settings->LoadStringVal(RomList_RomListCache)).Delete();
|
||||
|
||||
//clear all current items
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "1");
|
||||
ListView_DeleteAllItems((HWND)_this->m_hRomList);
|
||||
_this->DeallocateBrushs();
|
||||
_this->m_RomInfo.clear();
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "2");
|
||||
InvalidateRect((HWND)_this->m_hRomList, NULL, TRUE);
|
||||
Sleep(100);
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "3");
|
||||
|
||||
if (_this->m_WatchRomDir != g_Settings->LoadStringVal(RomList_GameDir))
|
||||
{
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "4");
|
||||
_this->WatchThreadStop();
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "5");
|
||||
_this->WatchThreadStart();
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "6");
|
||||
}
|
||||
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "7");
|
||||
stdstr RomDir = g_Settings->LoadStringVal(RomList_GameDir);
|
||||
stdstr LastRom = UISettingsLoadStringIndex(File_RecentGameFileIndex, 0);
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "8");
|
||||
|
||||
strlist FileNames;
|
||||
_this->FillRomList(FileNames, CPath(RomDir), "", LastRom.c_str());
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "9");
|
||||
_this->SaveRomList(FileNames);
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "10");
|
||||
CloseHandle(_this->m_RefreshThread);
|
||||
_this->m_RefreshThread = NULL;
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "11");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
WriteTrace(TraceUserInterface, TraceError, "Unhandled Exception ");
|
||||
}
|
||||
}
|
||||
|
||||
void CRomBrowser::ResetRomBrowserColomuns(void)
|
||||
{
|
||||
size_t Coloumn, index;
|
||||
|
@ -1481,7 +790,6 @@ void CRomBrowser::RomList_OpenRom(uint32_t /*pnmh*/)
|
|||
|
||||
if (!pRomInfo) { return; }
|
||||
m_StopRefresh = true;
|
||||
|
||||
delete g_DDRom;
|
||||
g_DDRom = NULL;
|
||||
|
||||
|
@ -1589,36 +897,6 @@ void CRomBrowser::RomList_SortList(void)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SaveRomList - save all the rom information about the current roms in the rom brower
|
||||
* to a cache file, so it is quick to reload the information
|
||||
*/
|
||||
void CRomBrowser::SaveRomList(strlist & FileList)
|
||||
{
|
||||
MD5 ListHash = RomListHash(FileList);
|
||||
|
||||
CPath FileName(g_Settings->LoadStringVal(RomList_RomListCache));
|
||||
CFile file(FileName, CFileBase::modeWrite | CFileBase::modeCreate);
|
||||
file.Write(ListHash.raw_digest(), 16);
|
||||
|
||||
//Write the size of ROM_INFO
|
||||
int32_t RomInfoSize = sizeof(ROM_INFO);
|
||||
file.Write(&RomInfoSize, sizeof(RomInfoSize));
|
||||
|
||||
//Write the Number of entries
|
||||
int32_t Entries = m_RomInfo.size();
|
||||
file.Write(&Entries, sizeof(Entries));
|
||||
|
||||
//Write Every Entry
|
||||
for (int32_t count = 0; count < Entries; count++)
|
||||
{
|
||||
file.Write(&m_RomInfo[count], RomInfoSize);
|
||||
}
|
||||
|
||||
//Close the file handle
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CRomBrowser::SaveRomListColoumnInfo(void)
|
||||
{
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "Start");
|
||||
|
@ -1823,147 +1101,3 @@ void CRomBrowser::HideRomList(void)
|
|||
PostMessage(m_MainWindow, WM_MAKE_FOCUS, 0, 0);
|
||||
}
|
||||
|
||||
bool CRomBrowser::RomDirNeedsRefresh(void)
|
||||
{
|
||||
bool InWatchThread = (m_WatchThreadID == GetCurrentThreadId());
|
||||
|
||||
//Get Old MD5 of file names
|
||||
stdstr FileName = g_Settings->LoadStringVal(RomList_RomListCache);
|
||||
HANDLE hFile = CreateFile(FileName.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
//if file does not exist then refresh the data
|
||||
return true;
|
||||
}
|
||||
|
||||
DWORD dwRead;
|
||||
unsigned char CurrentFileMD5[16];
|
||||
ReadFile(hFile, &CurrentFileMD5, sizeof(CurrentFileMD5), &dwRead, NULL);
|
||||
CloseHandle(hFile);
|
||||
|
||||
//Get Current MD5 of file names
|
||||
strlist FileNames;
|
||||
if (!GetRomFileNames(FileNames, CPath(g_Settings->LoadStringVal(RomList_GameDir)), stdstr(""), InWatchThread))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
FileNames.sort();
|
||||
|
||||
MD5 NewMd5 = RomListHash(FileNames);
|
||||
if (memcmp(NewMd5.raw_digest(), CurrentFileMD5, sizeof(CurrentFileMD5)) != 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
MD5 CRomBrowser::RomListHash(strlist & FileList)
|
||||
{
|
||||
stdstr NewFileNames;
|
||||
FileList.sort();
|
||||
for (strlist::iterator iter = FileList.begin(); iter != FileList.end(); iter++)
|
||||
{
|
||||
NewFileNames += *iter;
|
||||
NewFileNames += ";";
|
||||
}
|
||||
MD5 md5Hash((const unsigned char *)NewFileNames.c_str(), NewFileNames.length());
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "%s - %s", md5Hash.hex_digest(), NewFileNames.c_str());
|
||||
return md5Hash;
|
||||
}
|
||||
|
||||
void CRomBrowser::WatchRomDirChanged(CRomBrowser * _this)
|
||||
{
|
||||
try
|
||||
{
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "1");
|
||||
_this->m_WatchRomDir = g_Settings->LoadStringVal(RomList_GameDir);
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "2");
|
||||
if (_this->RomDirNeedsRefresh())
|
||||
{
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "2a");
|
||||
PostMessage((HWND)_this->m_MainWindow, WM_COMMAND, ID_FILE_REFRESHROMLIST, 0);
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "3");
|
||||
HANDLE hChange[] =
|
||||
{
|
||||
_this->m_WatchStopEvent,
|
||||
FindFirstChangeNotification(_this->m_WatchRomDir.c_str(), g_Settings->LoadBool(RomList_GameDirRecursive), FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_SIZE),
|
||||
};
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "4");
|
||||
for (;;)
|
||||
{
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "5");
|
||||
if (WaitForMultipleObjects(sizeof(hChange) / sizeof(hChange[0]), hChange, false, INFINITE) == WAIT_OBJECT_0)
|
||||
{
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "5a");
|
||||
FindCloseChangeNotification(hChange[1]);
|
||||
return;
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "5b");
|
||||
if (_this->RomDirNeedsRefresh())
|
||||
{
|
||||
PostMessage((HWND)_this->m_MainWindow, WM_COMMAND, ID_FILE_REFRESHROMLIST, 0);
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "5c");
|
||||
if (!FindNextChangeNotification(hChange[1]))
|
||||
{
|
||||
FindCloseChangeNotification(hChange[1]);
|
||||
return;
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "5d");
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
WriteTrace(TraceUserInterface, TraceError, __FUNCTION__ ": Unhandled Exception");
|
||||
}
|
||||
}
|
||||
|
||||
void CRomBrowser::WatchThreadStart(void)
|
||||
{
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "1");
|
||||
WatchThreadStop();
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "2");
|
||||
if (m_WatchStopEvent == NULL)
|
||||
{
|
||||
m_WatchStopEvent = CreateEvent(NULL, true, false, NULL);
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "3");
|
||||
m_WatchThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WatchRomDirChanged, this, 0, &m_WatchThreadID);
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "4");
|
||||
}
|
||||
|
||||
void CRomBrowser::WatchThreadStop(void)
|
||||
{
|
||||
if (m_WatchThread == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "1");
|
||||
SetEvent(m_WatchStopEvent);
|
||||
DWORD ExitCode = 0;
|
||||
for (int32_t count = 0; count < 20; count++)
|
||||
{
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "2");
|
||||
GetExitCodeThread(m_WatchThread, &ExitCode);
|
||||
if (ExitCode != STILL_ACTIVE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
Sleep(200);
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "3");
|
||||
if (ExitCode == STILL_ACTIVE)
|
||||
{
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "3a");
|
||||
TerminateThread(m_WatchThread, 0);
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "4");
|
||||
|
||||
CloseHandle(m_WatchThread);
|
||||
CloseHandle(m_WatchStopEvent);
|
||||
m_WatchStopEvent = NULL;
|
||||
m_WatchThread = NULL;
|
||||
m_WatchThreadID = 0;
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "5");
|
||||
}
|
|
@ -0,0 +1,861 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
#include "stdafx.h"
|
||||
|
||||
static const char* ROM_extensions[] =
|
||||
{
|
||||
"zip", "7z", "v64", "z64", "n64", "rom", "jap", "pal", "usa", "eur", "bin",
|
||||
};
|
||||
|
||||
CRomList::CRomList() :
|
||||
m_RefreshThread(NULL),
|
||||
m_NotesIniFile(NULL),
|
||||
m_ExtIniFile(NULL),
|
||||
m_ZipIniFile(NULL),
|
||||
m_RomIniFile(NULL),
|
||||
m_WatchThreadID(0),
|
||||
m_WatchThread(NULL),
|
||||
m_WatchStopEvent(NULL)
|
||||
{
|
||||
if (g_Settings)
|
||||
{
|
||||
m_NotesIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_Notes).c_str());
|
||||
m_ExtIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_ExtInfo).c_str());
|
||||
m_RomIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_RomDatabase).c_str());
|
||||
m_ZipIniFile = new CIniFile(g_Settings->LoadStringVal(RomList_7zipCache).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
CRomList::~CRomList()
|
||||
{
|
||||
WatchThreadStop();
|
||||
m_StopRefresh = true;
|
||||
if (m_NotesIniFile)
|
||||
{
|
||||
delete m_NotesIniFile;
|
||||
m_NotesIniFile = NULL;
|
||||
}
|
||||
if (m_ExtIniFile)
|
||||
{
|
||||
delete m_ExtIniFile;
|
||||
m_ExtIniFile = NULL;
|
||||
}
|
||||
if (m_RomIniFile)
|
||||
{
|
||||
delete m_RomIniFile;
|
||||
m_RomIniFile = NULL;
|
||||
}
|
||||
if (m_ZipIniFile)
|
||||
{
|
||||
delete m_ZipIniFile;
|
||||
m_ZipIniFile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CRomList::RefreshRomBrowser(void)
|
||||
{
|
||||
DWORD ThreadID;
|
||||
|
||||
if (m_RefreshThread)
|
||||
{
|
||||
return;
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "1");
|
||||
m_StopRefresh = false;
|
||||
m_RefreshThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)RefreshRomBrowserStatic, (LPVOID)this, 0, &ThreadID);
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "2");
|
||||
}
|
||||
|
||||
void CRomList::RefreshRomListThread(void)
|
||||
{
|
||||
//delete cache
|
||||
CPath(g_Settings->LoadStringVal(RomList_RomListCache)).Delete();
|
||||
|
||||
//clear all current items
|
||||
RomListReset();
|
||||
m_RomInfo.clear();
|
||||
|
||||
if (m_WatchRomDir != g_Settings->LoadStringVal(RomList_GameDir))
|
||||
{
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "4");
|
||||
WatchThreadStop();
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "5");
|
||||
WatchThreadStart();
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "6");
|
||||
}
|
||||
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "7");
|
||||
stdstr RomDir = g_Settings->LoadStringVal(RomList_GameDir);
|
||||
stdstr LastRom = UISettingsLoadStringIndex(File_RecentGameFileIndex, 0);
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "8");
|
||||
|
||||
strlist FileNames;
|
||||
FillRomList(FileNames, CPath(RomDir), "", LastRom.c_str());
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "9");
|
||||
SaveRomList(FileNames);
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "10");
|
||||
CloseHandle(m_RefreshThread);
|
||||
m_RefreshThread = NULL;
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "11");
|
||||
}
|
||||
|
||||
void CRomList::AddRomToList(const char * RomLocation)
|
||||
{
|
||||
ROM_INFO RomInfo;
|
||||
|
||||
memset(&RomInfo, 0, sizeof(ROM_INFO));
|
||||
strncpy(RomInfo.szFullFileName, RomLocation, (sizeof(RomInfo.szFullFileName) / sizeof(RomInfo.szFullFileName[0])) - 1);
|
||||
if (FillRomInfo(&RomInfo))
|
||||
{
|
||||
int32_t ListPos = m_RomInfo.size();
|
||||
m_RomInfo.push_back(RomInfo);
|
||||
RomAddedToList(ListPos);
|
||||
}
|
||||
}
|
||||
|
||||
void CRomList::FillRomList(strlist & FileList, const CPath & BaseDirectory, const char * Directory, const char * lpLastRom)
|
||||
{
|
||||
CPath SearchPath(BaseDirectory, "*");
|
||||
SearchPath.AppendDirectory(Directory);
|
||||
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "1 %s", (const char *)SearchPath);
|
||||
if (!SearchPath.FindFirst(CPath::FIND_ATTRIBUTE_ALLFILES))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
uint8_t ext_ID;
|
||||
int8_t new_list_entry = 0;
|
||||
const uint8_t exts = sizeof(ROM_extensions) / sizeof(ROM_extensions[0]);
|
||||
|
||||
WriteTrace(TraceUserInterface, TraceDebug, ": 2 %s m_StopRefresh = %d", (const char *)SearchPath, m_StopRefresh);
|
||||
if (m_StopRefresh) { break; }
|
||||
|
||||
if (SearchPath.IsDirectory())
|
||||
{
|
||||
if (g_Settings->LoadBool(RomList_GameDirRecursive))
|
||||
{
|
||||
CPath CurrentDir(Directory);
|
||||
CurrentDir.AppendDirectory(SearchPath.GetLastDirectory().c_str());
|
||||
FillRomList(FileList, BaseDirectory, CurrentDir, lpLastRom);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
AddFileNameToList(FileList, Directory, SearchPath);
|
||||
|
||||
stdstr Extension = stdstr(SearchPath.GetExtension()).ToLower();
|
||||
|
||||
for (ext_ID = 0; ext_ID < exts; ext_ID++)
|
||||
{
|
||||
if (Extension == ROM_extensions[ext_ID] && Extension != "7z")
|
||||
{
|
||||
new_list_entry = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (new_list_entry)
|
||||
{
|
||||
AddRomToList(SearchPath);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Extension == "7z")
|
||||
{
|
||||
try
|
||||
{
|
||||
C7zip ZipFile(SearchPath);
|
||||
if (!ZipFile.OpenSuccess())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
char ZipFileName[260];
|
||||
stdstr_f SectionName("%s-%d", ZipFile.FileName(ZipFileName, sizeof(ZipFileName)), ZipFile.FileSize());
|
||||
SectionName.ToLower();
|
||||
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "4 %s", SectionName.c_str());
|
||||
for (int32_t i = 0; i < ZipFile.NumFiles(); i++)
|
||||
{
|
||||
CSzFileItem * f = ZipFile.FileItem(i);
|
||||
if (f->IsDir)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ROM_INFO RomInfo;
|
||||
|
||||
std::wstring FileNameW = ZipFile.FileNameIndex(i);
|
||||
if (FileNameW.length() == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
stdstr FileName;
|
||||
FileName.FromUTF16(FileNameW.c_str());
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "5");
|
||||
char drive2[_MAX_DRIVE], dir2[_MAX_DIR], FileName2[MAX_PATH], ext2[_MAX_EXT];
|
||||
_splitpath(FileName.c_str(), drive2, dir2, FileName2, ext2);
|
||||
|
||||
WriteTrace(TraceUserInterface, TraceDebug, ": 6 %s", ext2);
|
||||
if (_stricmp(ext2, ".bin") == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "7");
|
||||
memset(&RomInfo, 0, sizeof(ROM_INFO));
|
||||
stdstr_f zipFileName("%s?%s", (LPCSTR)SearchPath, FileName.c_str());
|
||||
ZipFile.SetNotificationCallback((C7zip::LP7ZNOTIFICATION)NotificationCB, this);
|
||||
|
||||
strncpy(RomInfo.szFullFileName, zipFileName.c_str(), sizeof(RomInfo.szFullFileName) - 1);
|
||||
RomInfo.szFullFileName[sizeof(RomInfo.szFullFileName) - 1] = 0;
|
||||
strcpy(RomInfo.FileName, strstr(RomInfo.szFullFileName, "?") + 1);
|
||||
RomInfo.FileFormat = Format_7zip;
|
||||
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "8");
|
||||
char szHeader[0x90];
|
||||
if (m_ZipIniFile->GetString(SectionName.c_str(), FileName.c_str(), "", szHeader, sizeof(szHeader)) == 0)
|
||||
{
|
||||
uint8_t RomData[0x1000];
|
||||
if (!ZipFile.GetFile(i, RomData, sizeof(RomData)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "9");
|
||||
if (!CN64Rom::IsValidRomImage(RomData)) { continue; }
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "10");
|
||||
ByteSwapRomData(RomData, sizeof(RomData));
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "11");
|
||||
|
||||
stdstr RomHeader;
|
||||
for (int32_t x = 0; x < 0x40; x += 4)
|
||||
{
|
||||
RomHeader += stdstr_f("%08X", *((uint32_t *)&RomData[x]));
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "11a %s", RomHeader.c_str());
|
||||
int32_t CicChip = GetCicChipID(RomData);
|
||||
|
||||
//save this info
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "12");
|
||||
m_ZipIniFile->SaveString(SectionName.c_str(), FileName.c_str(), RomHeader.c_str());
|
||||
m_ZipIniFile->SaveNumber(SectionName.c_str(), stdstr_f("%s-Cic", FileName.c_str()).c_str(), CicChip);
|
||||
strcpy(szHeader, RomHeader.c_str());
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "13");
|
||||
uint8_t RomData[0x40];
|
||||
|
||||
for (int32_t x = 0; x < 0x40; x += 4)
|
||||
{
|
||||
const size_t delimit_offset = sizeof("FFFFFFFF") - 1;
|
||||
const char backup_character = szHeader[2 * x + delimit_offset];
|
||||
|
||||
szHeader[2 * x + delimit_offset] = '\0';
|
||||
*(uint32_t *)&RomData[x] = strtoul(&szHeader[2 * x], NULL, 16);
|
||||
szHeader[2 * x + delimit_offset] = backup_character;
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "14");
|
||||
{
|
||||
char InternalName[22];
|
||||
memcpy(InternalName, (void *)(RomData + 0x20), 20);
|
||||
for (int32_t count = 0; count < 20; count += 4)
|
||||
{
|
||||
InternalName[count] ^= InternalName[count + 3];
|
||||
InternalName[count + 3] ^= InternalName[count];
|
||||
InternalName[count] ^= InternalName[count + 3];
|
||||
InternalName[count + 1] ^= InternalName[count + 2];
|
||||
InternalName[count + 2] ^= InternalName[count + 1];
|
||||
InternalName[count + 1] ^= InternalName[count + 2];
|
||||
}
|
||||
InternalName[20] = '\0';
|
||||
wcscpy(RomInfo.InternalName, stdstr(InternalName).ToUTF16(stdstr::CODEPAGE_932).c_str());
|
||||
}
|
||||
RomInfo.RomSize = (int32_t)f->Size;
|
||||
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "15");
|
||||
RomInfo.CartID[0] = *(RomData + 0x3F);
|
||||
RomInfo.CartID[1] = *(RomData + 0x3E);
|
||||
RomInfo.CartID[2] = '\0';
|
||||
RomInfo.Manufacturer = *(RomData + 0x38);
|
||||
RomInfo.Country = *(RomData + 0x3D);
|
||||
RomInfo.CRC1 = *(uint32_t *)(RomData + 0x10);
|
||||
RomInfo.CRC2 = *(uint32_t *)(RomData + 0x14);
|
||||
m_ZipIniFile->GetNumber(SectionName.c_str(), stdstr_f("%s-Cic", FileName.c_str()).c_str(), (ULONG)-1, (uint32_t &)RomInfo.CicChip);
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "16");
|
||||
FillRomExtensionInfo(&RomInfo);
|
||||
|
||||
if (RomInfo.SelColor == -1)
|
||||
{
|
||||
RomInfo.SelColorBrush = (uint32_t)((HBRUSH)(COLOR_HIGHLIGHT + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
RomInfo.SelColorBrush = (uint32_t)CreateSolidBrush(RomInfo.SelColor);
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "17");
|
||||
int32_t ListPos = m_RomInfo.size();
|
||||
m_RomInfo.push_back(RomInfo);
|
||||
RomAddedToList(ListPos);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
WriteTrace(TraceUserInterface, TraceError, "execpetion processing %s", (LPCSTR)SearchPath);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
} while (SearchPath.FindNext());
|
||||
m_ZipIniFile->FlushChanges();
|
||||
}
|
||||
|
||||
void CRomList::NotificationCB(const char * Status, CRomList * /*_this*/)
|
||||
{
|
||||
g_Notify->DisplayMessage(5, Status);
|
||||
}
|
||||
|
||||
void CRomList::RefreshRomBrowserStatic(CRomList * _this)
|
||||
{
|
||||
_this->RefreshRomListThread();
|
||||
}
|
||||
|
||||
bool CRomList::LoadDataFromRomFile(const char * FileName, uint8_t * Data, int32_t DataLen, int32_t * RomSize, FILE_FORMAT & FileFormat)
|
||||
{
|
||||
uint8_t Test[4];
|
||||
|
||||
if (_strnicmp(&FileName[strlen(FileName) - 4], ".ZIP", 4) == 0)
|
||||
{
|
||||
int32_t len, port = 0, FoundRom;
|
||||
unz_file_info info;
|
||||
char zname[132];
|
||||
unzFile file;
|
||||
file = unzOpen(FileName);
|
||||
if (file == NULL) { return false; }
|
||||
|
||||
port = unzGoToFirstFile(file);
|
||||
FoundRom = false;
|
||||
while (port == UNZ_OK && FoundRom == false)
|
||||
{
|
||||
unzGetCurrentFileInfo(file, &info, zname, 128, NULL, 0, NULL, 0);
|
||||
if (unzLocateFile(file, zname, 1) != UNZ_OK)
|
||||
{
|
||||
unzClose(file);
|
||||
return true;
|
||||
}
|
||||
if (unzOpenCurrentFile(file) != UNZ_OK)
|
||||
{
|
||||
unzClose(file);
|
||||
return true;
|
||||
}
|
||||
unzReadCurrentFile(file, Test, 4);
|
||||
if (CN64Rom::IsValidRomImage(Test))
|
||||
{
|
||||
FoundRom = true;
|
||||
memcpy(Data, Test, 4);
|
||||
len = unzReadCurrentFile(file, &Data[4], DataLen - 4) + 4;
|
||||
|
||||
if ((int32_t)DataLen != len)
|
||||
{
|
||||
unzCloseCurrentFile(file);
|
||||
unzClose(file);
|
||||
return false;
|
||||
}
|
||||
*RomSize = info.uncompressed_size;
|
||||
if (unzCloseCurrentFile(file) == UNZ_CRCERROR)
|
||||
{
|
||||
unzClose(file);
|
||||
return false;
|
||||
}
|
||||
unzClose(file);
|
||||
}
|
||||
if (FoundRom == false)
|
||||
{
|
||||
unzCloseCurrentFile(file);
|
||||
port = unzGoToNextFile(file);
|
||||
}
|
||||
}
|
||||
if (FoundRom == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
FileFormat = Format_Zip;
|
||||
}
|
||||
else
|
||||
{
|
||||
HANDLE hFile = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE) { return false; }
|
||||
SetFilePointer(hFile, 0, 0, FILE_BEGIN);
|
||||
|
||||
DWORD dwRead;
|
||||
ReadFile(hFile, Test, 4, &dwRead, NULL);
|
||||
if (!CN64Rom::IsValidRomImage(Test)) { CloseHandle(hFile); return false; }
|
||||
SetFilePointer(hFile, 0, 0, FILE_BEGIN);
|
||||
if (!ReadFile(hFile, Data, DataLen, &dwRead, NULL)) { CloseHandle(hFile); return false; }
|
||||
*RomSize = GetFileSize(hFile, NULL);
|
||||
CloseHandle(hFile);
|
||||
FileFormat = Format_Uncompressed;
|
||||
}
|
||||
ByteSwapRomData(Data, DataLen);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CRomList::FillRomInfo(ROM_INFO * pRomInfo)
|
||||
{
|
||||
int32_t count;
|
||||
uint8_t RomData[0x1000];
|
||||
|
||||
if (!LoadDataFromRomFile(pRomInfo->szFullFileName, RomData, sizeof(RomData), &pRomInfo->RomSize, pRomInfo->FileFormat))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strstr(pRomInfo->szFullFileName, "?") != NULL)
|
||||
{
|
||||
strcpy(pRomInfo->FileName, strstr(pRomInfo->szFullFileName, "?") + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(pRomInfo->FileName, CPath(pRomInfo->szFullFileName).GetNameExtension().c_str(), sizeof(pRomInfo->FileName) / sizeof(pRomInfo->FileName[0]));
|
||||
}
|
||||
char InternalName[22];
|
||||
memcpy(InternalName, (void *)(RomData + 0x20), 20);
|
||||
for (count = 0; count < 20; count += 4)
|
||||
{
|
||||
InternalName[count] ^= InternalName[count + 3];
|
||||
InternalName[count + 3] ^= InternalName[count];
|
||||
InternalName[count] ^= InternalName[count + 3];
|
||||
InternalName[count + 1] ^= InternalName[count + 2];
|
||||
InternalName[count + 2] ^= InternalName[count + 1];
|
||||
InternalName[count + 1] ^= InternalName[count + 2];
|
||||
}
|
||||
InternalName[20] = '\0';
|
||||
wcscpy(pRomInfo->InternalName, stdstr(InternalName).ToUTF16(stdstr::CODEPAGE_932).c_str());
|
||||
pRomInfo->CartID[0] = *(RomData + 0x3F);
|
||||
pRomInfo->CartID[1] = *(RomData + 0x3E);
|
||||
pRomInfo->CartID[2] = '\0';
|
||||
pRomInfo->Manufacturer = *(RomData + 0x38);
|
||||
pRomInfo->Country = *(RomData + 0x3D);
|
||||
pRomInfo->CRC1 = *(uint32_t *)(RomData + 0x10);
|
||||
pRomInfo->CRC2 = *(uint32_t *)(RomData + 0x14);
|
||||
pRomInfo->CicChip = GetCicChipID(RomData);
|
||||
|
||||
FillRomExtensionInfo(pRomInfo);
|
||||
|
||||
if (pRomInfo->SelColor == -1)
|
||||
{
|
||||
pRomInfo->SelColorBrush = (uint32_t)((HBRUSH)(COLOR_HIGHLIGHT + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
pRomInfo->SelColorBrush = (uint32_t)CreateSolidBrush(pRomInfo->SelColor);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void CRomList::FillRomExtensionInfo(ROM_INFO * pRomInfo)
|
||||
{
|
||||
//Initialize the structure
|
||||
pRomInfo->UserNotes[0] = 0;
|
||||
pRomInfo->Developer[0] = 0;
|
||||
pRomInfo->ReleaseDate[0] = 0;
|
||||
pRomInfo->Genre[0] = 0;
|
||||
pRomInfo->Players = 1;
|
||||
pRomInfo->CoreNotes[0] = 0;
|
||||
pRomInfo->PluginNotes[0] = 0;
|
||||
wcscpy(pRomInfo->GoodName, L"#340#");
|
||||
wcscpy(pRomInfo->Status, L"Unknown");
|
||||
|
||||
//Get File Identifier
|
||||
char Identifier[100];
|
||||
sprintf(Identifier, "%08X-%08X-C:%X", pRomInfo->CRC1, pRomInfo->CRC2, pRomInfo->Country);
|
||||
|
||||
//Rom Notes
|
||||
wcsncpy(pRomInfo->UserNotes, m_NotesIniFile->GetString(Identifier, "Note", "").ToUTF16().c_str(), sizeof(pRomInfo->UserNotes) / sizeof(wchar_t));
|
||||
|
||||
//Rom Extension info
|
||||
wcsncpy(pRomInfo->Developer, m_ExtIniFile->GetString(Identifier, "Developer", "").ToUTF16().c_str(), sizeof(pRomInfo->Developer) / sizeof(wchar_t));
|
||||
wcsncpy(pRomInfo->ReleaseDate, m_ExtIniFile->GetString(Identifier, "ReleaseDate", "").ToUTF16().c_str(), sizeof(pRomInfo->ReleaseDate) / sizeof(wchar_t));
|
||||
wcsncpy(pRomInfo->Genre, m_ExtIniFile->GetString(Identifier, "Genre", "").ToUTF16().c_str(), sizeof(pRomInfo->Genre) / sizeof(wchar_t));
|
||||
m_ExtIniFile->GetNumber(Identifier, "Players", 1, (uint32_t &)pRomInfo->Players);
|
||||
wcsncpy(pRomInfo->ForceFeedback, m_ExtIniFile->GetString(Identifier, "ForceFeedback", "unknown").ToUTF16().c_str(), sizeof(pRomInfo->ForceFeedback) / sizeof(wchar_t));
|
||||
|
||||
//Rom Settings
|
||||
wcsncpy(pRomInfo->GoodName, m_RomIniFile->GetString(Identifier, "Good Name", stdstr().FromUTF16(pRomInfo->GoodName).c_str()).ToUTF16().c_str(), sizeof(pRomInfo->GoodName) / sizeof(wchar_t));
|
||||
wcsncpy(pRomInfo->Status, m_RomIniFile->GetString(Identifier, "Status", stdstr().FromUTF16(pRomInfo->Status).c_str()).ToUTF16().c_str(), sizeof(pRomInfo->Status) / sizeof(wchar_t));
|
||||
wcsncpy(pRomInfo->CoreNotes, m_RomIniFile->GetString(Identifier, "Core Note", "").ToUTF16().c_str(), sizeof(pRomInfo->CoreNotes) / sizeof(wchar_t));
|
||||
wcsncpy(pRomInfo->PluginNotes, m_RomIniFile->GetString(Identifier, "Plugin Note", "").ToUTF16().c_str(), sizeof(pRomInfo->PluginNotes) / sizeof(wchar_t));
|
||||
|
||||
//Get the text color
|
||||
stdstr String = m_RomIniFile->GetString("Rom Status", stdstr().FromUTF16(pRomInfo->Status).c_str(), "000000");
|
||||
pRomInfo->TextColor = (std::strtoul(String.c_str(), 0, 16) & 0xFFFFFF);
|
||||
pRomInfo->TextColor = (pRomInfo->TextColor & 0x00FF00) | ((pRomInfo->TextColor >> 0x10) & 0xFF) | ((pRomInfo->TextColor & 0xFF) << 0x10);
|
||||
|
||||
//Get the selected color
|
||||
String.Format("%ws.Sel", pRomInfo->Status);
|
||||
String = m_RomIniFile->GetString("Rom Status", String.c_str(), "FFFFFFFF");
|
||||
uint32_t selcol = std::strtoul(String.c_str(), NULL, 16);
|
||||
if (selcol & 0x80000000)
|
||||
{
|
||||
pRomInfo->SelColor = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
selcol = (selcol & 0x00FF00) | ((selcol >> 0x10) & 0xFF) | ((selcol & 0xFF) << 0x10);
|
||||
pRomInfo->SelColor = selcol;
|
||||
}
|
||||
|
||||
//Get the selected text color
|
||||
String.Format("%ws.Seltext", pRomInfo->Status);
|
||||
String = m_RomIniFile->GetString("Rom Status", String.c_str(), "FFFFFF");
|
||||
pRomInfo->SelTextColor = (std::strtoul(String.c_str(), 0, 16) & 0xFFFFFF);
|
||||
pRomInfo->SelTextColor = (pRomInfo->SelTextColor & 0x00FF00) | ((pRomInfo->SelTextColor >> 0x10) & 0xFF) | ((pRomInfo->SelTextColor & 0xFF) << 0x10);
|
||||
}
|
||||
|
||||
void CRomList::ByteSwapRomData(uint8_t * Data, int32_t DataLen)
|
||||
{
|
||||
int32_t count;
|
||||
|
||||
switch (*((uint32_t *)&Data[0]))
|
||||
{
|
||||
case 0x12408037:
|
||||
for (count = 0; count < DataLen; count += 4)
|
||||
{
|
||||
Data[count] ^= Data[count + 2];
|
||||
Data[count + 2] ^= Data[count];
|
||||
Data[count] ^= Data[count + 2];
|
||||
Data[count + 1] ^= Data[count + 3];
|
||||
Data[count + 3] ^= Data[count + 1];
|
||||
Data[count + 1] ^= Data[count + 3];
|
||||
}
|
||||
break;
|
||||
case 0x40072780: //64DD IPL
|
||||
case 0x40123780:
|
||||
for (count = 0; count < DataLen; count += 4)
|
||||
{
|
||||
Data[count] ^= Data[count + 3];
|
||||
Data[count + 3] ^= Data[count];
|
||||
Data[count] ^= Data[count + 3];
|
||||
Data[count + 1] ^= Data[count + 2];
|
||||
Data[count + 2] ^= Data[count + 1];
|
||||
Data[count + 1] ^= Data[count + 2];
|
||||
}
|
||||
break;
|
||||
case 0x80371240: break;
|
||||
}
|
||||
}
|
||||
|
||||
void CRomList::LoadRomList(void)
|
||||
{
|
||||
CPath FileName(g_Settings->LoadStringVal(RomList_RomListCache));
|
||||
CFile file(FileName, CFileBase::modeRead | CFileBase::modeNoTruncate);
|
||||
|
||||
if (!file.IsOpen())
|
||||
{
|
||||
//if file does not exist then refresh the data
|
||||
RefreshRomBrowser();
|
||||
return;
|
||||
}
|
||||
unsigned char md5[16];
|
||||
if (!file.Read(md5, sizeof(md5)))
|
||||
{
|
||||
file.Close();
|
||||
RefreshRomBrowser();
|
||||
return;
|
||||
}
|
||||
|
||||
//Read the size of ROM_INFO
|
||||
int32_t RomInfoSize = 0;
|
||||
if (!file.Read(&RomInfoSize, sizeof(RomInfoSize)) || RomInfoSize != sizeof(ROM_INFO))
|
||||
{
|
||||
file.Close();
|
||||
RefreshRomBrowser();
|
||||
return;
|
||||
}
|
||||
|
||||
//Read the Number of entries
|
||||
int32_t Entries = 0;
|
||||
file.Read(&Entries, sizeof(Entries));
|
||||
|
||||
//Read Every Entry
|
||||
m_RomInfo.clear();
|
||||
RomListReset();
|
||||
for (int32_t count = 0; count < Entries; count++)
|
||||
{
|
||||
ROM_INFO RomInfo;
|
||||
file.Read(&RomInfo, RomInfoSize);
|
||||
int32_t ListPos = m_RomInfo.size();
|
||||
m_RomInfo.push_back(RomInfo);
|
||||
RomAddedToList(ListPos);
|
||||
}
|
||||
RomListLoaded();
|
||||
}
|
||||
|
||||
/*
|
||||
* SaveRomList - save all the rom information about the current roms in the rom brower
|
||||
* to a cache file, so it is quick to reload the information
|
||||
*/
|
||||
void CRomList::SaveRomList(strlist & FileList)
|
||||
{
|
||||
MD5 ListHash = RomListHash(FileList);
|
||||
|
||||
CPath FileName(g_Settings->LoadStringVal(RomList_RomListCache));
|
||||
CFile file(FileName, CFileBase::modeWrite | CFileBase::modeCreate);
|
||||
file.Write(ListHash.raw_digest(), 16);
|
||||
|
||||
//Write the size of ROM_INFO
|
||||
int32_t RomInfoSize = sizeof(ROM_INFO);
|
||||
file.Write(&RomInfoSize, sizeof(RomInfoSize));
|
||||
|
||||
//Write the Number of entries
|
||||
int32_t Entries = m_RomInfo.size();
|
||||
file.Write(&Entries, sizeof(Entries));
|
||||
|
||||
//Write Every Entry
|
||||
for (int32_t count = 0; count < Entries; count++)
|
||||
{
|
||||
file.Write(&m_RomInfo[count], RomInfoSize);
|
||||
}
|
||||
|
||||
//Close the file handle
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CRomList::WatchRomDirChanged(CRomList * _this)
|
||||
{
|
||||
try
|
||||
{
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "1");
|
||||
_this->m_WatchRomDir = g_Settings->LoadStringVal(RomList_GameDir);
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "2");
|
||||
if (_this->RomDirNeedsRefresh())
|
||||
{
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "2a");
|
||||
_this->RomDirChanged();
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "3");
|
||||
HANDLE hChange[] =
|
||||
{
|
||||
_this->m_WatchStopEvent,
|
||||
FindFirstChangeNotification(_this->m_WatchRomDir.c_str(), g_Settings->LoadBool(RomList_GameDirRecursive), FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_SIZE),
|
||||
};
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "4");
|
||||
for (;;)
|
||||
{
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "5");
|
||||
if (WaitForMultipleObjects(sizeof(hChange) / sizeof(hChange[0]), hChange, false, INFINITE) == WAIT_OBJECT_0)
|
||||
{
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "5a");
|
||||
FindCloseChangeNotification(hChange[1]);
|
||||
return;
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "5b");
|
||||
if (_this->RomDirNeedsRefresh())
|
||||
{
|
||||
_this->RomDirChanged();
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "5c");
|
||||
if (!FindNextChangeNotification(hChange[1]))
|
||||
{
|
||||
FindCloseChangeNotification(hChange[1]);
|
||||
return;
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "5d");
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
WriteTrace(TraceUserInterface, TraceError, __FUNCTION__ ": Unhandled Exception");
|
||||
}
|
||||
}
|
||||
|
||||
bool CRomList::RomDirNeedsRefresh(void)
|
||||
{
|
||||
bool InWatchThread = (m_WatchThreadID == GetCurrentThreadId());
|
||||
|
||||
//Get Old MD5 of file names
|
||||
stdstr FileName = g_Settings->LoadStringVal(RomList_RomListCache);
|
||||
HANDLE hFile = CreateFile(FileName.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
//if file does not exist then refresh the data
|
||||
return true;
|
||||
}
|
||||
|
||||
DWORD dwRead;
|
||||
unsigned char CurrentFileMD5[16];
|
||||
ReadFile(hFile, &CurrentFileMD5, sizeof(CurrentFileMD5), &dwRead, NULL);
|
||||
CloseHandle(hFile);
|
||||
|
||||
//Get Current MD5 of file names
|
||||
strlist FileNames;
|
||||
if (!GetRomFileNames(FileNames, CPath(g_Settings->LoadStringVal(RomList_GameDir)), stdstr(""), InWatchThread))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
FileNames.sort();
|
||||
|
||||
MD5 NewMd5 = RomListHash(FileNames);
|
||||
if (memcmp(NewMd5.raw_digest(), CurrentFileMD5, sizeof(CurrentFileMD5)) != 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CRomList::WatchThreadStart(void)
|
||||
{
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "1");
|
||||
WatchThreadStop();
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "2");
|
||||
if (m_WatchStopEvent == NULL)
|
||||
{
|
||||
m_WatchStopEvent = CreateEvent(NULL, true, false, NULL);
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "3");
|
||||
m_WatchThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WatchRomDirChanged, this, 0, &m_WatchThreadID);
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "4");
|
||||
}
|
||||
|
||||
void CRomList::WatchThreadStop(void)
|
||||
{
|
||||
if (m_WatchThread == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "1");
|
||||
SetEvent(m_WatchStopEvent);
|
||||
DWORD ExitCode = 0;
|
||||
for (int32_t count = 0; count < 20; count++)
|
||||
{
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "2");
|
||||
GetExitCodeThread(m_WatchThread, &ExitCode);
|
||||
if (ExitCode != STILL_ACTIVE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
Sleep(200);
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "3");
|
||||
if (ExitCode == STILL_ACTIVE)
|
||||
{
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "3a");
|
||||
TerminateThread(m_WatchThread, 0);
|
||||
}
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "4");
|
||||
|
||||
CloseHandle(m_WatchThread);
|
||||
CloseHandle(m_WatchStopEvent);
|
||||
m_WatchStopEvent = NULL;
|
||||
m_WatchThread = NULL;
|
||||
m_WatchThreadID = 0;
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "5");
|
||||
}
|
||||
|
||||
MD5 CRomList::RomListHash(strlist & FileList)
|
||||
{
|
||||
stdstr NewFileNames;
|
||||
FileList.sort();
|
||||
for (strlist::iterator iter = FileList.begin(); iter != FileList.end(); iter++)
|
||||
{
|
||||
NewFileNames += *iter;
|
||||
NewFileNames += ";";
|
||||
}
|
||||
MD5 md5Hash((const unsigned char *)NewFileNames.c_str(), NewFileNames.length());
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "%s - %s", md5Hash.hex_digest(), NewFileNames.c_str());
|
||||
return md5Hash;
|
||||
}
|
||||
|
||||
void CRomList::AddFileNameToList(strlist & FileList, const stdstr & Directory, CPath & File)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
if (FileList.size() > 3000)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
stdstr Drive, Dir, Name, Extension;
|
||||
File.GetComponents(NULL, &Dir, &Name, &Extension);
|
||||
Extension.ToLower();
|
||||
for (i = 0; i < sizeof(ROM_extensions) / sizeof(ROM_extensions[0]); i++)
|
||||
{
|
||||
if (Extension == ROM_extensions[i])
|
||||
{
|
||||
stdstr FileName = Directory + Name + Extension;
|
||||
FileName.ToLower();
|
||||
FileList.push_back(FileName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CRomList::GetRomFileNames(strlist & FileList, const CPath & BaseDirectory, const std::string & Directory, bool InWatchThread)
|
||||
{
|
||||
if (!BaseDirectory.DirectoryExists())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
CPath SearchPath(BaseDirectory, "*.*");
|
||||
SearchPath.AppendDirectory(Directory.c_str());
|
||||
|
||||
if (!SearchPath.FindFirst(CPath::FIND_ATTRIBUTE_ALLFILES))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (InWatchThread && WaitForSingleObject(m_WatchStopEvent, 0) != WAIT_TIMEOUT)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SearchPath.IsDirectory())
|
||||
{
|
||||
if (g_Settings->LoadBool(RomList_GameDirRecursive))
|
||||
{
|
||||
CPath CurrentDir(Directory);
|
||||
CurrentDir.AppendDirectory(SearchPath.GetLastDirectory().c_str());
|
||||
GetRomFileNames(FileList, BaseDirectory, CurrentDir, InWatchThread);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddFileNameToList(FileList, Directory, SearchPath);
|
||||
}
|
||||
} while (SearchPath.FindNext());
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t CRomList::GetCicChipID(uint8_t * RomData)
|
||||
{
|
||||
__int64 CRC = 0;
|
||||
int32_t count;
|
||||
|
||||
for (count = 0x40; count < 0x1000; count += 4)
|
||||
{
|
||||
CRC += *(uint32_t *)(RomData + count);
|
||||
}
|
||||
switch (CRC)
|
||||
{
|
||||
case 0x000000D0027FDF31: return CIC_NUS_6101;
|
||||
case 0x000000CFFB631223: return CIC_NUS_6101;
|
||||
case 0x000000D057C85244: return CIC_NUS_6102;
|
||||
case 0x000000D6497E414B: return CIC_NUS_6103;
|
||||
case 0x0000011A49F60E96: return CIC_NUS_6105;
|
||||
case 0x000000D6D5BE5580: return CIC_NUS_6106;
|
||||
case 0x000001053BC19870: return CIC_NUS_5167; //64DD CONVERSION CIC
|
||||
case 0x000000D2E53EF008: return CIC_NUS_8303; //64DD IPL
|
||||
default:
|
||||
return CIC_UNKNOWN;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
class CRomList
|
||||
{
|
||||
public:
|
||||
enum FILE_FORMAT
|
||||
{
|
||||
Format_Uncompressed,
|
||||
Format_Zip,
|
||||
Format_7zip,
|
||||
};
|
||||
|
||||
struct ROM_INFO
|
||||
{
|
||||
char szFullFileName[300];
|
||||
FILE_FORMAT FileFormat;
|
||||
wchar_t Status[60];
|
||||
char FileName[200];
|
||||
wchar_t InternalName[22];
|
||||
wchar_t GoodName[200];
|
||||
wchar_t CartID[3];
|
||||
wchar_t PluginNotes[250];
|
||||
wchar_t CoreNotes[250];
|
||||
wchar_t UserNotes[250];
|
||||
wchar_t Developer[30];
|
||||
wchar_t ReleaseDate[30];
|
||||
wchar_t Genre[15];
|
||||
int32_t Players;
|
||||
uint32_t TextColor;
|
||||
int32_t SelColor;
|
||||
uint32_t SelTextColor;
|
||||
uint32_t SelColorBrush;
|
||||
int32_t RomSize;
|
||||
uint8_t Manufacturer;
|
||||
uint8_t Country;
|
||||
uint32_t CRC1;
|
||||
uint32_t CRC2;
|
||||
int32_t CicChip;
|
||||
wchar_t ForceFeedback[15];
|
||||
};
|
||||
|
||||
CRomList();
|
||||
virtual ~CRomList();
|
||||
|
||||
void RefreshRomBrowser(void);
|
||||
void LoadRomList(void);
|
||||
|
||||
protected:
|
||||
typedef std::vector<ROM_INFO> ROMINFO_LIST;
|
||||
virtual void RomListReset(void) {}
|
||||
virtual void RomAddedToList(int32_t /*ListPos*/) {}
|
||||
virtual void RomListLoaded(void) {}
|
||||
virtual void RomDirChanged(void) {}
|
||||
|
||||
void WatchThreadStart(void);
|
||||
void WatchThreadStop(void);
|
||||
|
||||
ROMINFO_LIST m_RomInfo;
|
||||
bool m_StopRefresh;
|
||||
|
||||
private:
|
||||
void AddRomToList(const char * RomLocation);
|
||||
void FillRomList(strlist & FileList, const CPath & BaseDirectory, const char * Directory, const char * lpLastRom);
|
||||
bool FillRomInfo(ROM_INFO * pRomInfo);
|
||||
void FillRomExtensionInfo(ROM_INFO * pRomInfo);
|
||||
bool LoadDataFromRomFile(const char * FileName, uint8_t * Data, int32_t DataLen, int32_t * RomSize, FILE_FORMAT & FileFormat);
|
||||
void AddFileNameToList(strlist & FileList, const stdstr & Directory, CPath & File);
|
||||
void SaveRomList(strlist & FileList);
|
||||
void RefreshRomListThread(void);
|
||||
bool GetRomFileNames(strlist & FileList, const CPath & BaseDirectory, const std::string & Directory, bool InWatchThread);
|
||||
MD5 RomListHash(strlist & FileList);
|
||||
|
||||
//Watch Directory Changed function
|
||||
HANDLE m_WatchThread, m_WatchStopEvent;
|
||||
DWORD m_WatchThreadID;
|
||||
bool RomDirNeedsRefresh(void); // Called from watch thread
|
||||
|
||||
static void NotificationCB(const char * Status, CRomList * _this);
|
||||
static void WatchRomDirChanged(CRomList * _this);
|
||||
static void RefreshRomBrowserStatic(CRomList * _this);
|
||||
static void ByteSwapRomData(uint8_t * Data, int DataLen);
|
||||
static int32_t GetCicChipID(uint8_t * RomData);
|
||||
|
||||
CIniFile * m_NotesIniFile;
|
||||
CIniFile * m_ExtIniFile;
|
||||
CIniFile * m_RomIniFile;
|
||||
CIniFile * m_ZipIniFile;
|
||||
HANDLE m_RefreshThread;
|
||||
stdstr m_WatchRomDir;
|
||||
|
||||
};
|
Loading…
Reference in New Issue