u32 VFSFileSystem::OpenFile(std::string filename, FileAccess access, const char *devicename) {
	if (access != FILEACCESS_READ) {
		ERROR_LOG(FILESYS, "VFSFileSystem only supports plain reading");
		return 0;
	}

	std::string fullName = GetLocalPath(filename);
	const char *fullNameC = fullName.c_str();
	DEBUG_LOG(FILESYS,"VFSFileSystem actually opening %s (%s)", fullNameC, filename.c_str());

	size_t size;
	u8 *data = VFSReadFile(fullNameC, &size);
	if (!data) {
		ERROR_LOG(FILESYS, "VFSFileSystem failed to open %s", filename.c_str());
		return 0;
	}

	OpenFileEntry entry;
	entry.fileData = data;
	entry.size = size;
	entry.seekPos = 0;
	u32 newHandle = hAlloc->GetNewHandle();
	entries[newHandle] = entry;
	return newHandle;
}
Beispiel #2
0
ChunkFile::ChunkFile(const char *filename, bool _read) {
	data=0;
	fn = filename;
	fastMode=false;
	numLevels=0;
	read=_read;
	pos=0;
	didFail=false;

	fastMode = read ? true : false;

	if (fastMode) {
		size_t size;
		data = (uint8_t *)VFSReadFile(filename, &size);
		if (!data) {
			ELOG("Chunkfile fail: %s", filename);
			didFail = true;
			return;
		}
		eof = (int)size;
		return;
	}

	if (file.open(filename, FILE_WRITE)) {
		didFail=false;
		eof=file.fileSize();
	}	else {
		didFail=true;
		return;
	}
}
Beispiel #3
0
bool IniFile::LoadFromVFS(const std::string &filename) {
	size_t size;
	uint8_t *data = VFSReadFile(filename.c_str(), &size);
	if (!data)
		return false;
	std::string str((const char*)data, size);
	delete [] data;

	std::stringstream sstream(str);
	return Load(sstream);
}
Beispiel #4
0
int LoadZIM(const char *filename, int *width, int *height, int *format, uint8_t **image) {
	size_t size;
	uint8_t *buffer = VFSReadFile(filename, &size);
	if (!buffer) {
		return 0;
	}
	int retval = LoadZIMPtr(buffer, (int)size, width, height, format, image);
	if (!retval) {
		ELOG("Not a valid ZIM file: %s", filename);
	}
	delete [] buffer;
	return retval;
}
Beispiel #5
0
bool Thin3DTexture::LoadFromFile(const std::string &filename, T3DImageType type) {
	filename_ = "";
	size_t fileSize;
	uint8_t *buffer = VFSReadFile(filename.c_str(), &fileSize);
	if (!buffer) {
		return false;
	}
	bool retval = LoadFromFileData(buffer, fileSize, type);
	if (retval) {
		filename_ = filename;
	}
	delete[] buffer;
	return retval;
}
Beispiel #6
0
static bool ReadVFSToString(const char *filename, std::string *contents, recursive_mutex *mtx) {
	size_t sz;
	uint8_t *data = VFSReadFile(filename, &sz);
	if (data) {
		if (mtx) {
			lock_guard lock(*mtx);
			*contents = std::string((const char *)data, sz);
		} else {
			*contents = std::string((const char *)data, sz);
		}
	}
	delete [] data;
	return data != nullptr;
}
Beispiel #7
0
bool glsl_recompile(GLSLProgram *program, std::string *error_message) {
	struct stat vs, fs;
	AutoCharArrayBuf vsh_src, fsh_src;

	if (strlen(program->vshader_filename) > 0 && 0 == stat(program->vshader_filename, &vs)) {
		program->vshader_mtime = vs.st_mtime;
		if (!program->vshader_source) {
			size_t sz;
			vsh_src.reset((char *)ReadLocalFile(program->vshader_filename, &sz));
		}
	} else {
		program->vshader_mtime = 0;
	}

	if (strlen(program->fshader_filename) > 0 && 0 == stat(program->fshader_filename, &fs)) {
		program->fshader_mtime = fs.st_mtime;
		if (!program->fshader_source) {
			size_t sz;
			fsh_src.reset((char *)ReadLocalFile(program->fshader_filename, &sz));
		}
	} else {
		program->fshader_mtime = 0;
	}

	if (!program->vshader_source && !vsh_src) {
		size_t sz;
		vsh_src.reset((char *)VFSReadFile(program->vshader_filename, &sz));
	}
	if (!program->vshader_source && !vsh_src) {
		ELOG("File missing: %s", program->vshader_filename);
		if (error_message) {
			*error_message = std::string("File missing: ") + program->vshader_filename;
		}
		return false;
	}
	if (!program->fshader_source && !fsh_src) {
		size_t sz;
		fsh_src.reset((char *)VFSReadFile(program->fshader_filename, &sz));
	}
	if (!program->fshader_source && !fsh_src) {
		ELOG("File missing: %s", program->fshader_filename);
		if (error_message) {
			*error_message = std::string("File missing: ") + program->fshader_filename;
		}
		return false;
	}

	GLuint vsh = glCreateShader(GL_VERTEX_SHADER);
	const GLchar *vsh_str = program->vshader_source ? program->vshader_source : (const GLchar *)(vsh_src);
	if (!CompileShader(vsh_str, vsh, program->vshader_filename, error_message)) {
		return false;
	}

	const GLchar *fsh_str = program->fshader_source ? program->fshader_source : (const GLchar *)(fsh_src);
	GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER);
	if (!CompileShader(fsh_str, fsh, program->fshader_filename, error_message)) {
		glDeleteShader(vsh);
		return false;
	}

	GLuint prog = glCreateProgram();
	glAttachShader(prog, vsh);
	glAttachShader(prog, fsh);

	glLinkProgram(prog);

	GLint linkStatus;
	glGetProgramiv(prog, GL_LINK_STATUS, &linkStatus);
	if (linkStatus == GL_FALSE) {
		GLint bufLength = 0;
		glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &bufLength);
		if (bufLength) {
			char* buf = new char[bufLength + 1];  // safety
			glGetProgramInfoLog(prog, bufLength, NULL, buf);
			ILOG("vsh: %i   fsh: %i", vsh, fsh);
			ELOG("Could not link shader program (linkstatus=%i):\n %s  \n", linkStatus, buf);
			if (error_message) {
				*error_message = buf;
			}
			delete [] buf;
		} else {
			ILOG("vsh: %i   fsh: %i", vsh, fsh);
			ELOG("Could not link shader program (linkstatus=%i). No OpenGL error log was available.", linkStatus);
			if (error_message) {
				*error_message = "(no error message available)";
			}
		}
		glDeleteShader(vsh);
		glDeleteShader(fsh);
		return false;
	}

	// Destroy the old program, if any.
	if (program->program_) {
		glDeleteProgram(program->program_);
	}

	program->program_ = prog;
	program->vsh_ = vsh;
	program->fsh_ = fsh;

	program->sampler0 = glGetUniformLocation(program->program_, "sampler0");
	program->sampler1 = glGetUniformLocation(program->program_, "sampler1");

	program->a_position	= glGetAttribLocation(program->program_, "a_position");
	program->a_color		 = glGetAttribLocation(program->program_, "a_color");
	program->a_normal		= glGetAttribLocation(program->program_, "a_normal");
	program->a_texcoord0 = glGetAttribLocation(program->program_, "a_texcoord0");
	program->a_texcoord1 = glGetAttribLocation(program->program_, "a_texcoord1");

	program->u_worldviewproj = glGetUniformLocation(program->program_, "u_worldviewproj");
	program->u_world = glGetUniformLocation(program->program_, "u_world");
	program->u_viewproj = glGetUniformLocation(program->program_, "u_viewproj");
	program->u_fog = glGetUniformLocation(program->program_, "u_fog");
	program->u_sundir = glGetUniformLocation(program->program_, "u_sundir");
	program->u_camerapos = glGetUniformLocation(program->program_, "u_camerapos");

	//ILOG("Shader compilation success: %s %s",
	//		 program->vshader_filename,
	//		 program->fshader_filename);
	return true;
}
Beispiel #8
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();
		}
	}
