From 1ea898e5d7daf0a3e049aca8dedb469ab9dab8e9 Mon Sep 17 00:00:00 2001
From: kub <derkub@gmail.com>
Date: Sun, 25 Jul 2021 23:38:06 +0200
Subject: [PATCH] platform support, bugfixes, optimisations, extensions for
 upscaling

not yet used in the code base
---
 platform/common/upscale.c |   6 +-
 platform/common/upscale.h | 134 +++++++++++++++++++++++++++++++++++---
 2 files changed, 128 insertions(+), 12 deletions(-)

diff --git a/platform/common/upscale.c b/platform/common/upscale.c
index 1d8c3f9e..a84b68c7 100644
--- a/platform/common/upscale.c
+++ b/platform/common/upscale.c
@@ -82,7 +82,7 @@ void upscale_clut_nn_256_320x224_240(u8 *__restrict di, int ds, u8 *__restrict s
 			h_upscale_nn_4_5(di, ds, si, ss, 256, f_nop);
 		}
 		/* line 7 */
-		di += 8*ds;
+		di -= 8*ds;
 		v_copy(&di[0], &di[-ds], 320, f_nop);
 		di += 8*ds;
 	}
@@ -149,7 +149,7 @@ void upscale_rgb_bln_256_320x224_240(u16 *__restrict di, int ds, u8 *__restrict
 		/* mixing line 3: line 2 = -ds, line 3 = +ds */
 			v_mix(&di[0], &di[-ds], &di[ds], 320, p_025, f_nop);
 			di += ds;
-		/* mixing lines 4-5: line n = 0, line n+1 = +ds */
+		/* mixing lines 4-5: line n-1 = 0, line n = +ds */
 		for (j = 0; j < 2; j++) {
 			v_mix(&di[0], &di[0], &di[ds], 320, p_025, f_nop);
 			di += ds;
@@ -183,7 +183,7 @@ void upscale_clut_nn_320x224_240(u8 *__restrict di, int ds, u8 *__restrict si, i
 			h_copy(di, ds, si, ss, 320, f_nop);
 		}
 
-		di += 8*ds;
+		di -= 8*ds;
 		v_copy(&di[0], &di[-ds], 320, f_nop);
 		di += 8*ds;
 
diff --git a/platform/common/upscale.h b/platform/common/upscale.h
index bb284df4..2c22edfe 100644
--- a/platform/common/upscale.h
+++ b/platform/common/upscale.h
@@ -29,11 +29,13 @@
 
 /* RGB565 pixel mixing, see https://www.compuphase.com/graphic/scale3.htm and
   			    http://blargg.8bitalley.com/info/rgb_mixing.html */
-//#define p_05(p1,p2)	(t=((p1)&(p2)) + ((((p1)^(p2))&~0x0821)>>1))
-#define p_05(p1,p2)	(t=((p1)+(p2) + ( ((p1)^(p2))&0x0821))>>1) // round up
+#define p_05(p1,p2)	(t=((p1)&(p2)) + ((((p1)^(p2))&~0x0821)>>1))
+//#define p_05(p1,p2)	(t=((p1)+(p2) + ( ((p1)^(p2))&0x0821))>>1) // round up
 //#define p_05(p1,p2)	(t=((p1)+(p2) - ( ((p1)^(p2))&0x0821))>>1) // round down
-#define p_025(p1,p2)	(t=((p1)+(p2) + ( ((p1)^(p2))&0x0821))>>1, \
-			   (( t)+(p2) + ( (( t)^(p2))&0x0821))>>1)
+#define p_025(p1,p2)	(t=((p1)&(p2)) + ((((p1)^(p2))&~0x0821)>>1), \
+			   (( t)&(p2)) + (((( t)^(p2))&~0x0821)>>1))
+//#define p_025(p1,p2)	(t=((p1)+(p2) + ( ((p1)^(p2))&0x0821))>>1, \
+//			   (( t)+(p2) + ( (( t)^(p2))&0x0821))>>1)
 #define p_075(p1,p2)	p_025(p2,p1)
 
 /* pixel transforms, result must be RGB565 */
