Exemple #1
0
void __UmdReplace(std::string filepath) {
	// Only get system from disc0 seems have been enough.
	IFileSystem* currentUMD = pspFileSystem.GetSystem("disc0:");
	if (!currentUMD)
		return;

	IFileSystem* umd2;
	FileInfo info;
	if (!getFileInfo(filepath.c_str(), &info))    // This shouldn't happen, but for safety.
		return;
	if (info.isDirectory) {
		umd2 = new VirtualDiscFileSystem(&pspFileSystem, filepath);
	} else {
		auto bd = constructBlockDevice(filepath.c_str());
		if (!bd)
			return;
		umd2 = new ISOFileSystem(&pspFileSystem, bd);

		pspFileSystem.Remount(currentUMD, umd2);
	}
	delete currentUMD;

	// TODO Is this always correct if UMD was not activated?
	u32 notifyArg = PSP_UMD_PRESENT | PSP_UMD_READABLE | PSP_UMD_CHANGED;
	if (driveCBId != -1)
		__KernelNotifyCallback(driveCBId, notifyArg);
}
Exemple #2
0
bool Load_PSP_ELF_PBP(const char *filename, std::string *error_string)
{
	// This is really just for headless, might need tweaking later.
	if (!PSP_CoreParameter().mountIso.empty())
	{
		auto bd = constructBlockDevice(PSP_CoreParameter().mountIso.c_str());
		if (bd != NULL) {
			ISOFileSystem *umd2 = new ISOFileSystem(&pspFileSystem, bd);

			pspFileSystem.Mount("umd1:", umd2);
			pspFileSystem.Mount("disc0:", umd2);
			pspFileSystem.Mount("umd:", umd2);
		}
	}

	std::string full_path = filename;
	std::string path, file, extension;
	SplitPath(ReplaceAll(full_path, "\\", "/"), &path, &file, &extension);
#ifdef _WIN32
	path = ReplaceAll(path, "/", "\\");
#endif

	DirectoryFileSystem *fs = new DirectoryFileSystem(&pspFileSystem, path);
	pspFileSystem.Mount("umd0:", fs);

	std::string finalName = "umd0:/" + file + extension;
	return __KernelLoadExec(finalName.c_str(), 0, error_string);
}
ProcessResult process(const char *iso, const char *output)
{
	BlockDevice *blockDevice = constructBlockDevice(iso);
	if (!blockDevice)
		return RESULT_INPUT_READ_FAIL;

	std::ofstream out;
	out.open(output);

	if (!out)
	{
		delete blockDevice;
		return RESULT_OUTPUT_WRITE_FAIL;
	}

	VolDescriptor desc;
	blockDevice->ReadBlock(16, (u8*)&desc);

	if (memcmp(desc.cd001, "CD001", 5))
	{
		fprintf(stderr, "ERROR: Block 16 does not start with CD001.\n");
		delete blockDevice;
		return RESULT_INPUT_PARSE_FAIL;
	}

	u32 rootSector = desc.root.firstDataSectorLE;
	u32 rootSize = desc.root.dataLengthLE;

	descend(blockDevice, rootSector, rootSize, out, "");

	delete blockDevice;
	return RESULT_SUCCESS;
}
Exemple #4
0
// We gather the game info before actually loading/booting the ISO
// to determine if the emulator should enable extra memory and
// double-sized texture coordinates.
void InitMemoryForGameISO(std::string fileToStart) {
	IFileSystem* umd2;

	// check if it's a disc directory
	FileInfo info;
	if (!getFileInfo(fileToStart.c_str(), &info)) return;

	if (info.isDirectory)
	{
		umd2 = new VirtualDiscFileSystem(&pspFileSystem, fileToStart);
	}
	else 
	{
		auto bd = constructBlockDevice(fileToStart.c_str());
		// Can't init anything without a block device...
		if (!bd)
			return;
		umd2 = new ISOFileSystem(&pspFileSystem, bd);
	}

	// Parse PARAM.SFO

	//pspFileSystem.Mount("host0:",umd2);
	pspFileSystem.Mount("umd0:", umd2);
	pspFileSystem.Mount("umd1:", umd2);
	pspFileSystem.Mount("disc0:", umd2);
	pspFileSystem.Mount("umd:", umd2);

	std::string gameID;

	std::string sfoPath("disc0:/PSP_GAME/PARAM.SFO");
	PSPFileInfo fileInfo = pspFileSystem.GetFileInfo(sfoPath.c_str());

	if (fileInfo.exists)
	{
		u8 *paramsfo = new u8[(size_t)fileInfo.size];
		u32 fd = pspFileSystem.OpenFile(sfoPath, FILEACCESS_READ);
		pspFileSystem.ReadFile(fd, paramsfo, fileInfo.size);
		pspFileSystem.CloseFile(fd);
		if (g_paramSFO.ReadSFO(paramsfo, (size_t)fileInfo.size))
		{
			gameID = g_paramSFO.GetValueString("DISC_ID");

			for (size_t i = 0; i < ARRAY_SIZE(g_HDRemasters); i++) {
				if(g_HDRemasters[i].gameID == gameID) {
					g_RemasterMode = true;
					Memory::g_MemorySize = g_HDRemasters[i].MemorySize;
					if(g_HDRemasters[i].DoubleTextureCoordinates)
						g_DoubleTextureCoordinates = true;
					break;
				}
			}
			DEBUG_LOG(LOADER, "HDRemaster mode is %s", g_RemasterMode? "true": "false");
		}
		delete [] paramsfo;
	}
}
Exemple #5
0
bool Load_PSP_ISO(const char *filename, std::string *error_string)
{
    ISOFileSystem *umd2 = new ISOFileSystem(&pspFileSystem, constructBlockDevice(filename));

    // Parse PARAM.SFO

    //pspFileSystem.Mount("host0:",umd2);
    pspFileSystem.Mount("umd0:", umd2);
    pspFileSystem.Mount("umd1:", umd2);
    pspFileSystem.Mount("disc0:", umd2);
    pspFileSystem.Mount("umd:", umd2);

    std::string sfoPath("disc0:/PSP_GAME/PARAM.SFO");
    PSPFileInfo fileInfo = pspFileSystem.GetFileInfo(sfoPath.c_str());
    if (fileInfo.exists)
    {
        u8 *paramsfo = new u8[(size_t)fileInfo.size];
        u32 fd = pspFileSystem.OpenFile(sfoPath, FILEACCESS_READ);
        pspFileSystem.ReadFile(fd, paramsfo, fileInfo.size);
        pspFileSystem.CloseFile(fd);
        if (g_paramSFO.ReadSFO(paramsfo, (size_t)fileInfo.size))
        {
            char title[1024];
            sprintf(title, "%s : %s", g_paramSFO.GetValueString("DISC_ID").c_str(), g_paramSFO.GetValueString("TITLE").c_str());
            INFO_LOG(LOADER, "%s", title);
            host->SetWindowTitle(title);
        }
        delete [] paramsfo;
    }


    std::string bootpath("disc0:/PSP_GAME/SYSDIR/EBOOT.BIN");
    // bypass patchers
    if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/EBOOT.OLD").exists) {
        bootpath = "disc0:/PSP_GAME/SYSDIR/EBOOT.OLD";
    }
    bool hasEncrypted = false;
    u32 fd;
    if ((fd = pspFileSystem.OpenFile(bootpath, FILEACCESS_READ)) != 0)
    {
        u8 head[4];
        pspFileSystem.ReadFile(fd, head, 4);
        if (memcmp(head, "~PSP", 4) == 0 || memcmp(head, "\x7F""ELF", 4) == 0) {
            hasEncrypted = true;
        }
        pspFileSystem.CloseFile(fd);
    }
    if (!hasEncrypted)
    {
        // try unencrypted BOOT.BIN
        bootpath = "disc0:/PSP_GAME/SYSDIR/BOOT.BIN";
    }

    INFO_LOG(LOADER,"Loading %s...", bootpath.c_str());
    return __KernelLoadExec(bootpath.c_str(), 0, error_string);
}
bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string)
{
	// This is really just for headless, might need tweaking later.
	if (PSP_CoreParameter().mountIsoLoader != nullptr)
	{
		auto bd = constructBlockDevice(PSP_CoreParameter().mountIsoLoader);
		if (bd != NULL) {
			ISOFileSystem *umd2 = new ISOFileSystem(&pspFileSystem, bd);

			pspFileSystem.Mount("umd1:", umd2);
			pspFileSystem.Mount("disc0:", umd2);
			pspFileSystem.Mount("umd:", umd2);
		}
	}

	std::string full_path = fileLoader->Path();
	std::string path, file, extension;
	SplitPath(ReplaceAll(full_path, "\\", "/"), &path, &file, &extension);
#ifdef _WIN32
	path = ReplaceAll(path, "/", "\\");
#endif

	if (!PSP_CoreParameter().mountRoot.empty())
	{
		// We don't want to worry about .. and cwd and such.
		const std::string rootNorm = NormalizePath(PSP_CoreParameter().mountRoot + "/");
		const std::string pathNorm = NormalizePath(path + "/");

		// If root is not a subpath of path, we can't boot the game.
		if (!startsWith(pathNorm, rootNorm))
		{
			*error_string = "Cannot boot ELF located outside mountRoot.";
			return false;
		}

		const std::string filepath = ReplaceAll(pathNorm.substr(rootNorm.size()), "\\", "/");
		file = filepath + "/" + file;
		path = rootNorm + "/";
		pspFileSystem.SetStartingDirectory(filepath);
	}

	DirectoryFileSystem *fs = new DirectoryFileSystem(&pspFileSystem, path);
	pspFileSystem.Mount("umd0:", fs);

	std::string finalName = "umd0:/" + file + extension;
	return __KernelLoadExec(finalName.c_str(), 0, error_string);
}
Exemple #7
0
void __UmdReplace(std::string filepath) {
	// TODO: This should really go through Loaders, no?  What if it's an invalid file?

	// Only get system from disc0 seems have been enough.
	IFileSystem* currentUMD = pspFileSystem.GetSystem("disc0:");
	IFileSystem* currentISOBlock = pspFileSystem.GetSystem("umd0:");
	if (!currentUMD)
		return;

	FileLoader *loadedFile = ConstructFileLoader(filepath);

	IFileSystem* umd2;
	if (!loadedFile->Exists()) {
		delete loadedFile;
		return;
	}
	UpdateLoadedFile(loadedFile);

	if (loadedFile->IsDirectory()) {
		umd2 = new VirtualDiscFileSystem(&pspFileSystem, filepath);
	} else {
		auto bd = constructBlockDevice(loadedFile);
		if (!bd)
			return;
		umd2 = new ISOFileSystem(&pspFileSystem, bd);
		pspFileSystem.Remount(currentUMD, umd2);

		if (currentUMD != currentISOBlock) {
			// We mounted an ISO block system separately.
			IFileSystem *iso = new ISOBlockSystem(static_cast<ISOFileSystem *>(umd2));
			pspFileSystem.Remount(currentISOBlock, iso);
			delete currentISOBlock;
		}
	}
	delete currentUMD;

	// TODO Is this always correct if UMD was not activated?
	u32 notifyArg = PSP_UMD_PRESENT | PSP_UMD_READABLE | PSP_UMD_CHANGED;
	if (driveCBId != -1)
		__KernelNotifyCallback(driveCBId, notifyArg);
}
Exemple #8
0
	static int CalculateCRCThread() {
		setCurrentThreadName("ReportCRC");

		// TODO: Use the blockDevice from pspFileSystem?
		FileLoader *fileLoader = ConstructFileLoader(crcFilename);
		BlockDevice *blockDevice = constructBlockDevice(fileLoader);

		u32 crc = 0;
		if (blockDevice) {
			crc = blockDevice->CalculateCRC();
		}

		delete blockDevice;
		delete fileLoader;

		lock_guard guard(crcLock);
		crcResults[crcFilename] = crc;
		crcCond.notify_one();

		return 0;
	}
	virtual void run() {
		delete info_->fileLoader;
		info_->fileLoader = ConstructFileLoader(gamePath_);
		if (!info_->fileLoader->Exists())
			return;

		std::string filename = gamePath_;
		info_->path = gamePath_;
		info_->fileType = Identify_File(info_->fileLoader);
		// Fallback title
		info_->title = getFilename(info_->path);

		switch (info_->fileType) {
		case FILETYPE_PSP_PBP:
		case FILETYPE_PSP_PBP_DIRECTORY:
			{
				std::string pbpFile = filename;
				if (info_->fileType == FILETYPE_PSP_PBP_DIRECTORY)
					pbpFile += "/EBOOT.PBP";

				PBPReader pbp(pbpFile.c_str());
				if (!pbp.IsValid()) {
					if (pbp.IsELF()) {
						goto handleELF;
					}
					ERROR_LOG(LOADER, "invalid pbp %s\n", pbpFile.c_str());
					return;
				}

				// First, PARAM.SFO.
				size_t sfoSize;
				u8 *sfoData = pbp.GetSubFile(PBP_PARAM_SFO, &sfoSize);
				{
					lock_guard lock(info_->lock);
					info_->paramSFO.ReadSFO(sfoData, sfoSize);
					info_->ParseParamSFO();
				}
				delete [] sfoData;

				// Then, ICON0.PNG.
				{
					lock_guard lock(info_->lock);
					if (pbp.GetSubFileSize(PBP_ICON0_PNG) > 0) {
						pbp.GetSubFileAsString(PBP_ICON0_PNG, &info_->iconTextureData);
					} else {
						// Read standard icon
						size_t sz;
						DEBUG_LOG(LOADER, "Loading unknown.png because a PBP was missing an icon");
						uint8_t *contents = VFSReadFile("unknown.png", &sz);
						if (contents) {
							lock_guard lock(info_->lock);
							info_->iconTextureData = std::string((const char *)contents, sz);
						}
						delete [] contents;
					}
					info_->iconDataLoaded = true;
				}

				if (info_->wantFlags & GAMEINFO_WANTBG) {
					if (pbp.GetSubFileSize(PBP_PIC0_PNG) > 0) {
						lock_guard lock(info_->lock);
						pbp.GetSubFileAsString(PBP_PIC0_PNG, &info_->pic0TextureData);
						info_->pic0DataLoaded = true;
					}
					if (pbp.GetSubFileSize(PBP_PIC1_PNG) > 0) {
						lock_guard lock(info_->lock);
						pbp.GetSubFileAsString(PBP_PIC1_PNG, &info_->pic1TextureData);
						info_->pic1DataLoaded = true;
					}
				}
				if (info_->wantFlags & GAMEINFO_WANTSND) {
					if (pbp.GetSubFileSize(PBP_SND0_AT3) > 0) {
						lock_guard lock(info_->lock);
						pbp.GetSubFileAsString(PBP_SND0_AT3, &info_->sndFileData);
						info_->sndDataLoaded = true;
					}
				}
			}
			break;

		case FILETYPE_PSP_ELF:
handleELF:
			// An elf on its own has no usable information, no icons, no nothing.
			info_->title = getFilename(filename);
			info_->id = "ELF000000";
			info_->id_version = "ELF000000_1.00";
			info_->paramSFOLoaded = true;
			{
				// Read standard icon
				size_t sz;
				uint8_t *contents = VFSReadFile("unknown.png", &sz);
				DEBUG_LOG(LOADER, "Loading unknown.png because there was an ELF");
				if (contents) {
					lock_guard lock(info_->lock);
					info_->iconTextureData = std::string((const char *)contents, sz);
					info_->iconDataLoaded = true;
				}
				delete [] contents;
			}
			break;

		case FILETYPE_PSP_DISC_DIRECTORY:
			{
				info_->fileType = FILETYPE_PSP_ISO;
				SequentialHandleAllocator handles;
				VirtualDiscFileSystem umd(&handles, gamePath_.c_str());

				// Alright, let's fetch the PARAM.SFO.
				std::string paramSFOcontents;
				if (ReadFileToString(&umd, "/PSP_GAME/PARAM.SFO", &paramSFOcontents, 0)) {
					lock_guard lock(info_->lock);
					info_->paramSFO.ReadSFO((const u8 *)paramSFOcontents.data(), paramSFOcontents.size());
					info_->ParseParamSFO();
				}

				ReadFileToString(&umd, "/PSP_GAME/ICON0.PNG", &info_->iconTextureData, &info_->lock);
				info_->iconDataLoaded = true;
				if (info_->wantFlags & GAMEINFO_WANTBG) {
					ReadFileToString(&umd, "/PSP_GAME/PIC0.PNG", &info_->pic0TextureData, &info_->lock);
					info_->pic0DataLoaded = true;
					ReadFileToString(&umd, "/PSP_GAME/PIC1.PNG", &info_->pic1TextureData, &info_->lock);
					info_->pic1DataLoaded = true;
				}
				if (info_->wantFlags & GAMEINFO_WANTSND) {
					ReadFileToString(&umd, "/PSP_GAME/SND0.AT3", &info_->sndFileData, &info_->lock);
					info_->pic1DataLoaded = true;
				}
				break;
			}
		case FILETYPE_PSP_ISO:
		case FILETYPE_PSP_ISO_NP:
			{
				info_->fileType = FILETYPE_PSP_ISO;
				SequentialHandleAllocator handles;
				// Let's assume it's an ISO.
				// TODO: This will currently read in the whole directory tree. Not really necessary for just a
				// few files.
				BlockDevice *bd = constructBlockDevice(info_->fileLoader);
				if (!bd)
					return;  // nothing to do here..
				ISOFileSystem umd(&handles, bd, "/PSP_GAME");

				// Alright, let's fetch the PARAM.SFO.
				std::string paramSFOcontents;
				if (ReadFileToString(&umd, "/PSP_GAME/PARAM.SFO", &paramSFOcontents, 0)) {
					lock_guard lock(info_->lock);
					info_->paramSFO.ReadSFO((const u8 *)paramSFOcontents.data(), paramSFOcontents.size());
					info_->ParseParamSFO();

					if (info_->wantFlags & GAMEINFO_WANTBG) {
						ReadFileToString(&umd, "/PSP_GAME/PIC0.PNG", &info_->pic0TextureData, &info_->lock);
						info_->pic0DataLoaded = true;
						ReadFileToString(&umd, "/PSP_GAME/PIC1.PNG", &info_->pic1TextureData, &info_->lock);
						info_->pic1DataLoaded = true;
					}
					if (info_->wantFlags & GAMEINFO_WANTSND) {
						ReadFileToString(&umd, "/PSP_GAME/SND0.AT3", &info_->sndFileData, &info_->lock);
						info_->pic1DataLoaded = true;
					}
				}

				// Fall back to unknown icon if ISO is broken/is a homebrew ISO, override is allowed though
				if (!ReadFileToString(&umd, "/PSP_GAME/ICON0.PNG", &info_->iconTextureData, &info_->lock)) {
					size_t sz;
					uint8_t *contents = VFSReadFile("unknown.png", &sz);
					DEBUG_LOG(LOADER, "Loading unknown.png because no icon was found");
					if (contents) {
						lock_guard lock(info_->lock);
						info_->iconTextureData = std::string((const char *)contents, sz);
					}
					delete [] contents;
				}
				info_->iconDataLoaded = true;
				break;
			}

			case FILETYPE_ARCHIVE_ZIP:
				info_->paramSFOLoaded = true;
				{
					// Read standard icon
					size_t sz;
					uint8_t *contents = VFSReadFile("zip.png", &sz);
					if (contents) {
						lock_guard lock(info_->lock);
						info_->iconTextureData = std::string((const char *)contents, sz);
						info_->iconDataLoaded = true;
					}
					delete [] contents;
				}
				break;

			case FILETYPE_ARCHIVE_RAR:
				info_->paramSFOLoaded = true;
				{
					// Read standard icon
					size_t sz;
					uint8_t *contents = VFSReadFile("rargray.png", &sz);
					if (contents) {
						lock_guard lock(info_->lock);
						info_->iconTextureData = std::string((const char *)contents, sz);
						info_->iconDataLoaded = true;
					}
					delete [] contents;
				}
				break;

			case FILETYPE_ARCHIVE_7Z:
				info_->paramSFOLoaded = true;
				{
					// Read standard icon
					size_t sz;
					uint8_t *contents = VFSReadFile("7z.png", &sz);
					if (contents) {
						lock_guard lock(info_->lock);
						info_->iconTextureData = std::string((const char *)contents, sz);
						info_->iconDataLoaded = true;
					}
					delete[] contents;
				}
				break;

			case FILETYPE_NORMAL_DIRECTORY:
			default:
				info_->paramSFOLoaded = true;
				break;
		}

		if (info_->wantFlags & GAMEINFO_WANTSIZE) {
			info_->gameSize = info_->GetGameSizeInBytes();
			info_->saveDataSize = info_->GetSaveDataSizeInBytes();
			info_->installDataSize = info_->GetInstallDataSizeInBytes();
		}
	}