Beispiel #9
0
bool glsl_recompile(GLSLProgram *program) {
	struct stat vs, fs;
	if (0 == stat(program->vshader_filename, &vs))
		program->vshader_mtime = vs.st_mtime;
	else
		program->vshader_mtime = 0;

	if (0 == stat(program->fshader_filename, &fs))
		program->fshader_mtime = fs.st_mtime;
	else
		program->fshader_mtime = 0;
	
	char *vsh_src = 0, *fsh_src = 0;

	if (!program->vshader_source) 
	{
		size_t sz;
		vsh_src = (char *)VFSReadFile(program->vshader_filename, &sz);
		if (!vsh_src) {
			ELOG("File missing: %s", program->vshader_filename);
			return false;
		}
	}
	if (!program->fshader_source)
	{
		size_t sz;
		fsh_src = (char *)VFSReadFile(program->fshader_filename, &sz);
		if (!fsh_src) {
			ELOG("File missing: %s", program->fshader_filename);
			delete [] vsh_src;
			return false;
		}
	}

	GLuint vsh = glCreateShader(GL_VERTEX_SHADER);
	const GLchar *vsh_str = program->vshader_source ? program->vshader_source : (const GLchar *)(vsh_src);
	if (!CompileShader(vsh_str, vsh, program->vshader_filename)) {
		return false;
	}
	delete [] vsh_src;

	const GLchar *fsh_str = program->fshader_source ? program->fshader_source : (const GLchar *)(fsh_src);
	GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER);
	if (!CompileShader(fsh_str, fsh, program->fshader_filename)) {
		glDeleteShader(vsh);
		return false;
	}
	delete [] fsh_src;

	GLuint prog = glCreateProgram();
	glAttachShader(prog, vsh);
	glAttachShader(prog, fsh);

	glLinkProgram(prog);

	GLint linkStatus;
	glGetProgramiv(prog, GL_LINK_STATUS, &linkStatus);
	if (linkStatus != GL_TRUE) {
		GLint bufLength = 0;
		glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &bufLength);
		if (bufLength) {
			char* buf = new char[bufLength];
			glGetProgramInfoLog(prog, bufLength, NULL, buf);
			FLOG("Could not link program:\n %s", buf);
			delete [] buf;	// we're dead!
		} else {
			FLOG("Could not link program.");
		}
		glDeleteShader(vsh);
		glDeleteShader(fsh);
		return false;
	}

	// Destroy the old program, if any.
	if (program->program_) {
		glDeleteProgram(program->program_);
	}

	program->program_ = prog;
	program->vsh_ = vsh;
	program->fsh_ = vsh;

	program->sampler0 = glGetUniformLocation(program->program_, "sampler0");
	program->sampler1 = glGetUniformLocation(program->program_, "sampler1");

	program->a_position	= glGetAttribLocation(program->program_, "a_position");
	program->a_color		 = glGetAttribLocation(program->program_, "a_color");
	program->a_normal		= glGetAttribLocation(program->program_, "a_normal");
	program->a_texcoord0 = glGetAttribLocation(program->program_, "a_texcoord0");
	program->a_texcoord1 = glGetAttribLocation(program->program_, "a_texcoord1");

	program->u_worldviewproj = glGetUniformLocation(program->program_, "u_worldviewproj");
	program->u_world = glGetUniformLocation(program->program_, "u_world");
	program->u_viewproj = glGetUniformLocation(program->program_, "u_viewproj");
	program->u_fog = glGetUniformLocation(program->program_, "u_fog");
	program->u_sundir = glGetUniformLocation(program->program_, "u_sundir");
	program->u_camerapos = glGetUniformLocation(program->program_, "u_camerapos");

	//ILOG("Shader compilation success: %s %s",
	//		 program->vshader_filename,
	//		 program->fshader_filename);
	return true;
}
Beispiel #10
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();
		}
	}
