From 1a57f5c5ad2265160322f4ad5d165a6b7ce9cac8 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sat, 25 Nov 2023 15:47:26 +0200 Subject: [PATCH] Keep RTG mouse cursor image in chunk format, convert when shape or also when colors change. --- od-win32/picasso96_win.cpp | 289 +++++++++++++++++++------------------ od-win32/picasso96_win.h | 1 - 2 files changed, 145 insertions(+), 145 deletions(-) diff --git a/od-win32/picasso96_win.cpp b/od-win32/picasso96_win.cpp index 4ebe6262..48c09bdb 100644 --- a/od-win32/picasso96_win.cpp +++ b/od-win32/picasso96_win.cpp @@ -92,6 +92,7 @@ int mman_GetWriteWatch (PVOID lpBaseAddress, SIZE_T dwRegionSize, PVOID *lpAddre void mman_ResetWatch (PVOID lpBaseAddress, SIZE_T dwRegionSize); void picasso_flushpixels(int index, uae_u8 *src, int offset, bool render); +int createwindowscursor(int monid, int set, int chipset); int p96refresh_active; bool have_done_picasso = 1; /* For the JIT compiler */ @@ -794,13 +795,19 @@ static void setupcursor(void) if (dptr) { for (int y = 0; y < CURSORMAXHEIGHT; y++) { uae_u8 *p2 = dptr + pitch * y; - memset (p2, 0, CURSORMAXWIDTH * bpp); + memset(p2, 0, CURSORMAXWIDTH * bpp); } if (cursordata && cursorwidth && cursorheight) { for (int y = 0; y < cursorheight; y++) { - uae_u8 *p1 = cursordata + cursorwidth * bpp * y; - uae_u8 *p2 = dptr + pitch * y; - memcpy (p2, p1, cursorwidth * bpp); + uae_u8 *p1 = cursordata + cursorwidth * y; + uae_u32 *p2 = (uae_u32*)(dptr + pitch * y); + for (int x = 0; x < cursorwidth; x++) { + uae_u8 c = *p1++; + if (c < 4) { + *p2 = cursorrgbn[c]; + } + p2++; + } } } D3D_setcursorsurface(rbc->monitor_id, false, NULL); @@ -1290,7 +1297,7 @@ void picasso_handle_vsync(void) if (!ad->picasso_on && uaegfx) { if (uaegfx_active) { - createwindowscursor(mon->monitor_id, 0, 0, 0, 0, 0, 1); + createwindowscursor(mon->monitor_id, 0, 1); } picasso_trigger_vblank(); if (!delayed_set_switch) @@ -1340,7 +1347,7 @@ static void picasso_handle_hsync(void) if (!ad->picasso_on) { if (uaegfx) { if (uaegfx_active) { - createwindowscursor(mon->monitor_id, 0, 0, 0, 0, 0, 1); + createwindowscursor(mon->monitor_id, 0, 1); } picasso_trigger_vblank(); } @@ -1835,208 +1842,202 @@ static void updatesprcolors (int bpp) } } -STATIC_INLINE void putmousepixel (uae_u8 *d, int bpp, int idx) -{ - uae_u32 val; - - val = cursorrgbn[idx]; - switch (bpp) - { - case 2: - ((uae_u16*)d)[0] = (uae_u16)val; - break; - case 4: - ((uae_u32*)d)[0] = (uae_u32)val; - break; - } -} - -static void putwinmousepixel (HDC andDC, HDC xorDC, int x, int y, int c, uae_u32 *ct) +static void putwinmousepixel(HDC andDC, HDC xorDC, int x, int y, int c, uae_u32 *ct) { if (c == 0) { - SetPixel (andDC, x, y, RGB (255, 255, 255)); - SetPixel (xorDC, x, y, RGB (0, 0, 0)); + SetPixel(andDC, x, y, RGB (255, 255, 255)); + SetPixel(xorDC, x, y, RGB (0, 0, 0)); } else { uae_u32 val = ct[c]; - SetPixel (andDC, x, y, RGB (0, 0, 0)); - SetPixel (xorDC, x, y, RGB ((val >> 16) & 0xff, (val >> 8) & 0xff, val & 0xff)); + SetPixel(andDC, x, y, RGB (0, 0, 0)); + SetPixel(xorDC, x, y, RGB ((val >> 16) & 0xff, (val >> 8) & 0xff, val & 0xff)); } } static int wincursorcnt; -static int tmp_sprite_w, tmp_sprite_h, tmp_sprite_hires, tmp_sprite_doubled; -static uae_u8 *tmp_sprite_data; +static int tmp_sprite_w, tmp_sprite_h; +static uae_u8 tmp_sprite_data[CURSORMAXWIDTH * CURSORMAXHEIGHT]; static uae_u32 tmp_sprite_colors[4]; extern uaecptr sprite_0; extern int sprite_0_width, sprite_0_height, sprite_0_doubled; extern uae_u32 sprite_0_colors[4]; -int createwindowscursor(int monid, uaecptr src, int w, int h, int hiressprite, int doubledsprite, int chipset) +static int createwindowscursor(int monid, int set, int chipset) { HBITMAP andBM, xorBM; HBITMAP andoBM, xoroBM; HDC andDC, xorDC, DC, mainDC; ICONINFO ic; - int x, y, yy, w2, h2; - int ret, isdata, datasize; + int ret = 0; + bool isdata; HCURSOR oldwincursor = wincursor; - uae_u8 *realsrc; uae_u32 *ct; TrapContext *ctx = NULL; + int w, h; + uae_u8 *image; + uae_u8 tmp_sprite[CURSORMAXWIDTH * CURSORMAXHEIGHT]; + int datasize = 0; - ret = 0; wincursor_shown = 0; - if (isfullscreen () > 0 || currprefs.input_tablet == 0 || !(currprefs.input_mouse_untrap & MOUSEUNTRAP_MAGIC)) + if (isfullscreen() > 0 || currprefs.input_tablet == 0 || !(currprefs.input_mouse_untrap & MOUSEUNTRAP_MAGIC)) { goto exit; - if (currprefs.input_magic_mouse_cursor != MAGICMOUSE_HOST_ONLY) + } + if (currprefs.input_magic_mouse_cursor != MAGICMOUSE_HOST_ONLY) { goto exit; + } if (chipset) { - if (!sprite_0 || !mousehack_alive ()) { - if (wincursor) - SetCursor (normalcursor); + w = sprite_0_width; + h = sprite_0_height; + uaecptr src = sprite_0; + int doubledsprite = sprite_0_doubled; + if (doubledsprite) { + w *= 2; + h *= 2; + } + int hiressprite = sprite_0_width / 16; + int ds = h * ((w + 15) / 16) * 4; + if (!sprite_0 || !mousehack_alive() || w > CURSORMAXWIDTH || h > CURSORMAXHEIGHT || !valid_address(src, ds)) { + if (wincursor) { + SetCursor(normalcursor); + } goto exit; } - w2 = w = sprite_0_width; - h2 = h = sprite_0_height; - hiressprite = sprite_0_width / 16; - doubledsprite = sprite_0_doubled; - if (doubledsprite) { - h2 *= 2; - w2 *= 2; + int yy = 0; + for (int y = 0, yy = 0; y < h; yy++) { + uae_u8 *dst = tmp_sprite + y * w; + int dbl; + uaecptr img = src + yy * 4 * hiressprite; + for (dbl = 0; dbl < (doubledsprite ? 2 : 1); dbl++) { + int x = 0; + while (x < w) { + uae_u32 d1 = trap_get_long(ctx, img); + uae_u32 d2 = trap_get_long(ctx, img + 2 * hiressprite); + int bits; + int maxbits = w - x; + + if (maxbits > 16 * hiressprite) { + maxbits = 16 * hiressprite; + } + for (bits = 0; bits < maxbits && x < w; bits++) { + uae_u8 c = ((d2 & 0x80000000) ? 2 : 0) + ((d1 & 0x80000000) ? 1 : 0); + d1 <<= 1; + d2 <<= 1; + *dst++ = c; + x++; + if (doubledsprite && x < w) { + *dst++ = c; + x++; + } + } + } + if (y <= h) { + y++; + } + } } - src = sprite_0; ct = sprite_0_colors; + image = tmp_sprite; } else { - h2 = h; - w2 = w; + w = cursorwidth; + h = cursorheight; ct = cursorrgbn; + image = cursordata; } - datasize = h * ((w + 15) / 16) * 4; - if (!valid_address(src, datasize)) { - goto exit; - } - realsrc = get_real_address (src); - if (w > 64 || h > 64) - goto exit; + datasize = h * ((w + 15) / 16) * 16; - if (wincursor && tmp_sprite_data) { - if (w == tmp_sprite_w && h == tmp_sprite_h && - !memcmp (tmp_sprite_data, realsrc, datasize) && !memcmp (tmp_sprite_colors, ct, sizeof (uae_u32)*4) - && hiressprite == tmp_sprite_hires && doubledsprite == tmp_sprite_doubled - ) { - if (GetCursor () == wincursor) { - wincursor_shown = 1; - return 1; - } + if (wincursor) { + if (w == tmp_sprite_w && h == tmp_sprite_h && !memcmp(tmp_sprite_data, image, datasize) && !memcmp(tmp_sprite_colors, ct, sizeof (uae_u32)*4)) { + if (GetCursor() == wincursor) { + wincursor_shown = 1; + return 1; + } } } - write_log (_T("wincursor: %dx%d hires=%d doubled=%d\n"), w2, h2, hiressprite, doubledsprite); - xfree (tmp_sprite_data); - tmp_sprite_data = NULL; + write_log(_T("wincursor: %dx%d\n"), w, h); + tmp_sprite_w = tmp_sprite_h = 0; DC = mainDC = andDC = xorDC = NULL; andBM = xorBM = NULL; - DC = GetDC (NULL); + DC = GetDC(NULL); if (!DC) goto end; - mainDC = CreateCompatibleDC (DC); - andDC = CreateCompatibleDC (DC); - xorDC = CreateCompatibleDC (DC); + mainDC = CreateCompatibleDC(DC); + andDC = CreateCompatibleDC(DC); + xorDC = CreateCompatibleDC(DC); if (!mainDC || !andDC || !xorDC) goto end; - andBM = CreateCompatibleBitmap (DC, w2, h2); - xorBM = CreateCompatibleBitmap (DC, w2, h2); + andBM = CreateCompatibleBitmap(DC, w, h); + xorBM = CreateCompatibleBitmap(DC, w, h); if (!andBM || !xorBM) goto end; - andoBM = (HBITMAP)SelectObject (andDC, andBM); - xoroBM = (HBITMAP)SelectObject (xorDC, xorBM); - - isdata = 0; - for (y = 0, yy = 0; y < h2; yy++) { - int dbl; - uaecptr img = src + yy * 4 * hiressprite; - for (dbl = 0; dbl < (doubledsprite ? 2 : 1); dbl++) { - x = 0; - while (x < w2) { - uae_u32 d1 = trap_get_long(ctx, img); - uae_u32 d2 = trap_get_long(ctx, img + 2 * hiressprite); - int bits; - int maxbits = w2 - x; - - if (maxbits > 16 * hiressprite) - maxbits = 16 * hiressprite; - for (bits = 0; bits < maxbits && x < w2; bits++) { - uae_u8 c = ((d2 & 0x80000000) ? 2 : 0) + ((d1 & 0x80000000) ? 1 : 0); - d1 <<= 1; - d2 <<= 1; - putwinmousepixel (andDC, xorDC, x, y, c, ct); - if (c > 0) - isdata = 1; - x++; - if (doubledsprite && x < w2) { - putwinmousepixel (andDC, xorDC, x, y, c, ct); - x++; - } - } + andoBM = (HBITMAP)SelectObject(andDC, andBM); + xoroBM = (HBITMAP)SelectObject(xorDC, xorBM); + + isdata = false; + for (int y = 0; y < h; y++) { + uae_u8 *s = image + y * w; + for (int x = 0; x < w; x++) { + int c = *s++; + putwinmousepixel(andDC, xorDC, x, y, c, ct); + if (c > 0) { + isdata = true; } - if (y <= h2) - y++; } } ret = 1; - SelectObject (andDC, andoBM); - SelectObject (xorDC, xoroBM); + SelectObject(andDC, andoBM); + SelectObject(xorDC, xoroBM); end: - DeleteDC (xorDC); - DeleteDC (andDC); - DeleteDC (mainDC); - ReleaseDC (NULL, DC); + DeleteDC(xorDC); + DeleteDC(andDC); + DeleteDC(mainDC); + ReleaseDC(NULL, DC); if (!isdata) { - wincursor = LoadCursor (NULL, IDC_ARROW); + wincursor = LoadCursor(NULL, IDC_ARROW); } else if (ret) { - memset (&ic, 0, sizeof ic); + memset(&ic, 0, sizeof ic); ic.hbmColor = xorBM; ic.hbmMask = andBM; - wincursor = CreateIconIndirect (&ic); + wincursor = CreateIconIndirect(&ic); tmp_sprite_w = w; tmp_sprite_h = h; - tmp_sprite_data = xmalloc (uae_u8, datasize); - tmp_sprite_hires = hiressprite; - tmp_sprite_doubled = doubledsprite; - memcpy (tmp_sprite_data, realsrc, datasize); - memcpy (tmp_sprite_colors, ct, sizeof (uae_u32) * 4); + memcpy(tmp_sprite_data, image, datasize); + memcpy(tmp_sprite_colors, ct, sizeof (uae_u32) * 4); } - DeleteObject (andBM); - DeleteObject (xorBM); + DeleteObject(andBM); + DeleteObject(xorBM); if (wincursor) { - SetCursor (wincursor); + SetCursor(wincursor); wincursor_shown = 1; } - if (!ret) - write_log (_T("RTG Windows color cursor creation failed\n")); + if (!ret) { + write_log(_T("RTG Windows color cursor creation failed\n")); + } exit: if (currprefs.input_tablet && (currprefs.input_mouse_untrap & MOUSEUNTRAP_MAGIC) && currprefs.input_magic_mouse_cursor == MAGICMOUSE_NATIVE_ONLY) { - if (GetCursor () != NULL) - SetCursor (NULL); + if (GetCursor() != NULL) + SetCursor(NULL); } else { - if (wincursor == oldwincursor && normalcursor != NULL) - SetCursor (normalcursor); + if (wincursor == oldwincursor && normalcursor != NULL) { + SetCursor(normalcursor); + } + } + if (oldwincursor) { + DestroyIcon(oldwincursor); } - if (oldwincursor) - DestroyIcon (oldwincursor); oldwincursor = NULL; return ret; @@ -2049,7 +2050,7 @@ int picasso_setwincursor(int monid) SetCursor(wincursor); return 1; } else if (!ad->picasso_on) { - if (createwindowscursor(monid, 0, 0, 0, 0, 0, 1)) + if (createwindowscursor(monid, 0, 1)) return 1; } return 0; @@ -2084,20 +2085,20 @@ static uae_u32 setspriteimage(TrapContext *ctx, uaecptr bi) bi, trap_get_long(ctx, bi + PSSO_BoardInfo_MouseImage), w, h, hiressprite - 1, doubledsprite, bi + PSSO_BoardInfo_MouseImage)); - if (!w || !h || trap_get_long(ctx, bi + PSSO_BoardInfo_MouseImage) == 0) { + uaecptr iptr = trap_get_long(ctx, bi + PSSO_BoardInfo_MouseImage); + int datasize = 4 * hiressprite + h * 4 * hiressprite; + + if (!w || !h || iptr == 0 || !valid_address(iptr, datasize)) { cursordeactivate = 1; ret = 1; goto end; } - createwindowscursor (0, trap_get_long(ctx, bi + PSSO_BoardInfo_MouseImage) + 4 * hiressprite, - w, h, hiressprite, doubledsprite, 0); - - cursordata = xmalloc (uae_u8, w * h * bpp); + cursordata = xmalloc (uae_u8, w * h); for (y = 0, yy = 0; y < h; y++, yy++) { - uae_u8 *p = cursordata + w * bpp * y; + uae_u8 *p = cursordata + w * y; uae_u8 *pprev = p; - uaecptr img = trap_get_long(ctx, bi + PSSO_BoardInfo_MouseImage) + 4 * hiressprite + yy * 4 * hiressprite; + uaecptr img = iptr + 4 * hiressprite + yy * 4 * hiressprite; x = 0; while (x < w) { uae_u32 d1 = trap_get_long(ctx, img); @@ -2109,19 +2110,17 @@ static uae_u32 setspriteimage(TrapContext *ctx, uaecptr bi) uae_u8 c = ((d2 & 0x80000000) ? 2 : 0) + ((d1 & 0x80000000) ? 1 : 0); d1 <<= 1; d2 <<= 1; - putmousepixel (p, bpp, c); - p += bpp; + *p++ = c; x++; if (doubledsprite && x < w) { - putmousepixel (p, bpp, c); - p += bpp; + *p++ = c; x++; } } } if (doubledsprite && y < h) { y++; - memcpy (p, pprev, w * bpp); + memcpy(p, pprev, w); } } @@ -2132,6 +2131,8 @@ static uae_u32 setspriteimage(TrapContext *ctx, uaecptr bi) if (cursorheight > CURSORMAXHEIGHT) cursorheight = CURSORMAXHEIGHT; + createwindowscursor(0, 1, 0); + setupcursor (); ret = 1; cursorok = TRUE; diff --git a/od-win32/picasso96_win.h b/od-win32/picasso96_win.h index 7b635d1e..94fc0854 100644 --- a/od-win32/picasso96_win.h +++ b/od-win32/picasso96_win.h @@ -692,7 +692,6 @@ extern void gfx_set_picasso_colors(int monid, RGBFTYPE rgbfmt); extern void gfx_set_picasso_state(int monid,int on); extern uae_u8 *gfx_lock_picasso(int monid, bool); extern void gfx_unlock_picasso(int monid, bool); -extern int createwindowscursor(int monid, uaecptr src, int w, int h, int hiressprite, int doubledsprite, int chipset); void lockrtg(void); void unlockrtg(void); -- 2.47.3