Exemple #10
0
// This may run off-main-thread and we thus can't use the global
// pspFileSystem (well, we could with synchronization but there might not
// even be a game running).
GameInfo *GameInfoCache::GetInfo(const std::string &gamePath, bool wantBG) {
	auto iter = info_.find(gamePath);
	if (iter != info_.end()) {
		GameInfo *info = iter->second;
		if (!info->wantBG && wantBG) {
			// Need to start over.
			delete info;
			goto again;
		}
		if (info->iconTextureData.size()) {
			info->iconTexture = new Texture();
			// TODO: We could actually do the PNG decoding as well on the async thread.
			// We'd have to split up Texture->LoadPNG though, creating some intermediate Image class maybe.
			if (info->iconTexture->LoadPNG((const u8 *)info->iconTextureData.data(), info->iconTextureData.size(), false)) {
				info->timeIconWasLoaded = time_now_d();
			}
			info->iconTextureData.clear();
		}
		if (info->pic0TextureData.size()) {
			info->pic0Texture = new Texture();
			if (info->pic0Texture->LoadPNG((const u8 *)info->pic0TextureData.data(), info->pic0TextureData.size(), false)) {
				info->timePic0WasLoaded = time_now_d();
			}
			info->pic0TextureData.clear();
		}
		if (info->pic1TextureData.size()) {
			info->pic1Texture = new Texture();
			if (info->pic1Texture->LoadPNG((const u8 *)info->pic1TextureData.data(), info->pic1TextureData.size(), false)) {
				info->timePic1WasLoaded = time_now_d();
			}
			info->pic1TextureData.clear();
		}
		iter->second->lastAccessedTime = time_now_d();
		return iter->second;
	}

again:

	// return info;

	// TODO: Everything below here should be asynchronous and run on a thread,
	// filling in the info as it goes.

	// A game can be either an UMD or a directory under ms0:/PSP/GAME .
	if (startsWith(gamePath, "ms0:/PSP/GAME")) {
		return 0;
	// TODO: The case of these extensions is not perfect.
	} else if (endsWith(gamePath, ".PBP") || endsWith(gamePath, ".elf")) {
		return 0;
	} else {
		SequentialHandleAllocator handles;
		// Let's assume it's an ISO.
		// TODO: This will currently read in the whole directory tree. Not really necessary for just a
		// few files.
		BlockDevice *bd = constructBlockDevice(gamePath.c_str());
		if (!bd)
			return 0;  // nothing to do here..
		ISOFileSystem umd(&handles, bd, "/PSP_GAME");

		GameInfo *info = new GameInfo();
		info->wantBG = wantBG;

		// Alright, let's fetch the PARAM.SFO.
		std::string paramSFOcontents;
		if (ReadFileToString(&umd, "/PSP_GAME/PARAM.SFO", &paramSFOcontents)) {
			lock_guard lock(info->lock);
			info->paramSFO.ReadSFO((const u8 *)paramSFOcontents.data(), paramSFOcontents.size());
			info->title = info->paramSFO.GetValueString("TITLE");
		}

		ReadFileToString(&umd, "/PSP_GAME/ICON0.PNG", &info->iconTextureData);
		if (wantBG) {
			{
				lock_guard lock(info->lock);
				ReadFileToString(&umd, "/PSP_GAME/PIC0.PNG", &info->pic0TextureData);
			}
			{
				lock_guard lock(info->lock);
				ReadFileToString(&umd, "/PSP_GAME/PIC1.PNG", &info->pic1TextureData);
			}
		}
		info_[gamePath] = info;
		return info;
	}

	return 0;
}
// We gather the game info before actually loading/booting the ISO
// to determine if the emulator should enable extra memory and
// double-sized texture coordinates.
void InitMemoryForGameISO(FileLoader *fileLoader) {
	IFileSystem* umd2;

	if (!fileLoader->Exists()) {
		return;
	}

	bool actualIso = false;
	if (fileLoader->IsDirectory())
	{
		umd2 = new VirtualDiscFileSystem(&pspFileSystem, fileLoader->Path());
	}
	else 
	{
		auto bd = constructBlockDevice(fileLoader);
		// Can't init anything without a block device...
		if (!bd)
			return;

#ifdef _M_X64
		if (g_Config.bCacheFullIsoInRam) {
			// The constructor destroys the original block device object after reading it.
			bd = new RAMBlockDevice(bd);
		}
#endif

		umd2 = new ISOFileSystem(&pspFileSystem, bd);
		actualIso = true;
	}

	// Parse PARAM.SFO

	//pspFileSystem.Mount("host0:",umd2);

	IFileSystem *entireIso = 0;
	if (actualIso) {
		entireIso = new ISOBlockSystem(static_cast<ISOFileSystem *>(umd2));
	} else {
		entireIso = umd2;
	}

	pspFileSystem.Mount("umd0:", entireIso);
	pspFileSystem.Mount("umd1:", entireIso);
	pspFileSystem.Mount("disc0:", umd2);
	pspFileSystem.Mount("umd:", entireIso);

	std::string gameID;

	std::string sfoPath("disc0:/PSP_GAME/PARAM.SFO");
	PSPFileInfo fileInfo = pspFileSystem.GetFileInfo(sfoPath.c_str());

	if (fileInfo.exists)
	{
		std::vector<u8> paramsfo;
		pspFileSystem.ReadEntireFile(sfoPath, paramsfo);
		if (g_paramSFO.ReadSFO(paramsfo))
		{
			gameID = g_paramSFO.GetValueString("DISC_ID");

			for (size_t i = 0; i < ARRAY_SIZE(g_HDRemasters); i++) {
				if(g_HDRemasters[i].gameID == gameID) {
					g_RemasterMode = true;
					Memory::g_MemorySize = g_HDRemasters[i].MemorySize;
					if(g_HDRemasters[i].DoubleTextureCoordinates)
						g_DoubleTextureCoordinates = true;
					break;
				}
			}
			DEBUG_LOG(LOADER, "HDRemaster mode is %s", g_RemasterMode? "true": "false");
		}
	}
}
Exemple #12
0
	virtual void run() {
		if (!info_->LoadFromPath(gamePath_))
			return;

		std::string filename = gamePath_;
		{
			lock_guard lock(info_->lock);
			info_->fileType = Identify_File(info_->GetFileLoader());
		}

		switch (info_->fileType) {
		case FILETYPE_PSP_PBP:
		case FILETYPE_PSP_PBP_DIRECTORY:
			{
				FileLoader *pbpLoader = info_->GetFileLoader();
				std::unique_ptr<FileLoader> altLoader;
				if (info_->fileType == FILETYPE_PSP_PBP_DIRECTORY) {
					pbpLoader = ConstructFileLoader(pbpLoader->Path() + "/EBOOT.PBP");
					altLoader.reset(pbpLoader);
				}

				PBPReader pbp(pbpLoader);
				if (!pbp.IsValid()) {
					if (pbp.IsELF()) {
						goto handleELF;
					}
					ERROR_LOG(LOADER, "invalid pbp %s\n", pbpLoader->Path().c_str());
					return;
				}

				// First, PARAM.SFO.
				std::vector<u8> sfoData;
				if (pbp.GetSubFile(PBP_PARAM_SFO, &sfoData)) {
					lock_guard lock(info_->lock);
					info_->paramSFO.ReadSFO(sfoData);
					info_->ParseParamSFO();
				}

				// Then, ICON0.PNG.
				if (pbp.GetSubFileSize(PBP_ICON0_PNG) > 0) {
					lock_guard lock(info_->lock);
					pbp.GetSubFileAsString(PBP_ICON0_PNG, &info_->iconTextureData);
				} else {
					// Read standard icon
					DEBUG_LOG(LOADER, "Loading unknown.png because a PBP was missing an icon");
					ReadVFSToString("unknown.png", &info_->iconTextureData, &info_->lock);
				}
				info_->iconDataLoaded = true;

				if (info_->wantFlags & GAMEINFO_WANTBG) {
					if (pbp.GetSubFileSize(PBP_PIC0_PNG) > 0) {
						lock_guard lock(info_->lock);
						pbp.GetSubFileAsString(PBP_PIC0_PNG, &info_->pic0TextureData);
						info_->pic0DataLoaded = true;
					}
					if (pbp.GetSubFileSize(PBP_PIC1_PNG) > 0) {
						lock_guard lock(info_->lock);
						pbp.GetSubFileAsString(PBP_PIC1_PNG, &info_->pic1TextureData);
						info_->pic1DataLoaded = true;
					}
				}
				if (info_->wantFlags & GAMEINFO_WANTSND) {
					if (pbp.GetSubFileSize(PBP_SND0_AT3) > 0) {
						lock_guard lock(info_->lock);
						pbp.GetSubFileAsString(PBP_SND0_AT3, &info_->sndFileData);
						info_->sndDataLoaded = true;
					}
				}
			}
			break;

		case FILETYPE_PSP_ELF:
handleELF:
			// An elf on its own has no usable information, no icons, no nothing.
			{
				lock_guard lock(info_->lock);
				info_->id = "ELF000000";
				info_->id_version = "ELF000000_1.00";
				info_->paramSFOLoaded = true;
			}

			// Read standard icon
			DEBUG_LOG(LOADER, "Loading unknown.png because there was an ELF");
			ReadVFSToString("unknown.png", &info_->iconTextureData, &info_->lock);
			info_->iconDataLoaded = true;
			break;

		case FILETYPE_PSP_SAVEDATA_DIRECTORY:
		{
			SequentialHandleAllocator handles;
			VirtualDiscFileSystem umd(&handles, gamePath_.c_str());

			// Alright, let's fetch the PARAM.SFO.
			std::string paramSFOcontents;
			if (ReadFileToString(&umd, "/PARAM.SFO", &paramSFOcontents, 0)) {
				lock_guard lock(info_->lock);
				info_->paramSFO.ReadSFO((const u8 *)paramSFOcontents.data(), paramSFOcontents.size());
				info_->ParseParamSFO();
			}

			ReadFileToString(&umd, "/ICON0.PNG", &info_->iconTextureData, &info_->lock);
			info_->iconDataLoaded = true;
			if (info_->wantFlags & GAMEINFO_WANTBG) {
				ReadFileToString(&umd, "/PIC1.PNG", &info_->pic1TextureData, &info_->lock);
				info_->pic1DataLoaded = true;
			}
			break;
		}

		case FILETYPE_PPSSPP_SAVESTATE:
		{
			info_->SetTitle(SaveState::GetTitle(gamePath_));

			lock_guard guard(info_->lock);

			// Let's use the screenshot as an icon, too.
			std::string screenshotPath = ReplaceAll(gamePath_, ".ppst", ".jpg");
			if (File::Exists(screenshotPath)) {
				if (readFileToString(false, screenshotPath.c_str(), info_->iconTextureData)) {
					info_->iconDataLoaded = true;
				}
			}
			break;
		}

		case FILETYPE_PSP_DISC_DIRECTORY:
			{
				info_->fileType = FILETYPE_PSP_ISO;
				SequentialHandleAllocator handles;
				VirtualDiscFileSystem umd(&handles, gamePath_.c_str());

				// Alright, let's fetch the PARAM.SFO.
				std::string paramSFOcontents;
				if (ReadFileToString(&umd, "/PSP_GAME/PARAM.SFO", &paramSFOcontents, 0)) {
					lock_guard lock(info_->lock);
					info_->paramSFO.ReadSFO((const u8 *)paramSFOcontents.data(), paramSFOcontents.size());
					info_->ParseParamSFO();
				}

				ReadFileToString(&umd, "/PSP_GAME/ICON0.PNG", &info_->iconTextureData, &info_->lock);
				info_->iconDataLoaded = true;
				if (info_->wantFlags & GAMEINFO_WANTBG) {
					ReadFileToString(&umd, "/PSP_GAME/PIC0.PNG", &info_->pic0TextureData, &info_->lock);
					info_->pic0DataLoaded = true;
					ReadFileToString(&umd, "/PSP_GAME/PIC1.PNG", &info_->pic1TextureData, &info_->lock);
					info_->pic1DataLoaded = true;
				}
				if (info_->wantFlags & GAMEINFO_WANTSND) {
					ReadFileToString(&umd, "/PSP_GAME/SND0.AT3", &info_->sndFileData, &info_->lock);
					info_->pic1DataLoaded = true;
				}
				break;
			}

		case FILETYPE_PSP_ISO:
		case FILETYPE_PSP_ISO_NP:
			{
				info_->fileType = FILETYPE_PSP_ISO;
				SequentialHandleAllocator handles;
				// Let's assume it's an ISO.
				// TODO: This will currently read in the whole directory tree. Not really necessary for just a
				// few files.
				BlockDevice *bd = constructBlockDevice(info_->GetFileLoader());
				if (!bd)
					return;  // nothing to do here..
				ISOFileSystem umd(&handles, bd, "/PSP_GAME");

				// Alright, let's fetch the PARAM.SFO.
				std::string paramSFOcontents;
				if (ReadFileToString(&umd, "/PSP_GAME/PARAM.SFO", &paramSFOcontents, nullptr)) {
					lock_guard lock(info_->lock);
					info_->paramSFO.ReadSFO((const u8 *)paramSFOcontents.data(), paramSFOcontents.size());
					info_->ParseParamSFO();

					if (info_->wantFlags & GAMEINFO_WANTBG) {
						ReadFileToString(&umd, "/PSP_GAME/PIC0.PNG", &info_->pic0TextureData, &info_->lock);
						info_->pic0DataLoaded = true;
						ReadFileToString(&umd, "/PSP_GAME/PIC1.PNG", &info_->pic1TextureData, &info_->lock);
						info_->pic1DataLoaded = true;
					}
					if (info_->wantFlags & GAMEINFO_WANTSND) {
						ReadFileToString(&umd, "/PSP_GAME/SND0.AT3", &info_->sndFileData, &info_->lock);
						info_->pic1DataLoaded = true;
					}
				}

				// Fall back to unknown icon if ISO is broken/is a homebrew ISO, override is allowed though
				if (!ReadFileToString(&umd, "/PSP_GAME/ICON0.PNG", &info_->iconTextureData, &info_->lock)) {
					DEBUG_LOG(LOADER, "Loading unknown.png because no icon was found");
					ReadVFSToString("unknown.png", &info_->iconTextureData, &info_->lock);
				}
				info_->iconDataLoaded = true;
				break;
			}

			case FILETYPE_ARCHIVE_ZIP:
				info_->paramSFOLoaded = true;
				{
					ReadVFSToString("zip.png", &info_->iconTextureData, &info_->lock);
					info_->iconDataLoaded = true;
				}
				break;

			case FILETYPE_ARCHIVE_RAR:
				info_->paramSFOLoaded = true;
				{
					ReadVFSToString("rargray.png", &info_->iconTextureData, &info_->lock);
					info_->iconDataLoaded = true;
				}
				break;

			case FILETYPE_ARCHIVE_7Z:
				info_->paramSFOLoaded = true;
				{
					ReadVFSToString("7z.png", &info_->iconTextureData, &info_->lock);
					info_->iconDataLoaded = true;
				}
				break;

			case FILETYPE_NORMAL_DIRECTORY:
			default:
				info_->paramSFOLoaded = true;
				break;
		}

		info_->hasConfig = g_Config.hasGameConfig(info_->id);

		if (info_->wantFlags & GAMEINFO_WANTSIZE) {
			lock_guard lock(info_->lock);
			info_->gameSize = info_->GetGameSizeInBytes();
			info_->saveDataSize = info_->GetSaveDataSizeInBytes();
			info_->installDataSize = info_->GetInstallDataSizeInBytes();
		}
		info_->pending = false;
		info_->DisposeFileLoader();
	}
