mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-24 16:49:50 +00:00
Merge pull request #8314 from unknownbrackets/remaster
Identify remasters based on UMD_DATA hash
This commit is contained in:
commit
290958060f
@ -15,7 +15,20 @@
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include "HDRemaster.h"
|
||||
#include "base/basictypes.h"
|
||||
#include "Core/HDRemaster.h"
|
||||
|
||||
bool g_RemasterMode;
|
||||
bool g_DoubleTextureCoordinates;
|
||||
|
||||
// TODO: Do all of the remasters aside from Monster Hunter/Shin Sangoku use double texture coordinates?
|
||||
extern const struct HDRemaster g_HDRemasters[] = {
|
||||
{ "NPJB40001", 0x04000000, false }, // MONSTER HUNTER PORTABLE 3rd HD Ver.
|
||||
{ "NPJB40002", 0x04000000, true }, // K-ON Houkago Live HD Ver
|
||||
{ "NPJB40003", 0x04000000, false }, // Shin Sangoku Musou Multi Raid 2 HD Ver
|
||||
{ "ULJM05170", 0x04000000, true, "ULJM-05170|55C069C631B22685|0001|G" }, // Eiyuu Densetsu Sora no Kiseki FC Kai HD Edition
|
||||
{ "ULJM05277", 0x04C00000, true, "ULJM-05277|0E8D71AFAA4F62D8|0001|G" }, // Eiyuu Densetsu: Sora no Kiseki SC Kai HD Edition
|
||||
{ "ULJM05353", 0x04C00000, true, "ULJM-05353|0061DA67EBD6B9C6|0001|G" }, // Eiyuu Densetsu: Sora no Kiseki 3rd Kai HD Edition
|
||||
};
|
||||
|
||||
const size_t g_HDRemastersCount = ARRAY_SIZE(g_HDRemasters);
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CommonTypes.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
|
||||
// This bool is the key to having the HD remasters work.
|
||||
// We keep it set to false by default in PSPLoaders.cpp
|
||||
@ -28,17 +28,10 @@ extern bool g_DoubleTextureCoordinates;
|
||||
|
||||
struct HDRemaster {
|
||||
const char *gameID;
|
||||
u32 MemorySize;
|
||||
bool DoubleTextureCoordinates;
|
||||
u32 memorySize;
|
||||
bool doubleTextureCoordinates;
|
||||
const char *umdDataValue;
|
||||
};
|
||||
|
||||
// TODO: Use UMD_DATA.bin to differentiate the Eiyuu games from the regular PSP editions.
|
||||
// TODO: Do all of the remasters aside from Monster Hunter/Shin Sangoku use double texture coordinates?
|
||||
const struct HDRemaster g_HDRemasters[] = {
|
||||
{ "NPJB40001", 0x04000000, false }, // MONSTER HUNTER PORTABLE 3rd HD Ver.
|
||||
{ "NPJB40002", 0x04000000, true }, // K-ON Houkago Live HD Ver
|
||||
{ "NPJB40003", 0x04000000, false }, // Shin Sangoku Musou Multi Raid 2 HD Ver
|
||||
// { "ULJM05170", 0x04000000, true }, // Eiyuu Densetsu Sora no Kiseki FC Kai HD Edition
|
||||
// { "ULJM05277", 0x04C00000, true }, // Eiyuu Densetsu: Sora no Kiseki SC Kai HD Edition, game needs 76 MB
|
||||
// { "ULJM05353", 0x04C00000, true }, // Eiyuu Densetsu: Sora no Kiseki 3rd Kai HD Edition, game needs 76 MB
|
||||
};
|
||||
extern const struct HDRemaster g_HDRemasters[];
|
||||
extern const size_t g_HDRemastersCount;
|
||||
|
@ -25,8 +25,10 @@
|
||||
#include "Core/Core.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/Debugger/Breakpoints.h"
|
||||
#include "Core/ELF/ParamSFO.h"
|
||||
#include "Core/MemMapHelpers.h"
|
||||
#include "Core/System.h"
|
||||
#include "Core/HDRemaster.h"
|
||||
#include "Core/Host.h"
|
||||
#include "Core/SaveState.h"
|
||||
#include "Core/HLE/HLE.h"
|
||||
@ -469,11 +471,12 @@ static void __IoAsyncEndCallback(SceUID threadID, SceUID prevCallbackId) {
|
||||
}
|
||||
}
|
||||
|
||||
static DirectoryFileSystem *memstickSystem = NULL;
|
||||
static DirectoryFileSystem *memstickSystem = nullptr;
|
||||
static DirectoryFileSystem *exdataSystem = nullptr;
|
||||
#if defined(USING_WIN_UI) || defined(APPLE)
|
||||
static DirectoryFileSystem *flash0System = NULL;
|
||||
static DirectoryFileSystem *flash0System = nullptr;
|
||||
#else
|
||||
static VFSFileSystem *flash0System = NULL;
|
||||
static VFSFileSystem *flash0System = nullptr;
|
||||
#endif
|
||||
|
||||
static void __IoManagerThread() {
|
||||
@ -506,6 +509,18 @@ void __IoInit() {
|
||||
pspFileSystem.Mount("fatms:", memstickSystem);
|
||||
pspFileSystem.Mount("pfat0:", memstickSystem);
|
||||
pspFileSystem.Mount("flash0:", flash0System);
|
||||
|
||||
if (g_RemasterMode) {
|
||||
const std::string gameId = g_paramSFO.GetValueString("DISC_ID");
|
||||
const std::string exdataPath = g_Config.memStickDirectory + "exdata/" + gameId + "/";
|
||||
if (File::Exists(exdataPath)) {
|
||||
exdataSystem = new DirectoryFileSystem(&pspFileSystem, exdataPath, FILESYSTEM_SIMULATE_FAT32);
|
||||
pspFileSystem.Mount("exdata0:", exdataSystem);
|
||||
INFO_LOG(SCEIO, "Mounted exdata/%s/ under memstick for exdata0:/", gameId.c_str());
|
||||
} else {
|
||||
INFO_LOG(SCEIO, "Did not find exdata/%s/ under memstick for exdata0:/", gameId.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
__KernelListenThreadEnd(&TellFsThreadEnded);
|
||||
|
||||
@ -558,10 +573,16 @@ void __IoShutdown() {
|
||||
pspFileSystem.Unmount("pfat0:", memstickSystem);
|
||||
pspFileSystem.Unmount("flash0:", flash0System);
|
||||
|
||||
if (g_RemasterMode && exdataSystem) {
|
||||
pspFileSystem.Unmount("exdata0:", exdataSystem);
|
||||
delete exdataSystem;
|
||||
exdataSystem = nullptr;
|
||||
}
|
||||
|
||||
delete memstickSystem;
|
||||
memstickSystem = NULL;
|
||||
memstickSystem = nullptr;
|
||||
delete flash0System;
|
||||
flash0System = NULL;
|
||||
flash0System = nullptr;
|
||||
|
||||
memStickCallbacks.clear();
|
||||
memStickFatCallbacks.clear();
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
|
||||
#include "base/stringutil.h"
|
||||
#include "file/file_util.h"
|
||||
#include "Common/FileUtil.h"
|
||||
|
||||
@ -191,19 +192,26 @@ IdentifiedFileType Identify_File(FileLoader *fileLoader) {
|
||||
return FILETYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
FileLoader *ResolveFileLoaderTarget(FileLoader *fileLoader) {
|
||||
IdentifiedFileType type = Identify_File(fileLoader);
|
||||
if (type == FILETYPE_PSP_PBP_DIRECTORY && !endsWith(fileLoader->Path(), "/EBOOT.PBP")) {
|
||||
std::string ebootFilename = fileLoader->Path() + "/EBOOT.PBP";
|
||||
|
||||
// Switch fileLoader to the actual EBOOT.
|
||||
delete fileLoader;
|
||||
fileLoader = ConstructFileLoader(ebootFilename);
|
||||
}
|
||||
return fileLoader;
|
||||
}
|
||||
|
||||
bool LoadFile(FileLoader **fileLoaderPtr, std::string *error_string) {
|
||||
FileLoader *&fileLoader = *fileLoaderPtr;
|
||||
// Note that this can modify filename!
|
||||
switch (Identify_File(fileLoader)) {
|
||||
case FILETYPE_PSP_PBP_DIRECTORY:
|
||||
{
|
||||
std::string filename = fileLoader->Path();
|
||||
std::string ebootFilename = filename + "/EBOOT.PBP";
|
||||
|
||||
// Switch fileLoader to the EBOOT.
|
||||
delete fileLoader;
|
||||
fileLoader = ConstructFileLoader(ebootFilename);
|
||||
|
||||
// TODO: Perhaps we should/can never get here now?
|
||||
fileLoader = ResolveFileLoaderTarget(fileLoader);
|
||||
if (fileLoader->Exists()) {
|
||||
INFO_LOG(LOADER, "File is a PBP in a directory!");
|
||||
IdentifiedFileType ebootType = Identify_File(fileLoader);
|
||||
@ -216,10 +224,14 @@ bool LoadFile(FileLoader **fileLoaderPtr, std::string *error_string) {
|
||||
*error_string = "PS1 EBOOTs are not supported by PPSSPP.";
|
||||
return false;
|
||||
}
|
||||
std::string path = filename;
|
||||
std::string path = fileLoader->Path();
|
||||
size_t pos = path.find("/PSP/GAME/");
|
||||
if (pos != std::string::npos)
|
||||
if (pos != std::string::npos) {
|
||||
if (path.rfind("/EBOOT.PBP") != std::string::npos) {
|
||||
path = path.substr(0, path.length() - strlen("/EBOOT.PBP"));
|
||||
}
|
||||
pspFileSystem.SetStartingDirectory("ms0:" + path.substr(pos));
|
||||
}
|
||||
return Load_PSP_ELF_PBP(fileLoader, error_string);
|
||||
} else {
|
||||
*error_string = "No EBOOT.PBP, misidentified game";
|
||||
|
@ -79,6 +79,8 @@ public:
|
||||
};
|
||||
|
||||
FileLoader *ConstructFileLoader(const std::string &filename);
|
||||
// Resolve to the target binary, ISO, or other file (e.g. from a directory.)
|
||||
FileLoader *ResolveFileLoaderTarget(FileLoader *fileLoader);
|
||||
|
||||
// This can modify the string, for example for stripping off the "/EBOOT.PBP"
|
||||
// for a FILETYPE_PSP_PBP_DIRECTORY.
|
||||
|
@ -98,6 +98,7 @@ void InitMemoryForGameISO(FileLoader *fileLoader) {
|
||||
//pspFileSystem.Mount("host0:", fileSystem);
|
||||
|
||||
std::string gameID;
|
||||
std::string umdData;
|
||||
|
||||
std::string sfoPath("disc0:/PSP_GAME/PARAM.SFO");
|
||||
PSPFileInfo fileInfo = pspFileSystem.GetFileInfo(sfoPath.c_str());
|
||||
@ -107,19 +108,28 @@ void InitMemoryForGameISO(FileLoader *fileLoader) {
|
||||
pspFileSystem.ReadEntireFile(sfoPath, paramsfo);
|
||||
if (g_paramSFO.ReadSFO(paramsfo)) {
|
||||
UseLargeMem(g_paramSFO.GetValueInt("MEMSIZE"));
|
||||
// TODO: Check the SFO for other parameters that might be useful for identifying?
|
||||
gameID = g_paramSFO.GetValueString("DISC_ID");
|
||||
}
|
||||
|
||||
std::vector<u8> umdDataBin;
|
||||
if (pspFileSystem.ReadEntireFile("disc0:/UMD_DATA.BIN", umdDataBin) >= 0) {
|
||||
umdData = std::string((const char *)&umdDataBin[0], umdDataBin.size());
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
for (size_t i = 0; i < g_HDRemastersCount; i++) {
|
||||
const auto &entry = g_HDRemasters[i];
|
||||
if (entry.gameID != gameID) {
|
||||
continue;
|
||||
}
|
||||
if (entry.umdDataValue && umdData.find(entry.umdDataValue) == umdData.npos) {
|
||||
continue;
|
||||
}
|
||||
|
||||
g_RemasterMode = true;
|
||||
Memory::g_MemorySize = entry.memorySize;
|
||||
g_DoubleTextureCoordinates = entry.doubleTextureCoordinates;
|
||||
break;
|
||||
}
|
||||
if (g_RemasterMode) {
|
||||
INFO_LOG(LOADER, "HDRemaster found, using increased memory");
|
||||
@ -264,15 +274,13 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string)
|
||||
path = ReplaceAll(path, "/", "\\");
|
||||
#endif
|
||||
|
||||
if (!PSP_CoreParameter().mountRoot.empty())
|
||||
{
|
||||
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))
|
||||
{
|
||||
if (!startsWith(pathNorm, rootNorm)) {
|
||||
*error_string = "Cannot boot ELF located outside mountRoot.";
|
||||
return false;
|
||||
}
|
||||
@ -281,6 +289,11 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string)
|
||||
file = filepath + "/" + file;
|
||||
path = rootNorm + "/";
|
||||
pspFileSystem.SetStartingDirectory(filepath);
|
||||
} else {
|
||||
size_t pos = path.find("/PSP/GAME/");
|
||||
if (pos != std::string::npos) {
|
||||
pspFileSystem.SetStartingDirectory("ms0:" + path.substr(pos));
|
||||
}
|
||||
}
|
||||
|
||||
DirectoryFileSystem *fs = new DirectoryFileSystem(&pspFileSystem, path);
|
||||
|
@ -184,7 +184,7 @@ void CPU_Init() {
|
||||
Memory::g_PSPModel = g_Config.iPSPModel;
|
||||
|
||||
std::string filename = coreParameter.fileToStart;
|
||||
loadedFile = ConstructFileLoader(filename);
|
||||
loadedFile = ResolveFileLoaderTarget(ConstructFileLoader(filename));
|
||||
#ifdef _M_X64
|
||||
if (g_Config.bCacheFullIsoInRam) {
|
||||
loadedFile = new RamCachingFileLoader(loadedFile);
|
||||
@ -206,17 +206,11 @@ void CPU_Init() {
|
||||
case FILETYPE_PSP_DISC_DIRECTORY:
|
||||
InitMemoryForGameISO(loadedFile);
|
||||
break;
|
||||
case FILETYPE_PSP_PBP_DIRECTORY: {
|
||||
// TODO: Can we get this lower into LoadFile?
|
||||
std::string ebootFilename = loadedFile->Path() + "/EBOOT.PBP";
|
||||
FileLoader *tempLoader = ConstructFileLoader(ebootFilename);
|
||||
InitMemoryForGamePBP(tempLoader);
|
||||
delete tempLoader;
|
||||
break;
|
||||
}
|
||||
case FILETYPE_PSP_PBP:
|
||||
InitMemoryForGamePBP(loadedFile);
|
||||
break;
|
||||
case FILETYPE_PSP_PBP_DIRECTORY:
|
||||
ERROR_LOG(LOADER, "PBP directory resolution failed.");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "util/text/utf8.h"
|
||||
|
||||
#include "Common/ChunkFile.h"
|
||||
#include "Core/HDRemaster.h"
|
||||
#include "Core/Host.h"
|
||||
#include "GPU/ge_constants.h"
|
||||
#include "GPU/GPUState.h"
|
||||
@ -44,6 +45,12 @@ struct PPGeVertex {
|
||||
float_le x, y, z;
|
||||
};
|
||||
|
||||
struct PPGeRemasterVertex {
|
||||
float_le u, v;
|
||||
u32_le color;
|
||||
float_le x, y, z;
|
||||
};
|
||||
|
||||
static PSPPointer<PspGeListArgs> listArgs;
|
||||
static u32 listArgsSize = sizeof(PspGeListArgs);
|
||||
static u32 savedContextPtr;
|
||||
@ -117,15 +124,23 @@ static void BeginVertexData() {
|
||||
vertexStart = dataWritePtr;
|
||||
}
|
||||
|
||||
static void Vertex(float x, float y, float u, float v, int tw, int th, u32 color = 0xFFFFFFFF)
|
||||
{
|
||||
PPGeVertex vtx;
|
||||
vtx.x = x - 0.5f; vtx.y = y - 0.5f; vtx.z = 0;
|
||||
vtx.u = u * tw - 0.5f; vtx.v = v * th - 0.5f;
|
||||
vtx.color = color;
|
||||
Memory::WriteStruct(dataWritePtr, &vtx);
|
||||
static void Vertex(float x, float y, float u, float v, int tw, int th, u32 color = 0xFFFFFFFF) {
|
||||
if (g_RemasterMode) {
|
||||
PPGeRemasterVertex vtx;
|
||||
vtx.x = x - 0.5f; vtx.y = y - 0.5f; vtx.z = 0;
|
||||
vtx.u = u * tw - 0.5f; vtx.v = v * th - 0.5f;
|
||||
vtx.color = color;
|
||||
Memory::WriteStruct(dataWritePtr, &vtx);
|
||||
dataWritePtr += sizeof(vtx);
|
||||
} else {
|
||||
PPGeVertex vtx;
|
||||
vtx.x = x - 0.5f; vtx.y = y - 0.5f; vtx.z = 0;
|
||||
vtx.u = u * tw - 0.5f; vtx.v = v * th - 0.5f;
|
||||
vtx.color = color;
|
||||
Memory::WriteStruct(dataWritePtr, &vtx);
|
||||
dataWritePtr += sizeof(vtx);
|
||||
}
|
||||
vertexCount++;
|
||||
dataWritePtr += sizeof(vtx);
|
||||
}
|
||||
|
||||
static void EndVertexDataAndDraw(int prim) {
|
||||
@ -298,7 +313,11 @@ void PPGeBegin()
|
||||
WriteCmd(GE_CMD_MAXZ, 0xFFFF);
|
||||
|
||||
// Through mode, so we don't have to bother with matrices
|
||||
WriteCmd(GE_CMD_VERTEXTYPE, GE_VTYPE_TC_16BIT | GE_VTYPE_COL_8888 | GE_VTYPE_POS_FLOAT | GE_VTYPE_THROUGH);
|
||||
if (g_RemasterMode) {
|
||||
WriteCmd(GE_CMD_VERTEXTYPE, GE_VTYPE_TC_FLOAT | GE_VTYPE_COL_8888 | GE_VTYPE_POS_FLOAT | GE_VTYPE_THROUGH);
|
||||
} else {
|
||||
WriteCmd(GE_CMD_VERTEXTYPE, GE_VTYPE_TC_16BIT | GE_VTYPE_COL_8888 | GE_VTYPE_POS_FLOAT | GE_VTYPE_THROUGH);
|
||||
}
|
||||
}
|
||||
|
||||
void PPGeEnd()
|
||||
|
Loading…
Reference in New Issue
Block a user