void FramebufferManagerGLES::CompilePostShader() {
	SetNumExtraFBOs(0);
	const ShaderInfo *shaderInfo = 0;
	if (g_Config.sPostShaderName != "Off") {
		ReloadAllPostShaderInfo();
		shaderInfo = GetPostShaderInfo(g_Config.sPostShaderName);
	}

	if (shaderInfo) {
		std::string errorString;
		postShaderAtOutputResolution_ = shaderInfo->outputResolution;

		size_t sz;
		char *vs = (char *)VFSReadFile(shaderInfo->vertexShaderFile.c_str(), &sz);
		if (!vs)
			return;
		char *fs = (char *)VFSReadFile(shaderInfo->fragmentShaderFile.c_str(), &sz);
		if (!fs) {
			free(vs);
			return;
		}

		std::string vshader;
		std::string fshader;
		bool translationFailed = false;
		if (gl_extensions.IsCoreContext) {
			// Gonna have to upconvert the shaders.
			if (!TranslateShader(&vshader, GLSL_300, nullptr, vs, GLSL_140, Draw::ShaderStage::VERTEX, &errorString)) {
				translationFailed = true;
				ELOG("Failed to translate post-vshader: %s", errorString.c_str());
			}
			if (!TranslateShader(&fshader, GLSL_300, nullptr, fs, GLSL_140, Draw::ShaderStage::FRAGMENT, &errorString)) {
				translationFailed = true;
				ELOG("Failed to translate post-fshader: %s", errorString.c_str());
			}
		} else {
			vshader = vs;
			fshader = fs;
		}

		if (!translationFailed) {
			SetNumExtraFBOs(1);

			std::vector<GLRShader *> shaders;
			shaders.push_back(render_->CreateShader(GL_VERTEX_SHADER, vshader, "postshader"));
			shaders.push_back(render_->CreateShader(GL_FRAGMENT_SHADER, fshader, "postshader"));
			std::vector<GLRProgram::UniformLocQuery> queries;
			queries.push_back({ &u_postShaderTex, "tex" });
			queries.push_back({ &deltaLoc_, "u_texelDelta" });
			queries.push_back({ &pixelDeltaLoc_, "u_pixelDelta" });
			queries.push_back({ &timeLoc_, "u_time" });
			queries.push_back({ &videoLoc_, "u_video" });

			std::vector<GLRProgram::Initializer> inits;
			inits.push_back({ &u_postShaderTex, 0, 0 });
			std::vector<GLRProgram::Semantic> semantics;
			semantics.push_back({ 0, "a_position" });
			semantics.push_back({ 1, "a_texcoord0" });
			postShaderProgram_ = render_->CreateProgram(shaders, semantics, queries, inits, false);
			postShaderModules_ = shaders;
		} else {
			ERROR_LOG(FRAMEBUF, "Failed to translate post shader!");
		}
		free(vs);
		free(fs);

		if (!postShaderProgram_) {
			// DO NOT turn this into a report, as it will pollute our logs with all kinds of
			// user shader experiments.
			ERROR_LOG(FRAMEBUF, "Failed to build post-processing program from %s and %s!\n%s", shaderInfo->vertexShaderFile.c_str(), shaderInfo->fragmentShaderFile.c_str(), errorString.c_str());
			ShowPostShaderError(errorString);
			usePostShader_ = false;
		} else {
			usePostShader_ = true;
		}
	} else {
		postShaderProgram_ = nullptr;
		usePostShader_ = false;
	}
}