aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorneonloop2023-01-11 16:28:41 +0000
committerneonloop2023-01-11 16:28:41 +0000
commit13447e236c51cd48372355e5c4d5e5379d39b892 (patch)
tree274173ac0d1e8cc0ef251f43e5dc37b2be058d90
parent319f038a28907277890b6122c4caf07842a4936c (diff)
downloadpicoarch-13447e236c51cd48372355e5c4d5e5379d39b892.tar.gz
picoarch-13447e236c51cd48372355e5c4d5e5379d39b892.tar.bz2
picoarch-13447e236c51cd48372355e5c4d5e5379d39b892.zip
Limits width for crop scaler to 320px
Makes crop scaler more useful for PlayStation / SNES games that use high horizontal resolution
-rw-r--r--.gitignore1
-rw-r--r--Makefile1
-rw-r--r--menu.c13
-rw-r--r--scale.c74
4 files changed, 60 insertions, 29 deletions
diff --git a/.gitignore b/.gitignore
index 1ab541e..759282c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
*.o
*.so
+*.opk
picoarch
/pkg
/profile
diff --git a/Makefile b/Makefile
index 21df610..9bf3536 100644
--- a/Makefile
+++ b/Makefile
@@ -182,6 +182,7 @@ cores: $(SOFILES)
clean: clean-libpicofe
rm -f $(OBJS) $(BIN) $(SOFILES)
rm -rf pkg
+ rm -f *.opk
clean-all: $(foreach core,$(CORES),clean-$(core)) clean
diff --git a/menu.c b/menu.c
index eee7b19..92da59c 100644
--- a/menu.c
+++ b/menu.c
@@ -492,6 +492,8 @@ static const char h_scale_filter[] =
"When stretching, how missing pixels are filled.\n"
"Nearest copies the last pixel. Sharp keeps pixels\n"
"aligned where possible. Smooth adds a blur effect.";
+
+static const char *men_scale_size[] = { "Native", "Aspect", "Full", NULL};
#else
static const char h_enable_drc[] =
"Dynamically adjusts audio rate for\n"
@@ -503,19 +505,20 @@ static const char h_audio_buffer_size[] =
"crackling at the cost of delayed sound.";
static const char h_scale_size[] =
- "How much to stretch the screen when\n"
- "scaling. Native does no stretching.\n"
- "Aspect uses the correct aspect ratio.\n"
- "Full uses the whole screen.";
+ "How to fill the display. Native does\n"
+ "no stretching. Aspect keeps the correct\n"
+ "aspect ratio. Full uses the whole\n"
+ "screen. Crop hides pixels on the sides.";
static const char h_scale_filter[] =
"When stretching, how missing pixels\n"
"are filled. Nearest copies the last\n"
"pixel. Sharp tries to keep pixels\n"
"aligned. Smooth adds a blur effect.";
-#endif
static const char *men_scale_size[] = { "Native", "Aspect", "Full", "Crop", NULL};
+#endif
+
static const char *men_scale_filter[] = { "Nearest", "Sharp", "Smooth", NULL};
static menu_entry e_menu_video_options[] =
diff --git a/scale.c b/scale.c
index 583ca5d..7097380 100644
--- a/scale.c
+++ b/scale.c
@@ -25,7 +25,8 @@ struct blend_args {
} blend_args;
static scaler_t scaler;
-static unsigned dst_w, dst_h, dst_offs;
+static scaler_t crop_scaler;
+static unsigned dst_w, dst_h, dst_offs, src_offs, w_offs;
struct dimensions prev;
#if __ARM_ARCH >= 5
@@ -105,26 +106,10 @@ static void scale_1x(unsigned w, unsigned h, size_t pitch, const void *src, void
}
static void scale_crop(unsigned w, unsigned h, size_t pitch, const void *src, void *dst) {
- int dst_y = ((SCREEN_HEIGHT - (short)h) / 2);
- int dst_x = ((SCREEN_WIDTH - (short)w) * SCREEN_BPP / 2);
+ src += src_offs;
+ w += w_offs;
- if (dst_y < 0) {
- src += -dst_y * pitch;
- dst_y = 0;
- h = SCREEN_HEIGHT;
- }
-
- if (dst_x < 0) {
- src += -dst_x;
- dst_x = 0;
- w = SCREEN_WIDTH;
- }
-
- dst += dst_y * SCREEN_PITCH + dst_x;
-
- for (unsigned y = 0; y < h; y++) {
- memcpy(dst + y * SCREEN_PITCH, src + y * pitch, w * SCREEN_BPP);
- }
+ crop_scaler(w, h, pitch, src, dst);
}
static void scale_nearest(unsigned w, unsigned h, size_t pitch, const void *src, void *dst) {
@@ -440,8 +425,42 @@ static void scale_select_scaler(unsigned w, unsigned h, size_t pitch) {
}
if (scale_size == SCALE_SIZE_CROP) {
- scaler = scale_crop;
- return;
+ int dst_x, dst_y;
+ src_offs = 0;
+
+ if (w <= 320) {
+ dst_x = ((SCREEN_WIDTH - (short)w) / 2);
+ } else {
+ /* Crop to 320px maximum. If larger, scale down after crop. */
+ int src_w;
+ if (strstr(core_name, "snes9x")) {
+ /* For SNES, keep aspect ratio same for hi-res and normal */
+ src_w = SCREEN_WIDTH * 2;
+ } else {
+ src_w = w / current_aspect_ratio;
+ }
+
+ dst_x = ((src_w - (short)w) / 2);
+ }
+
+ dst_y = ((SCREEN_HEIGHT - (short)h) / 2);
+ dst_w = w;
+ dst_h = h;
+
+ if (dst_y < 0) {
+ dst_y = 0;
+ dst_h = SCREEN_HEIGHT;
+ }
+
+ if (dst_x < 0) {
+ src_offs += -dst_x * SCREEN_BPP;
+ w_offs = dst_x * 2;
+ w += w_offs;
+ dst_x = 0;
+ dst_w = SCREEN_WIDTH;
+ }
+
+ dst_offs = dst_y * SCREEN_PITCH + dst_x * SCREEN_BPP;
} else if (scale_size == SCALE_SIZE_FULL) {
dst_w = SCREEN_WIDTH;
dst_h = SCREEN_HEIGHT;
@@ -499,7 +518,6 @@ static void scale_select_scaler(unsigned w, unsigned h, size_t pitch) {
if (!scaler && scale_filter == SCALE_FILTER_NEAREST) {
scaler = scale_nearest;
- return;
}
if (!scaler && (scale_filter == SCALE_FILTER_SHARP || scale_filter == SCALE_FILTER_SMOOTH)) {
@@ -523,12 +541,20 @@ static void scale_select_scaler(unsigned w, unsigned h, size_t pitch) {
blend_args.h_bp[1] = blend_args.h_ratio_out >> 1;
scaler = scale_blend;
- return;
}
if (!scaler) {
scaler = scale_1x;
}
+
+ if (scale_size == SCALE_SIZE_CROP) {
+ if (w <= SCREEN_WIDTH && h <= SCREEN_HEIGHT) {
+ crop_scaler = scale_1x;
+ } else {
+ crop_scaler = scaler;
+ }
+ scaler = scale_crop;
+ }
}
void scale_update_scaler(void) {