diff --git a/CMakeLists.txt b/CMakeLists.txt
index f02876b35c..d878580f4a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -737,6 +737,8 @@ add_library(${CoreLibName} ${CoreLinkType}
Core/CoreTiming.h
Core/CwCheat.cpp
Core/CwCheat.h
+ Core/HDRemaster.cpp
+ Core/HDRemaster.h
Core/Debugger/Breakpoints.cpp
Core/Debugger/Breakpoints.h
Core/Debugger/DebugInterface.h
diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj
index 4997efdf63..e2fb23c1b0 100644
--- a/Core/Core.vcxproj
+++ b/Core/Core.vcxproj
@@ -188,6 +188,7 @@
+
@@ -368,6 +369,7 @@
+
diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters
index 4cf70aa22e..bf8e25e7ca 100644
--- a/Core/Core.vcxproj.filters
+++ b/Core/Core.vcxproj.filters
@@ -436,6 +436,9 @@
HLE\Libraries
+
+ Core
+
@@ -807,6 +810,9 @@
HLE\Libraries
+
+ Core
+
diff --git a/Core/HDRemaster.cpp b/Core/HDRemaster.cpp
new file mode 100644
index 0000000000..88e2a13edb
--- /dev/null
+++ b/Core/HDRemaster.cpp
@@ -0,0 +1,21 @@
+// Copyright (c) 2012- PPSSPP Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0 or later versions.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official git repository and contact information can be found at
+// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
+
+#include "HDRemaster.h"
+
+bool g_RemasterMode;
+bool g_DoubleTextureCoordinates;
diff --git a/Core/HDRemaster.h b/Core/HDRemaster.h
new file mode 100644
index 0000000000..e6b6b4cadb
--- /dev/null
+++ b/Core/HDRemaster.h
@@ -0,0 +1,50 @@
+// Copyright (c) 2012- PPSSPP Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0 or later versions.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official git repository and contact information can be found at
+// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
+
+#pragma once
+
+#include
+#include "CommonTypes.h"
+
+// This bool is the key to having the HD remasters work.
+// We keep it set to false by default in PSPLoaders.cpp
+// in order to keep the 99% of other PSP games working happily.
+extern bool g_RemasterMode;
+extern bool g_DoubleTextureCoordinates;
+
+struct HDRemaster {
+ std::string gameID;
+ u64 MemorySize;
+ u64 MemoryEnd; //Seems to be different for each game as well
+ bool DoubleTextureCoordinates;
+};
+
+// TODO: Are those BLJM* IDs really valid? They seem to be the physical PS3 disk IDs,
+// but they're included for safety.
+// TODO: Do all of the remasters aside from Monster Hunter use double texture coordinates?
+// TODO: Are all remasters happy with this end address?
+const struct HDRemaster g_HDRemasters[] = {
+ { "NPJB40001", 0x4000000, 0x0BBFFFFF, false }, // MONSTER HUNTER PORTABLE 3rd HD Ver.
+ { "BLJM85002", 0x4000000, 0x0BBFFFFF, true }, // K-ON Houkago Live HD Ver
+ { "NPJB40002", 0x4000000, 0x0BBFFFFF, true }, // K-ON Houkago Live HD Ver
+ { "BLJM85003", 0x4000000, 0x0BBFFFFF, true }, // Shin Sangoku Musou Multi Raid 2 HD Ver
+ { "NPJB40003", 0x4000000, 0x0BBFFFFF, true }, // Shin Sangoku Musou Multi Raid 2 HD Ver
+ { "BLJM85004", 0x4000000, 0x0BBFFFFF, true }, // Eiyuu Densetsu Sora no Kiseki FC Kai HD Edition
+ { "NPJB40004", 0x4000000, 0x0BBFFFFF, true }, // Eiyuu Densetsu Sora no Kiseki FC Kai HD Edition
+ { "BLJM85005", 0x4000000, 0x0BBFFFFF, true }, // Eiyuu Densetsu: Sora no Kiseki SC Kai HD Edition
+ { "NPJB40005", 0x4000000, 0x0BBFFFFF, true }, // Eiyuu Densetsu: Sora no Kiseki SC Kai HD Edition
+};
diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp
index 0879b20bcf..82e2f85f14 100644
--- a/Core/MemMap.cpp
+++ b/Core/MemMap.cpp
@@ -55,17 +55,22 @@ u8 *m_pKernelRAM; // RAM mirrored up to "kernel space". Fully accessible at all
u8 *m_pPhysicalVRAM;
u8 *m_pUncachedVRAM;
+// Holds the ending address of the PSP's user space.
+// Required for HD Remasters to work properly.
+u32 g_MemoryEnd;
+u32 g_MemoryMask;
+u32 g_MemorySize;
// We don't declare the IO region in here since its handled by other means.
-static const MemoryView views[] =
+static MemoryView views[] =
{
{&m_pScratchPad, &m_pPhysicalScratchPad, 0x00010000, SCRATCHPAD_SIZE, 0},
{NULL, &m_pUncachedScratchPad, 0x40010000, SCRATCHPAD_SIZE, MV_MIRROR_PREVIOUS},
{&m_pVRAM, &m_pPhysicalVRAM, 0x04000000, 0x00800000, 0},
{NULL, &m_pUncachedVRAM, 0x44000000, 0x00800000, MV_MIRROR_PREVIOUS},
- {&m_pRAM, &m_pPhysicalRAM, 0x08000000, RAM_SIZE, 0}, // only from 0x08800000 is it usable (last 24 megs)
- {NULL, &m_pUncachedRAM, 0x48000000, RAM_SIZE, MV_MIRROR_PREVIOUS},
- {NULL, &m_pKernelRAM, 0x88000000, RAM_SIZE, MV_MIRROR_PREVIOUS},
+ {&m_pRAM, &m_pPhysicalRAM, 0x08000000, g_MemorySize, 0}, // only from 0x08800000 is it usable (last 24 megs)
+ {NULL, &m_pUncachedRAM, 0x48000000, g_MemorySize, MV_MIRROR_PREVIOUS},
+ {NULL, &m_pKernelRAM, 0x88000000, g_MemorySize, MV_MIRROR_PREVIOUS},
// TODO: There are a few swizzled mirrors of VRAM, not sure about the best way to
// implement those.
@@ -76,6 +81,12 @@ static const int num_views = sizeof(views) / sizeof(MemoryView);
void Init()
{
int flags = 0;
+ Memory::g_MemoryMask = Memory::g_MemorySize - 1;
+
+ for(int i = 0; i < ARRAY_SIZE(views); i++) {
+ if(views[i].size == 0)
+ views[i].size = g_MemorySize;
+ }
base = MemoryMap_Setup(views, num_views, flags, &g_arena);
INFO_LOG(MEMMAP, "Memory system initialized. RAM at %p (mirror at 0 @ %p, uncached @ %p)",
@@ -84,12 +95,20 @@ void Init()
void DoState(PointerWrap &p)
{
- p.DoArray(m_pRAM, RAM_SIZE);
+ p.DoArray(m_pRAM, g_MemorySize);
p.DoMarker("RAM");
p.DoArray(m_pVRAM, VRAM_SIZE);
p.DoMarker("VRAM");
p.DoArray(m_pScratchPad, SCRATCHPAD_SIZE);
p.DoMarker("ScratchPad");
+ p.Do(g_RemasterMode);
+ p.DoMarker("RemasterMode");
+ p.Do(g_MemoryEnd);
+ p.DoMarker("MemoryEnd");
+ p.Do(g_MemoryMask);
+ p.DoMarker("MemoryMask");
+ p.Do(g_DoubleTextureCoordinates); // TODO: Is there a more appropriate place for this?
+ p.DoMarker("DoubleTextureCoordinates");
}
void Shutdown()
@@ -104,7 +123,7 @@ void Shutdown()
void Clear()
{
if (m_pRAM)
- memset(m_pRAM, 0, RAM_SIZE);
+ memset(m_pRAM, 0, g_MemorySize);
if (m_pScratchPad)
memset(m_pScratchPad, 0, SCRATCHPAD_SIZE);
if (m_pVRAM)
diff --git a/Core/MemMap.h b/Core/MemMap.h
index 016c95e51b..fb35e30df2 100644
--- a/Core/MemMap.h
+++ b/Core/MemMap.h
@@ -23,6 +23,8 @@
#include "Common.h"
#include "CommonTypes.h"
+#include "HDRemaster.h"
+
// Enable memory checks in the Debug/DebugFast builds, but NOT in release
#if defined(_DEBUG) || defined(DEBUGFAST)
#define ENABLE_MEM_CHECK
@@ -55,22 +57,6 @@ typedef void (*readFn16)(u16&, const u32);
typedef void (*readFn32)(u32&, const u32);
typedef void (*readFn64)(u64&, const u32);
-inline u32 PSP_GetScratchpadMemoryBase() { return 0x00010000;}
-inline u32 PSP_GetScratchpadMemoryEnd() { return 0x00014000;}
-
-inline u32 PSP_GetKernelMemoryBase() { return 0x08000000;}
-inline u32 PSP_GetKernelMemoryEnd() { return 0x08400000;}
-// "Volatile" RAM is between 0x08400000 and 0x08800000, can be requested by the
-// game through sceKernelVolatileMemTryLock.
-
-inline u32 PSP_GetUserMemoryBase() { return 0x08800000;}
-inline u32 PSP_GetUserMemoryEnd() { return 0x0A000000;}
-
-inline u32 PSP_GetDefaultLoadAddress() { return 0x08804000;}
-//inline u32 PSP_GetDefaultLoadAddress() { return 0x0898dab0;}
-inline u32 PSP_GetVidMemBase() { return 0x04000000;}
-inline u32 PSP_GetVidMemEnd() { return 0x04800000;}
-
namespace Memory
{
// Base is a pointer to the base of the memory map. Yes, some MMU tricks
@@ -97,12 +83,12 @@ extern u8 *m_pUncachedRAM;
extern u8 *m_pPhysicalVRAM;
extern u8 *m_pUncachedVRAM;
-// TODO: Later PSP models got more RAM.
+extern u32 g_MemoryEnd; // End of PSP Userspace
+extern u32 g_MemorySize; // Replaces RAM_SIZE
+extern u32 g_MemoryMask; // Replaces RAM_MASK
+
enum
{
- RAM_SIZE = 0x2000000, // 32 MB - although only the upper 24 are available for the user.
- RAM_MASK = RAM_SIZE - 1,
-
VRAM_SIZE = 0x200000,
VRAM_MASK = VRAM_SIZE - 1,
@@ -355,6 +341,22 @@ struct PSPPointer
}
};
+inline u32 PSP_GetUserMemoryEnd() { return Memory::g_MemoryEnd;}
+inline u32 PSP_GetScratchpadMemoryBase() { return 0x00010000;}
+inline u32 PSP_GetScratchpadMemoryEnd() { return 0x00014000;}
+
+inline u32 PSP_GetKernelMemoryBase() { return 0x08000000;}
+inline u32 PSP_GetKernelMemoryEnd() { return 0x08400000;}
+// "Volatile" RAM is between 0x08400000 and 0x08800000, can be requested by the
+// game through sceKernelVolatileMemTryLock.
+
+inline u32 PSP_GetUserMemoryBase() { return 0x08800000;}
+
+inline u32 PSP_GetDefaultLoadAddress() { return 0x08804000;}
+//inline u32 PSP_GetDefaultLoadAddress() { return 0x0898dab0;}
+inline u32 PSP_GetVidMemBase() { return 0x04000000;}
+inline u32 PSP_GetVidMemEnd() { return 0x04800000;}
+
template
inline bool operator==(const PSPPointer &lhs, const PSPPointer &rhs)
{
diff --git a/Core/MemMapFunctions.cpp b/Core/MemMapFunctions.cpp
index 7858ce3bae..b5622af7da 100644
--- a/Core/MemMapFunctions.cpp
+++ b/Core/MemMapFunctions.cpp
@@ -41,20 +41,19 @@ namespace Memory
u8 *GetPointer(const u32 address)
{
- if ((address & 0x3E000000) == 0x08000000)
- {
- return m_pRAM + (address & RAM_MASK);
+ if ((address & 0x3E000000) == 0x08000000) {
+ return m_pRAM + (address & g_MemoryMask);
}
- else if ((address & 0x3F800000) == 0x04000000)
- {
+ else if ((address & 0x3F800000) == 0x04000000) {
return m_pVRAM + (address & VRAM_MASK);
}
- else if ((address & 0xBFFF0000) == 0x00010000)
- {
+ else if ((address & 0xBFFF0000) == 0x00010000) {
return m_pScratchPad + (address & SCRATCHPAD_MASK);
}
- else
- {
+ else if (g_RemasterMode && (address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize) {
+ return m_pRAM + (address & g_MemoryMask);
+ }
+ else {
ERROR_LOG(MEMMAP, "Unknown GetPointer %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]);
if (!g_Config.bIgnoreBadMemAccess) {
Core_EnableStepping(true);
@@ -72,19 +71,19 @@ inline void ReadFromHardware(T &var, const u32 address)
// Could just do a base-relative read, too.... TODO
- if ((address & 0x3E000000) == 0x08000000)
- {
- var = *((const T*)&m_pRAM[address & RAM_MASK]);
+ if ((address & 0x3E000000) == 0x08000000) {
+ var = *((const T*)&m_pRAM[address & g_MemoryMask]);
}
- else if ((address & 0x3F800000) == 0x04000000)
- {
+ else if ((address & 0x3F800000) == 0x04000000) {
var = *((const T*)&m_pVRAM[address & VRAM_MASK]);
}
- else if ((address & 0xBFFF0000) == 0x00010000)
- {
+ else if ((address & 0xBFFF0000) == 0x00010000) {
// Scratchpad
var = *((const T*)&m_pScratchPad[address & SCRATCHPAD_MASK]);
}
+ else if (g_RemasterMode && (address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize) {
+ var = *((const T*)&m_pRAM[address & g_MemoryMask]);
+ }
else
{
if (g_Config.bJit) {
@@ -105,18 +104,18 @@ inline void WriteToHardware(u32 address, const T data)
{
// Could just do a base-relative write, too.... TODO
- if ((address & 0x3E000000) == 0x08000000)
- {
- *(T*)&m_pRAM[address & RAM_MASK] = data;
+ if ((address & 0x3E000000) == 0x08000000) {
+ *(T*)&m_pRAM[address & g_MemoryMask] = data;
}
- else if ((address & 0x3F800000) == 0x04000000)
- {
+ else if ((address & 0x3F800000) == 0x04000000) {
*(T*)&m_pVRAM[address & VRAM_MASK] = data;
}
- else if ((address & 0xBFFF0000) == 0x00010000)
- {
+ else if ((address & 0xBFFF0000) == 0x00010000) {
*(T*)&m_pScratchPad[address & SCRATCHPAD_MASK] = data;
}
+ else if (g_RemasterMode && (address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize) {
+ *(T*)&m_pRAM[address & g_MemoryMask] = data;
+ }
else
{
if (g_Config.bJit) {
@@ -135,16 +134,16 @@ inline void WriteToHardware(u32 address, const T data)
bool IsValidAddress(const u32 address)
{
- if ((address & 0x3E000000) == 0x08000000)
- {
+ if ((address & 0x3E000000) == 0x08000000) {
return true;
}
- else if ((address & 0x3F800000) == 0x04000000)
- {
+ else if ((address & 0x3F800000) == 0x04000000) {
return true;
}
- else if ((address & 0xBFFF0000) == 0x00010000)
- {
+ else if ((address & 0xBFFF0000) == 0x00010000) {
+ return true;
+ }
+ else if (g_RemasterMode && (address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize) {
return true;
}
else
diff --git a/Core/PSPLoaders.cpp b/Core/PSPLoaders.cpp
index 1f8a7703f4..3234ae6baf 100644
--- a/Core/PSPLoaders.cpp
+++ b/Core/PSPLoaders.cpp
@@ -40,9 +40,11 @@
#include "HLE/sceKernelMemory.h"
#include "ELF/ParamSFO.h"
-bool Load_PSP_ISO(const char *filename, std::string *error_string)
-{
- ISOFileSystem *umd2 = new ISOFileSystem(&pspFileSystem, constructBlockDevice(filename));
+// 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) {
+ ISOFileSystem *umd2 = new ISOFileSystem(&pspFileSystem, constructBlockDevice(fileToStart.c_str()));
// Parse PARAM.SFO
@@ -51,6 +53,40 @@ bool Load_PSP_ISO(const char *filename, std::string *error_string)
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(int i = 0; i < ARRAY_SIZE(g_HDRemasters); i++) {
+ if(g_HDRemasters[i].gameID == gameID) {
+ g_RemasterMode = true;
+ Memory::g_MemoryEnd = g_HDRemasters[i].MemoryEnd;
+ 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;
+ }
+}
+
+bool Load_PSP_ISO(const char *filename, std::string *error_string)
+{
+ // Mounting stuff relocated to InitMemoryForGameISO due to HD Remaster restructuring of code.
std::string sfoPath("disc0:/PSP_GAME/PARAM.SFO");
PSPFileInfo fileInfo = pspFileSystem.GetFileInfo(sfoPath.c_str());
diff --git a/Core/PSPLoaders.h b/Core/PSPLoaders.h
index 4de0f2cb3e..5ebf339520 100644
--- a/Core/PSPLoaders.h
+++ b/Core/PSPLoaders.h
@@ -23,3 +23,4 @@
bool Load_PSP_ISO(const char *filename, std::string *error_string);
bool Load_PSP_ELF_PBP(const char *filename, std::string *error_string);
+void InitMemoryForGameISO(std::string fileToStart);
diff --git a/Core/System.cpp b/Core/System.cpp
index d4d4e22d87..d1f094b932 100644
--- a/Core/System.cpp
+++ b/Core/System.cpp
@@ -44,6 +44,7 @@
#include "CoreParameter.h"
#include "FileSystems/MetaFileSystem.h"
#include "Loaders.h"
+#include "PSPLoaders.h"
#include "ELF/ParamSFO.h"
#include "../Common/LogManager.h"
@@ -72,6 +73,20 @@ bool PSP_Init(const CoreParameter &coreParam, std::string *error_string)
coreParameter = coreParam;
currentCPU = &mipsr4k;
numCPUs = 1;
+
+ // Default memory settings
+ // Seems to be the safest place currently..
+ Memory::g_MemoryEnd = 0x0A000000; // End of PSP User space memory
+ Memory::g_MemorySize = 0x2000000; // 32 MB of ram by default
+ g_RemasterMode = false;
+ g_DoubleTextureCoordinates = false;
+
+ std::string filename = coreParam.fileToStart;
+ EmuFileType type = Identify_File(filename);
+
+ if(type == FILETYPE_PSP_ISO || type == FILETYPE_PSP_ISO_NP)
+ InitMemoryForGameISO(filename);
+
Memory::Init();
mipsr4k.Reset();
mipsr4k.pc = 0;
@@ -96,7 +111,6 @@ bool PSP_Init(const CoreParameter &coreParam, std::string *error_string)
// TODO: Check Game INI here for settings, patches and cheats, and modify coreParameter accordingly
- std::string filename = coreParameter.fileToStart;
if (!LoadFile(filename, error_string) || coreState == CORE_POWERDOWN)
{
pspFileSystem.Shutdown();
diff --git a/GPU/GLES/VertexDecoder.cpp b/GPU/GLES/VertexDecoder.cpp
index a037b2570b..eb7ff4f589 100644
--- a/GPU/GLES/VertexDecoder.cpp
+++ b/GPU/GLES/VertexDecoder.cpp
@@ -156,6 +156,15 @@ void VertexDecoder::Step_TcU16() const
*uv = *uvdata;
}
+void VertexDecoder::Step_TcU16Double() const
+{
+ u16 *uv = (u16*)(decoded_ + decFmt.uvoff);
+ const u16 *uvdata = (const u16*)(ptr_ + tcoff);
+ *uv = *uvdata;
+ uv[0] = uvdata[0] * 2;
+ uv[1] = uvdata[1] * 2;
+}
+
void VertexDecoder::Step_TcU16Through() const
{
u16 *uv = (u16 *)(decoded_ + decFmt.uvoff);
@@ -164,6 +173,14 @@ void VertexDecoder::Step_TcU16Through() const
uv[1] = uvdata[1];
}
+void VertexDecoder::Step_TcU16ThroughDouble() const
+{
+ u16 *uv = (u16 *)(decoded_ + decFmt.uvoff);
+ const u16 *uvdata = (const u16*)(ptr_ + tcoff);
+ uv[0] = uvdata[0] * 2;
+ uv[1] = uvdata[1] * 2;
+}
+
void VertexDecoder::Step_TcFloat() const
{
float *uv = (float *)(decoded_ + decFmt.uvoff);
@@ -476,6 +493,21 @@ static const StepFunction tcstep_through[4] = {
&VertexDecoder::Step_TcFloatThrough,
};
+// Some HD Remaster games double the u16 texture coordinates.
+static const StepFunction tcstep_Remaster[4] = {
+ 0,
+ &VertexDecoder::Step_TcU8,
+ &VertexDecoder::Step_TcU16Double,
+ &VertexDecoder::Step_TcFloat,
+};
+
+static const StepFunction tcstep_through_Remaster[4] = {
+ 0,
+ &VertexDecoder::Step_TcU8,
+ &VertexDecoder::Step_TcU16ThroughDouble,
+ &VertexDecoder::Step_TcFloatThrough,
+};
+
// TODO: Tc Morph
static const StepFunction colstep[8] = {
@@ -589,7 +621,10 @@ void VertexDecoder::SetVertexType(u32 fmt) {
if (tcalign[tc] > biggest)
biggest = tcalign[tc];
- steps_[numSteps_++] = throughmode ? tcstep_through[tc] : tcstep[tc];
+ if(g_DoubleTextureCoordinates)
+ steps_[numSteps_++] = throughmode ? tcstep_through_Remaster[tc] : tcstep_Remaster[tc];
+ else
+ steps_[numSteps_++] = throughmode ? tcstep_through[tc] : tcstep[tc];
switch (tc) {
case GE_VTYPE_TC_8BIT >> GE_VTYPE_TC_SHIFT:
diff --git a/GPU/GLES/VertexDecoder.h b/GPU/GLES/VertexDecoder.h
index 309e4f3369..770797af73 100644
--- a/GPU/GLES/VertexDecoder.h
+++ b/GPU/GLES/VertexDecoder.h
@@ -116,8 +116,10 @@ public:
void Step_TcU8() const;
void Step_TcU16() const;
+ void Step_TcU16Double() const;
void Step_TcFloat() const;
void Step_TcU16Through() const;
+ void Step_TcU16ThroughDouble() const;
void Step_TcFloatThrough() const;
// TODO: tcmorph
diff --git a/Qt/Core.pro b/Qt/Core.pro
index a81eea68dc..c8c8d9cb63 100755
--- a/Qt/Core.pro
+++ b/Qt/Core.pro
@@ -37,6 +37,7 @@ SOURCES += ../Core/CPU.cpp \ # Core
../Core/Core.cpp \
../Core/CoreTiming.cpp \
../Core/CwCheat.cpp \
+ ../Core/HDRemaster.cpp \
../Core/Host.cpp \
../Core/Loaders.cpp \
../Core/MemMap.cpp \
@@ -71,6 +72,7 @@ HEADERS += ../Core/CPU.h \
../Core/CoreParameter.h \
../Core/CoreTiming.h \
../Core/CwCheat.h \
+ ../Core/HDRemaster.h \
../Core/Host.h \
../Core/Loaders.h \
../Core/MemMap.h \
diff --git a/android/jni/Android.mk b/android/jni/Android.mk
index ab1e76df51..143c6fc9c0 100644
--- a/android/jni/Android.mk
+++ b/android/jni/Android.mk
@@ -193,6 +193,7 @@ LOCAL_SRC_FILES := \
$(SRC)/Core/CoreTiming.cpp \
$(SRC)/Core/CPU.cpp \
$(SRC)/Core/CwCheat.cpp \
+ $(SRC)/Core/HDRemaster.cpp \
$(SRC)/Core/Host.cpp \
$(SRC)/Core/Loaders.cpp \
$(SRC)/Core/PSPLoaders.cpp \