Merge pull request #159 from SuuperW/display

This commit is contained in:
zeromus 2018-07-21 15:27:56 -05:00 committed by GitHub
commit fe851aa10c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 182 additions and 198 deletions

View File

@ -33,8 +33,8 @@ namespace agg
extern const int8u gse4x8[];
extern const int8u gse5x7[];
extern const int8u gse5x9[];
extern const int8u gse6x12[];
extern const int8u gse6x9[];
extern const int8u gse6x12[];
extern const int8u gse7x11[];
extern const int8u gse7x11_bold[];
extern const int8u gse7x15[];

View File

@ -1170,7 +1170,7 @@ RECT CalculateDisplayLayoutWrapper(RECT rcClient, int targetWidth, int targetHei
return rc;
}
void UpdateWndRects(HWND hwnd)
void UpdateWndRects(HWND hwnd, RECT* newClientRect = NULL)
{
POINT ptClient;
RECT rc;
@ -1185,6 +1185,10 @@ void UpdateWndRects(HWND hwnd)
int oneScreenHeight, gapHeight;
int tbheight;
//if we're in the middle of resizing the window, GetClientRect will return the old rect
if (newClientRect)
rc = RECT(*newClientRect);
else
GetClientRect(hwnd, &rc);
if(maximized)
@ -1682,26 +1686,81 @@ struct GLDISPLAY
} gldisplay;
static void OGL_DrawTexture(RECT* srcRects, RECT* dstRects)
{
//don't change the original rects
RECT sRects[2];
sRects[0] = RECT(srcRects[0]);
sRects[1] = RECT(srcRects[1]);
//use clear+scissor for gap
if (video.screengap > 0)
{
//adjust client rect into scissor rect (0,0 at bottomleft)
glScissor(dstRects[2].left, dstRects[2].bottom, dstRects[2].right - dstRects[2].left, dstRects[2].top - dstRects[2].bottom);
u32 color_rev = (u32)ScreenGapColor;
int r = (color_rev >> 0) & 0xFF;
int g = (color_rev >> 8) & 0xFF;
int b = (color_rev >> 16) & 0xFF;
glClearColor(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f);
glEnable(GL_SCISSOR_TEST);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_SCISSOR_TEST);
}
//draw two screens
glBegin(GL_QUADS);
for (int i = 0; i<2; i++)
{
//none of this makes any goddamn sense. dont even try.
int idx = i;
int ofs = 0;
switch (video.rotation)
{
case 0:
break;
case 90:
ofs = 3;
idx = 1 - i;
std::swap(sRects[idx].right, sRects[idx].bottom);
std::swap(sRects[idx].left, sRects[idx].top);
break;
case 180:
idx = 1 - i;
ofs = 2;
break;
case 270:
std::swap(sRects[idx].right, sRects[idx].bottom);
std::swap(sRects[idx].left, sRects[idx].top);
ofs = 1;
break;
}
float u1 = sRects[idx].left / (float)video.width;
float u2 = sRects[idx].right / (float)video.width;
float v1 = sRects[idx].top / (float)video.height;
float v2 = sRects[idx].bottom / (float)video.height;
float u[] = { u1,u2,u2,u1 };
float v[] = { v1,v1,v2,v2 };
glTexCoord2f(u[(ofs + 0) % 4], v[(ofs + 0) % 4]);
glVertex2i(dstRects[i].left, dstRects[i].top);
glTexCoord2f(u[(ofs + 1) % 4], v[(ofs + 1) % 4]);
glVertex2i(dstRects[i].right, dstRects[i].top);
glTexCoord2f(u[(ofs + 2) % 4], v[(ofs + 2) % 4]);
glVertex2i(dstRects[i].right, dstRects[i].bottom);
glTexCoord2f(u[(ofs + 3) % 4], v[(ofs + 3) % 4]);
glVertex2i(dstRects[i].left, dstRects[i].bottom);
}
glEnd();
}
static void OGL_DoDisplay()
{
if(!gldisplay.begin()) return;
const NDSDisplayInfo &displayInfo = GPU->GetDisplayInfo();
static GLuint tex = 0;
if(tex == 0)
glGenTextures(1,&tex);
glBindTexture(GL_TEXTURE_2D,tex);
if(gpu_bpp == 15)
{
//yeah, it's 32bits here still. we've converted it previously, for compositing the HUD
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, video.width, video.height, 0, GL_BGRA, GL_UNSIGNED_BYTE, video.finalBuffer());
}
else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, video.width, video.height, 0, GL_BGRA, GL_UNSIGNED_BYTE, video.finalBuffer());
//the ds screen fills the texture entirely, so we dont have garbage at edge to worry about,
//but we need to make sure this is clamped for when filtering is selected
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
@ -1718,16 +1777,12 @@ static void OGL_DoDisplay()
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
}
glEnable(GL_TEXTURE_2D);
RECT rc;
HWND hwnd = MainWindow->getHWnd();
GetClientRect(hwnd,&rc);
int width = rc.right - rc.left;
int height = rc.bottom - rc.top;
glDisable(GL_LIGHTING);
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
@ -1737,41 +1792,22 @@ static void OGL_DoDisplay()
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//clear entire area, for cases where the screen is maximized
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
// get dest and src rects
RECT dr[] = {MainScreenRect, SubScreenRect, GapRect};
for(int i=0;i<2;i++) //dont change gap rect, for some reason
{
ScreenToClient(hwnd,(LPPOINT)&dr[i].left);
ScreenToClient(hwnd,(LPPOINT)&dr[i].right);
}
//clear entire area, for cases where the screen is maximized
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
//use clear+scissor for gap
if(video.screengap > 0)
{
//adjust client rect into scissor rect (0,0 at bottomleft)
dr[2].bottom = height - dr[2].bottom;
dr[2].top = height - dr[2].top;
glScissor(dr[2].left,dr[2].bottom,dr[2].right-dr[2].left,dr[2].top-dr[2].bottom);
u32 color_rev = (u32)ScreenGapColor;
int r = (color_rev>>0)&0xFF;
int g = (color_rev>>8)&0xFF;
int b = (color_rev>>16)&0xFF;
glClearColor(r/255.0f,g/255.0f,b/255.0f,1.0f);
glEnable(GL_SCISSOR_TEST);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_SCISSOR_TEST);
}
RECT srcRects [2];
const bool isMainGPUFirst = (displayInfo.engineID[NDSDisplayID_Main] == GPUEngineID_Main);
const bool isMainGPUFirst = (GPU->GetDisplayInfo().engineID[NDSDisplayID_Main] == GPUEngineID_Main);
if(video.swap == 0)
{
@ -1803,62 +1839,17 @@ static void OGL_DoDisplay()
// srcRects[1].left,srcRects[1].top, srcRects[1].right-srcRects[1].left, srcRects[1].bottom-srcRects[1].top
// );
glEnable(GL_TEXTURE_2D);
// draw DS display
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, video.width, video.height, 0, GL_BGRA, GL_UNSIGNED_BYTE, video.finalBuffer());
OGL_DrawTexture(srcRects, dr);
//draw two screens
glBegin(GL_QUADS);
for(int i=0;i<2;i++)
{
//none of this makes any goddamn sense. dont even try.
int idx = i;
int ofs = 0;
switch(video.rotation)
{
case 0:
break;
case 90:
ofs = 3;
idx = 1-i;
std::swap(srcRects[idx].right,srcRects[idx].bottom);
std::swap(srcRects[idx].left,srcRects[idx].top);
break;
case 180:
idx = 1-i;
ofs = 2;
break;
case 270:
std::swap(srcRects[idx].right,srcRects[idx].bottom);
std::swap(srcRects[idx].left,srcRects[idx].top);
ofs = 1;
break;
}
float u1 = srcRects[idx].left/(float)video.width;
float u2 = srcRects[idx].right/(float)video.width;
float v1 = srcRects[idx].top/(float)video.height;
float v2 = srcRects[idx].bottom/(float)video.height;
float u[] = {u1,u2,u2,u1};
float v[] = {v1,v1,v2,v2};
const GLfloat backlightIntensity = displayInfo.backlightIntensity[i];
glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glTexCoord2f(u[(ofs+0)%4],v[(ofs+0)%4]);
glVertex2i(dr[i].left,dr[i].top);
glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glTexCoord2f(u[(ofs+1)%4],v[(ofs+1)%4]);
glVertex2i(dr[i].right,dr[i].top);
glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glTexCoord2f(u[(ofs+2)%4],v[(ofs+2)%4]);
glVertex2i(dr[i].right,dr[i].bottom);
glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glTexCoord2f(u[(ofs+3)%4],v[(ofs+3)%4]);
glVertex2i(dr[i].left,dr[i].bottom);
}
glEnd();
// draw HUD
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GPU_FRAMEBUFFER_NATIVE_WIDTH, GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2, 0, GL_BGRA, GL_UNSIGNED_BYTE, aggDraw.hud->buf().buf());
OGL_DrawTexture(srcRects, dr);
glDisable(GL_BLEND);
gldisplay.showPage();
@ -1890,12 +1881,11 @@ static void DD_DoDisplay()
else
doRotate<pix15>(ddraw.surfDescBack.lpSurface);
break;
case 0:
break;
default:
{
if(ddraw.surfDescBack.ddpfPixelFormat.dwRGBBitCount != 0)
INFO("Unsupported color depth: %i bpp\n", ddraw.surfDescBack.ddpfPixelFormat.dwRGBBitCount);
//emu_halt();
}
break;
}
if (!ddraw.unlock()) return;
@ -2033,7 +2023,7 @@ static void DoDisplay_DrawHud()
}
//does a single display work unit. only to be used from the display thread
static void DoDisplay(bool firstTime)
static void DoDisplay()
{
Lock lock (win_backbuffer_sync);
@ -2050,26 +2040,11 @@ static void DoDisplay(bool firstTime)
else
ColorspaceConvertBuffer888XTo8888Opaque<true, false>((u32*)video.srcBuffer, video.buffer, video.srcBufferSize / 4);
if(ddhw || ddsw)
{
//some games use the backlight for fading effects
const size_t pixCount = video.prefilterWidth * video.prefilterHeight / 2;
const NDSDisplayInfo &displayInfo = GPU->GetDisplayInfo();
const size_t pixCount = displayInfo.customWidth * displayInfo.customHeight;
ColorspaceApplyIntensityToBuffer32<false, false>(video.buffer, pixCount, displayInfo.backlightIntensity[NDSDisplayID_Main]);
ColorspaceApplyIntensityToBuffer32<false, false>(video.buffer + pixCount, pixCount, displayInfo.backlightIntensity[NDSDisplayID_Touch]);
}
if(firstTime)
{
//on single core systems, draw straight to the screen
//we only do this once per emulated frame because we don't want to waste time redrawing
//on such lousy computers
if(CommonSettings.single_core())
{
aggDraw.hud->attach((u8*)video.buffer, video.width, video.height, video.width*4);
DoDisplay_DrawHud();
}
}
if(AnyLuaActive())
{
@ -2084,18 +2059,18 @@ static void DoDisplay(bool firstTime)
}
}
//apply user's filter
video.filter();
if(!CommonSettings.single_core())
{
//draw and composite the OSD (but not if we are drawing osd straight to screen)
DoDisplay_DrawHud();
T_AGG_RGBA target((u8*)video.finalBuffer(), video.width,video.height,video.width*4);
target.transformImage(aggDraw.hud->image<T_AGG_PF_RGBA>(), 0,0,video.width,video.height);
// draw hud
aggDraw.hud->clear();
DoDisplay_DrawHud();
if (ddhw || ddsw)
{
// DirectDraw doesn't support alpha blending, so we must scale and overlay the HUD ourselves.
T_AGG_RGBA target((u8*)video.buffer, video.prefilterWidth, video.prefilterHeight, video.prefilterWidth * 4);
target.transformImage(aggDraw.hud->image<T_AGG_PF_RGBA>(), 0, 0, video.prefilterWidth, video.prefilterHeight);
}
//apply user's filter
video.filter();
if(ddhw || ddsw)
{
@ -2104,7 +2079,6 @@ static void DoDisplay(bool firstTime)
}
else
{
//other cases..?
OGL_DoDisplay();
}
}
@ -2125,13 +2099,8 @@ void displayProc()
currDisplayBuffer = todo;
video.srcBuffer = (u8*)displayBuffers[currDisplayBuffer].buffer;
video.srcBufferSize = displayBuffers[currDisplayBuffer].size;
DoDisplay(true);
}
else
{
DoDisplay(false);
}
DoDisplay();
}
@ -2178,7 +2147,7 @@ void Display()
{
video.srcBuffer = (u8*)dispInfo.masterCustomBuffer;
video.srcBufferSize = dispInfo.customWidth * dispInfo.customHeight * dispInfo.pixelBytes * 2;
DoDisplay(true);
DoDisplay();
}
else
{
@ -2322,7 +2291,7 @@ static void StepRunLoop_Paused()
if(CommonSettings.single_core() && GetActiveWindow() == mainLoopData.hwnd)
{
video.srcBuffer = (u8*)GPU->GetDisplayInfo().masterCustomBuffer;
DoDisplay(true);
DoDisplay();
}
ServiceDisplayThreadInvocations();
@ -3793,7 +3762,17 @@ void FixAspectRatio()
void SetScreenGap(int gap)
{
RECT clientRect;
GetClientRect(MainWindow->getHWnd(), &clientRect);
RECT rc;
GetWindowRect(MainWindow->getHWnd(), &rc);
if (video.rotation == 0 || video.rotation == 180)
rc.bottom += (gap - video.screengap) * (clientRect.right - clientRect.left) / GPU_FRAMEBUFFER_NATIVE_WIDTH;
else
rc.right += (gap - video.screengap) * (clientRect.bottom - clientRect.top - MainWindowToolbar->GetHeight()) / GPU_FRAMEBUFFER_NATIVE_WIDTH;
video.screengap = gap;
MoveWindow(MainWindow->getHWnd(), rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE);
SetMinWindowSize();
FixAspectRatio();
UpdateWndRects(MainWindow->getHWnd());
@ -5038,12 +5017,11 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
wndHeightGapless = (MainScreenRect.bottom - MainScreenRect.top) + (SubScreenRect.bottom - SubScreenRect.top);
}
if(ForceRatio)
video.screengap = (wndHeight * video.width / wndWidth - video.height);
else
video.screengap = wndHeight * video.height / wndHeightGapless - video.height;
video.screengap = GPU_FRAMEBUFFER_NATIVE_WIDTH * (wndHeight - wndHeightGapless) / wndWidth;
UpdateWndRects(MainWindow->getHWnd());
rc.bottom -= rc.top; rc.top = 0;
rc.right -= rc.left; rc.left = 0;
UpdateWndRects(MainWindow->getHWnd(), &rc);
}
}
return 1;
@ -5208,7 +5186,7 @@ DOKEYDOWN:
{
const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo();
video.srcBuffer = (u8*)dispInfo.masterCustomBuffer;
DoDisplay(true);
DoDisplay();
}
}
@ -6656,11 +6634,12 @@ LRESULT CALLBACK GFX3DSettingsDlgProc(HWND hw, UINT msg, WPARAM wp, LPARAM lp)
}
if(IsDlgCheckboxChecked(hw,IDC_TEXSCALE_1)) CommonSettings.GFX3D_Renderer_TextureScalingFactor = 1;
if(IsDlgCheckboxChecked(hw,IDC_TEXSCALE_2)) CommonSettings.GFX3D_Renderer_TextureScalingFactor = 2;
if(IsDlgCheckboxChecked(hw,IDC_TEXSCALE_4)) CommonSettings.GFX3D_Renderer_TextureScalingFactor = 4;
else if(IsDlgCheckboxChecked(hw,IDC_TEXSCALE_2)) CommonSettings.GFX3D_Renderer_TextureScalingFactor = 2;
else if(IsDlgCheckboxChecked(hw,IDC_TEXSCALE_4)) CommonSettings.GFX3D_Renderer_TextureScalingFactor = 4;
if(IsDlgCheckboxChecked(hw, IDC_GPU_15BPP)) gpu_bpp = 15;
if(IsDlgCheckboxChecked(hw, IDC_GPU_18BPP)) gpu_bpp = 18;
if(IsDlgCheckboxChecked(hw, IDC_GPU_24BPP)) gpu_bpp = 24;
else if(IsDlgCheckboxChecked(hw, IDC_GPU_18BPP)) gpu_bpp = 18;
else if(IsDlgCheckboxChecked(hw, IDC_GPU_24BPP)) gpu_bpp = 24;
CommonSettings.GFX3D_Renderer_TextureDeposterize = IsDlgCheckboxChecked(hw,IDC_TEX_DEPOSTERIZE);
CommonSettings.GFX3D_Renderer_TextureSmoothing = IsDlgCheckboxChecked(hw,IDC_TEX_SMOOTH);
@ -6668,11 +6647,18 @@ LRESULT CALLBACK GFX3DSettingsDlgProc(HWND hw, UINT msg, WPARAM wp, LPARAM lp)
Lock lock(win_backbuffer_sync);
if(display_mutex) slock_lock(display_mutex);
Change3DCoreWithFallbackAndSave(ComboBox_GetCurSel(GetDlgItem(hw, IDC_3DCORE)));
if (newPrescaleHD != video.prescaleHD)
{
video.SetPrescale(newPrescaleHD, 1);
GPU->SetCustomFramebufferSize(GPU_FRAMEBUFFER_NATIVE_WIDTH*video.prescaleHD, GPU_FRAMEBUFFER_NATIVE_HEIGHT*video.prescaleHD);
}
SyncGpuBpp();
UpdateScreenRects();
if(display_mutex) slock_unlock(display_mutex);
// shrink buffer size if necessary
const NDSDisplayInfo &displayInfo = GPU->GetDisplayInfo();
size_t newBufferSize = displayInfo.customWidth * displayInfo.customHeight * 2 * displayInfo.pixelBytes;
if (newBufferSize < video.srcBufferSize) video.srcBufferSize = newBufferSize;
}
WritePrivateProfileBool("3D", "HighResolutionInterpolateColor", CommonSettings.GFX3D_HighResolutionInterpolateColor, IniName);

