aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author浅倉麗子2020-04-06 15:00:15 -0400
committer浅倉麗子2020-04-06 15:00:15 -0400
commit22fcbec0c977d0d2a02415b1c4b1b1f74c4ec246 (patch)
tree22c5d1539e35a1c6b88204a1a3c022ae22015365
parentAdd support for more framebuffer sizes (diff)
downloadsharpscale-22fcbec0c977d0d2a02415b1c4b1b1f74c4ec246.tar.gz
Add real and original scale modes and config
-rw-r--r--CMakeLists.txt1
-rw-r--r--config.c47
-rw-r--r--config.h15
-rw-r--r--main.c39
4 files changed, 91 insertions, 11 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f1e8a4a..a992ce1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -27,6 +27,7 @@ set(SELF "${PROJECT_NAME}.skprx")
add_executable("${ELF}"
main.c
+ config.c
)
target_link_libraries("${ELF}"
diff --git a/config.c b/config.c
new file mode 100644
index 0000000..2d843e3
--- /dev/null
+++ b/config.c
@@ -0,0 +1,47 @@
+/*
+Sharpscale
+Copyright (C) 2020 浅倉麗子
+
+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 3 of the License.
+
+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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <psp2kern/io/fcntl.h>
+#include <psp2kern/io/stat.h>
+#include "config.h"
+
+#define CONFIG_PATH "ur0:/data/sharpscale/config.txt"
+
+void read_config(sharpscale_config_t *config) {
+ SceUID fd = ksceIoOpen(CONFIG_PATH, SCE_O_RDONLY, 0);
+ if (fd < 0) { goto fail; }
+
+ char buf[4];
+ memset(buf, 0x00, sizeof(buf));
+ int ret = ksceIoRead(fd, buf, sizeof(buf) - 1);
+ ksceIoClose(fd);
+ if (ret != sizeof(buf) - 1) { goto fail; }
+
+ config->mode = strtol(buf, NULL, 10);
+ config->bilinear = strtol(buf + 2, NULL, 10);
+
+ if (config->mode < 0 || 2 < config->mode) { goto fail; }
+ if ((config->bilinear & ~1) != 0) { goto fail; }
+
+ return;
+
+fail:
+ config->mode = SHARPSCALE_MODE_INTEGER;
+ config->bilinear = 0;
+}
diff --git a/config.h b/config.h
new file mode 100644
index 0000000..dacc293
--- /dev/null
+++ b/config.h
@@ -0,0 +1,15 @@
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#define SHARPSCALE_MODE_ORIGINAL 0
+#define SHARPSCALE_MODE_INTEGER 1
+#define SHARPSCALE_MODE_REAL 2
+
+typedef struct {
+ int mode;
+ int bilinear;
+} sharpscale_config_t;
+
+void read_config(sharpscale_config_t *config);
+
+#endif
diff --git a/main.c b/main.c
index 6b71a2d..57dbc97 100644
--- a/main.c
+++ b/main.c
@@ -31,6 +31,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <psp2kern/lowio/iftu.h>
#include <taihen.h>
#include "scedisplay.h"
+#include "config.h"
#define GLZ(x) do {\
if ((x) < 0) { goto fail; }\
@@ -93,6 +94,8 @@ extern int module_get_offset(SceUID pid, SceUID modid, int segidx, size_t offset
#define GET_OFFSET(modid, seg, ofs, addr)\
module_get_offset(KERNEL_PID, modid, seg, ofs, (uintptr_t*)addr)
+static sharpscale_config_t ss_config;
+
// SceDisplay_8100B000
static SceDisplayHead *head_data = 0;
@@ -143,24 +146,36 @@ static int sceIftuSetInputFrameBuffer_hook(int plane, SceIftuPlaneState *state,
int head_w = head_data[cur_head_idx].head_w;
int head_h = head_data[cur_head_idx].head_h;
- int scale_w = head_w / fb_w;
- int scale_h = head_h / (fb_h - 16);
- int scale = (scale_w < scale_h) ? scale_w : scale_h;
+ if (ss_config.mode == SHARPSCALE_MODE_INTEGER) {
+ int scale_w = head_w / fb_w;
+ int scale_h = head_h / (fb_h - 16);
+ int scale = (scale_w < scale_h) ? scale_w : scale_h;
- if (scale > 0) {
- state->src_w = 0x10000 / scale;
- state->src_h = 0x10000 / scale;
+ if (scale > 0) {
+ state->src_w = 0x10000 / scale;
+ state->src_h = 0x10000 / scale;
- state->dst_x = (head_w - fb_w * scale) / 2;
- state->dst_y = (fb_h * scale <= head_h)
- ? (head_h - fb_h * scale) / 2
- : 0;
+ state->dst_x = (head_w - fb_w * scale) / 2;
+ state->dst_y = (fb_h * scale <= head_h)
+ ? (head_h - fb_h * scale) / 2
+ : 0;
+ }
+ } else if (ss_config.mode == SHARPSCALE_MODE_REAL) {
+ if (fb_w <= head_w && (fb_h - 16) <= head_h) {
+ state->src_w = 0x10000;
+ state->src_h = 0x10000;
+
+ state->dst_x = (head_w - fb_w) / 2;
+ state->dst_y = (fb_h <= head_h)
+ ? (head_h - fb_h) / 2
+ : 0;
+ }
}
cur_head_idx = -1;
done:
- bilinear = (bilinear == 1) ? 0 : bilinear;
+ bilinear = (!ss_config.bilinear && bilinear == 1) ? 0 : bilinear;
return TAI_CONTINUE(int, hook_ref[2], plane, state, bilinear, sync_mode);
}
@@ -190,6 +205,8 @@ int _start() __attribute__ ((weak, alias("module_start")));
int module_start(SceSize argc, const void *argv) { (void)argc; (void)argv;
startup();
+ read_config(&ss_config);
+
tai_module_info_t minfo;
minfo.size = sizeof(minfo);
GLZ(taiGetModuleInfoForKernel(KERNEL_PID, "SceDisplay", &minfo));