- added freeform editing of the screen gap size by dragging the window border (optional)
- added extra gap size option
- fixed bug with window sliding around when resizing from the top/left
- fixed(?) bug with default window size command setting invalid sizes after the rotation/gap settings have changed
- fixed some inconsistency in the restoring of forced aspect ratio when changing modes
- fixed window getting very squashed at large sizes even if force maintain ratio is on
This commit is contained in:
nitsuja 2009-08-04 07:44:39 +00:00
parent 52b7454046
commit 194723d96d
5 changed files with 204 additions and 44 deletions

View File

@ -91,10 +91,13 @@ void WINCLASS::setMinSize(int width, int height)
minHeight = height;
}
void WINCLASS::sizingMsg(WPARAM wParam, LPARAM lParam, BOOL keepRatio)
void WINCLASS::sizingMsg(WPARAM wParam, LPARAM lParam, LONG keepRatio)
{
RECT *rect = (RECT*)lParam;
int prevRight = rect->right;
int prevBottom = rect->bottom;
int _minWidth, _minHeight;
int xborder, yborder;
@ -124,30 +127,48 @@ void WINCLASS::sizingMsg(WPARAM wParam, LPARAM lParam, BOOL keepRatio)
rect->right = (rect->left + std::max(_minWidth, (int)(rect->right - rect->left)));
rect->bottom = (rect->top + std::max(_minHeight, (int)(rect->bottom - rect->top)));
bool horizontalDrag = (wParam == WMSZ_LEFT) || (wParam == WMSZ_RIGHT);
bool verticalDrag = (wParam == WMSZ_TOP) || (wParam == WMSZ_BOTTOM);
if(verticalDrag && !(keepRatio & KEEPY))
{
int clientHeight = rect->bottom - rect->top - ycaption - yborder - ymenu - yborder;
if(clientHeight < minHeight)
rect->bottom += minHeight - clientHeight;
}
else if(horizontalDrag && !(keepRatio & KEEPX))
{
int clientWidth = rect->right - rect->left - xborder - xborder;
if(clientWidth < minWidth)
rect->right += minWidth - clientWidth;
}
else
{
/* Apply the ratio stuff */
if(keepRatio)
{
switch(wParam)
{
case WMSZ_LEFT:
case WMSZ_RIGHT:
case WMSZ_TOPLEFT:
case WMSZ_TOPRIGHT:
case WMSZ_BOTTOMLEFT:
case WMSZ_BOTTOMRIGHT:
{
float ratio = ((rect->right - rect->left - xborder - xborder) / (float)minWidth);
rect->bottom = (LONG)((rect->top + ycaption + yborder + ymenu + (minHeight * ratio) + yborder));
}
break;
case WMSZ_TOP:
case WMSZ_BOTTOM:
float ratio1 = ((rect->right - rect->left - xborder - xborder ) / (float)minWidth);
float ratio2 = ((rect->bottom - rect->top - ycaption - yborder - ymenu - yborder) / (float)minHeight);
LONG correctedHeight = (LONG)((rect->top + ycaption + yborder + ymenu + (minHeight * ratio1) + yborder));
LONG correctedWidth = (LONG)((rect->left + xborder + (minWidth * ratio2) + xborder));
if(keepRatio & KEEPX)
{
float ratio = ((rect->bottom - rect->top - ycaption - yborder - ymenu - yborder) / (float)minHeight);
rect->right = (LONG)((rect->left + xborder + (minWidth * ratio) + xborder));
if((keepRatio & KEEPY) || (rect->bottom < correctedHeight))
{
if(verticalDrag)
rect->right = correctedWidth;
else
rect->bottom = correctedHeight;
}
}
else
{
if((keepRatio & KEEPY) && (rect->right < correctedWidth))
{
if(horizontalDrag)
rect->bottom = correctedHeight;
else
rect->right = correctedWidth;
}
break;
}
}
@ -159,6 +180,18 @@ void WINCLASS::sizingMsg(WPARAM wParam, LPARAM lParam, BOOL keepRatio)
if(ymenunew != ymenu)
rect->bottom += (ymenunew - ymenu);
// prevent "pushing" the window across the screen when resizing from the left or top
if(wParam == WMSZ_LEFT || wParam == WMSZ_TOPLEFT || wParam == WMSZ_BOTTOMLEFT)
{
rect->left -= rect->right - prevRight;
rect->right = prevRight;
}
if(wParam == WMSZ_TOP || wParam == WMSZ_TOPLEFT || wParam == WMSZ_TOPRIGHT)
{
rect->top -= rect->bottom - prevBottom;
rect->bottom = prevBottom;
}
}
void WINCLASS::setClientSize(int width, int height)

View File

@ -51,7 +51,14 @@ public:
void setMinSize(int width, int height);
void sizingMsg(WPARAM wParam, LPARAM lParam, BOOL keepRatio = FALSE);
enum // keepRatio flags
{
NOKEEP = 0x0,
KEEPX = 0x1,
KEEPY = 0x2,
};
void sizingMsg(WPARAM wParam, LPARAM lParam, LONG keepRatio = NOKEEP);
void setClientSize(int width, int height);
};

View File

@ -142,7 +142,8 @@ void wxTest() {
const int kGapNone = 0;
const int kGapBorder = 5;
const int kGapNDS = 64;
const int kGapNDS = 64; // extremely tilted (but some games seem to use this value)
const int kGapNDS2 = 90; // more normal viewing angle
static BOOL OpenCore(const char* filename);
@ -248,6 +249,7 @@ void SetScreenGap(int gap);
void SetRotate(HWND hwnd, int rot);
bool ForceRatio = true;
bool SeparationBorderDrag = true;
float DefaultWidth;
float DefaultHeight;
float widthTradeOff;
@ -402,9 +404,25 @@ void ScaleScreen(float factor)
{
if(windowSize == 0)
{
int w = GetPrivateProfileInt("Video", "Window width", 256, IniName);
int h = GetPrivateProfileInt("Video", "Window height", 384, IniName);
MainWindow->setClientSize(w, h);
int defw = GetPrivateProfileInt("Video", "Window width", 256, IniName);
int defh = GetPrivateProfileInt("Video", "Window height", 384, IniName);
// fix for wrong rotation
int w1x = video.rotatedwidthgap();
int h1x = video.rotatedheightgap();
if((defw > defh) != (w1x > h1x))
{
int temp = defw;
defw = defh;
defh = temp;
}
// fix for wrong gap
if(defh*w1x < h1x*defw)
defh = defw*h1x/w1x;
else if(defw*h1x < w1x*defh)
defw = defh*w1x/h1x;
MainWindow->setClientSize(defw, defh);
}
else
{
@ -416,6 +434,14 @@ void ScaleScreen(float factor)
}
}
void SetMinWindowSize()
{
if(ForceRatio)
MainWindow->setMinSize(video.rotatedwidth(), video.rotatedheight());
else
MainWindow->setMinSize(video.rotatedwidthgap(), video.rotatedheightgap());
}
void translateXY(s32& x, s32& y)
{
s32 tx=x, ty=y;
@ -1555,6 +1581,7 @@ int _main()
CommonSettings.hud.ShowMicrophone = GetPrivateProfileBool("Display","Display Microphone", false, IniName);
video.screengap = GetPrivateProfileInt("Display", "ScreenGap", 0, IniName);
SeparationBorderDrag = GetPrivateProfileBool("Display", "Window Split Border Drag", true, IniName);
FrameLimit = GetPrivateProfileBool("FrameLimit", "FrameLimit", true, IniName);
CommonSettings.showGpu.main = GetPrivateProfileInt("Display", "MainGpu", 1, IniName) != 0;
CommonSettings.showGpu.sub = GetPrivateProfileInt("Display", "SubGpu", 1, IniName) != 0;
@ -1625,7 +1652,7 @@ int _main()
exit(-1);
}
MainWindow->setMinSize(video.rotatedwidthgap(), video.rotatedheightgap());
SetMinWindowSize();
ScaleScreen(windowSize);
@ -2054,11 +2081,27 @@ void UpdateScreenRects()
}
}
// re-run the aspect ratio calculations if enabled
void FixAspectRatio()
{
if(windowSize != 0)
{
ScaleScreen(windowSize);
}
else if(ForceRatio)
{
RECT rc;
GetWindowRect(MainWindow->getHWnd(), &rc);
SendMessage(MainWindow->getHWnd(), WM_SIZING, WMSZ_BOTTOMRIGHT, (LPARAM)&rc);
MoveWindow(MainWindow->getHWnd(), rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, TRUE);
}
}
void SetScreenGap(int gap)
{
video.screengap = gap;
MainWindow->setMinSize(video.rotatedwidthgap(), video.rotatedheightgap());
MainWindow->setClientSize(video.rotatedwidthgap(), video.rotatedheightgap());
SetMinWindowSize();
FixAspectRatio();
UpdateWndRects(MainWindow->getHWnd());
}
@ -2107,7 +2150,7 @@ void SetRotate(HWND hwnd, int rot)
osd->setRotate(rot);
MainWindow->setMinSize((video.rotatedwidthgap()), video.rotatedheightgap());
SetMinWindowSize();
MainWindow->setClientSize(newwidth, newheight);
@ -2651,9 +2694,11 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
MainWindow->checkMenu(IDC_WINDOW4X, ((windowSize==4)));
//Screen Separation
MainWindow->checkMenu(IDM_SCREENSEP_NONE, ((video.screengap==0)));
MainWindow->checkMenu(IDM_SCREENSEP_BORDER, ((video.screengap==5)));
MainWindow->checkMenu(IDM_SCREENSEP_NDSGAP, ((video.screengap==64)));
MainWindow->checkMenu(IDM_SCREENSEP_NONE, ((video.screengap==kGapNone)));
MainWindow->checkMenu(IDM_SCREENSEP_BORDER, ((video.screengap==kGapBorder)));
MainWindow->checkMenu(IDM_SCREENSEP_NDSGAP, ((video.screengap==kGapNDS)));
MainWindow->checkMenu(IDM_SCREENSEP_NDSGAP2, ((video.screengap==kGapNDS2)));
MainWindow->checkMenu(IDM_SCREENSEP_DRAGEDIT, (SeparationBorderDrag));
//Counters / Etc.
MainWindow->checkMenu(ID_VIEW_FRAMECOUNTER,CommonSettings.hud.FrameCounterDisplay);
@ -2699,15 +2744,11 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
MainWindow->checkMenu(IDC_BACKGROUNDPAUSE, lostFocusPause);
//screen gaps
MainWindow->checkMenu(IDM_SCREENSEP_NONE, false);
MainWindow->checkMenu(IDM_SCREENSEP_BORDER, false);
MainWindow->checkMenu(IDM_SCREENSEP_NDSGAP, false);
if(video.screengap == kGapNone)
MainWindow->checkMenu(IDM_SCREENSEP_NONE, true);
else if(video.screengap == kGapBorder)
MainWindow->checkMenu(IDM_SCREENSEP_BORDER, true);
else if(video.screengap == kGapNDS)
MainWindow->checkMenu(IDM_SCREENSEP_NDSGAP, true);
MainWindow->checkMenu(IDM_SCREENSEP_NONE, ((video.screengap==kGapNone)));
MainWindow->checkMenu(IDM_SCREENSEP_BORDER, ((video.screengap==kGapBorder)));
MainWindow->checkMenu(IDM_SCREENSEP_NDSGAP, ((video.screengap==kGapNDS)));
MainWindow->checkMenu(IDM_SCREENSEP_NDSGAP2, ((video.screengap==kGapNDS2)));
MainWindow->checkMenu(IDM_SCREENSEP_DRAGEDIT, (SeparationBorderDrag));
//Save type
@ -2820,11 +2861,81 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
MainWindow->checkMenu(IDC_WINDOW4X, MF_BYCOMMAND | MF_UNCHECKED);
}
MainWindow->sizingMsg(wParam, lParam, ForceRatio);
RECT cRect, ncRect;
GetClientRect(MainWindow->getHWnd(), &cRect);
GetWindowRect(MainWindow->getHWnd(), &ncRect);
LONG forceRatioFlags = WINCLASS::NOKEEP;
bool setGap = false;
bool sideways = (video.rotation == 90) || (video.rotation == 270);
{
bool horizontalDrag = (wParam == WMSZ_LEFT) || (wParam == WMSZ_RIGHT);
bool verticalDrag = (wParam == WMSZ_TOP) || (wParam == WMSZ_BOTTOM);
int minX = video.rotatedwidthgap();
int minY = video.rotatedheightgap();
if(verticalDrag && !sideways && SeparationBorderDrag)
{
forceRatioFlags |= WINCLASS::KEEPX;
minY = (MainScreenRect.bottom - MainScreenRect.top) + (SubScreenRect.bottom - SubScreenRect.top);
setGap = true;
}
else if(horizontalDrag && sideways && SeparationBorderDrag)
{
forceRatioFlags |= WINCLASS::KEEPY;
minX = (MainScreenRect.right - MainScreenRect.left) + (SubScreenRect.right - SubScreenRect.left);
setGap = true;
}
else if(ForceRatio)
{
forceRatioFlags |= WINCLASS::KEEPX;
forceRatioFlags |= WINCLASS::KEEPY;
}
MainWindow->setMinSize(minX, minY);
}
MainWindow->sizingMsg(wParam, lParam, forceRatioFlags);
if(setGap)
{
RECT rc = *(RECT*)lParam;
rc.right += (cRect.right - cRect.left) - (ncRect.right - ncRect.left);
rc.bottom += (cRect.bottom - cRect.top) - (ncRect.bottom - ncRect.top);
int wndWidth, wndHeight, wndHeightGapless;
if(sideways)
{
wndWidth = (rc.bottom - rc.top);
wndHeight = (rc.right - rc.left);
wndHeightGapless = (MainScreenRect.right - MainScreenRect.left) + (SubScreenRect.right - SubScreenRect.left);
}
else
{
wndWidth = (rc.right - rc.left);
wndHeight = (rc.bottom - rc.top);
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;
UpdateWndRects(MainWindow->getHWnd());
}
}
return 1;
//break;
case WM_GETMINMAXINFO:
if(ForceRatio)
{
// extend the window size limits, otherwise they can make our window get squashed
PMINMAXINFO pmmi = (PMINMAXINFO)lParam;
pmmi->ptMaxTrackSize.x *= 4;
pmmi->ptMaxTrackSize.y *= 4;
return 1;
}
break;
case WM_KEYDOWN:
if(wParam != VK_PAUSE)
break;
@ -3658,6 +3769,13 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
case IDM_SCREENSEP_NDSGAP:
SetScreenGap(kGapNDS);
return 0;
case IDM_SCREENSEP_NDSGAP2:
SetScreenGap(kGapNDS2);
return 0;
case IDM_SCREENSEP_DRAGEDIT:
SeparationBorderDrag = !SeparationBorderDrag;
WritePrivateProfileInt("Display","Window Split Border Drag",(int)SeparationBorderDrag,IniName);
break;
case IDM_WEBSITE:
ShellExecute(NULL, "open", "http://desmume.sourceforge.net", NULL, NULL, SW_SHOWNORMAL);
return 0;
@ -3741,10 +3859,10 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
WritePrivateProfileInt("Video","Window Force Ratio",0,IniName);
}
else {
ForceRatio = TRUE;
FixAspectRatio();
RECT rc;
GetClientRect(hwnd, &rc);
ScaleScreen((rc.right - rc.left) / 256.0f);
ForceRatio = TRUE;
WritePrivateProfileInt("Video","Window Force Ratio",1,IniName);
WritePrivateProfileInt("Video", "Window width", (rc.right - rc.left), IniName);
WritePrivateProfileInt("Video", "Window height", (rc.bottom - rc.top), IniName);
@ -3754,7 +3872,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
case IDM_DEFSIZE:
{
if(windowSize)
if(windowSize != 1)
windowSize = 0;
ScaleScreen(1);

View File

@ -699,6 +699,8 @@
#define IDM_EXPORTBACKUPMEMORY 40018
#define IDM_STOPMOVIE 40019
#define IDC_LANG_CHINESE_SIMPLIFIED 40020
#define IDM_SCREENSEP_NDSGAP2 40021
#define IDM_SCREENSEP_DRAGEDIT 40022
#define ID_FILE_RECENTROM 40034
#define IDC_SAVETYPE7 40037
#define IDM_DEFSIZE 40038

Binary file not shown.