View File

@ -1398,7 +1398,7 @@ FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,50,45,50,14
PUSHBUTTON "Cancel",IDCANCEL,104,45,50,14
COMBOBOX IDC_FONTCOMBO,7,23,147,199,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_FONTCOMBO,7,23,147,199,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Select a HUD font",IDC_START,7,7,74,14
END

View File

@ -30,6 +30,8 @@ public:
int width;
int height;
int prefilterWidth;
int prefilterHeight;
int rotation;
int rotation_userset;
@ -59,6 +61,8 @@ public:
this->prescaleHD = prescaleHD;
this->prescalePost = prescalePost;
prefilterWidth = 256 * prescaleHD;
prefilterHeight = 192 * 2 * prescaleHD;
prescaleTotal = prescaleHD;
@ -74,8 +78,8 @@ public:
const int kPadSize = 4;
// raw buffer
size_t rawBufferWidth = 256 * prescaleHD + (kPadSize * 2);
size_t rawBufferHeight = 192 * 2 * prescaleHD + (kPadSize * 2);
size_t rawBufferWidth = prefilterWidth + (kPadSize * 2);
size_t rawBufferHeight = prefilterHeight + (kPadSize * 2);
rawBufferSize = rawBufferWidth * rawBufferHeight * 4;
buffer_raw = buffer = (u32*)malloc_alignedCacheLine(rawBufferSize);
@ -90,8 +94,6 @@ public:
// clean the new buffers
clear();
// prevent crashing when reducing the scaling
srcBufferSize = 0;
}
enum {
@ -134,8 +136,6 @@ public:
void reset() {
SetPrescale(1, 1); //should i do this here?
width = 256;
height = 384;
}
void setfilter(int filter) {
@ -148,42 +148,40 @@ public:
switch (filter) {
case NONE:
width = 256;
height = 384;
width = prefilterWidth;
height = prefilterHeight;
break;
case EPX1POINT5:
case EPXPLUS1POINT5:
case NEAREST1POINT5:
case NEARESTPLUS1POINT5:
width = 256 * 3 / 2;
height = 384 * 3 / 2;
width = prefilterWidth * 3 / 2;
height = prefilterHeight * 3 / 2;
break;
case _5XBRZ:
width = 256 * 5;
height = 384 * 5;
width = prefilterWidth * 5;
height = prefilterHeight * 5;
break;
case HQ4X:
case _4XBRZ:
width = 256 * 4;
height = 384 * 4;
width = prefilterWidth * 4;
height = prefilterHeight * 4;
break;
case _3XBRZ:
width = 256 * 3;
height = 384 * 3;
width = prefilterWidth * 3;
height = prefilterHeight * 3;
break;
case _2XBRZ:
default:
width = 256 * 2;
height = 384 * 2;
width = prefilterWidth * 2;
height = prefilterHeight * 2;
break;
}
width *= prescaleHD;
height *= prescaleHD;
ResizeBuffers();
}