diff options
author | 浅倉麗子 | 2020-04-22 00:51:39 -0400 |
---|---|---|
committer | 浅倉麗子 | 2020-04-22 00:51:39 -0400 |
commit | a50f0d62cb941e8ece005e62b130fb9c5f492a35 (patch) | |
tree | 2a762bf5b0ebf162af2407439981a3bca00a44f4 | |
parent | Use binary config file (diff) | |
download | sharpscale-a50f0d62cb941e8ece005e62b130fb9c5f492a35.tar.gz |
Add PS1 aspect ratio modes
-rw-r--r-- | CMakeLists.txt | 5 | ||||
-rw-r--r-- | README.md | 19 | ||||
-rw-r--r-- | config.c | 2 | ||||
-rw-r--r-- | config.h | 8 | ||||
-rw-r--r-- | main.c | 26 |
5 files changed, 53 insertions, 7 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index a992ce1..ea40516 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,11 +8,11 @@ if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) endif() endif() -project(sharpscale LANGUAGES C) include("$ENV{DOLCESDK}/share/dolce.cmake" REQUIRED) +project(sharpscale LANGUAGES C) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdlib -Wall -Wextra -O3 -std=c99") -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -nostdlib") if(LOG_PRINTF) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DLOG_PRINTF") @@ -35,6 +35,7 @@ target_link_libraries("${ELF}" SceDebugForDriver_stub SceDisplayForDriver_stub SceIofilemgrForDriver_stub + SceSblACMgrForDriver_stub SceSysclibForDriver_stub taihenForKernel_stub taihenModuleUtils_stub @@ -11,12 +11,23 @@ Sharpscale can be configured to different scaling methods. #### Scaling modes - Original: system default -- Integer: framebuffer is scaled by multiplying the width and height by the largest integer such that the resulting width and height is less than or equal to the display width and height, respectively -- Real: no scaling is performed +- Integer: scale by multiplying the width and height of the framebuffer by the largest integer less than or equal to four such that the product width and height is less than or equal to the display width and height, respectively +- Real: no scaling -In integer and real modes, if the framebuffer is already larger than the display, then the framebuffer is scaled down to fit the display, in the same manner as in original mode. +In integer and real modes, a few lines may be cropped from the top and bottom to preserve aspect ratio of the framebuffer. -In integer and real modes, up to 16 lines from the bottom may be cropped due to aspect ratio difference between the display resolution and framebuffer resolution. +#### PS1 aspect ratio modes + +PS1 aspect ratio modes only take effect in integer or real scaling modes but is applied before scaling. + +- Pixel: aspect ratio of the framebuffer +- 4∶3: aspect ratio is forced to 4∶3 +- 16∶9: aspect ratio is forced to 16∶9 + +Scaling and PS1 aspect ratio will not apply when + +- in integer and real modes, if the framebuffer is already larger than the display +- in 4∶3 and 16∶9 modes, aspect ratio is too different to be forced #### Bilinear filtering @@ -28,11 +28,13 @@ void read_config(SharpscaleConfig *config) { if (ret != sizeof(*config)) { goto fail; } if (SHARPSCALE_MODE_INVALID <= config->mode) { goto fail; } + if (SHARPSCALE_PSONE_MODE_INVALID <= config->psone_mode) { goto fail; } if (config->bilinear != false && config->bilinear != true) { goto fail; } return; fail: config->mode = SHARPSCALE_MODE_INTEGER; + config->psone_mode = SHARPSCALE_PSONE_MODE_4_3; config->bilinear = false; } @@ -12,8 +12,16 @@ typedef enum SharpscaleMode { SHARPSCALE_MODE_INVALID, } SharpscaleMode; +typedef enum SharpscalePSOneMode { + SHARPSCALE_PSONE_MODE_PIXEL, + SHARPSCALE_PSONE_MODE_4_3, + SHARPSCALE_PSONE_MODE_16_9, + SHARPSCALE_PSONE_MODE_INVALID, +} SharpscalePSOneMode; + typedef struct SharpscaleConfig { SharpscaleMode mode; + SharpscalePSOneMode psone_mode; bool bilinear; } SharpscaleConfig; @@ -29,6 +29,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. #include <psp2kern/kernel/modulemgr.h> #include <psp2kern/kernel/sysmem.h> #include <psp2kern/lowio/iftu.h> +#include <psp2kern/sblacmgr.h> #include <taihen.h> #include "scedisplay.h" #include "config.h" @@ -148,6 +149,25 @@ 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 ar_numer = 1; + int ar_denom = 1; + + if (ss_config.psone_mode != SHARPSCALE_PSONE_MODE_PIXEL + && (fb_w < 960 && fb_h < 544) + && !(fb_w == 480 && fb_h == 272) + && ksceSblACMgrIsPspEmu(SCE_KERNEL_PROCESS_ID_SELF)) { + + if (ss_config.psone_mode == SHARPSCALE_PSONE_MODE_4_3) { + ar_numer = 4 * fb_h; + ar_denom = 3 * fb_w; + fb_w = ar_numer / 3; + } else if (ss_config.psone_mode == SHARPSCALE_PSONE_MODE_16_9) { + ar_numer = 16 * fb_h; + ar_denom = 9 * fb_w; + fb_w = ar_numer / 9; + } + } + int scale = 0; if (ss_config.mode == SHARPSCALE_MODE_INTEGER) { @@ -156,8 +176,12 @@ static int sceIftuSetInputFrameBuffer_hook(int plane, SceIftuPlaneState *state, scale = (fb_w <= head_w && (fb_h - 16) <= head_h) ? 1 : 0; } + while (scale > 0 && 0x10000 * ar_denom / (scale * ar_numer) < 0x10000 / 4) { + scale--; + } + if (scale > 0) { - state->src_w = 0x10000 / scale; + state->src_w = 0x10000 * ar_denom / (scale * ar_numer); state->src_h = 0x10000 / scale; fb_w *= scale; |