From: Toni Wilen Date: Sun, 31 Jul 2022 18:06:21 +0000 (+0300) Subject: GDI positioning and hw sprite fixed. Integer scaling updates. X-Git-Tag: 41000~183 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=728edc83a53da1035adbfca07815d092d0e1b9ca;p=francis%2Fwinuae.git GDI positioning and hw sprite fixed. Integer scaling updates. --- diff --git a/include/gfxfilter.h b/include/gfxfilter.h index 801f2ef2..4ad8d25d 100644 --- a/include/gfxfilter.h +++ b/include/gfxfilter.h @@ -77,9 +77,8 @@ struct uae_filter extern struct uae_filter uaefilters[]; -void getfilterrect2(int monid, RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height, int aw, int ah, int scale, int temp_width, int temp_height); +void getfilterrect2(int monid, RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height, int aw, int ah, int scale, int *mode, int temp_width, int temp_height); void getfilteroffset(int monid, float *dx, float *dy, float *mx, float *my); -uae_u8 *getfilterbuffer3d(int monid, int *widthp, int *heightp, int *pitch, int *depth); uae_u8 *getfilterbuffer(int monid, int *widthp, int *heightp, int *pitch, int *depth); void freefilterbuffer(int monid, uae_u8*); @@ -87,7 +86,8 @@ void freefilterbuffer(int monid, uae_u8*); uae_u8 *uaegfx_getrtgbuffer(int monid, int *widthp, int *heightp, int *pitch, int *depth, uae_u8 *palette); void uaegfx_freertgbuffer(int monid, uae_u8 *dst); -extern void getrtgfilterrect2(int monid, RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height); +extern void getrtgfilterrect2(int monid, RECT *sr, RECT *dr, RECT *zr, int *mode, int dst_width, int dst_height); +extern float filterrectmult(int v1, float v2, int dmode); #endif /* GFXFILTER */ diff --git a/od-win32/direct3d.cpp b/od-win32/direct3d.cpp index 8ce1750e..dc258377 100644 --- a/od-win32/direct3d.cpp +++ b/od-win32/direct3d.cpp @@ -1,4 +1,6 @@ +/* Direct3D 9 graphics renderer */ + #include #include "resource.h" @@ -198,12 +200,13 @@ struct d3dstruct int ledwidth, ledheight; int max_texture_w, max_texture_h; int tin_w, tin_h, tout_w, tout_h, window_h, window_w; - int t_depth, dmult, dmultxh, dmultxv; + int t_depth, dmult, dmultxh, dmultxv, dmode; int required_sl_texture_w, required_sl_texture_h; int vsync2, guimode, maxscanline, variablerefresh; int resetcount; float cursor_x, cursor_y; float cursor_mx, cursor_my; + float xmult, ymult; bool cursor_v, cursor_scale; int statusbar_vx, statusbar_hx; @@ -2080,7 +2083,7 @@ static bool xD3D_getscalerect(int monid, float *mx, float *my, float *sx, float return true; } -static void setupscenecoords (struct d3dstruct *d3d, bool normalrender) +static void setupscenecoords(struct d3dstruct *d3d, bool normalrender) { int monid = d3d->num; struct vidbuf_description *vidinfo = &adisplays[monid].gfxvidinfo; @@ -2094,7 +2097,7 @@ static void setupscenecoords (struct d3dstruct *d3d, bool normalrender) //write_log (_T("%dx%d %dx%d %dx%d\n"), tin_w, tin_h, tin_w, tin_h, window_w, window_h); - getfilterrect2 (monid, &dr, &sr, &zr, d3d->window_w, d3d->window_h, d3d->tin_w / d3d->dmult, d3d->tin_h / d3d->dmult, d3d->dmult, d3d->tin_w, d3d->tin_h); + getfilterrect2 (monid, &dr, &sr, &zr, d3d->window_w, d3d->window_h, d3d->tin_w / d3d->dmult, d3d->tin_h / d3d->dmult, d3d->dmult, &d3d->dmode, d3d->tin_w, d3d->tin_h); if (memcmp (&sr, &sr2[monid], sizeof RECT) || memcmp (&dr, &dr2[monid], sizeof RECT) || memcmp (&zr, &zr2[monid], sizeof RECT)) { write_log (_T("POS (%d %d %d %d) - (%d %d %d %d)[%d,%d] (%d %d)\n"), @@ -2147,8 +2150,8 @@ static void setupscenecoords (struct d3dstruct *d3d, bool normalrender) } else { - tx = -0.5f + dw * d3d->tin_w / d3d->window_w / 2; - ty = +0.5f + dh * d3d->tin_h / d3d->window_h / 2; + tx = dw * d3d->tin_w / d3d->window_w / 2; + ty = dh * d3d->tin_h / d3d->window_h / 2; float xshift = (float)(- zr.left - sr.left); // - (tin_w - 2 * zr.left - w), float yshift = (float)(+ zr.top + sr.top - (d3d->tin_h - h)); @@ -2162,8 +2165,13 @@ static void setupscenecoords (struct d3dstruct *d3d, bool normalrender) tx += xshift; ty += yshift; + tx = (float)(int)(tx + 0.0f); + ty = (float)(int)(ty + 0.0f); } + d3d->xmult = filterrectmult(d3d->window_w, w, d3d->dmode); + d3d->ymult = filterrectmult(d3d->window_h, h, d3d->dmode); + MatrixTranslation (&d3d->m_matView_out, tx, ty, 1.0f); MatrixScaling (&d3d->m_matWorld_out, sw + 0.5f / sw, sh + 0.5f / sh, 1.0f); @@ -2853,7 +2861,7 @@ static const TCHAR *D3D_init2 (struct d3dstruct *d3d, HWND ahwnd, int w_w, int w if (d3d->d3d_ex && D3DEX) { write_log (_T("%s\n"), errmsg); D3DEX = 0; - return D3D_init(ahwnd, monid, w_w, w_h, depth, freq, mmulth, mmultv); + return D3D_init2(d3d, ahwnd, w_w, w_h, depth, freq, mmulth, mmultv); } D3D_free(monid, true); return errmsg; @@ -3043,12 +3051,17 @@ static void D3D_init_start (void *p) d3d->fakemode = false; } -static const TCHAR *xD3D_init (HWND ahwnd, int monid, int w_w, int w_h, int depth, int *freq, int mmulth, int mmultv) +static const TCHAR *xD3D_init (HWND ahwnd, int monid, int w_w, int w_h, int depth, int *freq, int mmulth, int mmultv, int *errp) { struct d3dstruct *d3d = &d3ddata[monid]; - if (!fakemodewaitms) - return D3D_init2 (d3d, ahwnd, w_w, w_h, depth, freq, mmulth, mmultv); + if (!fakemodewaitms) { + const TCHAR *v = D3D_init2(d3d, ahwnd, w_w, w_h, depth, freq, mmulth, mmultv); + if (v != NULL) { + *errp = 1; + } + return v; + } d3d->fakemode = true; d3dargs.hwnd = ahwnd; d3dargs.w = w_w; @@ -3542,8 +3555,8 @@ static void D3D_render2(struct d3dstruct *d3d, int mode) MatrixScaling(&t, ((float)(d3d->window_w) / (d3d->tout_w + 2 * d3d->cursor_offset2_x)) * d3d->cursor_mx, ((float)(d3d->window_h) / (d3d->tout_h + 2 * d3d->cursor_offset2_y)) * d3d->cursor_my, 0); else MatrixScaling(&t, d3d->cursor_mx, d3d->cursor_my, 0); - v.x = (float)d3d->cursor_x / d3d->cursor_mx + d3d->cursor_offset2_x; - v.y = (float)d3d->cursor_y / d3d->cursor_my + d3d->cursor_offset2_y; + v.x = (float)d3d->cursor_x + d3d->cursor_offset2_x; + v.y = (float)d3d->cursor_y + d3d->cursor_offset2_y; v.z = 0.0f; d3d->sprite->SetTransform(&t); d3d->sprite->Draw(d3d->cursorsurfaced3d, NULL, NULL, &v, 0xffffffff); @@ -3685,17 +3698,17 @@ static bool xD3D_setcursor(int monid, int x, int y, int width, int height, float } if (width && height) { - d3d->cursor_offset2_x = d3d->cursor_offset_x * d3d->window_w / width; - d3d->cursor_offset2_y = d3d->cursor_offset_y * d3d->window_h / height; - d3d->cursor_x = (float)x * d3d->window_w / width; - d3d->cursor_y = (float)y * d3d->window_h / height; - d3d->cursor_mx = mx; - d3d->cursor_my = my; + d3d->cursor_offset2_x = d3d->cursor_offset_x; + d3d->cursor_offset2_y = d3d->cursor_offset_y; + d3d->cursor_x = (float)x; + d3d->cursor_y = (float)y; + d3d->cursor_mx = mx * d3d->xmult; + d3d->cursor_my = my * d3d->ymult; } else { d3d->cursor_x = d3d->cursor_y = 0; d3d->cursor_offset2_x = d3d->cursor_offset2_y = 0; } - d3d->cursor_scale = !noscale; + d3d->cursor_scale = false; // !noscale; d3d->cursor_v = visible; return true; } diff --git a/od-win32/direct3d.h b/od-win32/direct3d.h index 09ffad88..63e5905e 100644 --- a/od-win32/direct3d.h +++ b/od-win32/direct3d.h @@ -8,7 +8,7 @@ struct extoverlay }; extern void(*D3D_free)(int, bool immediate); -extern const TCHAR* (*D3D_init)(HWND ahwnd, int, int w_w, int h_h, int depth, int *freq, int mmulth, int mmultv); +extern const TCHAR* (*D3D_init)(HWND ahwnd, int, int w_w, int h_h, int depth, int *freq, int mmulth, int mmultv, int *errp); extern bool(*D3D_alloctexture)(int, int, int); extern void(*D3D_refresh)(int); extern bool(*D3D_renderframe)(int, int,bool); diff --git a/od-win32/direct3d11.cpp b/od-win32/direct3d11.cpp index 670f5b43..ab5b0ab3 100644 --- a/od-win32/direct3d11.cpp +++ b/od-win32/direct3d11.cpp @@ -1,4 +1,6 @@ +/* Direct3D 11 graphics renderer */ + #include #include "resource.h" @@ -44,7 +46,7 @@ using Microsoft::WRL::ComPtr; #include void (*D3D_free)(int, bool immediate); -const TCHAR* (*D3D_init)(HWND ahwnd, int, int w_w, int h_h, int depth, int *freq, int mmulth, int mmultv); +const TCHAR *(*D3D_init)(HWND ahwnd, int, int w_w, int h_h, int depth, int *freq, int mmulth, int mmultv, int *err); bool (*D3D_alloctexture)(int, int, int); void(*D3D_refresh)(int); bool(*D3D_renderframe)(int, int,bool); @@ -261,7 +263,7 @@ struct d3d11struct DXGI_FORMAT scrformat; DXGI_FORMAT texformat; bool m_tearingSupport; - int dmult, dmultxh, dmultxv; + int dmult, dmultxh, dmultxv, dmode; int xoffset, yoffset; float xmult, ymult; DXGI_SWAP_CHAIN_DESC1 swapChainDesc; @@ -1493,14 +1495,14 @@ static bool UpdateBuffers(struct d3d11struct *d3d) positionY = (sh - bh) / 2 + d3d->yoffset; // Calculate the screen coordinates of the left side of the bitmap. - left = (sw + 1.0f) / -2.0f; + left = (sw + 0.5f) / -2.0f; left += positionX; // Calculate the screen coordinates of the right side of the bitmap. right = left + bw; // Calculate the screen coordinates of the top of the bitmap. - top = (sh + 1.0f) / 2.0f; + top = (sh + 0.5f) / 2.0f; top -= positionY; // Calculate the screen coordinates of the bottom of the bitmap. @@ -1532,7 +1534,7 @@ static void setupscenecoords(struct d3d11struct *d3d, bool normalrender) if (!normalrender) return; - getfilterrect2(d3d->num, &dr, &sr, &zr, d3d->m_screenWidth, d3d->m_screenHeight, d3d->m_bitmapWidth / d3d->dmult, d3d->m_bitmapHeight / d3d->dmult, d3d->dmult, d3d->m_bitmapWidth, d3d->m_bitmapHeight); + getfilterrect2(d3d->num, &dr, &sr, &zr, d3d->m_screenWidth, d3d->m_screenHeight, d3d->m_bitmapWidth / d3d->dmult, d3d->m_bitmapHeight / d3d->dmult, d3d->dmult, &d3d->dmode, d3d->m_bitmapWidth, d3d->m_bitmapHeight); if (!memcmp(&sr, &d3d->sr2, sizeof RECT) && !memcmp(&dr, &d3d->dr2, sizeof RECT) && !memcmp(&zr, &d3d->zr2, sizeof RECT)) { return; @@ -1571,8 +1573,8 @@ static void setupscenecoords(struct d3d11struct *d3d, bool normalrender) d3d->xoffset = tx + xshift - d3d->m_screenWidth / 2; d3d->yoffset = ty + yshift - d3d->m_screenHeight / 2; - d3d->xmult = d3d->m_screenWidth / w; - d3d->ymult = d3d->m_screenHeight / h; + d3d->xmult = filterrectmult(d3d->m_screenWidth, w, d3d->dmode); + d3d->ymult = filterrectmult(d3d->m_screenHeight, h, d3d->dmode); d3d->cursor_offset_x = -zr.left; d3d->cursor_offset_y = -zr.top; @@ -3413,11 +3415,13 @@ static int xxD3D11_init2(HWND ahwnd, int monid, int w_w, int w_h, int t_w, int t d3d->delayedfs = 0; d3d->device_errors = 0; - if (depth != 32) + if (depth != 32) { return 0; + } - if (!can_D3D11(false)) + if (!can_D3D11(false)) { return 0; + } d3d->m_bitmapWidth = t_w; d3d->m_bitmapHeight = t_h; @@ -3452,7 +3456,7 @@ static int xxD3D11_init2(HWND ahwnd, int monid, int w_w, int w_h, int t_w, int t if (!os_win8) { gui_message(_T("WinUAE Direct3D 11 mode requires Windows 7 Platform Update (KB2670838). Check Windows Update optional updates or download it from: https://www.microsoft.com/en-us/download/details.aspx?id=36805")); } - return false; + return 0; } } else { BOOL allowTearing = FALSE; @@ -4104,16 +4108,21 @@ static int xxD3D11_init(HWND ahwnd, int monid, int w_w, int w_h, int depth, int return xxD3D11_init2(ahwnd, monid, w_w, w_h, w_w, w_h, depth, freq, mmulth, mmultv); } -static const TCHAR *xD3D11_init(HWND ahwnd, int monid, int w_w, int w_h, int depth, int *freq, int mmulth, int mmultv) +static const TCHAR *xD3D11_init(HWND ahwnd, int monid, int w_w, int w_h, int depth, int *freq, int mmulth, int mmultv, int *errp) { - if (!can_D3D11(false)) + if (!can_D3D11(false)) { + *errp = 1; return _T("D3D11 FAILED TO INIT"); + } int v = xxD3D11_init(ahwnd, monid, w_w, w_h, depth, freq, mmulth, mmultv); - if (v > 0) + if (v > 0) { return NULL; + } xD3D11_free(monid, true); - if (v <= 0) + *errp = 1; + if (v <= 0) { return _T(""); + } return _T("D3D11 INITIALIZATION ERROR"); } @@ -5203,10 +5212,10 @@ static bool xD3D_setcursor(int monid, int x, int y, int width, int height, float return true; if (width && height) { - d3d->cursor_offset2_x = d3d->cursor_offset_x * d3d->m_screenWidth / width; - d3d->cursor_offset2_y = d3d->cursor_offset_y * d3d->m_screenHeight / height; - d3d->cursor_x = (float)x * d3d->m_screenWidth / width; - d3d->cursor_y = (float)y * d3d->m_screenHeight / height; + d3d->cursor_offset2_x = d3d->cursor_offset_x; + d3d->cursor_offset2_y = d3d->cursor_offset_y; + d3d->cursor_x = (float)x; + d3d->cursor_y = (float)y; } else { d3d->cursor_x = d3d->cursor_y = 0; d3d->cursor_offset2_x = d3d->cursor_offset2_y = 0; @@ -5214,21 +5223,16 @@ static bool xD3D_setcursor(int monid, int x, int y, int width, int height, float //write_log(_T("%.1fx%.1f %dx%d\n"), d3d->cursor_x, d3d->cursor_y, d3d->cursor_offset2_x, d3d->cursor_offset2_y); - float multx = 1.0f; - float multy = 1.0f; - if (d3d->cursor_scale) { - multx = ((float)(d3d->m_screenWidth) / ((d3d->m_bitmapWidth * d3d->dmult) + 2 * d3d->cursor_offset2_x)); - multy = ((float)(d3d->m_screenHeight) / ((d3d->m_bitmapHeight * d3d->dmult) + 2 * d3d->cursor_offset2_y)); - } + float multx = d3d->xmult; + float multy = d3d->ymult; - setspritescaling(&d3d->hwsprite, mx / multx, my / multy); + setspritescaling(&d3d->hwsprite, mx * multx, my * multy); d3d->hwsprite.x = d3d->cursor_x * multx + d3d->cursor_offset2_x * multx; d3d->hwsprite.y = d3d->cursor_y * multy + d3d->cursor_offset2_y * multy; //write_log(_T("-> %.1fx%.1f %.1f %.1f\n"), d3d->hwsprite.x, d3d->hwsprite.y, multx, multy); - d3d->cursor_scale = !noscale; d3d->cursor_v = visible; d3d->hwsprite.enabled = visible; d3d->hwsprite.bilinear = d3d->filterd3d->gfx_filter_bilinear; diff --git a/od-win32/gdirender.cpp b/od-win32/gdirender.cpp index 85bdab5e..ff06fb99 100644 --- a/od-win32/gdirender.cpp +++ b/od-win32/gdirender.cpp @@ -1,4 +1,6 @@ +/* GDI graphics renderer */ + #include #include "resource.h" @@ -50,10 +52,10 @@ struct gdistruct bool cursor_v, cursor_scale; RECT sr2, dr2, zr2; - int dmult, dmultxh, dmultxv; + int dmult, dmultxh, dmultxv, dmode; int xoffset, yoffset; float xmult, ymult; - int cursor_offset_x, cursor_offset_y, cursor_offset2_x, cursor_offset2_y; + int cursor_offset_x, cursor_offset_y; int bmxoffset, bmyoffset; int bmwidth, bmheight; @@ -72,9 +74,9 @@ static void setupscenecoords(struct gdistruct *gdi) { RECT sr, dr, zr; - getfilterrect2(gdi->num, &dr, &sr, &zr, gdi->wwidth, gdi->wheight, gdi->bm.width / gdi->dmult, gdi->bm.height / gdi->dmult, gdi->dmult, gdi->bm.width, gdi->bm.height); + getfilterrect2(gdi->num, &dr, &sr, &zr, gdi->wwidth, gdi->wheight, gdi->bm.width / gdi->dmult, gdi->bm.height / gdi->dmult, gdi->dmult, &gdi->dmode, gdi->bm.width, gdi->bm.height); - if (0 && !memcmp(&sr, &gdi->sr2, sizeof RECT) && !memcmp(&dr, &gdi->dr2, sizeof RECT) && !memcmp(&zr, &gdi->zr2, sizeof RECT)) { + if (!memcmp(&sr, &gdi->sr2, sizeof RECT) && !memcmp(&dr, &gdi->dr2, sizeof RECT) && !memcmp(&zr, &gdi->zr2, sizeof RECT)) { return; } if (1) { @@ -91,30 +93,61 @@ static void setupscenecoords(struct gdistruct *gdi) gdi->dr2 = dr; gdi->zr2 = zr; - int w = sr.right - sr.left; - int h = sr.bottom - sr.top; + float dw = (float)dr.right - dr.left; + float dh = (float)dr.bottom - dr.top; + float w = (float)sr.right - sr.left; + float h = (float)sr.bottom - sr.top; + + int tx = ((dr.right - dr.left) * gdi->bm.width) / (gdi->wwidth * 2); + int ty = ((dr.bottom - dr.top) * gdi->bm.height) / (gdi->wheight * 2); + + float sw = dw / gdi->wwidth; + float sh = dh / gdi->wheight; + + int xshift = -zr.left - sr.left; + int yshift = -zr.top - sr.top; + + xshift -= ((sr.right - sr.left) - gdi->wwidth) / 2; + yshift -= ((sr.bottom - sr.top) - gdi->wheight) / 2; + + gdi->xoffset = tx + xshift - gdi->wwidth / 2; + gdi->yoffset = ty + yshift - gdi->wheight / 2; + + gdi->xmult = filterrectmult(gdi->wwidth, w, gdi->dmode); + gdi->ymult = filterrectmult(gdi->wheight, h, gdi->dmode); + + gdi->cursor_offset_x = -zr.left; + gdi->cursor_offset_y = -zr.top; + + sw *= gdi->wwidth; + sh *= gdi->wheight; + + gdi->bmwidth = (int)(gdi->bm.width * gdi->xmult); + gdi->bmheight = (int)(gdi->bm.height * gdi->ymult); - int dw = dr.right - dr.left; - int dh = dr.bottom - dr.top; + int positionX, positionY; + int bw2 = gdi->bm.width; + int bh2 = gdi->bm.height; + int sw2 = gdi->wwidth; + int sh2 = gdi->wheight; - gdi->xmult = (float)gdi->wwidth / w; - gdi->ymult = (float)gdi->wheight / h; + positionX = (sw2 - bw2) / 2 + gdi->xoffset; + positionY = (sh2 - bh2) / 2 + gdi->yoffset; - gdi->bmwidth = gdi->bm.width * gdi->xmult; - gdi->bmheight = gdi->bm.height * gdi->ymult; + float left = sw2 / -2.0f; + left += positionX; - gdi->bmxoffset = (gdi->wwidth - gdi->bm.width) / 2; - gdi->bmyoffset = (gdi->wheight - gdi->bm.height) / 2; + float top = sh2 / -2.0f; + top += positionY; -// gdi->bmxoffset -= zr.left / gdi->xmult; -// gdi->bmxoffset = (gdi->wwidth - w * gdi->xmult) / 2; -// gdi->bmyoffset = (gdi->wheight - h * gdi->ymult) / 2; + left *= gdi->xmult; + top *= gdi->ymult; - //gdi->bmxoffset += (dw - gdi->wwidth) / gdi->xmult / 2; + left += gdi->wwidth / 2.0f; + top += gdi->wheight / 2.0f; -// gdi->bmxoffset += zr.left * gdi->xmult - ((sr.right - sr.left) - gdi->wwidth); -// gdi->bmyoffset = (gdi->wheight - gdi->bm.height) / 2; -// gdi->bmyoffset += zr.top * gdi->ymult - ((sr.bottom - sr.top) - gdi->wheight); + gdi->bmxoffset = (int)left; + gdi->bmyoffset = (int)top; gdi->eraseneeded = true; } @@ -149,6 +182,10 @@ static void freetexture(int monid) { struct gdistruct *gdi = &gdidata[monid]; freesprite(gdi, &gdi->bm); + if (gdi->hdc) { + ReleaseDC(gdi->hwnd, gdi->hdc); + gdi->hdc = NULL; + } } static bool allocsprite(struct gdistruct *gdi, struct gdibm *bm, int w, int h) @@ -298,7 +335,7 @@ static void gdi_paint(void) StretchBlt(gdi->buf.thdc, gdi->bmxoffset, gdi->bmyoffset, gdi->bmwidth, gdi->bmheight, gdi->bm.thdc, 0, 0, gdi->bm.width, gdi->bm.height, SRCCOPY); } if (gdi->cursor.active && gdi->cursor.hbm) { - TransparentBlt(gdi->buf.thdc, gdi->cursor.x, gdi->cursor.y, CURSORMAXWIDTH, CURSORMAXHEIGHT, gdi->cursor.thdc, 0, 0, CURSORMAXWIDTH, CURSORMAXHEIGHT, 0x000000); + TransparentBlt(gdi->buf.thdc, gdi->cursor.x, gdi->cursor.y, (int)(CURSORMAXWIDTH * gdi->xmult), (int)(CURSORMAXHEIGHT * gdi->ymult), gdi->cursor.thdc, 0, 0, CURSORMAXWIDTH, CURSORMAXHEIGHT, 0xfe00fe); } if (gdi->osd.active && gdi->osd.hbm) { TransparentBlt(gdi->buf.thdc, gdi->osd.x, gdi->osd.y, gdi->ledwidth, gdi->ledheight, gdi->osd.thdc, 0, 0, gdi->ledwidth, gdi->ledheight, 0x000000); @@ -334,11 +371,12 @@ void gdi_free(int monid, bool immediate) freesprite(gdi, &gdi->cursor); } -static const TCHAR *gdi_init(HWND ahwnd, int monid, int w_w, int w_h, int depth, int *freq, int mmulth, int mmultv) +static const TCHAR *gdi_init(HWND ahwnd, int monid, int w_w, int w_h, int depth, int *freq, int mmulth, int mmultv, int *errp) { struct gdistruct *gdi = &gdidata[monid]; if (isfullscreen() > 0) { + *errp = -1; return _T("GDI fullscreen not supported"); } @@ -356,6 +394,7 @@ static const TCHAR *gdi_init(HWND ahwnd, int monid, int w_w, int w_h, int depth, return NULL; } + *errp = 1; return _T("failed to allocate buffer"); } @@ -384,21 +423,20 @@ static bool gdi_setcursor(int monid, int x, int y, int width, int height, float } if (width && height) { - gdi->cursor_offset2_x = gdi->cursor_offset_x * gdi->wwidth / width; - gdi->cursor_offset2_y = gdi->cursor_offset_y * gdi->wheight / height; - gdi->cursor_x = (float)x * gdi->wwidth / width; - gdi->cursor_y = (float)y * gdi->wheight / height; - gdi->cursor_mx = mx; - gdi->cursor_my = my; + gdi->cursor.x = (int)((float)x * mx * gdi->xmult + gdi->cursor_offset_x * gdi->ymult + 0.5f); + gdi->cursor.y = (int)((float)y * my * gdi->ymult + gdi->cursor_offset_y * gdi->xmult + 0.5f); } else { - gdi->cursor_x = gdi->cursor_y = 0; - gdi->cursor_offset2_x = gdi->cursor_offset2_y = 0; + gdi->cursor.x = gdi->cursor.y = 0; + } + if (gdi->cursor.x < 0) { + gdi->cursor.x = 0; + } + if (gdi->cursor.y < 0) { + gdi->cursor.y = 0; } gdi->cursor_scale = !noscale; gdi->cursor.active = visible; return true; - - return false; } static uae_u8 *gdi_setcursorsurface(int monid, int *pitch) @@ -409,6 +447,18 @@ static uae_u8 *gdi_setcursorsurface(int monid, int *pitch) *pitch = gdi->cursor.pitch; return (uae_u8*)gdi->cursor.bits; } + for (int y = 0; y < CURSORMAXHEIGHT; y++) { + for (int x = 0; x < CURSORMAXWIDTH; x++) { + uae_u32 *p = (uae_u32*)((uae_u8*)gdi->cursor.bits + gdi->cursor.pitch * y + x * 4); + uae_u32 v = *p; + if ((v & 0xff000000) == 0x00000000) { + *p = 0xfe00fe; + } else { + *p = v & 0xffffff; + } + } + } + return NULL; } diff --git a/od-win32/win32_scaler.cpp b/od-win32/win32_scaler.cpp index 12e4f387..b0976dae 100644 --- a/od-win32/win32_scaler.cpp +++ b/od-win32/win32_scaler.cpp @@ -237,7 +237,7 @@ static int res_match(int w) return w; } -void getfilterrect2(int monid, RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height, int aw, int ah, int scale, int temp_width, int temp_height) +void getfilterrect2(int monid, RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height, int aw, int ah, int scale, int *mode, int temp_width, int temp_height) { struct AmigaMonitor *mon = &AMonitors[monid]; struct amigadisplay *ad = &adisplays[monid]; @@ -268,9 +268,10 @@ void getfilterrect2(int monid, RECT *sr, RECT *dr, RECT *zr, int dst_width, int float filter_vert_offset = currprefs.gf[ad->picasso_on].gfx_filter_vert_offset / 10000.0f; store_custom_limits (-1, -1, -1, -1); + *mode = 0; if (mon->screen_is_picasso) { - getrtgfilterrect2(monid, sr, dr, zr, dst_width, dst_height); + getrtgfilterrect2(monid, sr, dr, zr, mode, dst_width, dst_height); if (D3D_getscalerect && D3D_getscalerect(monid, &mrmx, &mrmy, &mrsx, &mrsy, dst_width, dst_height)) { sizeoffset(dr, zr, (int)mrmx, (int)mrmy); OffsetRect(dr, (int)mrsx, (int)mrsy); @@ -459,6 +460,8 @@ void getfilterrect2(int monid, RECT *sr, RECT *dr, RECT *zr, int dst_width, int maxh = (int)((maxh + mult - multadd) / mult); } + *mode = 1; + width_aspect = cw; height_aspect = ch; diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index cac252b6..7d034e88 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -1539,7 +1539,26 @@ void flush_clear_screen (struct vidbuffer *vb) } } -void getrtgfilterrect2(int monid, RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height) +float filterrectmult(int v1, float v2, int dmode) +{ + float v = v1 / v2; + int vv = (int)(v + 0.5f); + if (v > 1.5f && vv * v2 <= v1 && vv * (v2 + vv - 1) >= v1) { + return (float)vv; + } + if (!dmode) { + return v; + } + if (v > 0.2f && v < 0.3f) { + return 0.25f; + } + if (v > 0.4f && v < 0.6f) { + return 0.5f; + } + return (float)(int)(v + 0.5f); +} + +void getrtgfilterrect2(int monid, RECT *sr, RECT *dr, RECT *zr, int *mode, int dst_width, int dst_height) { struct AmigaMonitor *mon = &AMonitors[monid]; struct amigadisplay *ad = &adisplays[monid]; @@ -1554,6 +1573,8 @@ void getrtgfilterrect2(int monid, RECT *sr, RECT *dr, RECT *zr, int dst_width, i picasso_offset_mx = 1.0; picasso_offset_my = 1.0; + *mode = 0; + if (!ad->picasso_on) return; @@ -1579,13 +1600,14 @@ void getrtgfilterrect2(int monid, RECT *sr, RECT *dr, RECT *zr, int dst_width, i if (mon->scalepicasso == RTG_MODE_INTEGER_SCALE) { int divx = mon->currentmode.native_width / srcwidth; int divy = mon->currentmode.native_height / srcheight; - int mul = divx > divy ? divy : divx; - SetRect (dr, 0, 0, mon->currentmode.native_width / mul, mon->currentmode.native_height / mul); + int mul = !divx || !divy ? 1 : (divx > divy ? divy : divx); + SetRect(dr, 0, 0, mon->currentmode.native_width / mul, mon->currentmode.native_height / mul); int xx = (mon->currentmode.native_width / mul - srcwidth) / 2; - int yy = (mon->currentmode.native_height / mul - srcheight) / 2; + int yy = (mon->currentmode.native_height / mul - srcheight) / 2; picasso_offset_x = -xx; picasso_offset_y = -yy; mx = my = 1.0; + *mode = 1; } else if (mon->scalepicasso == RTG_MODE_CENTER) { int xx = (mon->currentmode.native_width - srcwidth) / 2; int yy = (mon->currentmode.native_height - srcheight) / 2; @@ -1872,18 +1894,28 @@ static void update_gfxparams(struct AmigaMonitor *mon) mon->scalepicasso = 0; if (mon->screen_is_picasso) { + bool diff = state->Width != mon->currentmode.native_width || state->Height != mon->currentmode.native_height; if (isfullscreen () < 0) { - if ((currprefs.gf[1].gfx_filter_autoscale == RTG_MODE_CENTER || currprefs.gf[1].gfx_filter_autoscale == RTG_MODE_SCALE || currprefs.win32_rtgallowscaling) && (state->Width != mon->currentmode.native_width || state->Height != mon->currentmode.native_height)) - mon->scalepicasso = 1; - if (currprefs.gf[1].gfx_filter_autoscale == RTG_MODE_CENTER) + if ((currprefs.gf[1].gfx_filter_autoscale == RTG_MODE_CENTER || currprefs.gf[1].gfx_filter_autoscale == RTG_MODE_SCALE || currprefs.win32_rtgallowscaling) && diff) { + mon->scalepicasso = RTG_MODE_SCALE; + } + if (currprefs.gf[1].gfx_filter_autoscale == RTG_MODE_INTEGER_SCALE && diff) { + mon->scalepicasso = RTG_MODE_INTEGER_SCALE; + } + if (currprefs.gf[1].gfx_filter_autoscale == RTG_MODE_CENTER && diff) { mon->scalepicasso = currprefs.gf[1].gfx_filter_autoscale; - if (!mon->scalepicasso && currprefs.win32_rtgscaleaspectratio) + } + if (!mon->scalepicasso && currprefs.win32_rtgscaleaspectratio) { mon->scalepicasso = -1; + } } else if (isfullscreen () > 0) { if (!canmatchdepth()) { // can't scale to different color depth if (mon->currentmode.native_width > state->Width && mon->currentmode.native_height > state->Height) { if (currprefs.gf[1].gfx_filter_autoscale) - mon->scalepicasso = 1; + mon->scalepicasso = RTG_MODE_SCALE; + if (currprefs.gf[1].gfx_filter_autoscale == RTG_MODE_INTEGER_SCALE) { + mon->scalepicasso = RTG_MODE_INTEGER_SCALE; + } } if (currprefs.gf[1].gfx_filter_autoscale == RTG_MODE_CENTER) mon->scalepicasso = currprefs.gf[1].gfx_filter_autoscale; @@ -1911,9 +1943,9 @@ static void update_gfxparams(struct AmigaMonitor *mon) } } else if (currprefs.gf[1].gfx_filter_autoscale == RTG_MODE_SCALE) { if (currprefs.gfx_monitor[mon->monitor_id].gfx_size.width > state->Width || currprefs.gfx_monitor[mon->monitor_id].gfx_size.height > state->Height) - mon->scalepicasso = 1; + mon->scalepicasso = RTG_MODE_SCALE; if ((currprefs.gfx_monitor[mon->monitor_id].gfx_size.width != state->Width || currprefs.gfx_monitor[mon->monitor_id].gfx_size.height != state->Height) && currprefs.win32_rtgallowscaling) { - mon->scalepicasso = 1; + mon->scalepicasso = RTG_MODE_SCALE; } else if (currprefs.gfx_monitor[mon->monitor_id].gfx_size.width < state->Width || currprefs.gfx_monitor[mon->monitor_id].gfx_size.height < state->Height) { // no always scaling and smaller? Back to normal size and set new configured max size mon->currentmode.current_width = changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_win.width = state->Width; @@ -1925,7 +1957,7 @@ static void update_gfxparams(struct AmigaMonitor *mon) } } else { if ((currprefs.gfx_monitor[mon->monitor_id].gfx_size.width != state->Width || currprefs.gfx_monitor[mon->monitor_id].gfx_size.height != state->Height) && currprefs.win32_rtgallowscaling) - mon->scalepicasso = 1; + mon->scalepicasso = RTG_MODE_SCALE; if (!mon->scalepicasso && currprefs.win32_rtgscaleaspectratio) mon->scalepicasso = -1; } @@ -3934,9 +3966,17 @@ retry: if (currprefs.gf[ad->picasso_on].gfx_filter_filtermodev == 0) { fmv = fmh; } + int errv = 0; const TCHAR *err = D3D_init(mon->hAmigaWnd, mon->monitor_id, mon->currentmode.native_width, mon->currentmode.native_height, - mon->currentmode.current_depth, &mon->currentmode.freq, fmh, fmv); - if (err) { + mon->currentmode.current_depth, &mon->currentmode.freq, fmh, fmv, &errv); + if (errv) { + if (errv == -1 && currprefs.gfx_api == 0) { + write_log("Retrying D3D %s\n", err); + changed_prefs.gfx_api = currprefs.gfx_api = 2; + changed_prefs.color_mode = currprefs.color_mode = 5; + update_gfxparams(mon); + goto retry; + } gfx_hdr = false; if (currprefs.gfx_api >= 2) { D3D_free(0, true); @@ -3949,9 +3989,9 @@ retry: d3d_select(&currprefs); error_log(_T("Direct3D11 failed to initialize ('%s'), falling back to Direct3D9."), err); err = D3D_init(mon->hAmigaWnd, mon->monitor_id, mon->currentmode.native_width, mon->currentmode.native_height, - mon->currentmode.current_depth, &mon->currentmode.freq, fmh, fmv); + mon->currentmode.current_depth, &mon->currentmode.freq, fmh, fmv, &errv); } - if (err) { + if (errv) { D3D_free(0, true); if (isfullscreen() > 0) { int idx = mon->screen_is_picasso ? 1 : 0;