void CGameListCtrl::ScanForISOs() { ClearIsoFiles(); CFileSearch::XStringVector Directories(SConfig::GetInstance().m_ISOFolder); if (SConfig::GetInstance().m_RecursiveISOFolder) { for (u32 i = 0; i < Directories.size(); i++) { File::FSTEntry FST_Temp; File::ScanDirectoryTree(Directories[i], FST_Temp); for (u32 j = 0; j < FST_Temp.children.size(); j++) { if (FST_Temp.children[j].isDirectory) { bool duplicate = false; for (u32 k = 0; k < Directories.size(); k++) { if (strcmp(Directories[k].c_str(), FST_Temp.children[j].physicalName.c_str()) == 0) { duplicate = true; break; } } if (!duplicate) Directories.push_back( FST_Temp.children[j].physicalName.c_str()); } } } } CFileSearch::XStringVector Extensions; if (SConfig::GetInstance().m_ListGC) Extensions.push_back("*.gcm"); if (SConfig::GetInstance().m_ListWii || SConfig::GetInstance().m_ListGC) { Extensions.push_back("*.iso"); Extensions.push_back("*.ciso"); Extensions.push_back("*.gcz"); Extensions.push_back("*.wbfs"); } if (SConfig::GetInstance().m_ListWad) Extensions.push_back("*.wad"); CFileSearch FileSearch(Extensions, Directories); const CFileSearch::XStringVector& rFilenames = FileSearch.GetFileNames(); if (rFilenames.size() > 0) { wxProgressDialog dialog( _("Scanning for ISOs"), _("Scanning..."), (int)rFilenames.size() - 1, this, wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_CAN_ABORT | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME | wxPD_SMOOTH // - makes updates as small as possible (down to 1px) ); for (u32 i = 0; i < rFilenames.size(); i++) { std::string FileName; SplitPath(rFilenames[i], NULL, &FileName, NULL); // Update with the progress (i) and the message dialog.Update(i, wxString::Format(_("Scanning %s"), wxString(FileName.c_str(), *wxConvCurrent).c_str())); if (dialog.WasCancelled()) break; std::auto_ptr<GameListItem> iso_file(new GameListItem(rFilenames[i])); const GameListItem& ISOFile = *iso_file; if (ISOFile.IsValid()) { bool list = true; switch(ISOFile.GetPlatform()) { case GameListItem::WII_DISC: if (!SConfig::GetInstance().m_ListWii) list = false; break; case GameListItem::WII_WAD: if (!SConfig::GetInstance().m_ListWad) list = false; break; default: if (!SConfig::GetInstance().m_ListGC) list = false; break; } switch(ISOFile.GetCountry()) { case DiscIO::IVolume::COUNTRY_TAIWAN: if (!SConfig::GetInstance().m_ListTaiwan) list = false; case DiscIO::IVolume::COUNTRY_KOREA: if (!SConfig::GetInstance().m_ListKorea) list = false; break; case DiscIO::IVolume::COUNTRY_JAPAN: if (!SConfig::GetInstance().m_ListJap) list = false; break; case DiscIO::IVolume::COUNTRY_USA: if (!SConfig::GetInstance().m_ListUsa) list = false; break; case DiscIO::IVolume::COUNTRY_FRANCE: if (!SConfig::GetInstance().m_ListFrance) list = false; break; case DiscIO::IVolume::COUNTRY_ITALY: if (!SConfig::GetInstance().m_ListItaly) list = false; break; default: if (!SConfig::GetInstance().m_ListPal) list = false; break; } if (list) m_ISOFiles.push_back(iso_file.release()); } } } if (SConfig::GetInstance().m_ListDrives) { const std::vector<std::string> drives = cdio_get_devices(); for (std::vector<std::string>::const_iterator iter = drives.begin(); iter != drives.end(); ++iter) { #ifdef __APPLE__ std::auto_ptr<GameListItem> gli(new GameListItem(*iter)); #else std::unique_ptr<GameListItem> gli(new GameListItem(*iter)); #endif if (gli->IsValid()) m_ISOFiles.push_back(gli.release()); } } std::sort(m_ISOFiles.begin(), m_ISOFiles.end()); }
void DGameTracker::ScanForGames() { setDisabled(true); CFileSearch::XStringVector dirs(SConfig::GetInstance().m_ISOFolder); if (SConfig::GetInstance().m_RecursiveISOFolder) { for (u32 i = 0; i < dirs.size(); i++) { File::FSTEntry FST_Temp; File::ScanDirectoryTree(dirs[i], FST_Temp); for (auto& entry : FST_Temp.children) { if (entry.isDirectory) { bool duplicate = false; for (auto& dir : dirs) { if (dir == entry.physicalName) { duplicate = true; break; } } if (!duplicate) dirs.push_back(entry.physicalName); } } } } for (std::string& dir : dirs) m_watcher.addPath(QString::fromStdString(dir)); CFileSearch::XStringVector exts; if (SConfig::GetInstance().m_ListGC) { exts.push_back("*.gcm"); exts.push_back("*.gcz"); } if (SConfig::GetInstance().m_ListWii || SConfig::GetInstance().m_ListGC) { exts.push_back("*.iso"); exts.push_back("*.ciso"); exts.push_back("*.wbfs"); } if (SConfig::GetInstance().m_ListWad) exts.push_back("*.wad"); CFileSearch FileSearch(exts, dirs); const CFileSearch::XStringVector& rFilenames = FileSearch.GetFileNames(); QList<GameFile*> newItems; QStringList allItems; if (!rFilenames.empty()) { for (u32 i = 0; i < rFilenames.size(); i++) { std::string FileName; SplitPath(rFilenames[i], nullptr, &FileName, nullptr); QString NameAndPath = QString::fromStdString(rFilenames[i]); allItems.append(NameAndPath); if (m_games.keys().contains(NameAndPath)) continue; GameFile* obj = new GameFile(rFilenames[i]); if (obj->IsValid()) { bool list = true; switch(obj->GetCountry()) { case DiscIO::IVolume::COUNTRY_AUSTRALIA: if (!SConfig::GetInstance().m_ListAustralia) list = false; break; case DiscIO::IVolume::COUNTRY_EUROPE: if (!SConfig::GetInstance().m_ListPal) list = false; break; case DiscIO::IVolume::COUNTRY_FRANCE: if (!SConfig::GetInstance().m_ListFrance) list = false; break; case DiscIO::IVolume::COUNTRY_GERMANY: if (!SConfig::GetInstance().m_ListGermany) list = false; break; case DiscIO::IVolume::COUNTRY_INTERNATIONAL: if (!SConfig::GetInstance().m_ListInternational) list = false; break; case DiscIO::IVolume::COUNTRY_ITALY: if (!SConfig::GetInstance().m_ListItaly) list = false; break; case DiscIO::IVolume::COUNTRY_JAPAN: if (!SConfig::GetInstance().m_ListJap) list = false; break; case DiscIO::IVolume::COUNTRY_KOREA: if (!SConfig::GetInstance().m_ListKorea) list = false; break; case DiscIO::IVolume::COUNTRY_NETHERLANDS: if (!SConfig::GetInstance().m_ListNetherlands) list = false; break; case DiscIO::IVolume::COUNTRY_RUSSIA: if (!SConfig::GetInstance().m_ListRussia) list = false; break; case DiscIO::IVolume::COUNTRY_SPAIN: if (!SConfig::GetInstance().m_ListSpain) list = false; break; case DiscIO::IVolume::COUNTRY_TAIWAN: if (!SConfig::GetInstance().m_ListTaiwan) list = false; break; case DiscIO::IVolume::COUNTRY_USA: if (!SConfig::GetInstance().m_ListUsa) list = false; break; case DiscIO::IVolume::COUNTRY_UNKNOWN: default: if (!SConfig::GetInstance().m_ListUnknown) list = false; break; } if (list) newItems.append(obj); } } } // Process all the new GameFiles for (GameFile* o : newItems) m_games.insert(o->GetFileName(), o); // Check for games that were removed QList<GameFile*> removedGames; for (QString& path : m_games.keys()) { if (!allItems.contains(path)) { removedGames.append(m_games.value(path)); m_games.remove(path); } } m_tree_widget->AddGames(newItems); m_grid_widget->AddGames(newItems); m_tree_widget->RemoveGames(removedGames); m_grid_widget->RemoveGames(removedGames); for (GameFile* file : removedGames) delete file; setDisabled(false); }
void CGameListCtrl::ScanForISOs() { ClearIsoFiles(); CFileSearch::XStringVector Directories(SConfig::GetInstance().m_ISOFolder); if (SConfig::GetInstance().m_RecursiveISOFolder) { for (u32 i = 0; i < Directories.size(); i++) { File::FSTEntry FST_Temp; File::ScanDirectoryTree(Directories[i], FST_Temp); for (auto& Entry : FST_Temp.children) { if (Entry.isDirectory) { bool duplicate = false; for (auto& Directory : Directories) { if (Directory == Entry.physicalName) { duplicate = true; break; } } if (!duplicate) Directories.push_back(Entry.physicalName); } } } } CFileSearch::XStringVector Extensions; if (SConfig::GetInstance().m_ListGC) Extensions.push_back("*.gcm"); if (SConfig::GetInstance().m_ListWii || SConfig::GetInstance().m_ListGC) { Extensions.push_back("*.iso"); Extensions.push_back("*.ciso"); Extensions.push_back("*.gcz"); Extensions.push_back("*.wbfs"); } if (SConfig::GetInstance().m_ListWad) Extensions.push_back("*.wad"); CFileSearch FileSearch(Extensions, Directories); const CFileSearch::XStringVector& rFilenames = FileSearch.GetFileNames(); if (rFilenames.size() > 0) { wxProgressDialog dialog( _("Scanning for ISOs"), _("Scanning..."), (int)rFilenames.size() - 1, this, wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_CAN_ABORT | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME | wxPD_SMOOTH // - makes updates as small as possible (down to 1px) ); for (u32 i = 0; i < rFilenames.size(); i++) { std::string FileName; SplitPath(rFilenames[i], nullptr, &FileName, nullptr); // Update with the progress (i) and the message dialog.Update(i, wxString::Format(_("Scanning %s"), StrToWxStr(FileName))); if (dialog.WasCancelled()) break; auto iso_file = std::make_unique<GameListItem>(rFilenames[i]); if (iso_file->IsValid()) { bool list = true; switch(iso_file->GetPlatform()) { case GameListItem::WII_DISC: if (!SConfig::GetInstance().m_ListWii) list = false; break; case GameListItem::WII_WAD: if (!SConfig::GetInstance().m_ListWad) list = false; break; default: if (!SConfig::GetInstance().m_ListGC) list = false; break; } switch(iso_file->GetCountry()) { case DiscIO::IVolume::COUNTRY_AUSTRALIA: if (!SConfig::GetInstance().m_ListAustralia) list = false; break; case DiscIO::IVolume::COUNTRY_GERMANY: if (!SConfig::GetInstance().m_ListGermany) list = false; break; case DiscIO::IVolume::COUNTRY_RUSSIA: if (!SConfig::GetInstance().m_ListRussia) list = false; break; case DiscIO::IVolume::COUNTRY_UNKNOWN: if (!SConfig::GetInstance().m_ListUnknown) list = false; break; case DiscIO::IVolume::COUNTRY_TAIWAN: if (!SConfig::GetInstance().m_ListTaiwan) list = false; break; case DiscIO::IVolume::COUNTRY_KOREA: if (!SConfig::GetInstance().m_ListKorea) list = false; break; case DiscIO::IVolume::COUNTRY_JAPAN: if (!SConfig::GetInstance().m_ListJap) list = false; break; case DiscIO::IVolume::COUNTRY_USA: if (!SConfig::GetInstance().m_ListUsa) list = false; break; case DiscIO::IVolume::COUNTRY_FRANCE: if (!SConfig::GetInstance().m_ListFrance) list = false; break; case DiscIO::IVolume::COUNTRY_ITALY: if (!SConfig::GetInstance().m_ListItaly) list = false; break; case DiscIO::IVolume::COUNTRY_SPAIN: if (!SConfig::GetInstance().m_ListSpain) list = false; break; case DiscIO::IVolume::COUNTRY_NETHERLANDS: if (!SConfig::GetInstance().m_ListNetherlands) list = false; break; default: if (!SConfig::GetInstance().m_ListPal) list = false; break; } if (list) m_ISOFiles.push_back(iso_file.release()); } } } if (SConfig::GetInstance().m_ListDrives) { const std::vector<std::string> drives = cdio_get_devices(); for (const auto& drive : drives) { auto gli = std::make_unique<GameListItem>(drive); if (gli->IsValid()) m_ISOFiles.push_back(gli.release()); } } std::sort(m_ISOFiles.begin(), m_ISOFiles.end()); }
bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) { u32 ReturnValue = FS_RESULT_OK; SIOCtlVBuffer CommandBuffer(_CommandAddress); // Prepare the out buffer(s) with zeros as a safety precaution // to avoid returning bad values for(u32 i = 0; i < CommandBuffer.NumberPayloadBuffer; i++) { Memory::Memset(CommandBuffer.PayloadBuffer[i].m_Address, 0, CommandBuffer.PayloadBuffer[i].m_Size); } switch(CommandBuffer.Parameter) { case IOCTLV_READ_DIR: { // the wii uses this function to define the type (dir or file) std::string DirName(HLE_IPC_BuildFilename((const char*)Memory::GetPointer( CommandBuffer.InBuffer[0].m_Address), CommandBuffer.InBuffer[0].m_Size)); INFO_LOG(WII_IPC_FILEIO, "FS: IOCTL_READ_DIR %s", DirName.c_str()); if (!File::Exists(DirName)) { WARN_LOG(WII_IPC_FILEIO, "FS: Search not found: %s", DirName.c_str()); ReturnValue = FS_FILE_NOT_EXIST; break; } else if (!File::IsDirectory(DirName)) { // It's not a directory, so error. // Games don't usually seem to care WHICH error they get, as long as it's < // Well the system menu CARES! WARN_LOG(WII_IPC_FILEIO, "\tNot a directory - return FS_RESULT_FATAL"); ReturnValue = FS_RESULT_FATAL; break; } // make a file search CFileSearch::XStringVector Directories; Directories.push_back(DirName); CFileSearch::XStringVector Extensions; Extensions.push_back("*.*"); CFileSearch FileSearch(Extensions, Directories); // it is one if ((CommandBuffer.InBuffer.size() == 1) && (CommandBuffer.PayloadBuffer.size() == 1)) { size_t numFile = FileSearch.GetFileNames().size(); INFO_LOG(WII_IPC_FILEIO, "\t%lu files found", (unsigned long)numFile); Memory::Write_U32((u32)numFile, CommandBuffer.PayloadBuffer[0].m_Address); } else { u32 MaxEntries = Memory::Read_U32(CommandBuffer.InBuffer[0].m_Address); memset(Memory::GetPointer(CommandBuffer.PayloadBuffer[0].m_Address), 0, CommandBuffer.PayloadBuffer[0].m_Size); size_t numFiles = 0; char* pFilename = (char*)Memory::GetPointer((u32)(CommandBuffer.PayloadBuffer[0].m_Address)); for (size_t i=0; i<FileSearch.GetFileNames().size(); i++) { if (i >= MaxEntries) break; std::string name, ext; SplitPath(FileSearch.GetFileNames()[i], NULL, &name, &ext); std::string FileName = name + ext; // Decode entities of invalid file system characters so that // games (such as HP:HBP) will be able to find what they expect. for (const Common::replace_t& r : replacements) { for (size_t j = 0; (j = FileName.find(r.second, j)) != FileName.npos; ++j) FileName.replace(j, r.second.length(), 1, r.first); } strcpy(pFilename, FileName.c_str()); pFilename += FileName.length(); *pFilename++ = 0x00; // termination numFiles++; INFO_LOG(WII_IPC_FILEIO, "\tFound: %s", FileName.c_str()); } Memory::Write_U32((u32)numFiles, CommandBuffer.PayloadBuffer[1].m_Address); } ReturnValue = FS_RESULT_OK; } break; case IOCTLV_GETUSAGE: { _dbg_assert_(WII_IPC_FILEIO, CommandBuffer.PayloadBuffer.size() == 2); _dbg_assert_(WII_IPC_FILEIO, CommandBuffer.PayloadBuffer[0].m_Size == 4); _dbg_assert_(WII_IPC_FILEIO, CommandBuffer.PayloadBuffer[1].m_Size == 4); // this command sucks because it asks of the number of used // fsBlocks and inodes // It should be correct, but don't count on it... const char *relativepath = (const char*)Memory::GetPointer(CommandBuffer.InBuffer[0].m_Address); std::string path(HLE_IPC_BuildFilename(relativepath, CommandBuffer.InBuffer[0].m_Size)); u32 fsBlocks = 0; u32 iNodes = 0; INFO_LOG(WII_IPC_FILEIO, "IOCTL_GETUSAGE %s", path.c_str()); if (File::IsDirectory(path)) { // LPFaint99: After I found that setting the number of inodes to the number of children + 1 for the directory itself // I decided to compare with sneek which has the following 2 special cases which are // Copyright (C) 2009-2011 crediar http://code.google.com/p/sneek/ if ((memcmp(relativepath, "/title/00010001", 16 ) == 0 ) || (memcmp(relativepath, "/title/00010005", 16) == 0 )) { fsBlocks = 23; // size is size/0x4000 iNodes = 42; // empty folders return a FileCount of 1 } else { File::FSTEntry parentDir; // add one for the folder itself, allows some games to create their save files // R8XE52 (Jurassic: The Hunted), STEETR (Tetris Party Deluxe) now create their saves with this change iNodes = 1 + File::ScanDirectoryTree(path, parentDir); u64 totalSize = ComputeTotalFileSize(parentDir); // "Real" size, to be converted to nand blocks fsBlocks = (u32)(totalSize / (16 * 1024)); // one bock is 16kb } ReturnValue = FS_RESULT_OK; INFO_LOG(WII_IPC_FILEIO, "FS: fsBlock: %i, iNodes: %i", fsBlocks, iNodes); } else { fsBlocks = 0; iNodes = 0; ReturnValue = FS_RESULT_OK; WARN_LOG(WII_IPC_FILEIO, "FS: fsBlock failed, cannot find directory: %s", path.c_str()); } Memory::Write_U32(fsBlocks, CommandBuffer.PayloadBuffer[0].m_Address); Memory::Write_U32(iNodes, CommandBuffer.PayloadBuffer[1].m_Address); } break; default: PanicAlert("CWII_IPC_HLE_Device_fs::IOCtlV: %i", CommandBuffer.Parameter); break; } Memory::Write_U32(ReturnValue, _CommandAddress+4); return true; }
void Init(const char *gameCode) { textureMap.clear(); texturecount = 0; CFileSearch::XStringVector Directories; //Directories.push_back(File::GetUserPath(D_HIRESTEXTURES_IDX)); char szDir[MAX_PATH]; sprintf(szDir, "%s%s", File::GetUserPath(D_HIRESTEXTURES_IDX).c_str(), gameCode); Directories.push_back(std::string(szDir)); for (u32 i = 0; i < Directories.size(); i++) { File::FSTEntry FST_Temp; File::ScanDirectoryTree(Directories[i], FST_Temp); for (u32 j = 0; j < FST_Temp.children.size(); j++) { if (FST_Temp.children.at(j).isDirectory) { bool duplicate = false; for (u32 k = 0; k < Directories.size(); k++) { if (strcmp(Directories[k].c_str(), FST_Temp.children.at(j).physicalName.c_str()) == 0) { duplicate = true; break; } } if (!duplicate) Directories.push_back(FST_Temp.children.at(j).physicalName.c_str()); } } } CFileSearch::XStringVector Extensions; Extensions.push_back("*.png"); Extensions.push_back("*.PNG"); Extensions.push_back("*.bmp"); Extensions.push_back("*.BMP"); Extensions.push_back("*.tga"); Extensions.push_back("*.TGA"); Extensions.push_back("*.dds"); Extensions.push_back("*.DDS"); Extensions.push_back("*.jpg"); // Why not? Could be useful for large photo-like textures Extensions.push_back("*.JPG"); CFileSearch FileSearch(Extensions, Directories); const CFileSearch::XStringVector& rFilenames = FileSearch.GetFileNames(); std::string code(gameCode); if (rFilenames.size() > 0) { for (u32 i = 0; i < rFilenames.size(); i++) { std::string FileName; std::string Extension; SplitPath(rFilenames[i], NULL, &FileName, &Extension); std::pair<std::string, std::string> Pair(rFilenames[i], Extension); std::vector<std::string> nameparts; std::istringstream issfilename(FileName); std::string nameitem; while (std::getline(issfilename, nameitem, '_')) { nameparts.push_back(nameitem); } if (nameparts.size() >= 3) { u32 hash = 0; u32 format = 0; u32 mip = 0; sscanf(nameparts[1].c_str(), "%x", &hash); sscanf(nameparts[2].c_str(), "%i", &format); if (nameparts.size() > 3 && nameparts[3].size() > 3) { sscanf(nameparts[3].substr(3, std::string::npos).c_str(), "%i", &mip); } u64 key = ((u64)hash) | (((u64)format) << 32) | (((u64)mip) << 48); if (nameparts[0].compare(code) == 0 && textureMap.find(key) == textureMap.end()) { texturecount++; textureMap.insert(std::map<u64, std::pair<std::string, std::string>>::value_type(key, Pair)); } } } } }