void InputConfigDialog::UpdateProfileComboBox()
{
	std::string pname(File::GetUserPath(D_CONFIG_IDX));
	pname += PROFILES_PATH;
	pname += m_plugin.profile_name;

	CFileSearch::XStringVector exts;
	exts.push_back("*.ini");
	CFileSearch::XStringVector dirs;
	dirs.push_back(pname);
	CFileSearch cfs(exts, dirs);
	const CFileSearch::XStringVector& sv = cfs.GetFileNames();

	wxArrayString strs;
	for (auto si = sv.cbegin(); si != sv.cend(); ++si)
	{
		std::string str(si->begin() + si->find_last_of('/') + 1 , si->end() - 4) ;
		strs.push_back(StrToWxStr(str));
	}

	for (GamepadPage* page : m_padpages)
	{
		page->profile_cbox->Clear();
		page->profile_cbox->Append(strs);
	}
}
void InputConfigDialog::UpdateProfileComboBox()
{
	std::string pname(File::GetUserPath(D_CONFIG_IDX));
	pname += PROFILES_PATH;
	pname += m_plugin.profile_name;

	CFileSearch::XStringVector exts;
	exts.push_back("*.ini");
	CFileSearch::XStringVector dirs;
	dirs.push_back(pname);
	CFileSearch cfs(exts, dirs);
	const CFileSearch::XStringVector& sv = cfs.GetFileNames();

	wxArrayString strs;
	CFileSearch::XStringVector::const_iterator si = sv.begin(),
		se = sv.end();
	for (; si!=se; ++si)
	{
		std::string str(si->begin() + si->find_last_of('/') + 1 , si->end() - 4) ;
		strs.push_back(StrToWxStr(str));
	}

	std::vector< GamepadPage* >::iterator i = m_padpages.begin(),
		e = m_padpages.end();
	for (; i != e; ++i)
	{
		(*i)->profile_cbox->Clear();
		(*i)->profile_cbox->Append(strs);
	}
}
GCMemcardDirectory::GCMemcardDirectory(const std::string& directory, int slot, u16 sizeMb, bool ascii, DiscIO::IVolume::ECountry card_region, int gameId)
	: MemoryCardBase(slot, sizeMb)
	, m_GameId(gameId)
	, m_LastBlock(-1)
	, m_hdr(slot, sizeMb, ascii)
	, m_bat1(sizeMb)
	, m_saves(0)
	, m_SaveDirectory(directory)
	, m_exiting(false)
{
	// Use existing header data if available
	if (File::Exists(m_SaveDirectory + MC_HDR))
	{
		File::IOFile hdrfile((m_SaveDirectory + MC_HDR), "rb");
		hdrfile.ReadBytes(&m_hdr, BLOCK_SIZE);
	}

	File::FSTEntry FST_Temp;
	File::ScanDirectoryTree(m_SaveDirectory, FST_Temp);

	CFileSearch::XStringVector Directory;
	Directory.push_back(m_SaveDirectory);
	CFileSearch::XStringVector Extensions;
	Extensions.push_back("*.gci");

	CFileSearch FileSearch(Extensions, Directory);
	const CFileSearch::XStringVector& rFilenames = FileSearch.GetFileNames();

	if (rFilenames.size() > 112)
	{
		Core::DisplayMessage(
		StringFromFormat("WARNING: There are more than 112 save files on this memorycards"\
		"\n Only loading the first 112 in the folder, unless the gameid is the current games id"),
		4000);
	}

	for (auto gciFile : rFilenames)
	{
		if (m_saves.size() == DIRLEN)
		{
			PanicAlertT("There are too many gci files in the folder\n%s\nOnly the first 127 will be available",
				m_SaveDirectory.c_str());
			break;
		}
		int index = LoadGCI(gciFile, card_region, m_saves.size() > 112 );
		if (index != NO_INDEX)
		{
			m_loaded_saves.push_back(m_saves.at(index).m_gci_header.GCI_FileName());
		}

	}

	m_loaded_saves.clear();
	m_dir1.fixChecksums();
	m_dir2 = m_dir1;
	m_bat2 = m_bat1;

	m_flush_thread = std::thread(&GCMemcardDirectory::FlushThread, this);
}
Exemple #4
0
void Init(const std::string& gameCode)
{
    textureMap.clear();

    CFileSearch::XStringVector Directories;

    std::string szDir = StringFromFormat("%s%s", File::GetUserPath(D_HIRESTEXTURES_IDX).c_str(), gameCode.c_str());
    Directories.push_back(szDir);

    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 = {
        "*.png",
        "*.bmp",
        "*.tga",
        "*.dds",
        "*.jpg" // Why not? Could be useful for large photo-like textures
    };

    CFileSearch FileSearch(Extensions, Directories);
    const CFileSearch::XStringVector& rFilenames = FileSearch.GetFileNames();

    const std::string code = StringFromFormat("%s_", gameCode.c_str());

    if (rFilenames.size() > 0)
    {
        for (auto& rFilename : rFilenames)
        {
            std::string FileName;
            SplitPath(rFilename, nullptr, &FileName, nullptr);

            if (FileName.substr(0, code.length()).compare(code) == 0 && textureMap.find(FileName) == textureMap.end())
                textureMap.insert(std::map<std::string, std::string>::value_type(FileName, rFilename));
        }
    }
}
Exemple #5
0
CFileSearch::CFileSearch(const CFileSearch::XStringVector& _rSearchStrings, const CFileSearch::XStringVector& _rDirectories)
{
	// Reverse the loop order for speed?
	for (size_t j = 0; j < _rSearchStrings.size(); j++)
	{
		for (size_t i = 0; i < _rDirectories.size(); i++)
		{
			FindFiles(_rSearchStrings[j], _rDirectories[i]);
		}
	}
}
Exemple #6
0
void Init(const char *gameCode)
{
	textureMap.clear();

	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("*.bmp");
	Extensions.push_back("*.tga");
	Extensions.push_back("*.dds");
	Extensions.push_back("*.jpg"); // Why not? Could be useful for large photo-like textures

	CFileSearch FileSearch(Extensions, Directories);
	const CFileSearch::XStringVector& rFilenames = FileSearch.GetFileNames();
	char code[MAX_PATH];
	sprintf(code, "%s_", gameCode);

	if (rFilenames.size() > 0)
	{
		for (u32 i = 0; i < rFilenames.size(); i++)
		{
			std::string FileName;
			SplitPath(rFilenames[i], NULL, &FileName, NULL);

			if (FileName.substr(0, strlen(code)).compare(code) == 0 && textureMap.find(FileName) == textureMap.end())
				textureMap.insert(std::map<std::string, std::string>::value_type(FileName, rFilenames[i]));
		}
	}
}
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 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());
}
Exemple #9
0
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);
}
Exemple #10
0
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());
}
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));
				}
			}
			
		}
	}
}