mirror of
https://github.com/LIV2/WinUAE.git
synced 2025-12-06 00:12:52 +00:00
1245 lines
34 KiB
C++
1245 lines
34 KiB
C++
|
|
#include "sysconfig.h"
|
|
#include "sysdeps.h"
|
|
|
|
#ifdef GFXFILTER
|
|
|
|
#include "options.h"
|
|
#include "custom.h"
|
|
#include "xwin.h"
|
|
#include "dxwrap.h"
|
|
#include "win32.h"
|
|
#include "win32gfx.h"
|
|
#include "gfxfilter.h"
|
|
#include "dxwrap.h"
|
|
#include "statusline.h"
|
|
#include "drawing.h"
|
|
#include "direct3d.h"
|
|
|
|
#include <float.h>
|
|
|
|
#define AUTORESIZE_FRAME_DELAY 10
|
|
|
|
struct uae_filter uaefilters[] =
|
|
{
|
|
{ UAE_FILTER_NULL, 0, 1, _T("Null filter"), _T("null"), UAE_FILTER_MODE_16_16 | UAE_FILTER_MODE_32_32 },
|
|
|
|
{ UAE_FILTER_SCALE2X, 0, 2, _T("Scale2X"), _T("scale2x"), UAE_FILTER_MODE_16_16 | UAE_FILTER_MODE_32_32 },
|
|
|
|
{ UAE_FILTER_HQ2X, 0, 2, _T("hq2x"), _T("hq2x"), UAE_FILTER_MODE_16_16 | UAE_FILTER_MODE_16_32, },
|
|
|
|
{ UAE_FILTER_HQ3X, 0, 3, _T("hq3x"), _T("hq3x"), UAE_FILTER_MODE_16_16 | UAE_FILTER_MODE_16_32 },
|
|
|
|
{ UAE_FILTER_HQ4X, 0, 4, _T("hq4x"), _T("hq4x"), UAE_FILTER_MODE_16_16 | UAE_FILTER_MODE_16_32 },
|
|
|
|
{ UAE_FILTER_SUPEREAGLE, 0, 2, _T("SuperEagle"), _T("supereagle"), UAE_FILTER_MODE_16_16 | UAE_FILTER_MODE_16_32 },
|
|
|
|
{ UAE_FILTER_SUPER2XSAI, 0, 2, _T("Super2xSaI"), _T("super2xsai"), UAE_FILTER_MODE_16_16 | UAE_FILTER_MODE_16_32 },
|
|
|
|
{ UAE_FILTER_2XSAI, 0, 2, _T("2xSaI"), _T("2xsai"), UAE_FILTER_MODE_16_16 | UAE_FILTER_MODE_16_32 },
|
|
|
|
{ UAE_FILTER_PAL, 1, 1, _T("PAL"), _T("pal"), UAE_FILTER_MODE_16_16 | UAE_FILTER_MODE_32_32 },
|
|
|
|
{ 0 }
|
|
};
|
|
|
|
static float filteroffsetx, filteroffsety, filterxmult = 1.0, filterymult = 1.0;
|
|
static int dst_width, dst_height, amiga_width, amiga_height, amiga_depth, dst_depth, scale;
|
|
static int dst_width2, dst_height2, amiga_width2, amiga_height2, amiga_depth2, dst_depth2;
|
|
static int temp_width, temp_height;
|
|
uae_u8 *bufmem_ptr;
|
|
static LPDIRECTDRAWSURFACE7 tempsurf;
|
|
static uae_u8 *tempsurf2, *tempsurf3;
|
|
static int cleartemp;
|
|
static uae_u32 rc[256], gc[256], bc[256];
|
|
static int deskw, deskh;
|
|
static int d3d;
|
|
static bool inited;
|
|
|
|
void getfilteroffset(int monid, float *dx, float *dy, float *mx, float *my)
|
|
{
|
|
*dx = filteroffsetx;
|
|
*dy = filteroffsety;
|
|
*mx = filterxmult;
|
|
*my = filterymult;
|
|
}
|
|
|
|
static void getinit(int monid)
|
|
{
|
|
if (isfullscreen()) {
|
|
struct MultiDisplay *md = getdisplay(&currprefs, monid);
|
|
|
|
deskw = md->rect.right - md->rect.left;
|
|
deskh = md->rect.bottom - md->rect.top;
|
|
} else {
|
|
deskw = dst_width;
|
|
deskh = dst_height;
|
|
}
|
|
}
|
|
|
|
static uae_u8 *getfilterrect1 (RECT *sr, RECT *dr, int dst_width, int dst_height, int dst_depth, int aw, int ah, int scale, int temp_width, int temp_height, uae_u8 *dptr, int pitch)
|
|
{
|
|
int aws, ahs;
|
|
|
|
aws = aw * scale;
|
|
ahs = ah * scale;
|
|
|
|
SetRect (sr, 0, 0, 0, 0);
|
|
dr->left = sr->left + (temp_width - aws) /2;
|
|
dr->top = sr->top + (temp_height - ahs) / 2;
|
|
dptr += dr->left * (dst_depth / 8);
|
|
dptr += dr->top * pitch;
|
|
return dptr;
|
|
}
|
|
|
|
static void sizeoffset (RECT *dr, RECT *zr, int w, int h)
|
|
{
|
|
dr->right -= w;
|
|
dr->bottom -= h;
|
|
OffsetRect (zr, w / 2, h / 2);
|
|
}
|
|
|
|
static void getmanualpos(int monid, int *cxp, int *cyp, int *cwp, int *chp)
|
|
{
|
|
struct vidbuf_description *avidinfo = &adisplays[monid].gfxvidinfo;
|
|
int v, cx, cy, cw, ch;
|
|
bool native = isnativevidbuf(monid);
|
|
|
|
cx = *cxp;
|
|
cy = *cyp;
|
|
v = currprefs.gfx_xcenter_pos;
|
|
if (v >= 0)
|
|
cx = (v >> (RES_MAX - currprefs.gfx_resolution)) - cx;
|
|
|
|
v = currprefs.gfx_ycenter_pos;
|
|
if (v >= 0)
|
|
cy = (v >> (VRES_MAX - currprefs.gfx_vresolution)) - cy;
|
|
|
|
v = currprefs.gfx_xcenter_size;
|
|
if (v <= 0) {
|
|
if (programmedmode && native) {
|
|
cw = avidinfo->outbuffer->outwidth << (RES_MAX - currprefs.gfx_resolution);
|
|
} else {
|
|
cw = native ? AMIGA_WIDTH_MAX << RES_MAX : avidinfo->outbuffer->outwidth;
|
|
}
|
|
} else {
|
|
cw = v;
|
|
}
|
|
cw >>= (RES_MAX - currprefs.gfx_resolution);
|
|
|
|
v = currprefs.gfx_ycenter_size;
|
|
if (v <= 0) {
|
|
if (programmedmode && native) {
|
|
ch = avidinfo->outbuffer->outheight << (VRES_MAX - currprefs.gfx_vresolution);
|
|
} else {
|
|
ch = native ? AMIGA_HEIGHT_MAX << VRES_MAX : avidinfo->outbuffer->outheight;
|
|
}
|
|
} else {
|
|
ch = v;
|
|
}
|
|
ch >>= (VRES_MAX - currprefs.gfx_vresolution);
|
|
|
|
*cxp = cx;
|
|
*cyp = cy;
|
|
*cwp = cw;
|
|
*chp = ch;
|
|
}
|
|
|
|
static bool get_auto_aspect_ratio(int monid, int cw, int ch, int crealh, int scalemode, float *autoaspectratio)
|
|
{
|
|
struct amigadisplay *ad = &adisplays[monid];
|
|
*autoaspectratio = 0;
|
|
if (currprefs.gf[ad->picasso_on].gfx_filter_keep_autoscale_aspect && cw > 0 && ch > 0 && crealh > 0 && (scalemode == AUTOSCALE_NORMAL ||
|
|
scalemode == AUTOSCALE_INTEGER_AUTOSCALE || scalemode == AUTOSCALE_MANUAL)) {
|
|
float cw2 = cw;
|
|
float ch2 = ch;
|
|
int res = currprefs.gfx_resolution - currprefs.gfx_vresolution;
|
|
|
|
if (res < 0)
|
|
cw2 *= 1 << (-res);
|
|
else if (res > 0)
|
|
cw2 /= 1 << res;
|
|
*autoaspectratio = (cw2 / ch2) / (4.0 / 3.0);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static bool get_aspect(int monid, float *dstratiop, float *srcratiop, float *xmultp, float *ymultp, bool doautoaspect, float autoaspectratio, int keep_aspect, int filter_aspect)
|
|
{
|
|
struct amigadisplay *ad = &adisplays[monid];
|
|
bool aspect = false;
|
|
float dstratio = *dstratiop;
|
|
float srcratio = *srcratiop;
|
|
|
|
*xmultp = 1.0;
|
|
*ymultp = 1.0;
|
|
|
|
if (keep_aspect || filter_aspect != 0) {
|
|
|
|
if (keep_aspect) {
|
|
if (isvga()) {
|
|
if (keep_aspect == 1)
|
|
dstratio = dstratio * 0.93f;
|
|
} else {
|
|
if (currprefs.ntscmode) {
|
|
dstratio = dstratio * 1.21f;
|
|
if (keep_aspect == 2 && ispal())
|
|
dstratio = dstratio * 0.93f;
|
|
else if (keep_aspect == 1 && !ispal())
|
|
dstratio = dstratio * 0.98f;
|
|
} else {
|
|
if (keep_aspect == 2 && ispal())
|
|
dstratio = dstratio * 0.95f;
|
|
else if (keep_aspect == 1 && !ispal())
|
|
dstratio = dstratio * 0.95f;
|
|
}
|
|
}
|
|
}
|
|
aspect = true;
|
|
|
|
} else if (doautoaspect) {
|
|
|
|
aspect = true;
|
|
|
|
}
|
|
|
|
if (aspect) {
|
|
|
|
if (doautoaspect) {
|
|
srcratio *= autoaspectratio;
|
|
}
|
|
|
|
if (srcratio > dstratio) {
|
|
*ymultp = (*ymultp) * srcratio / dstratio;
|
|
} else {
|
|
*xmultp = (*xmultp) * dstratio / srcratio;
|
|
}
|
|
}
|
|
*dstratiop = dstratio;
|
|
*srcratiop = srcratio;
|
|
return aspect;
|
|
}
|
|
|
|
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)
|
|
{
|
|
struct AmigaMonitor *mon = &AMonitors[monid];
|
|
struct amigadisplay *ad = &adisplays[monid];
|
|
struct vidbuf_description *avidinfo = &adisplays[monid].gfxvidinfo;
|
|
struct uae_filter *usedfilter = mon->usedfilter;
|
|
struct monconfig *gmc = &currprefs.gfx_monitor[mon->monitor_id];
|
|
struct monconfig *gmh = &changed_prefs.gfx_monitor[mon->monitor_id];
|
|
float srcratio, dstratio;
|
|
int aws, ahs;
|
|
int xs, ys;
|
|
int extraw, extrah;
|
|
int fpuv;
|
|
bool specialmode = !isnativevidbuf(monid);
|
|
float mrmx, mrmy, mrsx, mrsy;
|
|
int extraw2;
|
|
bool doautoaspect = false;
|
|
float autoaspectratio;
|
|
int keep_aspect = currprefs.gf[ad->picasso_on].gfx_filter_keep_aspect;
|
|
int filter_aspect = currprefs.gf[ad->picasso_on].gfx_filter_aspect;
|
|
int palntscadjust = 1;
|
|
|
|
float filter_horiz_zoom = currprefs.gf[ad->picasso_on].gfx_filter_horiz_zoom / 1000.0f;
|
|
float filter_vert_zoom = currprefs.gf[ad->picasso_on].gfx_filter_vert_zoom / 1000.0f;
|
|
float filter_horiz_zoom_mult = currprefs.gf[ad->picasso_on].gfx_filter_horiz_zoom_mult;
|
|
float filter_vert_zoom_mult = currprefs.gf[ad->picasso_on].gfx_filter_vert_zoom_mult;
|
|
float filter_horiz_offset = currprefs.gf[ad->picasso_on].gfx_filter_horiz_offset / 10000.0f;
|
|
float filter_vert_offset = currprefs.gf[ad->picasso_on].gfx_filter_vert_offset / 10000.0f;
|
|
|
|
store_custom_limits (-1, -1, -1, -1);
|
|
|
|
if (!usedfilter && !currprefs.gfx_api) {
|
|
filter_horiz_zoom = filter_vert_zoom = 0.0;
|
|
filter_horiz_zoom_mult = filter_vert_zoom_mult = 1.0;
|
|
filter_horiz_offset = filter_vert_offset = 0.0;
|
|
}
|
|
|
|
if (mon->screen_is_picasso) {
|
|
getrtgfilterrect2(monid, sr, dr, zr, dst_width, dst_height);
|
|
if (D3D_getscalerect && D3D_getscalerect(monid, &mrmx, &mrmy, &mrsx, &mrsy, dst_width, dst_height)) {
|
|
sizeoffset(dr, zr, mrmx, mrmy);
|
|
OffsetRect(dr, mrsx, mrsy);
|
|
}
|
|
return;
|
|
}
|
|
|
|
fpux_save (&fpuv);
|
|
|
|
getinit(monid);
|
|
aws = aw * scale;
|
|
ahs = ah * scale;
|
|
//write_log (_T("%d %d %d\n"), dst_width, temp_width, aws);
|
|
extraw = -aws * (filter_horiz_zoom - currprefs.gf[ad->picasso_on].gfx_filteroverlay_overscan * 10) / 2.0f;
|
|
extrah = -ahs * (filter_vert_zoom - currprefs.gf[ad->picasso_on].gfx_filteroverlay_overscan * 10) / 2.0f;
|
|
|
|
extraw2 = 0;
|
|
if (D3D_getscalerect && D3D_getscalerect(monid, &mrmx, &mrmy, &mrsx, &mrsy, avidinfo->outbuffer->inwidth2, avidinfo->outbuffer->inheight2)) {
|
|
extraw2 = mrmx;
|
|
//extrah -= mrmy;
|
|
}
|
|
|
|
SetRect (sr, 0, 0, dst_width, dst_height);
|
|
SetRect (zr, 0, 0, 0, 0);
|
|
dr->left = (temp_width - aws) / 2;
|
|
dr->top = (temp_height - ahs) / 2;
|
|
|
|
dr->left -= (dst_width - aws) / 2;
|
|
dr->top -= (dst_height - ahs) / 2;
|
|
|
|
dr->right = dr->left + dst_width;
|
|
dr->bottom = dr->top + dst_height;
|
|
|
|
filteroffsetx = 0;
|
|
filteroffsety = 0;
|
|
float xmult = filter_horiz_zoom_mult;
|
|
float ymult = filter_vert_zoom_mult;
|
|
|
|
int scalemode = currprefs.gf[ad->picasso_on].gfx_filter_autoscale;
|
|
int oscalemode = changed_prefs.gf[ad->picasso_on].gfx_filter_autoscale;
|
|
if (scalemode == AUTOSCALE_OVERSCAN_BLANK) {
|
|
oscalemode = scalemode = AUTOSCALE_NONE;
|
|
}
|
|
|
|
srcratio = 4.0f / 3.0f;
|
|
|
|
if (!specialmode && scalemode == AUTOSCALE_STATIC_AUTO) {
|
|
int w = (dst_width / 2) << currprefs.gfx_resolution;
|
|
int h = (dst_height / 2) << currprefs.gfx_vresolution;
|
|
filter_aspect = 0;
|
|
keep_aspect = 0;
|
|
palntscadjust = 1;
|
|
if (w >= 640 && w <= 800 && h >= 480 && h <= 600) {
|
|
scalemode = AUTOSCALE_NONE;
|
|
} else {
|
|
float dstratio = 1.0f * dst_width / dst_height;
|
|
scalemode = AUTOSCALE_STATIC_NOMINAL;
|
|
if (dstratio > srcratio + 0.1 || dstratio < srcratio - 0.1) {
|
|
filter_aspect = -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (filter_aspect > 0) {
|
|
dstratio = (filter_aspect / ASPECTMULT) * 1.0f / (filter_aspect & (ASPECTMULT - 1));
|
|
} else if (filter_aspect < 0) {
|
|
if (isfullscreen() && deskw > 0 && deskh > 0)
|
|
dstratio = 1.0f * deskw / deskh;
|
|
else
|
|
dstratio = 1.0f * dst_width / dst_height;
|
|
} else {
|
|
dstratio = srcratio;
|
|
}
|
|
|
|
bool scl = false;
|
|
int width_aspect = -1;
|
|
int height_aspect = -1;
|
|
bool autoaspect_done = false;
|
|
|
|
if (scalemode) {
|
|
int cw, ch, cx, cy, cv, crealh = 0;
|
|
static int oxmult, oymult;
|
|
|
|
filterxmult = scale;
|
|
filterymult = scale;
|
|
|
|
if (scalemode == AUTOSCALE_STATIC_MAX || scalemode == AUTOSCALE_STATIC_NOMINAL ||
|
|
scalemode == AUTOSCALE_INTEGER || scalemode == AUTOSCALE_INTEGER_AUTOSCALE) {
|
|
|
|
if (specialmode) {
|
|
cx = 0;
|
|
cy = 0;
|
|
cw = avidinfo->outbuffer->outwidth;
|
|
ch = avidinfo->outbuffer->outheight;
|
|
} else {
|
|
cx = 0;
|
|
cy = 0;
|
|
cw = avidinfo->drawbuffer.inwidth;
|
|
ch = avidinfo->drawbuffer.inheight;
|
|
cv = 1;
|
|
if (!(beamcon0 & 0x80) && (scalemode == AUTOSCALE_STATIC_NOMINAL)) { // || scalemode == AUTOSCALE_INTEGER)) {
|
|
cx = 28 << currprefs.gfx_resolution;
|
|
cy = 10 << currprefs.gfx_vresolution;
|
|
cw -= 40 << currprefs.gfx_resolution;
|
|
ch -= 20 << currprefs.gfx_vresolution;
|
|
}
|
|
set_custom_limits (cw, ch, cx, cy);
|
|
store_custom_limits (cw, ch, cx, cy);
|
|
scl = true;
|
|
}
|
|
|
|
if (scalemode == AUTOSCALE_INTEGER || scalemode == AUTOSCALE_INTEGER_AUTOSCALE) {
|
|
int maxw = gmc->gfx_size.width;
|
|
int maxh = gmc->gfx_size.height;
|
|
double mult = 1;
|
|
bool ok = true;
|
|
|
|
if (currprefs.gfx_xcenter_pos >= 0 || currprefs.gfx_ycenter_pos >= 0) {
|
|
changed_prefs.gf[ad->picasso_on].gfx_filter_horiz_offset = currprefs.gf[ad->picasso_on].gfx_filter_horiz_offset = 0.0;
|
|
changed_prefs.gf[ad->picasso_on].gfx_filter_vert_offset = currprefs.gf[ad->picasso_on].gfx_filter_vert_offset = 0.0;
|
|
filter_horiz_offset = 0.0;
|
|
filter_vert_offset = 0.0;
|
|
get_custom_topedge (&cx, &cy, false);
|
|
}
|
|
|
|
if (scalemode == AUTOSCALE_INTEGER_AUTOSCALE) {
|
|
ok = get_custom_limits (&cw, &ch, &cx, &cy, &crealh) != 0;
|
|
if (ok) {
|
|
set_custom_limits(cw, ch, cx, cy);
|
|
store_custom_limits(cw, ch, cx, cy);
|
|
}
|
|
}
|
|
if (scalemode == AUTOSCALE_INTEGER || ok == false) {
|
|
getmanualpos(monid, &cx, &cy, &cw, &ch);
|
|
set_custom_limits(cw, ch, cx, cy);
|
|
store_custom_limits(cw, ch, cx, cy);
|
|
}
|
|
|
|
#if 0
|
|
doautoaspect = get_auto_aspect_ratio(cw, ch, crealh, scalemode, &autoaspectratio);
|
|
autoaspect_done = true;
|
|
|
|
if (get_aspect(&dstratio, &srcratio, &xmult, &ymult, doautoaspect, autoaspectratio, keep_aspect, filter_aspect)) {
|
|
cw += cw - cw * xmult;
|
|
ch += ch - ch * ymult;
|
|
}
|
|
#endif
|
|
|
|
int cw2 = cw + cw * filter_horiz_zoom;
|
|
int ch2 = ch + ch * filter_vert_zoom;
|
|
|
|
extraw = 0;
|
|
extrah = 0;
|
|
xmult = 1.0;
|
|
ymult = 1.0;
|
|
filter_horiz_zoom = 0;
|
|
filter_vert_zoom = 0;
|
|
filter_horiz_zoom_mult = 1.0;
|
|
filter_vert_zoom_mult = 1.0;
|
|
|
|
double multadd = 1.0 / (1 << currprefs.gf[ad->picasso_on].gfx_filter_integerscalelimit);
|
|
if (cw2 > maxw || ch2 > maxh) {
|
|
while (cw2 / mult > maxw || ch2 / mult > maxh)
|
|
mult += multadd;
|
|
maxw = maxw * mult;
|
|
maxh = maxh * mult;
|
|
} else {
|
|
while (cw2 * (mult + multadd) <= maxw && ch2 * (mult + multadd) <= maxh)
|
|
mult += multadd;
|
|
maxw = (maxw + mult - multadd) / mult;
|
|
maxh = (maxh + mult - multadd) / mult;
|
|
}
|
|
|
|
width_aspect = cw;
|
|
height_aspect = ch;
|
|
|
|
//write_log(_T("(%dx%d) (%dx%d) ww=%d hh=%d w=%d h=%d m=%d\n"), cx, cy, cw, ch, currprefs.gfx_size.width, currprefs.gfx_size.height, maxw, maxh, mult);
|
|
cx -= (maxw - cw) / 2;
|
|
cw = maxw;
|
|
cy -= (maxh - ch) / 2;
|
|
ch = maxh;
|
|
}
|
|
|
|
} else if (scalemode == AUTOSCALE_MANUAL) {
|
|
|
|
changed_prefs.gf[ad->picasso_on].gfx_filter_horiz_offset = currprefs.gf[ad->picasso_on].gfx_filter_horiz_offset = 0.0;
|
|
changed_prefs.gf[ad->picasso_on].gfx_filter_vert_offset = currprefs.gf[ad->picasso_on].gfx_filter_vert_offset = 0.0;
|
|
filter_horiz_offset = 0.0;
|
|
filter_vert_offset = 0.0;
|
|
|
|
get_custom_topedge (&cx, &cy, currprefs.gfx_xcenter_pos < 0 && currprefs.gfx_ycenter_pos < 0);
|
|
//write_log (_T("%dx%d %dx%d\n"), cx, cy, currprefs.gfx_resolution, currprefs.gfx_vresolution);
|
|
|
|
getmanualpos(monid, &cx, &cy, &cw, &ch);
|
|
set_custom_limits(cw, ch, cx, cy);
|
|
store_custom_limits(cw, ch, cx, cy);
|
|
scl = true;
|
|
|
|
//write_log (_T("%dx%d %dx%d %dx%d\n"), currprefs.gfx_xcenter_pos, currprefs.gfx_ycenter_pos, cx, cy, cw, ch);
|
|
|
|
cv = 1;
|
|
|
|
} else if (scalemode == AUTOSCALE_CENTER) {
|
|
|
|
cv = get_custom_limits(&cw, &ch, &cx, &cy, &crealh);
|
|
if (cv) {
|
|
store_custom_limits(cw, ch, cx, cy);
|
|
}
|
|
|
|
} else if (scalemode == AUTOSCALE_RESIZE) {
|
|
|
|
cv = get_custom_limits (&cw, &ch, &cx, &cy, &crealh);
|
|
if (cv) {
|
|
set_custom_limits(cw, ch, cx, cy);
|
|
store_custom_limits(cw, ch, cx, cy);
|
|
scl = true;
|
|
}
|
|
|
|
} else {
|
|
|
|
cv = get_custom_limits (&cw, &ch, &cx, &cy, &crealh);
|
|
if (cv) {
|
|
set_custom_limits (cw, ch, cx, cy);
|
|
store_custom_limits (cw, ch, cx, cy);
|
|
scl = true;
|
|
}
|
|
|
|
}
|
|
|
|
if (!scl) {
|
|
set_custom_limits (0, 0, 0, 0);
|
|
}
|
|
|
|
if (!autoaspect_done) {
|
|
doautoaspect = get_auto_aspect_ratio(monid, cw, ch, crealh, scalemode, &autoaspectratio);
|
|
}
|
|
|
|
if (currprefs.gfx_api == 0) {
|
|
if (cx < 0)
|
|
cx = 0;
|
|
if (cy < 0)
|
|
cy = 0;
|
|
}
|
|
|
|
if (cv) {
|
|
int diff;
|
|
|
|
if (scalemode == AUTOSCALE_CENTER) {
|
|
|
|
int ww = cw * scale;
|
|
int hh = ch * scale;
|
|
|
|
SetRect (sr, 0, 0, dst_width, dst_height);
|
|
SetRect (zr, 0, 0, 0, 0);
|
|
|
|
dr->left = (temp_width - aws) /2;
|
|
dr->top = (temp_height - ahs) / 2;
|
|
dr->right = dr->left + dst_width * scale;
|
|
dr->bottom = dr->top + dst_height * scale;
|
|
|
|
OffsetRect (zr, cx * scale - (dst_width - ww) / 2, cy * scale - (dst_height - hh) / 2);
|
|
goto cont;
|
|
|
|
} else if (scalemode == AUTOSCALE_RESIZE && isfullscreen() == 0 && !currprefs.gf[ad->picasso_on].gfx_filteroverlay[0]) {
|
|
|
|
static int lastresize = 0;
|
|
static int lastdelay = 1;
|
|
static int ocw, och, ocx, ocy, lcw, lch, lcx, lcy;
|
|
int useold = 0;
|
|
|
|
lastresize--;
|
|
if (lastresize > 0) {
|
|
if (cw != lcw || ch != lch || cx != lcx || cy != lcy)
|
|
lastresize = AUTORESIZE_FRAME_DELAY;
|
|
useold = 1;
|
|
} else if (lastdelay == 0) {
|
|
lastdelay = 2;
|
|
useold = 1;
|
|
} else if (lastdelay > 0) {
|
|
lastdelay--;
|
|
useold = 1;
|
|
if (lastdelay == 0) {
|
|
lastdelay = -1;
|
|
useold = 0;
|
|
}
|
|
}
|
|
|
|
lcw = cw;
|
|
lch = ch;
|
|
lcx = cx;
|
|
lcy = cy;
|
|
if (useold && !config_changed) {
|
|
cw = ocw;
|
|
ch = och;
|
|
cx = ocx;
|
|
cy = ocy;
|
|
} else {
|
|
ocw = cw;
|
|
och = ch;
|
|
ocx = cx;
|
|
ocy = cy;
|
|
lastresize = AUTORESIZE_FRAME_DELAY;
|
|
lastdelay = 0;
|
|
}
|
|
float scalex = currprefs.gf[ad->picasso_on].gfx_filter_horiz_zoom_mult > 0 ? currprefs.gf[ad->picasso_on].gfx_filter_horiz_zoom_mult : 1.0f;
|
|
float scaley = currprefs.gf[ad->picasso_on].gfx_filter_vert_zoom_mult > 0 ? currprefs.gf[ad->picasso_on].gfx_filter_vert_zoom_mult : 1.0f;
|
|
SetRect (sr, 0, 0, cw * scale * scalex, ch * scale * scaley);
|
|
dr->left = (temp_width - aws) /2;
|
|
dr->top = (temp_height - ahs) / 2;
|
|
dr->right = dr->left + cw * scale;
|
|
dr->bottom = dr->top + ch * scale;
|
|
OffsetRect (zr, cx * scale, cy * scale);
|
|
int ww = (dr->right - dr->left) * scalex;
|
|
int hh = (dr->bottom - dr->top) * scaley;
|
|
if (currprefs.gfx_xcenter_size >= 0)
|
|
ww = currprefs.gfx_xcenter_size;
|
|
if (currprefs.gfx_ycenter_size >= 0)
|
|
hh = currprefs.gfx_ycenter_size;
|
|
if (scalemode == oscalemode) {
|
|
int oldwinw = gmc->gfx_size_win.width;
|
|
int oldwinh = gmc->gfx_size_win.height;
|
|
gmh->gfx_size_win.width = ww;
|
|
gmh->gfx_size_win.height = hh;
|
|
fixup_prefs_dimensions (&changed_prefs);
|
|
if (oldwinw != gmh->gfx_size_win.width || oldwinh != gmh->gfx_size_win.height)
|
|
set_config_changed ();
|
|
}
|
|
OffsetRect (zr, -(gmh->gfx_size_win.width - ww + 1) / 2, -(gmh->gfx_size_win.height - hh + 1) / 2);
|
|
filteroffsetx = -zr->left / scale;
|
|
filteroffsety = -zr->top / scale;
|
|
goto end;
|
|
}
|
|
|
|
dr->left = (temp_width - aws) /2;
|
|
dr->top = (temp_height - ahs) / 2;
|
|
dr->right = dr->left + dst_width * scale;
|
|
dr->bottom = dr->top + dst_height * scale;
|
|
|
|
OffsetRect (zr, cx * scale, cy * scale);
|
|
|
|
sizeoffset (dr, zr, extraw, extrah);
|
|
|
|
dr->right -= (dst_width - cw) * scale;
|
|
dr->bottom -= (dst_height - ch) * scale;
|
|
|
|
filteroffsetx = -zr->left / scale;
|
|
filteroffsety = -zr->top / scale;
|
|
|
|
bool aspect = false;
|
|
|
|
int diffx, diffy;
|
|
|
|
if (width_aspect > 0) {
|
|
diffx = width_aspect;
|
|
} else {
|
|
diffx = dr->right - dr->left;
|
|
}
|
|
if (height_aspect > 0) {
|
|
diffy = height_aspect;
|
|
} else {
|
|
diffy = dr->bottom - dr->top;
|
|
}
|
|
|
|
if (get_aspect(monid, &dstratio, &srcratio, &xmult, &ymult, doautoaspect, autoaspectratio, keep_aspect, filter_aspect)) {
|
|
diff = diffx - diffx * xmult;
|
|
sizeoffset(dr, zr, diff, 0);
|
|
filteroffsetx += -diff / 2;
|
|
|
|
diff = diffy - diffy * ymult;
|
|
sizeoffset(dr, zr, 0, diff);
|
|
filteroffsety += -diff / 2;
|
|
}
|
|
|
|
OffsetRect (zr, (int)(-filter_horiz_offset * aws), 0);
|
|
OffsetRect (zr, 0, (int)(-filter_vert_offset * ahs));
|
|
|
|
diff = dr->right - dr->left;
|
|
filterxmult = ((float)dst_width * scale) / diff;
|
|
diff = dr->bottom - dr->top;
|
|
filterymult = ((float)dst_height * scale) / diff;
|
|
|
|
goto end;
|
|
}
|
|
|
|
}
|
|
cont:
|
|
|
|
if (!filter_horiz_zoom_mult && !filter_vert_zoom_mult) {
|
|
|
|
sizeoffset (dr, zr, extraw, extrah);
|
|
|
|
if (keep_aspect) {
|
|
float xm, ym, m;
|
|
|
|
xm = aws / dst_width;
|
|
ym = ahs / dst_height;
|
|
if (xm < ym)
|
|
xm = ym;
|
|
else
|
|
ym = xm;
|
|
xmult = ymult = xm;
|
|
|
|
m = (aws * dst_width) / (ahs * dst_height);
|
|
dstratio = dstratio * m;
|
|
}
|
|
|
|
}
|
|
|
|
if (currprefs.ntscmode) {
|
|
if (palntscadjust && ispal()) {
|
|
dstratio = dstratio * (625 / 525.0);
|
|
}
|
|
if (keep_aspect == 2 && ispal ())
|
|
dstratio = dstratio * 0.93f;
|
|
else if (keep_aspect == 1 && !ispal ())
|
|
dstratio = dstratio * 0.98f;
|
|
} else {
|
|
if (palntscadjust && !ispal()) {
|
|
dstratio = dstratio * (625 / 525.0);
|
|
}
|
|
if (keep_aspect == 2 && ispal ())
|
|
dstratio = dstratio * 0.95f;
|
|
else if (keep_aspect == 1 && !ispal ())
|
|
dstratio = dstratio * 0.95f;
|
|
}
|
|
|
|
if (srcratio > dstratio) {
|
|
ymult = ymult * srcratio / dstratio;
|
|
} else {
|
|
xmult = xmult * dstratio / srcratio;
|
|
}
|
|
|
|
if (xmult <= 0.01)
|
|
xmult = (float)dst_width / aws;
|
|
else
|
|
xmult = xmult + xmult * filter_horiz_zoom / 2.0f;
|
|
if (ymult <= 0.01)
|
|
ymult = (float)dst_height / ahs;
|
|
else
|
|
ymult = ymult + ymult * filter_vert_zoom / 2.0f;
|
|
|
|
if (!filter_horiz_zoom_mult && !filter_vert_zoom_mult) {
|
|
if (currprefs.ntscmode) {
|
|
ymult /= 1.21f;
|
|
}
|
|
}
|
|
|
|
OffsetRect (zr, (int)(-filter_horiz_offset * aws), 0);
|
|
OffsetRect (zr, 0, (int)(-filter_vert_offset * ahs));
|
|
|
|
xs = dst_width;
|
|
if (xmult)
|
|
xs -= dst_width / xmult;
|
|
ys = dst_height;
|
|
if (ymult)
|
|
ys -= dst_height / ymult;
|
|
sizeoffset (dr, zr, xs, ys);
|
|
|
|
filterxmult = xmult;
|
|
filterymult = ymult;
|
|
filteroffsetx += (dst_width - aw * filterxmult) / 2;
|
|
filteroffsety += (dst_height - ah * filterymult) / 2;
|
|
|
|
end:
|
|
|
|
if (D3D_getscalerect && D3D_getscalerect(monid, &mrmx, &mrmy, &mrsx, &mrsy, avidinfo->outbuffer->inwidth2, avidinfo->outbuffer->inheight2)) {
|
|
sizeoffset (dr, zr, mrmx, mrmy);
|
|
OffsetRect (dr, mrsx, mrsy);
|
|
}
|
|
|
|
check_custom_limits();
|
|
|
|
fpux_restore (&fpuv);
|
|
|
|
#if 0
|
|
int rw, rh, rx, ry;
|
|
get_custom_raw_limits (&rw, &rh, &rx, &ry);
|
|
rw <<= RES_MAX - currprefs.gfx_resolution;
|
|
rx <<= RES_MAX - currprefs.gfx_resolution;
|
|
rh <<= VRES_MAX - currprefs.gfx_vresolution;
|
|
ry <<= VRES_MAX - currprefs.gfx_vresolution;
|
|
write_log (_T("%d %d %d %d\n"), rx, rw, ry, rh);
|
|
#endif
|
|
|
|
}
|
|
|
|
void freefilterbuffer(int monid, uae_u8 *buf)
|
|
{
|
|
struct AmigaMonitor *mon = &AMonitors[monid];
|
|
struct vidbuf_description *avidinfo = &adisplays[monid].gfxvidinfo;
|
|
struct vidbuffer *vb = avidinfo->outbuffer;
|
|
struct uae_filter *usedfilter = mon->usedfilter;
|
|
|
|
if (!vb)
|
|
return;
|
|
if (usedfilter == NULL) {
|
|
unlockscr3d(vb);
|
|
}
|
|
}
|
|
|
|
uae_u8 *getfilterbuffer(int monid, int *widthp, int *heightp, int *pitch, int *depth)
|
|
{
|
|
struct AmigaMonitor *mon = &AMonitors[monid];
|
|
struct vidbuf_description *avidinfo = &adisplays[monid].gfxvidinfo;
|
|
struct vidbuffer *vb = avidinfo->outbuffer;
|
|
struct uae_filter *usedfilter = mon->usedfilter;
|
|
|
|
*widthp = 0;
|
|
*heightp = 0;
|
|
*depth = amiga_depth;
|
|
if (!vb)
|
|
return NULL;
|
|
if (usedfilter == NULL) {
|
|
if (!lockscr3d(vb)) {
|
|
return NULL;
|
|
}
|
|
}
|
|
*widthp = vb->outwidth;
|
|
*heightp = vb->outheight;
|
|
if (pitch)
|
|
*pitch = vb->rowbytes;
|
|
*depth = vb->pixbytes * 8;
|
|
return vb->bufmem;
|
|
#if 0
|
|
RECT dr, sr, zr;
|
|
uae_u8 *p;
|
|
int w, h;
|
|
if (usedfilter->type == UAE_FILTER_DIRECT3D) {
|
|
return getfilterbuffer3d (widthp, heightp, pitch, depth);
|
|
} else {
|
|
getfilterrect2 (&dr, &sr, &zr, dst_width, dst_height, amiga_width, amiga_height, scale, temp_width, temp_height);
|
|
}
|
|
w = sr.right - sr.left;
|
|
h = sr.bottom - sr.top;
|
|
p = vb->bufmem;
|
|
if (pitch)
|
|
*pitch = vb->rowbytes;
|
|
p += (zr.top - (h / 2)) * vb->rowbytes + (zr.left - (w / 2)) * amiga_depth / 8;
|
|
*widthp = w;
|
|
*heightp = h;
|
|
return p;
|
|
#endif
|
|
}
|
|
|
|
static void statusline(int monid)
|
|
{
|
|
DDSURFACEDESC2 desc;
|
|
RECT sr, dr;
|
|
int y;
|
|
int lx, ly;
|
|
int slx, sly;
|
|
|
|
if (!(currprefs.leds_on_screen & STATUSLINE_CHIPSET) || !tempsurf)
|
|
return;
|
|
statusline_getpos(monid, &slx, &sly, dst_width, dst_height);
|
|
int m = statusline_get_multiplier(monid);
|
|
lx = dst_width;
|
|
ly = dst_height;
|
|
SetRect(&sr, slx, 0, slx + lx, TD_TOTAL_HEIGHT * m);
|
|
SetRect(&dr, slx, sly, slx + lx, sly + TD_TOTAL_HEIGHT * m);
|
|
DirectDraw_BlitRect(tempsurf, &sr, NULL, &dr);
|
|
if (DirectDraw_LockSurface(tempsurf, &desc)) {
|
|
statusline_render(0, (uae_u8*)desc.lpSurface, dst_depth / 8, desc.lPitch, lx, ly, rc, gc, bc, NULL);
|
|
for (y = 0; y < TD_TOTAL_HEIGHT * m; y++) {
|
|
uae_u8 *buf = (uae_u8*)desc.lpSurface + y * desc.lPitch;
|
|
draw_status_line_single(monid, buf, dst_depth / 8, y, lx, rc, gc, bc, NULL);
|
|
}
|
|
DirectDraw_UnlockSurface(tempsurf);
|
|
DirectDraw_BlitRect(NULL, &dr, tempsurf, &sr);
|
|
}
|
|
}
|
|
|
|
void S2X_configure(int monid, int rb, int gb, int bb, int rs, int gs, int bs)
|
|
{
|
|
if (monid)
|
|
return;
|
|
Init_2xSaI(rb, gb, bb, rs, gs, bs);
|
|
hq_init(rb, gb, bb, rs, gs, bs);
|
|
PAL_init(monid);
|
|
bufmem_ptr = 0;
|
|
}
|
|
|
|
void S2X_reset(int monid)
|
|
{
|
|
if (monid)
|
|
return;
|
|
if (!inited)
|
|
return;
|
|
S2X_init(monid, dst_width2, dst_height2, amiga_depth2);
|
|
}
|
|
|
|
void S2X_free(int monid)
|
|
{
|
|
if (monid)
|
|
return;
|
|
|
|
changed_prefs.leds_on_screen &= ~STATUSLINE_TARGET;
|
|
currprefs.leds_on_screen &= ~STATUSLINE_TARGET;
|
|
|
|
freesurface (tempsurf);
|
|
tempsurf = 0;
|
|
xfree (tempsurf2);
|
|
tempsurf2 = 0;
|
|
xfree (tempsurf3);
|
|
tempsurf3 = 0;
|
|
filteroffsetx = 0;
|
|
filteroffsety = 0;
|
|
filterxmult = 1.0;
|
|
filterymult = 1.0;
|
|
scale = 1;
|
|
inited = false;
|
|
}
|
|
|
|
bool S2X_init(int monid, int dw, int dh, int dd)
|
|
{
|
|
if (monid)
|
|
return false;
|
|
|
|
struct vidbuf_description *avidinfo = &adisplays[monid].gfxvidinfo;
|
|
struct amigadisplay *ad = &adisplays[monid];
|
|
struct vidbuffer *vb = avidinfo->outbuffer;
|
|
struct AmigaMonitor *mon = &AMonitors[monid];
|
|
struct uae_filter *usedfilter = mon->usedfilter;
|
|
int flags = 0;
|
|
|
|
dst_width2 = dw;
|
|
dst_height2 = dh;
|
|
dst_depth2 = dd;
|
|
amiga_width2 = vb->outwidth;
|
|
amiga_height2 = vb->outheight;
|
|
amiga_depth2 = vb->pixbytes * 8;
|
|
|
|
S2X_free(monid);
|
|
d3d = currprefs.gfx_api;
|
|
changed_prefs.leds_on_screen |= STATUSLINE_TARGET;
|
|
currprefs.leds_on_screen |= STATUSLINE_TARGET;
|
|
statusline_set_multiplier(monid, dw, dh);
|
|
|
|
if (d3d)
|
|
dd = amiga_depth2;
|
|
|
|
if (dd == 32)
|
|
alloc_colors_rgb (8, 8, 8, 16, 8, 0, 0, 0, 0, 0, rc, gc, bc);
|
|
else
|
|
alloc_colors_rgb (5, 6, 5, 11, 5, 0, 0, 0, 0, 0, rc, gc, bc);
|
|
|
|
if (WIN32GFX_IsPicassoScreen(mon))
|
|
return true;
|
|
|
|
if (!currprefs.gf[ad->picasso_on].gfx_filter || !usedfilter) {
|
|
usedfilter = &uaefilters[0];
|
|
scale = 1;
|
|
} else {
|
|
scale = usedfilter->intmul;
|
|
flags = usedfilter->flags;
|
|
if ((amiga_depth2 == 16 && !(flags & UAE_FILTER_MODE_16)) || (amiga_depth2 == 32 && !(flags & UAE_FILTER_MODE_32))) {
|
|
usedfilter = &uaefilters[0];
|
|
scale = 1;
|
|
changed_prefs.gf[ad->picasso_on].gfx_filter = usedfilter->type;
|
|
}
|
|
}
|
|
#if 0
|
|
int res_shift;
|
|
res_shift = RES_MAX - currprefs.gfx_resolution;
|
|
if (currprefs.gfx_xcenter_size > 0 && (currprefs.gfx_xcenter_size >> res_shift) < aw)
|
|
aw = currprefs.gfx_xcenter_size >> res_shift;
|
|
res_shift = VRES_MAX - currprefs.gfx_vresolution;
|
|
if (currprefs.gfx_ycenter_size > 0 && (currprefs.gfx_ycenter_size >> res_shift) < ah)
|
|
ah = currprefs.gfx_ycenter_size >> res_shift;
|
|
#endif
|
|
dst_width = dw;
|
|
dst_height = dh;
|
|
dst_depth = dd;
|
|
amiga_width = vb->outwidth;
|
|
amiga_height = vb->outheight;
|
|
amiga_depth = vb->pixbytes * 8;
|
|
|
|
if (d3d) {
|
|
int mh = currprefs.gf[ad->picasso_on].gfx_filter_filtermodeh + 1;
|
|
if (mh < scale)
|
|
mh = scale;
|
|
temp_width = dst_width * mh;
|
|
int mv = currprefs.gf[ad->picasso_on].gfx_filter_filtermodev + 1;
|
|
if (mv < scale)
|
|
mv = scale;
|
|
temp_height = dst_height * mv;
|
|
} else {
|
|
temp_width = dst_width * 2;
|
|
temp_height = dst_height * 2;
|
|
}
|
|
|
|
if (usedfilter->type == UAE_FILTER_HQ2X || usedfilter->type == UAE_FILTER_HQ3X || usedfilter->type == UAE_FILTER_HQ4X) {
|
|
int w = amiga_width > dst_width ? amiga_width : dst_width;
|
|
int h = amiga_height > dst_height ? amiga_height : dst_height;
|
|
tempsurf2 = xmalloc (uae_u8, w * h * (amiga_depth / 8) * ((scale + 1) / 2));
|
|
tempsurf3 = xmalloc (uae_u8, w * h *(dst_depth / 8) * 4 * scale);
|
|
}
|
|
if (!d3d) {
|
|
for (;;) {
|
|
if (temp_width > dxcaps.maxwidth)
|
|
temp_width = dxcaps.maxwidth;
|
|
if (temp_height > dxcaps.maxheight)
|
|
temp_height = dxcaps.maxheight;
|
|
if (temp_width < dst_width)
|
|
temp_width = dst_width;
|
|
if (temp_height < dst_height)
|
|
temp_height = dst_height;
|
|
tempsurf = allocsurface(temp_width, temp_height);
|
|
if (tempsurf)
|
|
break;
|
|
if (temp_width >= 2 * dst_width || temp_height >= 2 * dst_height) {
|
|
temp_width = dst_width * 3 / 2;
|
|
temp_height = dst_height * 3 / 2;
|
|
continue;
|
|
}
|
|
if (temp_width == dst_width * 3 / 2 || temp_height == dst_height * 2) {
|
|
temp_width = dst_width * 4 / 3;
|
|
temp_height = dst_height * 4 / 3;
|
|
continue;
|
|
}
|
|
if (temp_width > dst_width || temp_height > dst_height) {
|
|
temp_width = dst_width;
|
|
temp_height = dst_height;
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if (!tempsurf && !d3d) {
|
|
write_log (_T("DDRAW: failed to create temp surface (%dx%d)\n"), temp_width, temp_height);
|
|
return false;
|
|
}
|
|
inited = true;
|
|
return true;
|
|
}
|
|
|
|
void S2X_render(int monid, int y_start, int y_end)
|
|
{
|
|
struct AmigaMonitor *mon = &AMonitors[monid];
|
|
struct amigadisplay *ad = &adisplays[monid];
|
|
struct uae_filter *usedfilter = mon->usedfilter;
|
|
struct vidbuf_description *avidinfo = &adisplays[monid].gfxvidinfo;
|
|
struct vidbuffer *vb = avidinfo->outbuffer;
|
|
int aw, ah, aws, ahs;
|
|
uae_u8 *dptr, *enddptr, *sptr, *endsptr;
|
|
int ok = 0;
|
|
RECT sr, dr, zr;
|
|
DDSURFACEDESC2 desc;
|
|
int pitch, surf_height;
|
|
uae_u8 *surfstart;
|
|
|
|
aw = amiga_width;
|
|
ah = amiga_height;
|
|
aws = aw * scale;
|
|
ahs = ah * scale;
|
|
|
|
if (ah < 16)
|
|
return;
|
|
if (aw < 16)
|
|
return;
|
|
if (!vb->bufmem)
|
|
return;
|
|
|
|
sptr = vb->bufmem;
|
|
endsptr = vb->bufmemend;
|
|
bufmem_ptr = sptr;
|
|
|
|
if (d3d) {
|
|
if (D3D_restore)
|
|
D3D_restore(monid, true);
|
|
surfstart = D3D_locktexture(monid, &pitch, &surf_height, y_start < 0);
|
|
if (surfstart == NULL)
|
|
return;
|
|
} else {
|
|
if (tempsurf == NULL)
|
|
return;
|
|
if (cleartemp) {
|
|
DirectDraw_ClearSurface (tempsurf);
|
|
cleartemp = 0;
|
|
}
|
|
if (!DirectDraw_LockSurface (tempsurf, &desc))
|
|
return;
|
|
pitch = desc.lPitch;
|
|
surfstart = (uae_u8*)desc.lpSurface;
|
|
surf_height = desc.dwHeight;
|
|
}
|
|
dptr = surfstart;
|
|
enddptr = dptr + pitch * surf_height;
|
|
if (!d3d) {
|
|
dptr = getfilterrect1 (&sr, &dr, dst_width, dst_height, dst_depth, aw, ah, scale, temp_width, temp_height, dptr, pitch);
|
|
}
|
|
|
|
if (!dptr) /* weird things can happen */
|
|
goto end;
|
|
if (dptr < surfstart)
|
|
dptr = surfstart;
|
|
|
|
if (usedfilter->type == UAE_FILTER_SCALE2X) { /* 16+32/2X */
|
|
|
|
if (dptr + pitch * ah * 2 >= enddptr)
|
|
ah = (enddptr - dptr) / (pitch * 2);
|
|
|
|
if (amiga_depth == 16 && dst_depth == 16) {
|
|
AdMame2x (sptr, vb->rowbytes, dptr, pitch, aw, ah);
|
|
ok = 1;
|
|
} else if (amiga_depth == 32 && dst_depth == 32) {
|
|
AdMame2x32 (sptr, vb->rowbytes, dptr, pitch, aw, ah);
|
|
ok = 1;
|
|
}
|
|
|
|
} else if (usedfilter->type == UAE_FILTER_HQ2X || usedfilter->type == UAE_FILTER_HQ3X || usedfilter->type == UAE_FILTER_HQ4X) { /* 32/2X+3X+4X */
|
|
|
|
#ifndef CPU_64_BIT
|
|
|
|
if (tempsurf2 && scale >= 2 && scale <= 4) {
|
|
/* Aaaaaaaarghhhghgh.. */
|
|
uae_u8 *sptr2 = tempsurf3;
|
|
uae_u8 *dptr2 = tempsurf2;
|
|
int i;
|
|
for (i = 0; i < ah; i++) {
|
|
int w = aw * (amiga_depth / 8);
|
|
memcpy (dptr2, sptr, w);
|
|
dptr2 += w;
|
|
sptr += vb->rowbytes;
|
|
}
|
|
if (amiga_depth == 16 && dst_depth == 32) {
|
|
if (usedfilter->type == UAE_FILTER_HQ2X)
|
|
hq2x_32 (tempsurf2, tempsurf3, aw, ah, aws * 4);
|
|
else if (usedfilter->type == UAE_FILTER_HQ3X)
|
|
hq3x_32 (tempsurf2, tempsurf3, aw, ah, aws * 4);
|
|
else if (usedfilter->type == UAE_FILTER_HQ4X)
|
|
hq4x_32 (tempsurf2, tempsurf3, aw, ah, aws * 4);
|
|
ok = 1;
|
|
} else if (amiga_depth == 16 && dst_depth == 16) {
|
|
if (usedfilter->type == UAE_FILTER_HQ2X)
|
|
hq2x_16 (tempsurf2, tempsurf3, aw, ah, aws * 2);
|
|
else if (usedfilter->type == UAE_FILTER_HQ3X)
|
|
hq3x_16 (tempsurf2, tempsurf3, aw, ah, aws * 2);
|
|
else if (usedfilter->type == UAE_FILTER_HQ4X)
|
|
hq4x_16 (tempsurf2, tempsurf3, aw, ah, aws * 2);
|
|
ok = 1;
|
|
}
|
|
for (i = 0; i < ah * scale; i++) {
|
|
int w = aw * scale * (dst_depth / 8);
|
|
if (dptr + w > enddptr)
|
|
break;
|
|
memcpy (dptr, sptr2, w);
|
|
sptr2 += w;
|
|
dptr += pitch;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
} else if (usedfilter->type == UAE_FILTER_SUPEREAGLE) { /* 16/32/2X */
|
|
|
|
if (dptr + pitch * ah * 2 >= enddptr)
|
|
ah = (enddptr - dptr) / (pitch * 2);
|
|
|
|
if (scale == 2 && amiga_depth == 16) {
|
|
if (dst_depth == 16) {
|
|
SuperEagle_16 (sptr, vb->rowbytes, dptr, pitch, aw, ah);
|
|
ok = 1;
|
|
} else if (dst_depth == 32) {
|
|
SuperEagle_32 (sptr, vb->rowbytes, dptr, pitch, aw, ah);
|
|
ok = 1;
|
|
}
|
|
}
|
|
|
|
} else if (usedfilter->type == UAE_FILTER_SUPER2XSAI) { /* 16/32/2X */
|
|
|
|
if (dptr + pitch * ah * 2 >= enddptr)
|
|
ah = (enddptr - dptr) / (pitch * 2);
|
|
|
|
if (scale == 2 && amiga_depth == 16) {
|
|
if (dst_depth == 16) {
|
|
Super2xSaI_16 (sptr, vb->rowbytes, dptr, pitch, aw, ah);
|
|
ok = 1;
|
|
} else if (dst_depth == 32) {
|
|
Super2xSaI_32 (sptr, vb->rowbytes, dptr, pitch, aw, ah);
|
|
ok = 1;
|
|
}
|
|
}
|
|
|
|
} else if (usedfilter->type == UAE_FILTER_2XSAI) { /* 16/32/2X */
|
|
|
|
if (dptr + pitch * ah * 2 >= enddptr)
|
|
ah = (enddptr - dptr) / (pitch * 2);
|
|
|
|
if (scale == 2 && amiga_depth == 16) {
|
|
if (dst_depth == 16) {
|
|
_2xSaI_16 (sptr, vb->rowbytes, dptr, pitch, aw, ah);
|
|
ok = 1;
|
|
} else if (dst_depth == 32) {
|
|
_2xSaI_32 (sptr, vb->rowbytes, dptr, pitch, aw, ah);
|
|
ok = 1;
|
|
}
|
|
}
|
|
|
|
} else if (usedfilter->type == UAE_FILTER_PAL) { /* 16/32/1X */
|
|
|
|
if (amiga_depth == 32 && dst_depth == 32) {
|
|
PAL_1x1_32 ((uae_u32*)sptr, vb->rowbytes, (uae_u32*)dptr, pitch, aw, ah);
|
|
ok = 1;
|
|
} else if (amiga_depth == 16 && dst_depth == 16) {
|
|
PAL_1x1_16 ((uae_u16*)sptr, vb->rowbytes, (uae_u16*)dptr, pitch, aw, ah);
|
|
ok = 1;
|
|
}
|
|
|
|
} else { /* null */
|
|
|
|
if (amiga_depth == dst_depth) {
|
|
int w = aw * dst_depth / 8;
|
|
if (y_start < 0) {
|
|
uae_u8 *d = dptr;
|
|
uae_u8 *s = sptr;
|
|
for (int y = 0; y < ah && d + w <= enddptr; y++) {
|
|
memcpy(d, s, w);
|
|
s += vb->rowbytes;
|
|
d += pitch;
|
|
}
|
|
} else {
|
|
uae_u8 *d = dptr + y_start * pitch;
|
|
uae_u8 *s = sptr + y_start * vb->rowbytes;
|
|
for (int y = y_start; y < ah && y < y_end && d + w <= enddptr; y++) {
|
|
memcpy(d, s, w);
|
|
s += vb->rowbytes;
|
|
d += pitch;
|
|
}
|
|
}
|
|
}
|
|
ok = 1;
|
|
|
|
}
|
|
|
|
if (ok == 0 && currprefs.gf[ad->picasso_on].gfx_filter) {
|
|
usedfilter = &uaefilters[0];
|
|
changed_prefs.gf[ad->picasso_on].gfx_filter = usedfilter->type;
|
|
}
|
|
|
|
end:
|
|
if (d3d) {
|
|
;//D3D_unlocktexture (); unlock in win32gfx.c
|
|
} else {
|
|
DirectDraw_UnlockSurface (tempsurf);
|
|
|
|
getfilterrect2(monid, &dr, &sr, &zr, dst_width, dst_height, aw, ah, scale, temp_width, temp_height);
|
|
//write_log (_T("(%d %d %d %d) - (%d %d %d %d) (%d %d)\n"), dr.left, dr.top, dr.right, dr.bottom, sr.left, sr.top, sr.right, sr.bottom, zr.left, zr.top);
|
|
OffsetRect (&sr, zr.left, zr.top);
|
|
if (sr.left < 0)
|
|
sr.left = 0;
|
|
if (sr.top < 0)
|
|
sr.top = 0;
|
|
if (sr.right <= temp_width && sr.bottom <= temp_height) {
|
|
if (sr.left < sr.right && sr.top < sr.bottom)
|
|
DirectDraw_BlitRect (NULL, &dr, tempsurf, &sr);
|
|
}
|
|
statusline(monid);
|
|
}
|
|
}
|
|
|
|
void S2X_refresh(int monid)
|
|
{
|
|
if (monid)
|
|
return;
|
|
DirectDraw_ClearSurface(NULL);
|
|
S2X_render(monid, -1, -1);
|
|
}
|
|
|
|
int S2X_getmult(int monid)
|
|
{
|
|
if (monid)
|
|
return 1;
|
|
struct AmigaMonitor *mon = &AMonitors[monid];
|
|
struct uae_filter *usedfilter = mon->usedfilter;
|
|
if (!usedfilter)
|
|
return 1;
|
|
if (mon->screen_is_picasso)
|
|
return 1;
|
|
return usedfilter->intmul;
|
|
}
|
|
|
|
#endif
|