aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornotaz2014-12-25 04:44:22 +0200
committernotaz2014-12-25 04:44:22 +0200
commit35d3fd2efb47352edf794255da3e4745f6bd0a0d (patch)
treed40223d6670c64a0ab815ad82b93a40c1fd03823
parent288e55cb4784f2313821551ef97addffce49eb99 (diff)
downloadpcsx_rearmed-35d3fd2efb47352edf794255da3e4745f6bd0a0d.tar.gz
pcsx_rearmed-35d3fd2efb47352edf794255da3e4745f6bd0a0d.tar.bz2
pcsx_rearmed-35d3fd2efb47352edf794255da3e4745f6bd0a0d.zip
frontend: scanline efect and memcard saving
-rw-r--r--frontend/cspace.h3
-rw-r--r--frontend/cspace_neon.S85
-rw-r--r--frontend/menu.c39
-rw-r--r--frontend/menu.h1
-rw-r--r--frontend/plugin_lib.c13
5 files changed, 138 insertions, 3 deletions
diff --git a/frontend/cspace.h b/frontend/cspace.h
index 1a9e339..8c92d2d 100644
--- a/frontend/cspace.h
+++ b/frontend/cspace.h
@@ -8,6 +8,9 @@ void bgr888_to_rgb888(void *dst, const void *src, int bytes);
void bgr888_to_rgb565(void *dst, const void *src, int bytes);
void rgb888_to_rgb565(void *dst, const void *src, int bytes);
+void bgr555_to_rgb565_b(void *dst, const void *src, int bytes,
+ int brightness2k); // 0-0x0800
+
void bgr_to_uyvy_init(void);
void rgb565_to_uyvy(void *d, const void *s, int pixels);
void bgr555_to_uyvy(void *d, const void *s, int pixels);
diff --git a/frontend/cspace_neon.S b/frontend/cspace_neon.S
index 342876f..8b201db 100644
--- a/frontend/cspace_neon.S
+++ b/frontend/cspace_neon.S
@@ -72,12 +72,93 @@ btr16_end16:
bxlt lr
@ very rare
- vld1.16 d0, [r1]!
+ vld1.16 {d0}, [r1]!
vshl.u16 d1, d0, #11
vshl.u16 d2, d0, #1
vsri.u16 d1, d0, #10
vbit d1, d2, d30
- vst1.16 d1, [r0]!
+ vst1.16 {d1}, [r0]!
+ bx lr
+
+
+@ note: may overflow source
+FUNCTION(bgr555_to_rgb565_b): @ dst, src, bytes, int brightness2k // 0-0x0800
+ pld [r1]
+ vdup.16 q15, r3
+ vpush {q4-q7}
+ mov r3, #0x1f
+ vdup.16 q14, r3
+0:
+ pld [r1, #64*2]
+ vldmia r1!, {q0-q3}
+ vand.u16 q8, q0, q14
+ vand.u16 q9, q1, q14
+ vand.u16 q10, q2, q14
+ vand.u16 q11, q3, q14
+ vmul.u16 q4, q8, q15
+ vmul.u16 q5, q9, q15
+ vmul.u16 q6, q10, q15
+ vmul.u16 q7, q11, q15
+
+ vshr.u16 q8, q0, #5
+ vshr.u16 q9, q1, #5
+ vshr.u16 q10, q2, #5
+ vshr.u16 q11, q3, #5
+ vand.u16 q8, q14
+ vand.u16 q9, q14
+ vand.u16 q10, q14
+ vand.u16 q11, q14
+ vmul.u16 q8, q15
+ vmul.u16 q9, q15
+ vmul.u16 q10, q15
+ vmul.u16 q11, q15
+ vsri.u16 q4, q8, #5
+ vsri.u16 q5, q9, #5
+ vsri.u16 q6, q10, #5
+ vsri.u16 q7, q11, #5
+
+ vshr.u16 q8, q0, #10
+ vshr.u16 q9, q1, #10
+ vshr.u16 q10, q2, #10
+ vshr.u16 q11, q3, #10
+ vand.u16 q8, q14
+ vand.u16 q9, q14
+ vand.u16 q10, q14
+ vand.u16 q11, q14
+ vmul.u16 q8, q15
+ vmul.u16 q9, q15
+ vmul.u16 q10, q15
+ vmul.u16 q11, q15
+ vsri.u16 q4, q8, #11
+ vsri.u16 q5, q9, #11
+ vsri.u16 q6, q10, #11
+ vsri.u16 q7, q11, #11
+
+ subs r2, r2, #64
+ ble 1f
+ vstmia r0!, {q4-q7}
+ b 0b
+
+1:
+ blt 0f
+ vstmia r0!, {q4-q7}
+ b btr16b_end
+0:
+ subs r2, r2, #8
+ blt btr16b_end
+ vst1.16 {q4}, [r0]!
+ subs r2, r2, #8
+ blt btr16b_end
+ vst1.16 {q5}, [r0]!
+ subs r2, r2, #8
+ blt btr16b_end
+ vst1.16 {q6}, [r0]!
+ subs r2, r2, #8
+ blt btr16b_end
+ vst1.16 {q7}, [r0]!
+
+btr16b_end:
+ vpop {q4-q7}
bx lr
diff --git a/frontend/menu.c b/frontend/menu.c
index a37ab05..cfa3284 100644
--- a/frontend/menu.c
+++ b/frontend/menu.c
@@ -83,6 +83,8 @@ typedef enum
MA_OPT_SWFILTER,
MA_OPT_GAMMA,
MA_OPT_VOUT_MODE,
+ MA_OPT_SCANLINES,
+ MA_OPT_SCANLINE_LEVEL,
} menu_id;
static int last_vout_w, last_vout_h, last_vout_bpp;
@@ -90,8 +92,9 @@ static int cpu_clock, cpu_clock_st, volume_boost, frameskip;
static char last_selected_fname[MAXPATHLEN];
static int config_save_counter, region, in_type_sel1, in_type_sel2;
static int psx_clock;
-static int memcard1_sel, memcard2_sel;
+static int memcard1_sel = -1, memcard2_sel = -1;
int g_opts, g_scaler, g_gamma = 100;
+int scanlines, scanline_level = 20;
int soft_scaling, analog_deadzone; // for Caanoo
int soft_filter;
@@ -333,6 +336,8 @@ static void menu_set_defconfig(void)
analog_deadzone = 50;
soft_scaling = 1;
soft_filter = 0;
+ scanlines = 0;
+ scanline_level = 20;
plat_target.vout_fullscreen = 0;
psx_clock = DEFAULT_PSX_CLOCK;
@@ -398,6 +403,8 @@ static const struct {
CE_INTVAL(g_layer_w),
CE_INTVAL(g_layer_h),
CE_INTVAL(soft_filter),
+ CE_INTVAL(scanlines),
+ CE_INTVAL(scanline_level),
CE_INTVAL(plat_target.vout_method),
CE_INTVAL(plat_target.hwfilter),
CE_INTVAL(plat_target.vout_fullscreen),
@@ -407,6 +414,8 @@ static const struct {
CE_INTVAL(in_type_sel1),
CE_INTVAL(in_type_sel2),
CE_INTVAL(analog_deadzone),
+ CE_INTVAL(memcard1_sel),
+ CE_INTVAL(memcard2_sel),
CE_INTVAL_N("adev0_is_nublike", in_adev_is_nublike[0]),
CE_INTVAL_N("adev1_is_nublike", in_adev_is_nublike[1]),
CE_INTVAL_V(frameskip, 3),
@@ -664,6 +673,29 @@ fail:
if (strcmp(Config.Spu, spu_plugins[i]) == 0)
{ spu_plugsel = i; break; }
+ // memcard selections
+ char mcd1_old[sizeof(Config.Mcd1)];
+ char mcd2_old[sizeof(Config.Mcd2)];
+ strcpy(mcd1_old, Config.Mcd1);
+ strcpy(mcd2_old, Config.Mcd2);
+
+ if ((unsigned int)memcard1_sel < ARRAY_SIZE(memcards)) {
+ if (memcard1_sel == 0)
+ strcpy(Config.Mcd1, "none");
+ else if (memcards[memcard1_sel] != NULL)
+ snprintf(Config.Mcd1, sizeof(Config.Mcd1), ".%s%s",
+ MEMCARD_DIR, memcards[memcard1_sel]);
+ }
+ if ((unsigned int)memcard2_sel < ARRAY_SIZE(memcards)) {
+ if (memcard2_sel == 0)
+ strcpy(Config.Mcd2, "none");
+ else if (memcards[memcard2_sel] != NULL)
+ snprintf(Config.Mcd2, sizeof(Config.Mcd2), ".%s%s",
+ MEMCARD_DIR, memcards[memcard2_sel]);
+ }
+ if (strcmp(mcd1_old, Config.Mcd1) || strcmp(mcd2_old, Config.Mcd2))
+ LoadMcds(Config.Mcd1, Config.Mcd2);
+
return ret;
}
@@ -1209,6 +1241,7 @@ static const char h_cscaler[] = "Displays the scaler layer, you can resize it\
"using d-pad or move it using R+d-pad";
static const char h_overlay[] = "Overlay provides hardware accelerated scaling";
static const char h_soft_filter[] = "Works only if game uses low resolution modes";
+static const char h_scanline_l[] = "Scanline brightness, 0-100%";
static const char h_gamma[] = "Gamma/brightness adjustment (default 100)";
static int menu_loop_cscaler(int id, int keys)
@@ -1270,6 +1303,10 @@ static menu_entry e_menu_gfx_options[] =
mee_onoff ("Software Scaling", MA_OPT_SCALER2, soft_scaling, 1),
mee_enum ("Hardware Filter", MA_OPT_HWFILTER, plat_target.hwfilter, men_dummy),
mee_enum_h ("Software Filter", MA_OPT_SWFILTER, soft_filter, men_soft_filter, h_soft_filter),
+#ifdef __ARM_NEON__
+ mee_onoff ("Scanlines", MA_OPT_SCANLINES, scanlines, 1),
+ mee_range_h ("Scanline brightness", MA_OPT_SCANLINE_LEVEL, scanline_level, 0, 100, h_scanline_l),
+#endif
mee_range_h ("Gamma adjustment", MA_OPT_GAMMA, g_gamma, 1, 200, h_gamma),
// mee_onoff ("Vsync", 0, vsync, 1),
mee_cust_h ("Setup custom scaler", MA_OPT_VARSCALER_C, menu_loop_cscaler, NULL, h_cscaler),
diff --git a/frontend/menu.h b/frontend/menu.h
index 6b1e55f..81cd1ba 100644
--- a/frontend/menu.h
+++ b/frontend/menu.h
@@ -29,6 +29,7 @@ enum g_soft_filter_opts {
};
extern int g_opts, g_scaler, g_gamma;
+extern int scanlines, scanline_level;
extern int soft_scaling, analog_deadzone;
extern int soft_filter;
diff --git a/frontend/plugin_lib.c b/frontend/plugin_lib.c
index 64f96a0..163d4f1 100644
--- a/frontend/plugin_lib.c
+++ b/frontend/plugin_lib.c
@@ -371,6 +371,19 @@ static void pl_vout_flip(const void *vram, int stride, int bgr24, int w, int h)
neon_eagle2x_16_16(src, (void *)dest, w,
stride * 2, dstride * 2, h);
}
+ else if (scanlines != 0 && scanline_level != 100)
+ {
+ int l = scanline_level * 2048 / 100;
+
+ for (; h1 >= 2; h1 -= 2)
+ {
+ bgr555_to_rgb565(dest, src, w * 2);
+ dest += dstride * 2, src += stride;
+
+ bgr555_to_rgb565_b(dest, src, w * 2, l);
+ dest += dstride * 2, src += stride;
+ }
+ }
#endif
else
{