From 40ef8ffd28a3a91d9170662e8c3fce249f25a357 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Mon, 10 Apr 2023 16:47:29 +0300 Subject: [PATCH] D3D11 world matrix fix, D3D11 rotation support, HW cursor clipping --- cfgfile.cpp | 9 +- include/options.h | 1 + od-win32/direct3d.cpp | 101 +++++++--- od-win32/direct3d11.cpp | 288 +++++++++++++++++++---------- od-win32/gdirender.cpp | 33 +++- od-win32/picasso96_win.cpp | 4 +- od-win32/shaders/VertexShader.h | 218 +++++++++++++++------- od-win32/shaders/VertexShader.hlsl | 4 +- od-win32/win32gfx.cpp | 5 +- 9 files changed, 460 insertions(+), 203 deletions(-) diff --git a/cfgfile.cpp b/cfgfile.cpp index 33663c92..c30d524f 100644 --- a/cfgfile.cpp +++ b/cfgfile.cpp @@ -2528,6 +2528,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_dwrite_ext(f, _T("gfx_filter_overlay"), ext, _T("%s%s"), gf->gfx_filteroverlay, _tcschr (gf->gfx_filteroverlay, ',') ? _T(",") : _T("")); } + cfgfile_dwrite_ext(f, _T("gfx_filter_rotation"), ext, _T("%d"), gf->gfx_filter_rotation); } cfgfile_dwrite (f, _T("gfx_luminance"), _T("%d"), p->gfx_luminance); cfgfile_dwrite (f, _T("gfx_contrast"), _T("%d"), p->gfx_contrast); @@ -3655,7 +3656,6 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) || cfgfile_intval(option, value, _T("gfx_horizontal_extra"), &p->gfx_extrawidth, 1) || cfgfile_intval(option, value, _T("gfx_vertical_extra"), &p->gfx_extraheight, 1) || cfgfile_intval(option, value, _T("gfx_monitorblankdelay"), &p->gfx_monitorblankdelay, 1) - || cfgfile_intval(option, value, _T("gfx_rotation"), &p->gfx_rotation, 1) || cfgfile_intval (option, value, _T("floppy0sound"), &p->floppyslots[0].dfxclick, 1) || cfgfile_intval (option, value, _T("floppy1sound"), &p->floppyslots[1].dfxclick, 1) @@ -3744,6 +3744,12 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) || cfgfile_strval (option, value, _T("absolute_mouse"), &p->input_tablet, abspointers, 0)) return 1; + if (cfgfile_intval(option, value, _T("gfx_rotation"), &p->gfx_rotation, 1)) { + p->gf[GF_NORMAL].gfx_filter_rotation = p->gfx_rotation; + p->gf[GF_INTERLACE].gfx_filter_rotation = p->gfx_rotation; + return 1; + } + if (cfgfile_multichoice(option, value, _T("debugging_features"), &p->debugging_features, debugfeatures)) return 1; @@ -3795,6 +3801,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) || cfgfile_intval(option, value, _T("gfx_filter_bilinear"), ext, &gf->gfx_filter_bilinear, 1) || cfgfile_intval(option, value, _T("gfx_filter_keep_autoscale_aspect"), ext, &gf->gfx_filter_keep_autoscale_aspect, 1) || cfgfile_intval(option, value, _T("gfx_filter_enable"), ext, &gf->enable, 1) + || cfgfile_intval(option, value, _T("gfx_filter_rotation"), ext, &gf->gfx_filter_rotation, 1) || cfgfile_string(option, value, _T("gfx_filter_mask"), ext, gf->gfx_filtermask[2 * MAX_FILTERSHADERS], sizeof gf->gfx_filtermask[2 * MAX_FILTERSHADERS] / sizeof (TCHAR))) { return 1; diff --git a/include/options.h b/include/options.h index fa0b1ac3..81df3879 100644 --- a/include/options.h +++ b/include/options.h @@ -407,6 +407,7 @@ struct gfx_filterdata int gfx_filter_autoscale; int gfx_filter_integerscalelimit; int gfx_filter_keep_autoscale_aspect; + int gfx_filter_rotation; bool changed; }; diff --git a/od-win32/direct3d.cpp b/od-win32/direct3d.cpp index 15b28032..f7d6f393 100644 --- a/od-win32/direct3d.cpp +++ b/od-win32/direct3d.cpp @@ -168,6 +168,8 @@ struct d3dstruct float mask2texture_wwx, mask2texture_hhx, mask2texture_minusx, mask2texture_minusy; float mask2texture_multx, mask2texture_multy, mask2texture_offsetw; LPDIRECT3DTEXTURE9 cursorsurfaced3d; + uae_u8 *cursorsurfaced3dtexbuf; + bool cursorsurfaced3dtexbufupdated; struct d3d9overlay *extoverlays; IDirect3DVertexBuffer9 *vertexBuffer; ID3DXSprite *sprite; @@ -2083,9 +2085,8 @@ 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) { - int monid = d3d->num; struct vidbuf_description *vidinfo = &adisplays[monid].gfxvidinfo; RECT sr, dr, zr; float w, h; @@ -2171,10 +2172,12 @@ static void setupscenecoords(struct d3dstruct *d3d, bool normalrender) MatrixScaling (&d3d->m_matWorld_out, sw + 0.5f / sw, sh + 0.5f / sh, 1.0f); - if (currprefs.gfx_rotation) { + struct amigadisplay *ad = &adisplays[monid]; + int rota = currprefs.gf[ad->picasso_on ? GF_RTG : ad->interlace_on ? GF_INTERLACE : GF_NORMAL].gfx_filter_rotation; + if (rota) { const float PI = 3.14159265358979f; D3DXMATRIXA16 mrot; - D3DXMatrixRotationZ(&mrot, PI / 180.0f * currprefs.gfx_rotation); + D3DXMatrixRotationZ(&mrot, PI / 180.0f * rota); D3DXMATRIXA16 tmprmatrix; D3DXMatrixMultiply(&tmprmatrix, &d3d->m_matWorld_out, &mrot); d3d->m_matWorld_out = tmprmatrix; @@ -2398,6 +2401,8 @@ static void invalidatedeviceobjects (struct d3dstruct *d3d) d3d->cursorsurfaced3d->Release (); d3d->cursorsurfaced3d = NULL; } + xfree(d3d->cursorsurfaced3dtexbuf); + d3d->cursorsurfaced3dtexbuf = NULL; struct d3d9overlay *ov = d3d->extoverlays; while (ov) { struct d3d9overlay *next = ov->next; @@ -2516,6 +2521,8 @@ static int restoredeviceobjects (struct d3dstruct *d3d) int curw = CURSORMAXWIDTH, curh = CURSORMAXHEIGHT; d3d->cursorsurfaced3d = createtext (d3d, curw, curh, D3DFMT_A8R8G8B8); + d3d->cursorsurfaced3dtexbuf = xcalloc(uae_u8, curw * curh * 4); + d3d->cursorsurfaced3dtexbufupdated = false; d3d->cursor_v = false; d3d->cursor_scale = false; @@ -3352,7 +3359,7 @@ static void clearrt(struct d3dstruct *d3d) hr = d3d->d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(color[0], d3ddebug ? 0x80 : color[1], color[2]), 0, 0); } -static void D3D_render2(struct d3dstruct *d3d, int mode) +static void D3D_render2(struct d3dstruct *d3d, int mode, int monid) { struct AmigaMonitor *mon = &AMonitors[d3d - d3ddata]; HRESULT hr; @@ -3419,7 +3426,7 @@ static void D3D_render2(struct d3dstruct *d3d, int mode) masktexture = s->masktexture; } - setupscenecoords(d3d, normalrender); + setupscenecoords(d3d, normalrender, monid); hr = d3d->d3ddev->SetTransform (D3DTS_PROJECTION, &d3d->m_matProj); hr = d3d->d3ddev->SetTransform (D3DTS_VIEW, &d3d->m_matView); hr = d3d->d3ddev->SetTransform (D3DTS_WORLD, &d3d->m_matWorld); @@ -3518,7 +3525,7 @@ static void D3D_render2(struct d3dstruct *d3d, int mode) } else { // non-shader version - setupscenecoords (d3d, normalrender); + setupscenecoords (d3d, normalrender, monid); hr = d3d->d3ddev->SetTransform (D3DTS_PROJECTION, &d3d->m_matProj); hr = d3d->d3ddev->SetTransform (D3DTS_VIEW, &d3d->m_matView); hr = d3d->d3ddev->SetTransform (D3DTS_WORLD, &d3d->m_matWorld); @@ -3686,6 +3693,63 @@ static void D3D_render2(struct d3dstruct *d3d, int mode) write_log (_T("%s: EndScene() %s\n"), D3DHEAD, D3D_ErrorString (hr)); } +static void updatecursorsurface(int monid) +{ + struct d3dstruct *d3d = &d3ddata[monid]; + D3DLOCKED_RECT locked; + int cx = (int)d3d->cursor_x; + int cy = (int)d3d->cursor_y; + int width = CURSORMAXWIDTH; + int height = CURSORMAXHEIGHT; + + if (!d3d->cursorsurfaced3d || !d3d->cursorsurfaced3dtexbuf) { + return; + } + + if (d3d->cursorsurfaced3dtexbufupdated && cx >= 0 && cy >= 0 && cx + width <= d3d->tin_w && cy + height <= d3d->tin_h) { + return; + } + + d3d->cursorsurfaced3dtexbufupdated = false; + HRESULT hr = d3d->cursorsurfaced3d->LockRect(0, &locked, NULL, 0); + if (SUCCEEDED(hr)) { + int pitch = locked.Pitch; + uae_u8 *b = (uae_u8 *)locked.pBits; + int cx = (int)d3d->cursor_x; + int cy = (int)d3d->cursor_y; + uae_u8 *s = d3d->cursorsurfaced3dtexbuf; + for (int h = 0; h < CURSORMAXHEIGHT; h++) { + int w = width; + int x = 0; + if (cx + w > d3d->tin_w) { + w -= (cx + w) - d3d->tin_w; + } + if (cx < 0) { + x = -cx; + w -= -cx; + } + if (w <= 0 || cy + h > d3d->tin_h) { + memset(b, 0, width * 4); + } else { + if (x > 0) { + memset(b, 0, x * 4); + } + memcpy(b + x * 4, s + x * 4, w * 4); + if (w < width) { + memset(b + w * 4, 0, (width - w) * 4); + } + } + b += pitch; + s += width * 4; + } + d3d->cursorsurfaced3d->UnlockRect(0); + + if (cx >= 0 && cy >= 0 && cx + width <= d3d->tin_w && cy + height <= d3d->tin_h) { + d3d->cursorsurfaced3dtexbufupdated = true; + } + } +} + static bool xD3D_setcursor(int monid, int x, int y, int width, int height, float mx, float my, bool visible, bool noscale) { struct d3dstruct *d3d = &d3ddata[monid]; @@ -3707,6 +3771,9 @@ static bool xD3D_setcursor(int monid, int x, int y, int width, int height, float } d3d->cursor_scale = false; // !noscale; d3d->cursor_v = visible; + + updatecursorsurface(monid); + return true; } @@ -3882,7 +3949,7 @@ static bool xD3D_renderframe(int monid, int mode, bool immediate) return true; } - D3D_render2 (d3d, mode); + D3D_render2 (d3d, mode, monid); flushgpu (d3d, immediate); return true; @@ -3939,7 +4006,7 @@ static void xD3D_refresh (int monid) return; createscanlines(d3d, 0); for (int i = 0; i < 3; i++) { - D3D_render2(d3d, true); + D3D_render2(d3d, true, monid); D3D_showframe2(d3d, true); } } @@ -4010,7 +4077,7 @@ static void xD3D_guimode(int monid, int guion) waitfakemode (d3d); if (!isd3d (d3d)) return; - D3D_render2(d3d, true); + D3D_render2(d3d, true, monid); D3D_showframe2(d3d, true); hr = d3d->d3ddev->SetDialogBoxMode (guion ? TRUE : FALSE); if (FAILED (hr)) @@ -4093,18 +4160,10 @@ static uae_u8 *xD3D_setcursorsurface(int monid, int *pitch) { struct d3dstruct *d3d = &d3ddata[monid]; if (pitch) { - D3DLOCKED_RECT locked; - if (!d3d->cursorsurfaced3d) - return NULL; - HRESULT hr = d3d->cursorsurfaced3d->LockRect(0, &locked, NULL, 0); - if (FAILED(hr)) - return NULL; - *pitch = locked.Pitch; - return (uae_u8*)locked.pBits; - } else { - d3d->cursorsurfaced3d->UnlockRect(0); - return NULL; + *pitch = CURSORMAXWIDTH * 4; + return d3d->cursorsurfaced3dtexbuf; } + return NULL; } static bool xD3D_getscanline(int *scanline, bool *invblank) diff --git a/od-win32/direct3d11.cpp b/od-win32/direct3d11.cpp index 3bded993..a5f7e917 100644 --- a/od-win32/direct3d11.cpp +++ b/od-win32/direct3d11.cpp @@ -201,6 +201,10 @@ struct d3d11sprite bool enabled; bool alpha; bool bilinear; + bool rotation; + bool screenlimit; + uae_u8 *texbuf; + bool updated; }; struct d3doverlay @@ -264,7 +268,7 @@ struct d3d11struct DXGI_FORMAT texformat; bool m_tearingSupport; int dmult, dmultxh, dmultxv, dmode; - int xoffset, yoffset; + float xoffset, yoffset; float xmult, ymult; DXGI_SWAP_CHAIN_DESC1 swapChainDesc; DXGI_SWAP_CHAIN_FULLSCREEN_DESC fsSwapChainDesc; @@ -446,6 +450,15 @@ static void TurnOffAlphaBlending(struct d3d11struct *d3d) d3d->m_deviceContext->OMSetBlendState(d3d->m_alphaDisableBlendingState, blendFactor, 0xffffffff); } +static float get_rotation(struct d3d11struct *d3d, int monid) +{ + struct amigadisplay *ad = &adisplays[monid]; + int rota = currprefs.gf[ad->picasso_on ? GF_RTG : ad->interlace_on ? GF_INTERLACE : GF_NORMAL].gfx_filter_rotation; + const float PI = 3.14159265358979f; + float rot = PI / 180.0f * rota; + return rot; +} + #define D3DX_DEFAULT ((UINT) -1) static bool psEffect_ParseParameters(struct d3d11struct *d3d, ID3DX11Effect *effect, struct shaderdata11 *s, char *fxname, char *data, UINT flags1) @@ -1493,52 +1506,42 @@ static bool UpdateVertexArray(struct d3d11struct *d3d, ID3D11Buffer *vertexbuffe return true; } -static bool UpdateBuffers(struct d3d11struct *d3d) +static bool UpdateBuffers(struct d3d11struct *d3d, int monid) { - float left, right, top, bottom; - int positionX, positionY; int bw = d3d->m_bitmapWidth; int bh = d3d->m_bitmapHeight; int sw = d3d->m_screenWidth; int sh = d3d->m_screenHeight; - positionX = (sw - bw) / 2 + d3d->xoffset; - positionY = (sh - bh) / 2 + d3d->yoffset; - - // Calculate the screen coordinates of the left side of the bitmap. - left = sw / -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 / 2.0f; - top -= positionY; - - // Calculate the screen coordinates of the bottom of the bitmap. - bottom = top - bh; + float positionX = d3d->xoffset; + float positionY = -d3d->yoffset; float slleft = 0; float sltop = 0; - float slright = (float)bw / sw * d3d->xmult; - float slbottom = (float)bh / sh * d3d->ymult; + float slright = (float)bw * d3d->xmult / sw; + float slbottom = (float)bh * d3d->ymult / sh; slright = slleft + slright; slbottom = sltop + slbottom; - left *= d3d->xmult; - right *= d3d->xmult; - top *= d3d->ymult; - bottom *= d3d->ymult; + float rot = get_rotation(d3d, monid); - write_log(_T("-> %f %f %f %f %f %f\n"), left, top, right, bottom, d3d->xmult, d3d->ymult); + D3DXMATRIX scaling, rotation, translation, worldMatrix; + xD3DXMatrixScaling(&scaling, bw * d3d->xmult, bh * d3d->ymult, 1.0f); + xD3DXMatrixRotationZ(&rotation, rot); - UpdateVertexArray(d3d, d3d->m_vertexBuffer, left, top, right, bottom, slleft, sltop, slright, slbottom); + xD3DXMatrixTranslation(&translation, positionX, positionY, 0.0f); + + xD3DXMatrixMultiply(&worldMatrix, &scaling, &rotation); + xD3DXMatrixMultiply(&worldMatrix, &worldMatrix, &translation); + + d3d->m_worldMatrix = worldMatrix; + + UpdateVertexArray(d3d, d3d->m_vertexBuffer, -0.5f, 0.5f, 0.5f, -0.5f, slleft, sltop, slright, slbottom); return true; } -static void setupscenecoords(struct d3d11struct *d3d, bool normalrender) +static void setupscenecoords(struct d3d11struct *d3d, bool normalrender, int monid) { RECT sr, dr, zr; @@ -1581,18 +1584,21 @@ static void setupscenecoords(struct d3d11struct *d3d, bool normalrender) xshift -= ((sr.right - sr.left) - d3d->m_screenWidth) / 2; yshift -= ((sr.bottom - sr.top) - d3d->m_screenHeight) / 2; - d3d->xoffset = tx + xshift - d3d->m_screenWidth / 2; - d3d->yoffset = ty + yshift - d3d->m_screenHeight / 2; + d3d->xoffset = (float)tx + xshift - d3d->m_screenWidth / 2.0f; + d3d->yoffset = (float)ty + yshift - d3d->m_screenHeight / 2.0f; d3d->xmult = filterrectmult(d3d->m_screenWidth, w, d3d->dmode); d3d->ymult = filterrectmult(d3d->m_screenHeight, h, d3d->dmode); + d3d->xoffset *= d3d->xmult; + d3d->yoffset *= d3d->ymult; + d3d->cursor_offset_x = -zr.left; d3d->cursor_offset_y = -zr.top; write_log(_T("%d %d %.f %.f\n"), d3d->xoffset, d3d->yoffset, d3d->xmult, d3d->ymult); - UpdateBuffers(d3d); + UpdateBuffers(d3d, monid); xD3DXMatrixOrthoOffCenterLH(&d3d->m_matProj_out, 0, w + 0.05f, 0, h + 0.05f, 0.0f, 1.0f); xD3DXMatrixTranslation(&d3d->m_matView_out, (float)tx, (float)ty, 1.0f); @@ -1753,6 +1759,8 @@ static void freesprite(struct d3d11sprite *s) s->indexbuffer->Release(); if (s->matrixbuffer) s->matrixbuffer->Release(); + if (s->texbuf) + xfree(s->texbuf); memset(s, 0, sizeof(struct d3d11sprite)); } @@ -1909,16 +1917,26 @@ static void setsprite(struct d3d11struct *d3d, struct d3d11sprite *s, float x, f s->y = y; } -static bool allocsprite(struct d3d11struct *d3d, struct d3d11sprite *s, int width, int height, bool alpha) +static bool allocsprite(struct d3d11struct *d3d, struct d3d11sprite *s, int width, int height, bool alpha, bool rotation, bool screenlimit) { D3D11_TEXTURE2D_DESC desc; D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; HRESULT hr; freesprite(s); + s->width = width; s->height = height; s->alpha = alpha; + s->rotation = rotation; + s->screenlimit = screenlimit; + + if (screenlimit) { + s->texbuf = xcalloc(uae_u8, width * height * 4); + if (!s->texbuf) { + return false; + } + } if (!InitializeBuffers(d3d, &s->vertexbuffer, &s->indexbuffer)) goto err; @@ -2035,8 +2053,8 @@ static bool CreateTexture(struct d3d11struct *d3d) return false; } - desc.Width = d3d->m_screenWidth; - desc.Height = d3d->m_screenHeight; + desc.Width = d3d->m_bitmapWidth; + desc.Height = d3d->m_bitmapHeight; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; hr = d3d->m_device->CreateTexture2D(&desc, nullptr, &d3d->screenshottexturetx); if (FAILED(hr)) { @@ -2075,12 +2093,12 @@ static bool CreateTexture(struct d3d11struct *d3d) d3d->statusbar_hx = d3d->statusbar_vx = statusline_set_multiplier(mon->monitor_id, d3d->m_screenWidth, d3d->m_screenHeight) / 100; d3d->ledwidth = d3d->m_screenWidth; d3d->ledheight = TD_TOTAL_HEIGHT * d3d->statusbar_vx; - allocsprite(d3d, &d3d->osd, d3d->ledwidth, d3d->ledheight, true); + allocsprite(d3d, &d3d->osd, d3d->ledwidth, d3d->ledheight, true, false, false); d3d->osd.enabled = true; d3d->cursor_v = false; d3d->cursor_scale = false; - allocsprite(d3d, &d3d->hwsprite, CURSORMAXWIDTH, CURSORMAXHEIGHT, true); + allocsprite(d3d, &d3d->hwsprite, CURSORMAXWIDTH, CURSORMAXHEIGHT, true, true, true); write_log(_T("D3D11 %dx%d main texture allocated\n"), d3d->m_bitmapWidth, d3d->m_bitmapHeight); @@ -2619,7 +2637,7 @@ static int createmask2texture(struct d3d11struct *d3d, const TCHAR *filename) } d3d->mask2texture_w = (float)img.width; d3d->mask2texture_h = (float)img.height; - if (!allocsprite(d3d, &d3d->mask2texture, img.width, img.height, true)) + if (!allocsprite(d3d, &d3d->mask2texture, img.width, img.height, true, true, false)) goto end; D3D11_MAPPED_SUBRESOURCE map; @@ -2675,7 +2693,7 @@ static int createmask2texture(struct d3d11struct *d3d, const TCHAR *filename) d3d->mask2texture_offsetw = (d3d->m_screenWidth - d3d->mask2texture_ww) / 2; if (d3d->mask2texture_offsetw > 0) { - allocsprite(d3d, &d3d->blanksprite, (int)(d3d->mask2texture_offsetw + 1), d3d->m_screenHeight, false); + allocsprite(d3d, &d3d->blanksprite, (int)(d3d->mask2texture_offsetw + 1), d3d->m_screenHeight, false, false, false); } xmult = d3d->mask2texture_multx; @@ -2724,7 +2742,7 @@ static int createmask2texture(struct d3d11struct *d3d, const TCHAR *filename) if (load_png_image(zf, &ledimg)) { if (ledimg.width == img.width && ledimg.height == img.height) { narrowimg(&ledimg, &d3d->mask2textureledoffsets[i * 2 + 0], &d3d->mask2textureledoffsets[i * 2 + 1], tmp1); - if (allocsprite(d3d, &d3d->mask2textureleds[i], ledimg.width, ledimg.height, true)) { + if (allocsprite(d3d, &d3d->mask2textureleds[i], ledimg.width, ledimg.height, true, false, false)) { D3D11_MAPPED_SUBRESOURCE map; hr = d3d->m_deviceContext->Map(d3d->mask2textureleds[i].texture, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); if (SUCCEEDED(hr)) { @@ -2736,7 +2754,7 @@ static int createmask2texture(struct d3d11struct *d3d, const TCHAR *filename) d3d->mask2textureleds[i].enabled = true; d3d->mask2textureleds[i].bilinear = true; if (ledtypes[i] == LED_POWER) { - if (allocsprite(d3d, &d3d->mask2textureled_power_dim, ledimg.width, ledimg.height, true)) { + if (allocsprite(d3d, &d3d->mask2textureled_power_dim, ledimg.width, ledimg.height, true, false, false)) { hr = d3d->m_deviceContext->Map(d3d->mask2textureled_power_dim.texture, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); if (SUCCEEDED(hr)) { for (int j = 0; j < ledimg.height; j++) { @@ -3057,7 +3075,7 @@ static bool TextureShaderClass_InitializeShader(struct d3d11struct *d3d) return true; } -static bool initd3d(struct d3d11struct *d3d) +static bool initd3d(struct d3d11struct *d3d, int monid) { HRESULT result; ID3D11Texture2D *backBufferPtr; @@ -3173,7 +3191,7 @@ static bool initd3d(struct d3d11struct *d3d) return false; if (!InitializeBuffers(d3d, &d3d->m_vertexBuffer, &d3d->m_indexBuffer)) return false; - if (!UpdateBuffers(d3d)) + if (!UpdateBuffers(d3d, monid)) return false; settransform(d3d, NULL); @@ -4251,34 +4269,50 @@ static void TextureShaderClass_RenderShader(struct d3d11struct *d3d) d3d->m_deviceContext->DrawIndexed(INDEXCOUNT, 0, 0); } -static void RenderSprite(struct d3d11struct *d3d, struct d3d11sprite *spr) +static void RenderSprite(struct d3d11struct *d3d, struct d3d11sprite *spr, int monid) { - float left, top, right, bottom; + D3DXMATRIX scaling, rotation, translation, worldMatrix; + float left, top; + float w, h; + float rot = 0; if (!spr->enabled) return; - left = (float)((d3d->m_screenWidth + 1) / -2); - left += spr->x; - top = (float)((d3d->m_screenHeight + 1) / 2); - top -= spr->y; + left = spr->x; + top = -spr->y; if (spr->outwidth) { - right = left + spr->outwidth; + w = spr->outwidth; } else { - right = left + spr->width; + w = (float)spr->width; } if (spr->outheight) { - bottom = top - spr->outheight; + h = spr->outheight; } else { - bottom = top - spr->height; + h = (float)spr->height; + } + + if (spr->rotation) { + rot = get_rotation(d3d, monid); } - UpdateVertexArray(d3d, spr->vertexbuffer, left, top, right, bottom, 0, 0, 0, 0); + xD3DXMatrixScaling(&scaling, w, h, 1.0f); + xD3DXMatrixRotationZ(&rotation, rot); + + left += (int)(w / 2 + 0.5f) - d3d->m_screenWidth / 2; + top += (int)(-h / 2 - 0.5f) + d3d->m_screenHeight / 2; + + xD3DXMatrixTranslation(&translation, left, top, 0.0f); + + xD3DXMatrixMultiply(&worldMatrix, &scaling, &rotation); + xD3DXMatrixMultiply(&worldMatrix, &worldMatrix, &translation); + + UpdateVertexArray(d3d, spr->vertexbuffer, -0.5f, 0.5f, 0.5f, -0.5f, 0, 0, 0, 0); RenderBuffers(d3d, spr->vertexbuffer, spr->indexbuffer); - if (!setmatrix(d3d, spr->matrixbuffer, d3d->m_worldMatrix, d3d->m_viewMatrix, d3d->m_orthoMatrix)) + if (!setmatrix(d3d, spr->matrixbuffer, worldMatrix, d3d->m_viewMatrix, d3d->m_orthoMatrix)) return; if (spr->alpha) @@ -4304,11 +4338,11 @@ static void RenderSprite(struct d3d11struct *d3d, struct d3d11sprite *spr) static void setspritescaling(struct d3d11sprite *spr, float w, float h) { - spr->outwidth = w * spr->width + 0.5f; - spr->outheight = h * spr->height + 0.5f; + spr->outwidth = w * spr->width; + spr->outheight = h * spr->height; } -static void renderoverlay(struct d3d11struct *d3d) +static void renderoverlay(struct d3d11struct *d3d, int monid) { if (!d3d->mask2texture.enabled) return; @@ -4341,7 +4375,7 @@ static void renderoverlay(struct d3d11struct *d3d) #endif setsprite(d3d, spr, d3d->mask2texture_offsetw, 0); - RenderSprite(d3d, spr); + RenderSprite(d3d, spr, monid); for (int i = 0; overlayleds[i]; i++) { bool led = leds[ledtypes[i]] != 0; @@ -4354,7 +4388,7 @@ static void renderoverlay(struct d3d11struct *d3d) setsprite(d3d, sprled, d3d->mask2texture_offsetw + d3d->mask2textureledoffsets[i * 2 + 0] * d3d->mask2texture_multx, d3d->mask2textureledoffsets[i * 2 + 1] * d3d->mask2texture_multy); - RenderSprite(d3d, sprled); + RenderSprite(d3d, sprled, monid); } } } @@ -4362,9 +4396,9 @@ static void renderoverlay(struct d3d11struct *d3d) if (d3d->mask2texture_offsetw > 0) { struct d3d11sprite *bspr = &d3d->blanksprite; setsprite(d3d, bspr, 0, 0); - RenderSprite(d3d, bspr); + RenderSprite(d3d, bspr, monid); setsprite(d3d, bspr, d3d->mask2texture_offsetw + d3d->mask2texture_ww, 0); - RenderSprite(d3d, bspr); + RenderSprite(d3d, bspr, monid); } } @@ -4511,19 +4545,19 @@ static bool renderframe(struct d3d11struct *d3d) return true; } -static bool TextureShaderClass_Render(struct d3d11struct *d3d) +static bool TextureShaderClass_Render(struct d3d11struct *d3d, int monid) { renderframe(d3d); - RenderSprite(d3d, &d3d->hwsprite); + RenderSprite(d3d, &d3d->hwsprite, monid); - renderoverlay(d3d); + renderoverlay(d3d, monid); - RenderSprite(d3d, &d3d->osd); + RenderSprite(d3d, &d3d->osd, monid); struct d3doverlay *ov = d3d->extoverlays; while (ov) { - RenderSprite(d3d, &ov->s); + RenderSprite(d3d, &ov->s, monid); ov = ov->next; } @@ -4570,17 +4604,17 @@ static void CameraClass_Render(struct d3d11struct *d3d) xD3DXMatrixLookAtLH(&d3d->m_viewMatrix, &position, &lookAt, &up); } -static bool GraphicsClass_Render(struct d3d11struct *d3d, float rotation, bool normalrender) +static bool GraphicsClass_Render(struct d3d11struct *d3d, bool normalrender, int monid) { bool result; - setupscenecoords(d3d, normalrender); + setupscenecoords(d3d, normalrender, monid); // Generate the view matrix based on the camera's position. CameraClass_Render(d3d); // Render the bitmap with the texture shader. - result = TextureShaderClass_Render(d3d); + result = TextureShaderClass_Render(d3d, monid); if (!result) return false; @@ -4718,7 +4752,7 @@ static bool restore(struct d3d11struct *d3d) return true; } -static void resizemode(struct d3d11struct *d3d); +static void resizemode(struct d3d11struct *d3d, int monid); static bool xD3D11_renderframe(int monid, int mode, bool immediate) { @@ -4750,7 +4784,7 @@ static bool xD3D11_renderframe(int monid, int mode, bool immediate) if (d3d->delayedfs || !d3d->texture2d || !d3d->d3dinit_done) return false; - GraphicsClass_Render(d3d, 0, mode < 0 || (mode & 1)); + GraphicsClass_Render(d3d, mode < 0 || (mode & 1), monid); if (d3d->filenotificationhandle != NULL) { bool notify = false; @@ -4851,7 +4885,7 @@ static void xD3D11_refresh(int monid) } -static bool D3D11_resize_do(struct d3d11struct *d3d) +static bool D3D11_resize_do(struct d3d11struct *d3d, int monid) { HRESULT hr; @@ -4892,21 +4926,21 @@ static bool D3D11_resize_do(struct d3d11struct *d3d) write_log(_T("D3D11_resize -> none\n")); } - resizemode(d3d); + resizemode(d3d, monid); write_log(_T("D3D11 resize exit\n")); return true; } -static bool recheck(struct d3d11struct *d3d) +static bool recheck(struct d3d11struct *d3d, int monid) { bool r = false; if (xD3D11_quit(d3d)) return r; - r = D3D11_resize_do(d3d); + r = D3D11_resize_do(d3d, monid); if (d3d->resizeretry) { - resizemode(d3d); + resizemode(d3d, monid); return r; } if (!d3d->delayedfs) @@ -4925,7 +4959,7 @@ static bool xD3D11_alloctexture(int monid, int w, int h) struct d3d11struct *d3d = &d3d11data[monid]; bool v; - recheck(d3d); + recheck(d3d, monid); if (d3d->invalidmode) return false; @@ -4948,7 +4982,7 @@ static bool xD3D11_alloctexture(int monid, int w, int h) d3d->delayedrestore = true; } - setupscenecoords(d3d, true); + setupscenecoords(d3d, true, monid); changed_prefs.leds_on_screen |= STATUSLINE_TARGET; currprefs.leds_on_screen |= STATUSLINE_TARGET; @@ -5023,7 +5057,7 @@ static void xD3D11_flushtexture(int monid, int miny, int maxy) static void xD3D11_restore(int monid, bool checkonly) { struct d3d11struct *d3d = &d3d11data[monid]; - recheck(d3d); + recheck(d3d, monid); } static void xD3D11_vblank_reset(double freq) @@ -5046,7 +5080,7 @@ static void xD3D11_change(int monid, int temp) clearcnt = 0; } -static void resizemode(struct d3d11struct *d3d) +static void resizemode(struct d3d11struct *d3d, int monid) { d3d->resizeretry = false; if (!d3d->invalidmode) { @@ -5064,7 +5098,7 @@ static void resizemode(struct d3d11struct *d3d) } } if (!d3d->invalidmode) { - if (!initd3d(d3d)) { + if (!initd3d(d3d, monid)) { xD3D11_free(d3d->num, true); gui_message(_T("D3D11 Resize failed.")); d3d->invalidmode = true; @@ -5210,9 +5244,62 @@ bool D3D11_capture(int monid, void **data, int *w, int *h, int *pitch, bool rend return false; } +static void updatecursorsurface(int monid) +{ + struct d3d11struct *d3d = &d3d11data[monid]; + struct d3d11sprite *sp = &d3d->hwsprite; + int cx = (int)d3d->cursor_x; + int cy = (int)d3d->cursor_y; + int width = sp->width; + int height = sp->height; + + if (sp->updated && cx >= 0 && cy >= 0 && cx + width <= d3d->m_bitmapWidth && cy + height <= d3d->m_bitmapHeight) { + return; + } + + sp->updated = false; + D3D11_MAPPED_SUBRESOURCE map; + HRESULT hr = d3d->m_deviceContext->Map(sp->texture, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); + if (SUCCEEDED(hr)) { + int pitch = map.RowPitch; + uae_u8 *b = (uae_u8 *)map.pData; + uae_u8 *s = sp->texbuf; + for (int h = 0; h < sp->height; h++) { + int w = width; + int x = 0; + if (cx + w > d3d->m_bitmapWidth) { + w -= (cx + w) - d3d->m_bitmapWidth; + } + if (cx < 0) { + x = -cx; + w -= -cx; + } + if (w <= 0 || cy + h > d3d->m_bitmapHeight) { + memset(b, 0, width * 4); + } else { + if (x > 0) { + memset(b, 0, x * 4); + } + memcpy(b + x * 4, s + x * 4, w * 4); + if (w < width) { + memset(b + w * 4, 0, (width - w) * 4); + } + } + b += pitch; + s += width * 4; + } + d3d->m_deviceContext->Unmap(d3d->hwsprite.texture, 0); + + if (cx >= 0 && cy >= 0 && cx + width <= d3d->m_bitmapWidth && cy + height <= d3d->m_bitmapHeight) { + sp->updated = true; + } + } +} + static bool xD3D_setcursor(int monid, int x, int y, int width, int height, float mx, float my, bool visible, bool noscale) { struct d3d11struct *d3d = &d3d11data[monid]; + struct d3d11sprite *sp = &d3d->hwsprite; //write_log(_T("setcursor %d %dx%d %dx%d %d %d\n"), monid, x, y, width, height, visible, noscale); @@ -5234,37 +5321,34 @@ static bool xD3D_setcursor(int monid, int x, int y, int width, int height, float float multx = d3d->xmult; float multy = d3d->ymult; - setspritescaling(&d3d->hwsprite, mx * multx, my * multy); + setspritescaling(sp, 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; + sp->x = d3d->cursor_x * multx; + sp->y = d3d->cursor_y * multy; + sp->x += d3d->cursor_offset2_x * multx; + sp->y += d3d->cursor_offset2_y * multy; //write_log(_T("-> %.1fx%.1f %.1f %.1f\n"), d3d->hwsprite.x, d3d->hwsprite.y, multx, multy); d3d->cursor_v = visible; - d3d->hwsprite.enabled = visible; - d3d->hwsprite.bilinear = d3d->filterd3d->gfx_filter_bilinear; + sp->enabled = visible; + sp->bilinear = d3d->filterd3d->gfx_filter_bilinear; + + updatecursorsurface(monid); + return true; } static uae_u8 *xD3D_setcursorsurface(int monid, int *pitch) { struct d3d11struct *d3d = &d3d11data[monid]; - if (!d3d->hwsprite.texture) + if (!d3d->hwsprite.texbuf) return NULL; if (pitch) { - D3D11_MAPPED_SUBRESOURCE map; - HRESULT hr = d3d->m_deviceContext->Map(d3d->hwsprite.texture, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); - if (FAILED(hr)) { - write_log(_T("HWSprite Map failed %08x\n"), hr); - return NULL; - } - *pitch = map.RowPitch; - return (uae_u8*)map.pData; - } else { - d3d->m_deviceContext->Unmap(d3d->hwsprite.texture, 0); - return NULL; + *pitch = d3d->hwsprite.width * 4; + return d3d->hwsprite.texbuf; } + return NULL; } static bool xD3D11_getscalerect(int monid, float *mx, float *my, float *sx, float *sy, int width, int height) @@ -5298,9 +5382,9 @@ static bool xD3D11_run(int monid) if (xD3D11_quit(d3d)) return false; - if (recheck(d3d)) + if (recheck(d3d, monid)) return true; - return D3D11_resize_do(d3d); + return D3D11_resize_do(d3d, monid); } static bool xD3D11_extoverlay(struct extoverlay *ext, int monid) @@ -5352,7 +5436,7 @@ static bool xD3D11_extoverlay(struct extoverlay *ext, int monid) ov = xcalloc(d3doverlay, 1); s = &ov->s; - if (!allocsprite(d3d, s, ext->width, ext->height, true)) { + if (!allocsprite(d3d, s, ext->width, ext->height, true, false, false)) { xfree(ov); return false; } diff --git a/od-win32/gdirender.cpp b/od-win32/gdirender.cpp index 85973d8a..650013e5 100644 --- a/od-win32/gdirender.cpp +++ b/od-win32/gdirender.cpp @@ -24,6 +24,7 @@ struct gdibm bool active; int x, y; int width, height, depth; + int maxw, maxh; HDC thdc; HBITMAP hbm; HGDIOBJ oldbm; @@ -325,6 +326,7 @@ static bool gdi_renderframe(int monid, int mode, bool immediate) { struct gdistruct *gdi = &gdidata[monid]; + setupscenecoords(gdi); return gdi->bm.hbm != NULL; } @@ -343,7 +345,6 @@ static void gdi_paint(void) } if (gdi->bm.hbm) { - setupscenecoords(gdi); 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) { @@ -367,6 +368,12 @@ static void gdi_paint(void) ch -= d; y += d; } + if (x + cw > gdi->cursor.maxw) { + cw -= (x + cw) - gdi->cursor.maxw; + } + if (y + ch > gdi->cursor.maxh) { + ch -= (y + ch) - gdi->cursor.maxh; + } if (cw > 0 && ch > 0) { TransparentBlt(gdi->buf.thdc, x, y, (int)(cw * gdi->xmult), (int)(ch * gdi->ymult), gdi->cursor.thdc, cx, cy, cw, ch, 0xfe00fe); } @@ -377,7 +384,7 @@ static void gdi_paint(void) struct gdioverlay *ov = gdi->extoverlays; while (ov) { if (ov->tex.bits) { - TransparentBlt(gdi->buf.thdc, ov->x, ov->y, ov->tex.width, ov->tex.height, ov->tex.thdc, 0, 0, ov->tex.width, ov->tex.height, 0x000000); + TransparentBlt(gdi->buf.thdc, ov->x, ov->y, ov->tex.width, ov->tex.height, ov->tex.thdc, 0, 0, ov->tex.width, ov->tex.height, 0xfe00fe); } ov = ov->next; } @@ -494,6 +501,8 @@ static bool gdi_setcursor(int monid, int x, int y, int width, int height, float } gdi->cursor.x = cx; gdi->cursor.y = cy; + gdi->cursor.maxw = (int)((float)gdi->bmwidth * mx * gdi->xmult + gdi->cursor_offset_x * gdi->ymult + 0.5f); + gdi->cursor.maxh = (int)((float)gdi->bmheight * my * gdi->ymult + gdi->cursor_offset_y * gdi->xmult + 0.5f); gdi->cursor_scale = !noscale; gdi->cursor.active = visible; return true; @@ -532,6 +541,12 @@ static bool gdi_extoverlay(struct extoverlay *ext, int monid) struct gdioverlay *ov, *ovprev, *ov2; struct gdibm *s = NULL; + if (gdi->depth < 32) { + return false; + } + + gdi->eraseneeded = true; + ov = gdi->extoverlays; ovprev = NULL; while (ov) { @@ -566,7 +581,7 @@ static bool gdi_extoverlay(struct extoverlay *ext, int monid) return true; } - if (ext->width <= 0 || ext->height <= 0) + if (ext->width <= 0 || ext->height <= 0 || !ext->data) return false; ov = xcalloc(gdioverlay, 1); @@ -580,7 +595,6 @@ static bool gdi_extoverlay(struct extoverlay *ext, int monid) s = &ov->tex; ov->id = ext->idx; - ov2 = gdi->extoverlays; ovprev = NULL; @@ -603,7 +617,16 @@ static bool gdi_extoverlay(struct extoverlay *ext, int monid) ov->y = ext->ypos; for (int y = 0; y < ext->height; y++) { - memcpy((uae_u8 *)s->bits + y * s->pitch, ext->data + y * ext->width * 4, ext->width * 4); + for (int x = 0; x < ext->width; x++) { + uae_u32 *sp = (uae_u32*)(ext->data + ext->width * y * 4 + x * 4); + uae_u32 *p = (uae_u32*)((uae_u8*)s->bits + s->pitch * y + x * 4); + uae_u32 v = *sp; + if ((v & 0xff000000) == 0x00000000) { + *p = 0xfe00fe; + } else { + *p = v & 0xffffff; + } + } } return true; diff --git a/od-win32/picasso96_win.cpp b/od-win32/picasso96_win.cpp index b273efb5..4e2fcf7b 100644 --- a/od-win32/picasso96_win.cpp +++ b/od-win32/picasso96_win.cpp @@ -5606,8 +5606,8 @@ static void picasso_flushpixels(int index, uae_u8 *src, int off, bool render) if (!split && vidinfo->rtg_clear_flag) { uae_u8 *p2 = dst; - for (int h = 0; h < vidinfo->height; h++) { - memset(p2, 0, vidinfo->width * vidinfo->pixbytes); + for (int h = 0; h < vidinfo->maxheight; h++) { + memset(p2, 0, vidinfo->maxwidth * vidinfo->pixbytes); p2 += vidinfo->rowbytes; } vidinfo->rtg_clear_flag--; diff --git a/od-win32/shaders/VertexShader.h b/od-win32/shaders/VertexShader.h index 1aec1050..26673496 100644 --- a/od-win32/shaders/VertexShader.h +++ b/od-win32/shaders/VertexShader.h @@ -8,8 +8,8 @@ // cbuffer MatrixBuffer // { // -// float4x4 worldMatrix; // Offset: 0 Size: 64 [unused] -// float4x4 viewMatrix; // Offset: 64 Size: 64 [unused] +// float4x4 worldMatrix; // Offset: 0 Size: 64 +// float4x4 viewMatrix; // Offset: 64 Size: 64 // float4x4 projectionMatrix; // Offset: 128 Size: 64 // // } @@ -45,8 +45,8 @@ // // Target Reg Buffer Start Reg # of Regs Data Conversion // ---------- ------- --------- --------- ---------------------- -// c1 cb0 8 2 ( FLT, FLT, FLT, FLT) -// c3 cb0 11 1 ( FLT, FLT, FLT, FLT) +// c1 cb0 0 10 ( FLT, FLT, FLT, FLT) +// c11 cb0 11 1 ( FLT, FLT, FLT, FLT) // // // Runtime generated constant mappings: @@ -59,21 +59,29 @@ // Level9 shader bytecode: // vs_2_0 - def c4, 1, 0, 0, 0 + def c12, 1, 0, 0, 0 dcl_texcoord v0 dcl_texcoord1 v1 dcl_texcoord2 v2 - mad r0, v0.xyzx, c4.xxxy, c4.yyyx + mad r0, v0.xyzx, c12.xxxy, c12.yyyx dp4 r1.x, r0, c1 dp4 r1.y, r0, c2 - dp4 r0.x, r0, c3 + dp4 r1.z, r0, c3 + dp4 r1.w, r0, c4 + dp4 r0.x, r1, c5 + dp4 r0.y, r1, c6 + dp4 r0.z, r1, c7 + dp4 r0.w, r1, c8 + dp4 r1.x, r0, c9 + dp4 r1.y, r0, c10 + dp4 r0.x, r0, c11 mad oPos.xy, r0.x, c0, r1 mov oPos.w, r0.x - mov oPos.z, c4.y + mov oPos.z, c12.y mov oT0.xy, v1 mov oT0.zw, v2.xyyx -// approximately 9 instruction slots used +// approximately 17 instruction slots used vs_4_0 dcl_constantbuffer CB0[12], immediateIndexed dcl_input v0.xyz @@ -82,44 +90,52 @@ dcl_input v2.xy dcl_output_siv o0.xyzw, position dcl_output o1.xy dcl_output o1.zw -dcl_temps 1 +dcl_temps 2 mov o0.z, l(0) mov r0.xyz, v0.xyzx mov r0.w, l(1.000000) +dp4 r1.x, r0.xyzw, cb0[0].xyzw +dp4 r1.y, r0.xyzw, cb0[1].xyzw +dp4 r1.z, r0.xyzw, cb0[2].xyzw +dp4 r1.w, r0.xyzw, cb0[3].xyzw +dp4 r0.x, r1.xyzw, cb0[4].xyzw +dp4 r0.y, r1.xyzw, cb0[5].xyzw +dp4 r0.z, r1.xyzw, cb0[6].xyzw +dp4 r0.w, r1.xyzw, cb0[7].xyzw dp4 o0.x, r0.xyzw, cb0[8].xyzw dp4 o0.y, r0.xyzw, cb0[9].xyzw dp4 o0.w, r0.xyzw, cb0[11].xyzw mov o1.xy, v1.xyxx mov o1.zw, v2.xxxy ret -// Approximately 9 instruction slots used +// Approximately 17 instruction slots used #endif const BYTE VertexShader[] = { - 68, 88, 66, 67, 197, 81, - 252, 82, 198, 231, 219, 116, - 97, 173, 17, 112, 116, 142, - 183, 245, 1, 0, 0, 0, - 244, 4, 0, 0, 6, 0, + 68, 88, 66, 67, 32, 72, + 217, 207, 174, 158, 89, 255, + 99, 171, 168, 106, 173, 214, + 227, 47, 1, 0, 0, 0, + 116, 6, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, - 76, 1, 0, 0, 136, 2, - 0, 0, 4, 3, 0, 0, - 24, 4, 0, 0, 132, 4, + 204, 1, 0, 0, 8, 4, + 0, 0, 132, 4, 0, 0, + 152, 5, 0, 0, 4, 6, 0, 0, 65, 111, 110, 57, - 12, 1, 0, 0, 12, 1, + 140, 1, 0, 0, 140, 1, 0, 0, 0, 2, 254, 255, - 204, 0, 0, 0, 64, 0, + 76, 1, 0, 0, 64, 0, 0, 0, 2, 0, 36, 0, 0, 0, 60, 0, 0, 0, 60, 0, 0, 0, 36, 0, 1, 0, 60, 0, 0, 0, - 8, 0, 2, 0, 1, 0, + 0, 0, 10, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 11, 0, 1, 0, 3, 0, + 11, 0, 1, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 254, 255, - 81, 0, 0, 5, 4, 0, + 81, 0, 0, 5, 12, 0, 15, 160, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -131,57 +147,121 @@ const BYTE VertexShader[] = 2, 128, 2, 0, 15, 144, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 36, 144, - 4, 0, 64, 160, 4, 0, + 12, 0, 64, 160, 12, 0, 21, 160, 9, 0, 0, 3, 1, 0, 1, 128, 0, 0, 228, 128, 1, 0, 228, 160, 9, 0, 0, 3, 1, 0, 2, 128, 0, 0, 228, 128, 2, 0, 228, 160, 9, 0, - 0, 3, 0, 0, 1, 128, + 0, 3, 1, 0, 4, 128, 0, 0, 228, 128, 3, 0, - 228, 160, 4, 0, 0, 4, - 0, 0, 3, 192, 0, 0, - 0, 128, 0, 0, 228, 160, - 1, 0, 228, 128, 1, 0, - 0, 2, 0, 0, 8, 192, - 0, 0, 0, 128, 1, 0, - 0, 2, 0, 0, 4, 192, - 4, 0, 85, 160, 1, 0, - 0, 2, 0, 0, 3, 224, - 1, 0, 228, 144, 1, 0, - 0, 2, 0, 0, 12, 224, - 2, 0, 20, 144, 255, 255, - 0, 0, 83, 72, 68, 82, - 52, 1, 0, 0, 64, 0, - 1, 0, 77, 0, 0, 0, - 89, 0, 0, 4, 70, 142, - 32, 0, 0, 0, 0, 0, - 12, 0, 0, 0, 95, 0, - 0, 3, 114, 16, 16, 0, - 0, 0, 0, 0, 95, 0, - 0, 3, 50, 16, 16, 0, - 1, 0, 0, 0, 95, 0, - 0, 3, 50, 16, 16, 0, - 2, 0, 0, 0, 103, 0, - 0, 4, 242, 32, 16, 0, - 0, 0, 0, 0, 1, 0, - 0, 0, 101, 0, 0, 3, - 50, 32, 16, 0, 1, 0, - 0, 0, 101, 0, 0, 3, - 194, 32, 16, 0, 1, 0, - 0, 0, 104, 0, 0, 2, - 1, 0, 0, 0, 54, 0, - 0, 5, 66, 32, 16, 0, + 228, 160, 9, 0, 0, 3, + 1, 0, 8, 128, 0, 0, + 228, 128, 4, 0, 228, 160, + 9, 0, 0, 3, 0, 0, + 1, 128, 1, 0, 228, 128, + 5, 0, 228, 160, 9, 0, + 0, 3, 0, 0, 2, 128, + 1, 0, 228, 128, 6, 0, + 228, 160, 9, 0, 0, 3, + 0, 0, 4, 128, 1, 0, + 228, 128, 7, 0, 228, 160, + 9, 0, 0, 3, 0, 0, + 8, 128, 1, 0, 228, 128, + 8, 0, 228, 160, 9, 0, + 0, 3, 1, 0, 1, 128, + 0, 0, 228, 128, 9, 0, + 228, 160, 9, 0, 0, 3, + 1, 0, 2, 128, 0, 0, + 228, 128, 10, 0, 228, 160, + 9, 0, 0, 3, 0, 0, + 1, 128, 0, 0, 228, 128, + 11, 0, 228, 160, 4, 0, + 0, 4, 0, 0, 3, 192, + 0, 0, 0, 128, 0, 0, + 228, 160, 1, 0, 228, 128, + 1, 0, 0, 2, 0, 0, + 8, 192, 0, 0, 0, 128, + 1, 0, 0, 2, 0, 0, + 4, 192, 12, 0, 85, 160, + 1, 0, 0, 2, 0, 0, + 3, 224, 1, 0, 228, 144, + 1, 0, 0, 2, 0, 0, + 12, 224, 2, 0, 20, 144, + 255, 255, 0, 0, 83, 72, + 68, 82, 52, 2, 0, 0, + 64, 0, 1, 0, 141, 0, + 0, 0, 89, 0, 0, 4, + 70, 142, 32, 0, 0, 0, + 0, 0, 12, 0, 0, 0, + 95, 0, 0, 3, 114, 16, + 16, 0, 0, 0, 0, 0, + 95, 0, 0, 3, 50, 16, + 16, 0, 1, 0, 0, 0, + 95, 0, 0, 3, 50, 16, + 16, 0, 2, 0, 0, 0, + 103, 0, 0, 4, 242, 32, + 16, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 101, 0, + 0, 3, 50, 32, 16, 0, + 1, 0, 0, 0, 101, 0, + 0, 3, 194, 32, 16, 0, + 1, 0, 0, 0, 104, 0, + 0, 2, 2, 0, 0, 0, + 54, 0, 0, 5, 66, 32, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 5, + 114, 0, 16, 0, 0, 0, + 0, 0, 70, 18, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 128, 63, + 17, 0, 0, 8, 18, 0, + 16, 0, 1, 0, 0, 0, + 70, 14, 16, 0, 0, 0, + 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, - 54, 0, 0, 5, 114, 0, + 0, 0, 17, 0, 0, 8, + 34, 0, 16, 0, 1, 0, + 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 70, 142, + 32, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 17, 0, + 0, 8, 66, 0, 16, 0, + 1, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, - 70, 18, 16, 0, 0, 0, - 0, 0, 54, 0, 0, 5, + 70, 142, 32, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 17, 0, 0, 8, 130, 0, + 16, 0, 1, 0, 0, 0, + 70, 14, 16, 0, 0, 0, + 0, 0, 70, 142, 32, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 17, 0, 0, 8, + 18, 0, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 1, 0, 0, 0, 70, 142, + 32, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 17, 0, + 0, 8, 34, 0, 16, 0, + 0, 0, 0, 0, 70, 14, + 16, 0, 1, 0, 0, 0, + 70, 142, 32, 0, 0, 0, + 0, 0, 5, 0, 0, 0, + 17, 0, 0, 8, 66, 0, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 1, 0, + 0, 0, 70, 142, 32, 0, + 0, 0, 0, 0, 6, 0, + 0, 0, 17, 0, 0, 8, 130, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 128, 63, 17, 0, + 0, 0, 70, 14, 16, 0, + 1, 0, 0, 0, 70, 142, + 32, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 17, 0, 0, 8, 18, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, @@ -206,10 +286,10 @@ const BYTE VertexShader[] = 6, 20, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, - 0, 0, 9, 0, 0, 0, - 1, 0, 0, 0, 0, 0, + 0, 0, 17, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, - 3, 0, 0, 0, 0, 0, + 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -245,11 +325,11 @@ const BYTE VertexShader[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 0, 0, 0, 0, - 64, 0, 0, 0, 0, 0, + 64, 0, 0, 0, 2, 0, 0, 0, 184, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 0, 64, 0, 0, 0, - 64, 0, 0, 0, 0, 0, + 64, 0, 0, 0, 2, 0, 0, 0, 184, 0, 0, 0, 0, 0, 0, 0, 211, 0, 0, 0, 128, 0, 0, 0, diff --git a/od-win32/shaders/VertexShader.hlsl b/od-win32/shaders/VertexShader.hlsl index b2b54f4b..3d43c76a 100644 --- a/od-win32/shaders/VertexShader.hlsl +++ b/od-win32/shaders/VertexShader.hlsl @@ -21,7 +21,9 @@ PixelInputType TextureVertexShader(VertexInputType input) { PixelInputType output; input.position.w = 1.0f; - output.position = mul(input.position, projectionMatrix); + output.position = mul(input.position, worldMatrix); + output.position = mul(output.position, viewMatrix); + output.position = mul(output.position, projectionMatrix); output.position.z = 0.0f; output.tex = input.tex; output.sl = input.sl; diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index 72f083dc..efa4e72a 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -2203,6 +2203,7 @@ int check_prefs_changed_gfx(void) c |= gf->gfx_filter_blur != gfc->gfx_filter_blur ? (1) : 0; c |= gf->gfx_filter_aspect != gfc->gfx_filter_aspect ? (1) : 0; + c |= gf->gfx_filter_rotation != gfc->gfx_filter_rotation ? (1) : 0; c |= gf->gfx_filter_keep_aspect != gfc->gfx_filter_keep_aspect ? (1) : 0; c |= gf->gfx_filter_keep_autoscale_aspect != gfc->gfx_filter_keep_autoscale_aspect ? (1) : 0; c |= gf->gfx_filter_luminance != gfc->gfx_filter_luminance ? (1) : 0; @@ -4076,8 +4077,8 @@ bool target_graphics_buffer_update(int monid) graphicsbuffer_retry = false; if (mon->screen_is_picasso) { - w = state->Width > vidinfo->width ? state->Width : vidinfo->width; - h = state->Height > vidinfo->height ? state->Height : vidinfo->height; + w = state->Width; + h = state->Height; } else { struct vidbuffer *vb = avidinfo->drawbuffer.tempbufferinuse ? &avidinfo->tempbuffer : &avidinfo->drawbuffer; avidinfo->outbuffer = vb; -- 2.47.3