Exemple #13
0
	virtual void run() {
		getFileInfo(gamePath_.c_str(), &info_->fileInfo);
		if (!info_->fileInfo.exists)
			return;

		std::string filename = gamePath_;
		info_->fileType = Identify_File(filename);

		switch (info_->fileType) {
		case FILETYPE_PSP_PBP:
		case FILETYPE_PSP_PBP_DIRECTORY:
			{
				std::string pbpFile = filename;
				if (info_->fileType == FILETYPE_PSP_PBP_DIRECTORY)
					pbpFile += "/EBOOT.PBP";

				PBPReader pbp(pbpFile.c_str());
				if (!pbp.IsValid())
					return;

				// First, PARAM.SFO.
				size_t sfoSize;
				u8 *sfoData = pbp.GetSubFile(PBP_PARAM_SFO, &sfoSize);
				{
					lock_guard lock(info_->lock);
					info_->paramSFO.ReadSFO(sfoData, sfoSize);
					info_->title = info_->paramSFO.GetValueString("TITLE");
					info_->id = info_->paramSFO.GetValueString("DISC_ID");
					info_->id_version = info_->paramSFO.GetValueString("DISC_ID") + "_" + info_->paramSFO.GetValueString("DISC_VERSION");

					info_->paramSFOLoaded = true;
				}
				delete [] sfoData;

				// Then, ICON0.PNG.
				{
					lock_guard lock(info_->lock);
					if (pbp.GetSubFileSize(PBP_ICON0_PNG) > 0) {
						pbp.GetSubFileAsString(PBP_ICON0_PNG, &info_->iconTextureData);
					} else {
						// Read standard icon
						size_t sz;
						INFO_LOG(HLE, "Loading unknown.png because a PBP was missing an icon");
						uint8_t *contents = VFSReadFile("unknown.png", &sz);
						if (contents) {
							lock_guard lock(info_->lock);
							info_->iconTextureData = std::string((const char *)contents, sz);
						}
						delete [] contents;
					}
				}

				if (info_->wantBG) {
					if (pbp.GetSubFileSize(PBP_PIC1_PNG) > 0) {
						lock_guard lock(info_->lock);
						pbp.GetSubFileAsString(PBP_PIC1_PNG, &info_->pic1TextureData);
					}
				}
			}

			break;

		case FILETYPE_PSP_ELF:
			// An elf on its own has no usable information, no icons, no nothing.
			info_->title = getFilename(filename);
			info_->id = "ELF000000";
			info_->id_version = "ELF000000_1.00";
			info_->paramSFOLoaded = true;

			{
				// Read standard icon
				size_t sz;
				uint8_t *contents = VFSReadFile("unknown.png", &sz);
				INFO_LOG(HLE, "Loading unknown.png because there was an ELF");
				if (contents) {
					lock_guard lock(info_->lock);
					info_->iconTextureData = std::string((const char *)contents, sz);
				}
				delete [] contents;
			}

			break;

		case FILETYPE_PSP_DISC_DIRECTORY:
			{
				info_->fileType = FILETYPE_PSP_ISO;
				SequentialHandleAllocator handles;
				VirtualDiscFileSystem umd(&handles,gamePath_.c_str());
				
				// Alright, let's fetch the PARAM.SFO.
				std::string paramSFOcontents;
				if (ReadFileToString(&umd, "/PSP_GAME/PARAM.SFO", &paramSFOcontents, 0)) {
					lock_guard lock(info_->lock);
					info_->paramSFO.ReadSFO((const u8 *)paramSFOcontents.data(), paramSFOcontents.size());
					info_->title = info_->paramSFO.GetValueString("TITLE");
					info_->id = info_->paramSFO.GetValueString("DISC_ID");
					info_->id_version = info_->paramSFO.GetValueString("DISC_ID") + "_" + info_->paramSFO.GetValueString("DISC_VERSION");

					info_->paramSFOLoaded = true;
				}

				ReadFileToString(&umd, "/PSP_GAME/ICON0.PNG", &info_->iconTextureData, &info_->lock);
				if (info_->wantBG) {
					ReadFileToString(&umd, "/PSP_GAME/PIC0.PNG", &info_->pic0TextureData, &info_->lock);
				}
				ReadFileToString(&umd, "/PSP_GAME/PIC1.PNG", &info_->pic1TextureData, &info_->lock);
				break;
			}
		case FILETYPE_PSP_ISO:
		case FILETYPE_PSP_ISO_NP:
			{
				info_->fileType = FILETYPE_PSP_ISO;
				SequentialHandleAllocator handles;
				// Let's assume it's an ISO.
				// TODO: This will currently read in the whole directory tree. Not really necessary for just a
				// few files.
				BlockDevice *bd = constructBlockDevice(gamePath_.c_str());
				if (!bd)
					return;  // nothing to do here..
				ISOFileSystem umd(&handles, bd, "/PSP_GAME");

				// Alright, let's fetch the PARAM.SFO.
				std::string paramSFOcontents;
				if (ReadFileToString(&umd, "/PSP_GAME/PARAM.SFO", &paramSFOcontents, 0)) {
					lock_guard lock(info_->lock);
					info_->paramSFO.ReadSFO((const u8 *)paramSFOcontents.data(), paramSFOcontents.size());
					info_->title = info_->paramSFO.GetValueString("TITLE");
					info_->id = info_->paramSFO.GetValueString("DISC_ID");
					info_->id_version = info_->paramSFO.GetValueString("DISC_ID") + "_" + info_->paramSFO.GetValueString("DISC_VERSION");

					info_->paramSFOLoaded = true;
				} else {
					// Fall back to the filename for title if ISO is broken
					info_->title = gamePath_;
				}

				ReadFileToString(&umd, "/PSP_GAME/ICON0.PNG", &info_->iconTextureData, &info_->lock);
				if (info_->wantBG) {
					ReadFileToString(&umd, "/PSP_GAME/PIC0.PNG", &info_->pic0TextureData, &info_->lock);
				}
				ReadFileToString(&umd, "/PSP_GAME/PIC1.PNG", &info_->pic1TextureData, &info_->lock);
				break;
			}
		
			case FILETYPE_NORMAL_DIRECTORY:
				info_->title = gamePath_;
				break;

			default:
			{
				std::string fn, ext;
				SplitPath(gamePath_, 0, &fn, &ext);
				info_->title = fn + "." + ext;
			}
			break;
		}
		// probably only want these when we ask for the background image...
		// should maybe flip the flag to "onlyIcon"
		if (info_->wantBG) {
			info_->gameSize = info_->GetGameSizeInBytes();
			info_->saveDataSize = info_->GetSaveDataSizeInBytes();
		}
	}