@@ -43,7 +45,9 @@
 /*
 scalers h:
 256->320:       - (4:5)         (256x224/240 -> 320x224/240)
+256->299:	- (6:7)		(256x224 -> 299x224, DAR 4:3, 10.5 px border )
 160->320:       - (1:2) 2x      (160x144 -> 320x240, GG)
+160->288:	- (5:9)		(160x144 -> 288x216, GG alt?)
 */
 
 /* scale 4:5 */
@@ -51,7 +55,7 @@ scalers h:
 	/* 1111 1222 2233 3334 4444 */			\
 	/*   1    2    2    3    4  */			\
 	int i;						\
-	for (i = 0; i < w; i += 4, si += 4, di += 5) {	\
+	for (i = w/4; i > 0; i--, si += 4, di += 5) {	\
 		di[0] = f(si[0]);			\
 		di[1] = f(si[1]);			\
 		di[2] = f(si[1]);			\
@@ -66,7 +70,7 @@ scalers h:
 	/* 1111 1222 2233 3334 4444 */			\
 	/*   1    2   2+3   3    4  */			\
 	int i, t;					\
-	for (i = 0; i < w; i += 4, si += 4, di += 5) {	\
+	for (i = w/4; i > 0; i--, si += 4, di += 5) {	\
 		di[0] = f(si[0]);			\
 		di[1] = f(si[1]);			\
 		di[2] = p_05(f(si[1]),f(si[2]));	\
@@ -81,7 +85,7 @@ scalers h:
 	/* 1111 1222 2233 3334 4444 */			\
 	/*   1   2+3  2+3  3+4   4  */			\
 	int i, t;					\
-	for (i = 0; i < w; i += 4, si += 4, di += 5) {	\
+	for (i = w/4; i > 0; i--, si += 4, di += 5) {	\
 		di[0] = f(si[0]);			\
 		di[1] = p_025(f(si[0]),f(si[1]));	\
 		di[2] = p_05 (f(si[1]),f(si[2]));	\
@@ -92,10 +96,120 @@ scalers h:
 	si += ss - w;					\
 } while (0)
 
+/* scale 6:7 */
+#define h_upscale_nn_6_7(di,ds,si,ss,w,f) do {		\
+	/* 111111 122222 223333 333444 444455 555556 666666 */ \
+	/*   1      2      3       3     4      5      6    */ \
+	int i;						\
+	for (i = w/6; i > 0; i--, si += 6, di += 7) {	\
+		di[0] = f(si[0]);			\
+		di[1] = f(si[1]);			\
+		di[2] = f(si[2]);			\
+		di[3] = f(si[2]);			\
+		di[4] = f(si[3]);			\
+		di[5] = f(si[4]);			\
+		di[6] = f(si[5]);			\
+	}						\
+	di += ds - w/6*7;				\
+	si += ss - w;					\
+} while (0)
+
+#define h_upscale_snn_6_7(di,ds,si,ss,w,f) do {		\
+	/* 111111 122222 223333 333444 444455 555556 666666 */ \
+	/*   1      2      3      3+4    4      5      6    */ \
+	int i, t;					\
+	for (i = w/6; i > 0; i--, si += 6, di += 7) {	\
+		di[0] = f(si[0]);			\
+		di[1] = f(si[1]);			\
+		di[2] = f(si[2]);			\
+		di[3] = p_05(f(si[2]),f(si[3]));	\
+		di[4] = f(si[3]);			\
+		di[5] = f(si[4]);			\
+		di[6] = f(si[5]);			\
+	}						\
+	di += ds - w/6*7;				\
+	si += ss - w;					\
+} while (0)
+
+#define h_upscale_bln_6_7(di,ds,si,ss,w,f) do {		\
+	/* 111111 122222 223333 333444 444455 555556 666666 */ \
+	/*   1      2      2+3    3+4    4+5    5      6    */ \
+	int i, t;					\
+	for (i = w/6; i > 0; i--, si += 6, di += 7) {	\
+		di[0] = f(si[0]);			\
+		di[1] = f(si[1]);			\
+		di[2] = p_025(f(si[1]),f(si[2]));	\
+		di[3] = p_05 (f(si[3]),f(si[3]));	\
+		di[4] = p_075(f(si[2]),f(si[4]));	\
+		di[5] = f(si[4]);			\
+		di[6] = f(si[5]);			\
+	}						\
+	di += ds - w/6*7;				\
+	si += ss - w;					\
+} while (0)
+
+/* scale 5:9 */
+#define h_upscale_nn_5_9(di,ds,si,ss,w,f) do {		\
+	/* 11111 11112 22222 22233 33333 33444 44444 45555 55555 */ \
+	/*   1     1     2     2     3     4     4     5     5   */ \
+	int i;						\
+	for (i = w/5; i > 0; i--, si += 5, di += 9) {	\
+		di[0] = f(si[0]);			\
+		di[1] = f(si[0]);			\
+		di[2] = f(si[1]);			\
+		di[3] = f(si[1]);			\
+		di[4] = f(si[2]);			\
+		di[5] = f(si[3]);			\
+		di[6] = f(si[3]);			\
+		di[7] = f(si[4]);			\
+		di[8] = f(si[4]);			\
+	}						\
+	di += ds - w/5*9;				\
+	si += ss - w;					\
+} while (0)
+
+#define h_upscale_snn_5_9(di,ds,si,ss,w,f) do {		\
+	/* 11111 11112 22222 22233 33333 33444 44444 45555 55555 */ \
+	/*   1     1     2    2+3    3    3+4    4     5     5   */ \
+	int i, t;					\
+	for (i = w/5; i > 0; i--, si += 5, di += 9) {	\
+		di[0] = f(si[0]);			\
+		di[1] = f(si[0]);			\
+		di[2] = f(si[1]);			\
+		di[3] = p_05(f(si[1]),f(si[2]));	\
+		di[4] = f(si[2]);			\
+		di[5] = p_05(f(si[2]),f(si[3]));	\
+		di[6] = f(si[3]);			\
+		di[7] = f(si[4]);			\
+		di[8] = f(si[4]);			\
+	}						\
+	di += ds - w/5*9;				\
+	si += ss - w;					\
+} while (0)
+
+#define h_upscale_bln_5_9(di,ds,si,ss,w,f) do {		\
+	/* 11111 11112 22222 22233 33333 33444 44444 45555 55555 */ \
+	/*   1    1+2    2    2+3    3    3+4    4    4+5    5   */ \
+	int i, t;					\
+	for (i = w/5; i > 0; i--, si += 5, di += 9) {	\
+		di[0] = f(si[0]);			\
+		di[1] = p_075(f(si[0]),f(si[1]));	\
+		di[2] = f(si[1]);			\
+		di[3] = p_075(f(si[1]),f(si[2]));	\
+		di[4] = f(si[2]);			\
+		di[5] = p_025(f(si[2]),f(si[3]));	\
+		di[6] = f(si[3]);			\
+		di[5] = p_025(f(si[3]),f(si[4]));	\
+		di[8] = f(si[4]);			\
+	}						\
+	di += ds - w/5*9;				\
+	si += ss - w;					\
+} while (0)
+
 /* scale 1:2 integer scale */
 #define h_upscale_nn_1_2(di,ds,si,ss,w,f) do {		\
 	int i;						\
-	for (i = 0; i < w; i += 2, si += 2, di += 4) {	\
+	for (i = w/2; i > 0; i--, si += 2, di += 4) {	\
 		di[0] = f(si[0]);			\
 		di[1] = f(si[0]);			\
 		di[2] = f(si[1]);			\
@@ -108,7 +222,7 @@ scalers h:
 /* scale 1:1, copy */
 #define h_copy(di,ds,si,ss,w,f) do {			\
 	int i;						\
-	for (i = 0; i < w; i += 4, si += 4, di += 4) {	\
+	for (i = w/4; i > 0; i--, si += 4, di += 4) {	\
 		di[0] = f(si[0]);			\
 		di[1] = f(si[1]);			\
 		di[2] = f(si[2]);			\
@@ -121,7 +235,9 @@ scalers h:
 /*
 scalers v:
 224->240:       - (14:15)       (256/320x224 -> 320x240)
+224->238:       - (16:17)       (256/320x224 -> 320x238 alt?)
 144->240:       - (3:5)         (160x144 -> 320x240, GG)
+144->216:	- (2:3)		(160x144 -> 288x216, GG alt?)
 */
 
 #define v_mix(di,li,ri,w,p_mix,f) do {			\
-- 
2.39.5