diff --git a/pkg/worker/caged/libretro/image/canvas.c b/pkg/worker/caged/libretro/image/canvas.c index 66b00cd83..59af9772f 100644 --- a/pkg/worker/caged/libretro/image/canvas.c +++ b/pkg/worker/caged/libretro/image/canvas.c @@ -1,142 +1,82 @@ #include "canvas.h" -__inline int rot_x(int t, int x, int y, int w, int h) { +__inline xy rotate(int t, int x, int y, int w, int h) { + xy p = {x, y}; switch (t) { - case 1: - return r90_x(x,y,w,h); + case A90: + p.x = r90_x(x,y,w,h); + p.y = r90_y(x,y,w,h); break; - case 2: - return r180_x(x,y,w,h); + case A180: + p.x = r180_x(x,y,w,h); + p.y = r180_y(x,y,w,h); break; - case 3: - return r270_x(x,y,w,h); + case A270: + p.x = r270_x(x,y,w,h); + p.y = r270_y(x,y,w,h); break; - case 4: - return fy180_x(x,y,w,h); + case F180: + p.x = fy180_x(x,y,w,h); + p.y = fy180_y(x,y,w,h); break; } - return x; + return p; } -__inline int rot_y(int t, int x, int y, int w, int h) { - switch (t) { - case 1: - return r90_y(x,y,w,h); - break; - case 2: - return r180_y(x,y,w,h); - break; - case 3: - return r270_y(x,y,w,h); - break; - case 4: - return fy180_y(x,y,w,h); - break; - } - return y; - } +__inline uint32_t _565(uint32_t x) { + return ((x >> 8 & 0xf8) | ((x >> 3 & 0xfc) << 8) | ((x << 3 & 0xfc) << 16)); // | 0xff000000 +} +__inline uint32_t _8888rev(uint32_t px) { + return (((px >> 16) & 0xff) | (px & 0xff00) | ((px << 16) & 0xff0000)); // | 0xff000000) +} + +void RGBA(int pix, uint32_t *__restrict dst, void *__restrict source, int y, int h, int w, int hh, int dw, int pad, int rot) { + int x; + xy rxy; -void RGBA(int pix, void *destination, void *source, int yy, int yn, int xw, int xh, int dw, int pad, int rot) { switch (pix) { - case BIT_SHORT5551: - break; + //case BIT_SHORT5551: + // break; case BIT_INT_8888REV: - if (rot == 0) { - i8888(destination, source, yy, yn, xw, pad); + uint32_t *src32 = source; + int pad32 = pad >> 2; + if (rot == NO_ROT) { + for (; y < h; ++y) { + for (x = 0; x < w; ++x) { + *dst++ = _8888rev(*src32++); + } + src32 += pad32; + } } else { - i8888r(destination, source, yy, yn, xw, xh, dw, pad, rot); + for (; y < h; ++y) { + for (x = 0; x < w; ++x) { + rxy = rotate(rot, x, y, w, hh); + dst[rxy.x+rxy.y*w] = _8888rev(*src32++); + } + src32 += pad32; + } } break; case BIT_SHORT565: - if (rot == 0) { - i565(destination, source, yy, yn, xw, pad); + uint16_t *src16 = source; + int pad16 = pad >> 1; + if (rot == NO_ROT) { + for (; y < h; ++y) { + for (x = 0; x < w; ++x) { + *dst++ = _565(*src16++); + } + src16 += pad16; + } } else { - i565r(destination, source, yy, yn, xw, xh, dw, pad, rot); + for (; y < h; ++y) { + for (x = 0; x < w; ++x) { + rxy = rotate(rot, x, y, w, hh); + dst[rxy.x+rxy.y*dw] = _565(*src16++); + } + src16 += pad16; + } } break; } } - -void i565(void *destination, void *source, int yy, int yn, int xw, int pad) { - uint8_t *src = source; // must be in bytes because of possible padding in bytes - uint32_t *dst = destination; - - int y, x; - uint32_t px; - - for (y = yy; y < yn; ++y) { - for (x = 0; x < xw; ++x) { - px = *(uint16_t *)src; - src += 2; - *dst++ = _565(px); - } - src += pad; - } -} - -void i565r(void *destination, void *source, int yy, int yn, int xw, int xh, int dw, int pad, int rot) { - uint8_t *src = source; - uint32_t *dst = destination; - - uint32_t px; - - int x, y, dx, dy; - - for (y = yy; y < yn; ++y) { - for (x = 0; x < xw; ++x) { - px = *(uint16_t *)src; - src += 2; - - dx = rot_x(rot, x, y, xw, xh); - dy = rot_y(rot, x, y, xw, xh); - - dst[dx+dy*dw] = _565(px); - } - src += pad; - } -} - -void i8888r(void *destination, void *source, int yy, int yn, int xw, int xh, int dw, int pad, int rot) { - uint8_t *src = source; - uint32_t *dst = destination; - - int y, x; - uint32_t px; - - int dx, dy; - - for (y = yy; y < yn; ++y) { - for (x = 0; x < xw; ++x) { - px = *(uint32_t *)src; - - dx = rot_x(rot, x, y, xw, xh); - dy = rot_y(rot, x, y, xw, xh); - - dst[dx+dy*dw] = _8888rev(px); - src += 4; - } - src += pad; - } -} - -void i8888(void *destination, void *source, int yy, int yn, int xw, int pad) { - uint8_t *src = source; // must be in bytes because of possible padding in bytes - uint32_t *dst = destination; - - int y, x; - uint32_t px; - - for (y = yy; y < yn; ++y) { - for (x = 0; x < xw; ++x) { - px = *(uint32_t *)src; - src += 4; - *dst++ = _8888rev(px); - } - src += pad; - } -} - -uint32_t px8888rev(uint32_t px) { - return _8888rev(px); -} diff --git a/pkg/worker/caged/libretro/image/canvas.go b/pkg/worker/caged/libretro/image/canvas.go index 035876a51..31d9750b8 100644 --- a/pkg/worker/caged/libretro/image/canvas.go +++ b/pkg/worker/caged/libretro/image/canvas.go @@ -138,21 +138,22 @@ func (c *Canvas) Draw(encoding uint32, rot Rotation, w, h, packedW, bpp int, dat func frame(encoding uint32, dst *Frame, data []byte, yy int, hn int, w int, h int, pwb int, bpp int, rot Rotation) { sPtr := unsafe.Pointer(&data[yy*pwb]) - dPtr := unsafe.Pointer(&dst.Pix[yy*dst.Stride]) // some cores can zero-right-pad rows to the packed width value pad := pwb - w*bpp if pad < 0 { pad = 0 } - if rot != 0 { - dPtr = unsafe.Pointer(&dst.Pix[0]) + ds := 0 + if rot == 0 { + ds = yy * dst.Stride } + dPtr := (*C.uint32_t)(unsafe.Pointer(&dst.Pix[ds])) C.RGBA(C.int(encoding), dPtr, sPtr, C.int(yy), C.int(yy+hn), C.int(w), C.int(h), C.int(dst.Stride>>2), C.int(pad), C.int(rot)) } -func _8888rev(px uint32) uint32 { return uint32(C.px8888rev(C.uint32_t(px))) } +func _8888rev(px uint32) uint32 { return uint32(C._8888rev(C.uint32_t(px))) } func rotate(t int, x int, y int, w int, h int) (int, int) { - return int(C.rot_x(C.int(t), C.int(x), C.int(y), C.int(w), C.int(h))), - int(C.rot_y(C.int(t), C.int(x), C.int(y), C.int(w), C.int(h))) + var rot C.xy = C.rotate(C.int(t), C.int(x), C.int(y), C.int(w), C.int(h)) + return int(rot.x), int(rot.y) } diff --git a/pkg/worker/caged/libretro/image/canvas.h b/pkg/worker/caged/libretro/image/canvas.h index f89a0f273..93b5d7e62 100644 --- a/pkg/worker/caged/libretro/image/canvas.h +++ b/pkg/worker/caged/libretro/image/canvas.h @@ -7,6 +7,12 @@ #define BIT_INT_8888REV 1 #define BIT_SHORT565 2 +#define NO_ROT 0 +#define A90 1 +#define A180 2 +#define A270 3 +#define F180 4 + // Rotate90 is 90° CCW or 270° CW. #define r90_x(x, y, w, h) ( y ) #define r90_y(x, y, w, h) ( (w - 1) - x ) @@ -23,20 +29,15 @@ #define fy180_x(x, y, w, h) ( x ) #define fy180_y(x, y, w, h) ( (h - 1) - y ) -int rot_x(int t, int x, int y, int w, int h); -int rot_y(int t, int x, int y, int w, int h); - -#define _565(x) ((x >> 8 & 0xf8) | ((x >> 3 & 0xfc) << 8) | ((x << 3 & 0xfc) << 16)); // | 0xff000000 -#define _8888rev(px) (((px >> 16) & 0xff) | (px & 0xff00) | ((px << 16) & 0xff0000)); // | 0xff000000) - +typedef struct XY { + int x, y; +} xy; -void RGBA(int pix, void *destination, void *source, int yy, int yn, int xw, int xh, int dw, int pad, int rot); +xy rotate(int t, int x, int y, int w, int h); -void i565(void *destination, void *source, int yy, int yn, int xw, int pad); -void i8888(void *destination, void *source, int yy, int yn, int xw, int pad); -void i565r(void *destination, void *source, int yy, int yn, int xw, int xh, int dw, int pad, int rot); -void i8888r(void *destination, void *source, int yy, int yn, int xw, int xh, int dw, int pad, int rot); +void RGBA(int pix, uint32_t *dst, void *source, int y, int h, int w, int hh, int dw, int pad, int rot); -uint32_t px8888rev(uint32_t px); +uint32_t _565(uint32_t x); +uint32_t _8888rev(uint32_t px); #endif