aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md4
-rw-r--r--README.md11
-rw-r--r--main.c89
3 files changed, 94 insertions, 10 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 941439b..b942b32 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
### Changelog
+#### v1.1.0
+
+- Add 960x544 MSAA 4x mode
+
#### v1.0.1
- Fix black video when using the undub patch in 1920x1080 mode
diff --git a/README.md b/README.md
index f95852e..3bcf1a1 100644
--- a/README.md
+++ b/README.md
@@ -2,18 +2,18 @@
[Download binary](https://forum.devchroma.nl/index.php/topic,193.0.html) | [Report bugs](https://github.com/cuevavirus/hdpatch/issues) | [Source code](https://git.shotatoshounenwachigau.moe/vita/p4goldenhd/)
-This patch provides two rendering modes for Persona 4 Golden on the Vita and PSTV:
+This patch provides three rendering modes for Persona 4 Golden on the Vita and PSTV:
1. 1920x1080
2. 1280x720
+3. 960x544 MSAA 4x
Preview images (1920x1080): [1](https://git.shotatoshounenwachigau.moe/vita/p4goldenhd/plain/preview1.png?h=assets) [2](https://git.shotatoshounenwachigau.moe/vita/p4goldenhd/plain/preview2.png?h=assets) [3](https://git.shotatoshounenwachigau.moe/vita/p4goldenhd/plain/preview3.png?h=assets) [4](https://git.shotatoshounenwachigau.moe/vita/p4goldenhd/plain/preview4.png?h=assets)
## Installation
1. Install Persona 4 Golden and install the latest update, if available.
-2. Install [Sharpscale](https://forum.devchroma.nl/index.php/topic,112.0.html) and turn on "Unlock framebuffer size" in the configuration app.
-3. Install `p4goldenhd.suprx` under the appropriate title ID in your taiHEN config.
+2. Install `p4goldenhd.suprx` under the appropriate title ID in your taiHEN config.
- `PCSG00004` Japan
- `PCSG00563` Japan (reprint)
- `PCSE00120` North America
@@ -27,11 +27,13 @@ For example,
ur0:/tai/p4goldenhd.suprx
```
+If you are using the 1280x720 or 1920x1080 patch, install [Sharpscale](https://forum.devchroma.nl/index.php/topic,112.0.html) and turn on "Unlock framebuffer size" in the configuration app.
+
If you are using a Vita, you can use [udcd-uvc](https://github.com/xerpi/vita-udcd-uvc) to output 1280x720 by USB.
## Performance
-Overclocking is required for good performance. With 1920x1080, framerate ranges between 20-30 FPS, with 25-30 FPS in all but the most graphically intensive areas. With 1280x720, framerate is 30 FPS.
+Overclocking is required for good performance. For 1920x1080, framerate ranges between 20-30 FPS, with 25-30 FPS in all but the most graphically intensive areas. For 1280x720 and 960x544 MSAA 4x, the framerate is 30 FPS.
## Building
@@ -46,6 +48,7 @@ Define `PATCH_MODE` when building:
- `0` 1280x720
- `1` 1920x1080
+- `2` 960x544 MSAA 4x
## Contributing
diff --git a/main.c b/main.c
index aa41cb2..acdb1de 100644
--- a/main.c
+++ b/main.c
@@ -19,6 +19,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <stdbool.h>
#include <string.h>
#include <psp2/display.h>
+#include <psp2/gxm.h>
#include <psp2/kernel/clib.h>
#include <psp2/kernel/modulemgr.h>
#include <psp2/kernel/processmgr.h>
@@ -38,6 +39,7 @@ extern int font_sfn_len;
#define MODE_720 0
#define MODE_1080 1
+#define MODE_544 2
#if PATCH_MODE == MODE_720
#pragma message "Compiling 1280x720"
@@ -49,6 +51,11 @@ extern int font_sfn_len;
#define FB_PITCH 1920
#define FB_WIDTH 1920
#define FB_HEIGHT 1080
+#elif PATCH_MODE == MODE_544
+ #pragma message "Compiling 960x544 MSAA 4x"
+ #define FB_PITCH 1024
+ #define FB_WIDTH 960
+ #define FB_HEIGHT 544
#else
#pragma GCC error "Invalid PATCH_MODE"
#endif
@@ -82,7 +89,7 @@ static struct {
#define N_INJECT 8
static SceUID inject_id[N_INJECT];
-#define N_HOOK 5
+#define N_HOOK 8
static SceUID hook_id[N_HOOK];
static tai_hook_ref_t hook_ref[N_HOOK];
@@ -100,6 +107,18 @@ static SceUID hook_import(int idx, char *mod, int libnid, int funcnid, void *fun
#define HOOK_IMPORT(idx, mod, libnid, funcnid, func)\
hook_import(idx, mod, libnid, funcnid, func##_hook)
+#if PATCH_MODE == MODE_544
+
+static SceUID hook_offset(int idx, int mod, int ofs, void *func) {
+ hook_id[idx] = taiHookFunctionOffset(hook_ref+idx, mod, 0, ofs, 1, func);
+ LOG("Hooked %d UID %08X\n", idx, hook_id[idx]);
+ return hook_id[idx];
+}
+#define HOOK_OFFSET(idx, mod, ofs, func)\
+ hook_offset(idx, mod, ofs, func##_hook)
+
+#endif
+
static int UNINJECT(int idx) {
int ret = 0;
if (inject_id[idx] >= 0) {
@@ -133,6 +152,8 @@ static int sceDisplaySetFrameBuf_hook(SceDisplayFrameBuf *fb, int mode) {
fb->height = FB_HEIGHT;
fnblit_set_fb(fb->base, fb->pitch, fb->width, fb->height);
+
+#if PATCH_MODE != MODE_544
if (failed) {
fb->width = 960;
fb->height = 544;
@@ -141,18 +162,22 @@ static int sceDisplaySetFrameBuf_hook(SceDisplayFrameBuf *fb, int mode) {
} else if (sceKernelGetProcessTimeLow() - start_time < 15 * 1000 * 1000) {
fnblit_printf(0, 0, "Persona 4 Golden HD Patch success: %dx%d", FB_WIDTH, FB_HEIGHT);
}
+#else
+ if (sceKernelGetProcessTimeLow() - start_time < 15 * 1000 * 1000) {
+ fnblit_printf(0, 0, "Persona 4 Golden HD Patch success: 960x544 MSAA 4x");
+ }
+#endif
+
}
int ret = TAI_NEXT(sceDisplaySetFrameBuf_hook, hook_ref[0], fb, mode);
-
- if (!failed && fb && fb->base && fb->pitch == FB_PITCH
- && fb->width == FB_WIDTH && fb->height == FB_HEIGHT) {
- failed = ret < 0;
- }
+ failed = failed || ret < 0;
return ret;
}
+#if PATCH_MODE != MODE_544
+
static int sceGxmSetUniformDataF_hook(
void *uniformBuffer,
void *parameter,
@@ -177,6 +202,46 @@ static int sceGxmSetUniformDataF_hook(
uniformBuffer, parameter, componentOffset, componentCount, sourceData);
}
+#else
+
+static int color_surface_init_1_hook(void *color_surface_ctx,
+ int color_format, int width, int height, int msaa,
+ int pitch, int pitch2, int scenes_per_frame) {
+
+ if (width == FB_WIDTH && height == FB_HEIGHT) {
+ msaa = SCE_GXM_MULTISAMPLE_4X;
+ }
+
+ return TAI_NEXT(color_surface_init_1_hook, hook_ref[5], color_surface_ctx,
+ color_format, width, height, msaa,
+ pitch, pitch2, scenes_per_frame);
+}
+
+static int color_surface_init_2_hook(void *color_surface_ctx,
+ int color_format, int width, int height, int msaa, int pitch,
+ int tex_height, int scenes_per_frame, void *color_data) {
+
+ if (width == FB_WIDTH && height == FB_HEIGHT) {
+ msaa = SCE_GXM_MULTISAMPLE_4X;
+ }
+
+ return TAI_NEXT(color_surface_init_2_hook, hook_ref[6], color_surface_ctx,
+ color_format, width, height, msaa, pitch,
+ tex_height, scenes_per_frame, color_data);
+}
+
+static int depth_surface_init_hook(void *depth_surface_ctx,
+ int format, int pitch, int height, int flags) {
+
+ pitch *= 2;
+ height *= 2;
+
+ return TAI_NEXT(depth_surface_init_hook, hook_ref[7], depth_surface_ctx,
+ format, pitch, height, flags);
+}
+
+#endif
+
#if PATCH_MODE == MODE_1080
static SceUID sceKernelAllocMemBlock_hook(char *name, int type, int size, void *opt) {
@@ -273,6 +338,8 @@ int module_start(SceSize argc, const void *argv) { (void)argc; (void)argv;
GLZ(INJECT_DATA(1, p4g_modid, 1, ofs_3dbuf + 4, (float[]){(float)FB_HEIGHT}, 4));
GLZ(INJECT_DATA(2, p4g_modid, 1, ofs_3dbuf + 8, (float[]){(float)FB_PITCH}, 4));
+#if PATCH_MODE != MODE_544
+
// main/UI buffer
uint16_t nop_nop[2] = {0xBF00, 0xBF00};
@@ -290,6 +357,16 @@ int module_start(SceSize argc, const void *argv) { (void)argc; (void)argv;
// fix scaling
GLZ(HOOK_IMPORT(1, P4G_MOD_NAME, 0xF76B66BD, 0x65DD0C84, sceGxmSetUniformDataF));
+#else
+
+ // multisample anti-aliasing
+
+ GLZ(HOOK_OFFSET(5, p4g_modid, ofs_instr + 0x270C, color_surface_init_1));
+ GLZ(HOOK_OFFSET(6, p4g_modid, ofs_instr + 0x25C0, color_surface_init_2));
+ GLZ(HOOK_OFFSET(7, p4g_modid, ofs_instr + 0x28A2, depth_surface_init));
+
+#endif
+
// memory management
#if PATCH_MODE == MODE_1080