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*);
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 */
+/* Direct3D 9 graphics renderer */
+
#include <windows.h>
#include "resource.h"
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;
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;
//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"),
} 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));
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);
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;
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;
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);
}
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;
}
};
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);
+/* Direct3D 11 graphics renderer */
+
#include <windows.h>
#include "resource.h"
#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);
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;
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.
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;
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;
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;
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;
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");
}
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;
//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;
+/* GDI graphics renderer */
+
#include <windows.h>
#include "resource.h"
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;
{
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) {
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;
}
{
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)
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);
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");
}
return NULL;
}
+ *errp = 1;
return _T("failed to allocate buffer");
}
}
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)
*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;
}
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];
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);
maxh = (int)((maxh + mult - multadd) / mult);
}
+ *mode = 1;
+
width_aspect = cw;
height_aspect = ch;
}
}
-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];
picasso_offset_mx = 1.0;
picasso_offset_my = 1.0;
+ *mode = 0;
+
if (!ad->picasso_on)
return;
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;
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;
}
} 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;
}
} 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;
}
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);
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;