]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
GDI positioning and hw sprite fixed. Integer scaling updates.
authorToni Wilen <twilen@winuae.net>
Sun, 31 Jul 2022 18:06:21 +0000 (21:06 +0300)
committerToni Wilen <twilen@winuae.net>
Sun, 31 Jul 2022 18:06:21 +0000 (21:06 +0300)
include/gfxfilter.h
od-win32/direct3d.cpp
od-win32/direct3d.h
od-win32/direct3d11.cpp
od-win32/gdirender.cpp
od-win32/win32_scaler.cpp
od-win32/win32gfx.cpp

index 801f2ef253eb59b78c78275d76f9043cfd183a0f..4ad8d25d0ee624d1504ad84e6e6a1ee411fedfb6 100644 (file)
@@ -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 */
 
index 8ce1750e47a0d62931a16d95245b3646423a4c2d..dc258377189cf22b86214738f407c5640316a337 100644 (file)
@@ -1,4 +1,6 @@
 
+/* Direct3D 9 graphics renderer */
+
 #include <windows.h>
 #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;
 }
index 09ffad880a98730ef71c6db4f4a733e5d6c90c9d..63e5905e0f4e56dcf354e7977d4df0cea649d3b9 100644 (file)
@@ -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);
index 670f5b43d415eda6b3cfdaf55f66ec4a4965e142..ab5b0ab325fe3a9f7d8bd1682c11401b0883b7f3 100644 (file)
@@ -1,4 +1,6 @@
 
+/* Direct3D 11 graphics renderer */
+
 #include <windows.h>
 #include "resource.h"
 
@@ -44,7 +46,7 @@ using Microsoft::WRL::ComPtr;
 #include <Dwmapi.h>
 
 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;
index 85bdab5ec21d45c99375e008d419822e722a3a88..ff06fb99b87143114028e40bc5beaea2cbc9a132 100644 (file)
@@ -1,4 +1,6 @@
 
+/* GDI graphics renderer */
+
 #include <windows.h>
 #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;
 }
 
index 12e4f387a690198e4d4c91549ea3ff0ec02b7426..b0976daeab641c1a4b3c4e5290024b9478572840 100644 (file)
@@ -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;
 
index cac252b6e167d46f6c71d7bc110990adfb439856..7d034e882199bb4198efacc0edef572d1cc252bf 100644 (file)
@@ -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;