various improvements to the new LCDs settings.
- you can select "main screen first" to automatically put the main GPU screen on top. combining this with the "one LCD" setting lets games like NSMB and Sonic Rush be playable on a single screen (it auto-switches to the screen that has the character on it). - fully exclude screen gap from calculations when in single screen or side-by-side mode - make OSD elements stay consistently located when flipping the LCDs around - possibly improved the stylus-dragged-offscreen behavior for the alternate layouts
This commit is contained in:
parent
2c8473e761
commit
71022e6920
|
@ -56,6 +56,26 @@ static bool IsHudDummy (HudCoordinates *hud)
|
|||
return (hud->x == 666 && hud->y == 666);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static T calcY(T y) // alters a GUI element y coordinate as necessary to obey swapScreens and singleScreen settings
|
||||
{
|
||||
if(osd->singleScreen)
|
||||
{
|
||||
if(y >= 192)
|
||||
y -= 192;
|
||||
if(osd->swapScreens)
|
||||
y += 192;
|
||||
}
|
||||
else if(osd->swapScreens)
|
||||
{
|
||||
if(y >= 192)
|
||||
y -= 192;
|
||||
else
|
||||
y += 192;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
void EditHud(s32 x, s32 y, HudStruct *hudstruct) {
|
||||
|
||||
u32 i = 0;
|
||||
|
@ -70,7 +90,7 @@ void EditHud(s32 x, s32 y, HudStruct *hudstruct) {
|
|||
}
|
||||
|
||||
if((x >= hud.x && x <= hud.x + hud.xsize) &&
|
||||
(y >= hud.y && y <= hud.y + hud.ysize) && !hudstruct->clicked ) {
|
||||
(calcY(y) >= calcY(hud.y) && calcY(y) <= calcY(hud.y) + hud.ysize) && !hudstruct->clicked ) {
|
||||
|
||||
hud.clicked=1;
|
||||
hud.storedx = x - hud.x;
|
||||
|
@ -200,7 +220,7 @@ static void drawPad(double x, double y, double ratio) {
|
|||
|
||||
// aligning to odd half-pixel boundaries prevents agg2d from blurring thin straight lines
|
||||
x = floor(x) + 0.5;
|
||||
y = floor(y) + 0.5;
|
||||
y = floor(calcY(y)) + 0.5;
|
||||
double xc = 41 - 0.5;
|
||||
double yc = 20 - 0.5;
|
||||
|
||||
|
@ -346,7 +366,7 @@ static void TextualInputDisplay() {
|
|||
std::string str(buttonChars+i, 2);
|
||||
str[1] = '\0';
|
||||
|
||||
aggDraw.hud->renderTextDropshadowed(x, Hud.InputDisplay.y, str);
|
||||
aggDraw.hud->renderTextDropshadowed(x, calcY(Hud.InputDisplay.y), str);
|
||||
}
|
||||
|
||||
// touch pad
|
||||
|
@ -362,7 +382,7 @@ static void TextualInputDisplay() {
|
|||
{
|
||||
sprintf(str, "%d,%d", gameTouchX, gameTouchY);
|
||||
aggDraw.hud->lineColor(255,255,255,255);
|
||||
aggDraw.hud->renderTextDropshadowed(x, Hud.InputDisplay.y, str);
|
||||
aggDraw.hud->renderTextDropshadowed(x, calcY(Hud.InputDisplay.y), str);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -370,19 +390,20 @@ static void TextualInputDisplay() {
|
|||
{
|
||||
sprintf(str, "%d,%d", gameTouchX, gameTouchY);
|
||||
aggDraw.hud->lineColor(255,48,48,255);
|
||||
aggDraw.hud->renderTextDropshadowed(x, Hud.InputDisplay.y-(physicalTouchOn?8:0), str);
|
||||
aggDraw.hud->renderTextDropshadowed(x, calcY(Hud.InputDisplay.y)-(physicalTouchOn?8:0), str);
|
||||
}
|
||||
if(physicalTouchOn)
|
||||
{
|
||||
sprintf(str, "%d,%d", physicalTouchX, physicalTouchY);
|
||||
aggDraw.hud->lineColor(0,255,0,255);
|
||||
aggDraw.hud->renderTextDropshadowed(x, Hud.InputDisplay.y+(gameTouchOn?8:0), str);
|
||||
aggDraw.hud->renderTextDropshadowed(x, calcY(Hud.InputDisplay.y)+(gameTouchOn?8:0), str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void TouchDisplay() {
|
||||
// note: calcY should not be used in this function.
|
||||
aggDraw.hud->lineWidth(1.0);
|
||||
|
||||
temptouch.X = NDS_getRawUserInput().touch.touchX >> 4;
|
||||
|
@ -400,7 +421,7 @@ static void TouchDisplay() {
|
|||
aggDraw.hud->line(temptouch.X - 256, temptouch.Y + 192, temptouch.X + 256, temptouch.Y + 192); //horiz
|
||||
aggDraw.hud->line(temptouch.X, temptouch.Y - 256, temptouch.X, temptouch.Y + 384); //vert
|
||||
aggDraw.hud->fillColor(0, 0, 0, touchalpha[i]);
|
||||
aggDraw.hud->rectangle(temptouch.X-1, temptouch.Y-1 + 192, temptouch.X+1, temptouch.Y+1 + 192);
|
||||
aggDraw.hud->rectangle(temptouch.X-1, temptouch.Y + 192-1, temptouch.X+1, temptouch.Y + 192+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -427,7 +448,7 @@ static s64 slotTimer=0;
|
|||
|
||||
static void DrawStateSlots(){
|
||||
|
||||
const int yloc = Hud.SavestateSlots.y; //160
|
||||
const int yloc = calcY(Hud.SavestateSlots.y); //160
|
||||
const int xloc = Hud.SavestateSlots.x; //8
|
||||
|
||||
s64 fadecounter = 512 - (hudTimer-slotTimer)/4; //change constant to alter fade speed
|
||||
|
@ -476,10 +497,10 @@ static void DrawEditableElementIndicators()
|
|||
aggDraw.hud->fillColor(0,0,0,0);
|
||||
aggDraw.hud->lineColor(0,0,0,64);
|
||||
aggDraw.hud->lineWidth(2.0);
|
||||
aggDraw.hud->rectangle(hud.x,hud.y,hud.x+hud.xsize+1.0,hud.y+hud.ysize+1.0);
|
||||
aggDraw.hud->rectangle(hud.x,calcY(hud.y),hud.x+hud.xsize+1.0,calcY(hud.y)+hud.ysize+1.0);
|
||||
aggDraw.hud->lineColor(255,hud.clicked?127:255,0,255);
|
||||
aggDraw.hud->lineWidth(1.0);
|
||||
aggDraw.hud->rectangle(hud.x-0.5,hud.y-0.5,hud.x+hud.xsize+0.5,hud.y+hud.ysize+0.5);
|
||||
aggDraw.hud->rectangle(hud.x-0.5,calcY(hud.y)-0.5,hud.x+hud.xsize+0.5,calcY(hud.y)+hud.ysize+0.5);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
@ -562,6 +583,9 @@ OSDCLASS::OSDCLASS(u8 core)
|
|||
|
||||
rotAngle = 0;
|
||||
|
||||
singleScreen = false;
|
||||
swapScreens = false;
|
||||
|
||||
needUpdate = false;
|
||||
|
||||
if (core==0)
|
||||
|
@ -705,7 +729,7 @@ void OSDCLASS::addFixed(u16 x, u16 y, const char *fmt, ...)
|
|||
va_end(list);
|
||||
|
||||
aggDraw.hud->lineColor(255,255,255);
|
||||
aggDraw.hud->renderTextDropshadowed(x,y,msg);
|
||||
aggDraw.hud->renderTextDropshadowed(x,calcY(y),msg);
|
||||
|
||||
needUpdate = true;
|
||||
}
|
||||
|
|
|
@ -104,8 +104,12 @@ private:
|
|||
bool needUpdate;
|
||||
|
||||
bool checkTimers();
|
||||
|
||||
public:
|
||||
char name[7]; // for debuging
|
||||
bool singleScreen;
|
||||
bool swapScreens;
|
||||
|
||||
OSDCLASS(u8 core);
|
||||
~OSDCLASS();
|
||||
|
||||
|
|
|
@ -3631,7 +3631,7 @@ DEFINE_LUA_FUNCTION(input_getcurrentinputstatus, "")
|
|||
// mouse position in game screen pixel coordinates
|
||||
{
|
||||
void UnscaleScreenCoords(s32& x, s32& y);
|
||||
void ToDSScreenRelativeCoords(s32& x, s32& y, bool bottomScreen);
|
||||
void ToDSScreenRelativeCoords(s32& x, s32& y, int bottomScreen);
|
||||
|
||||
POINT point;
|
||||
GetCursorPos(&point);
|
||||
|
@ -3640,7 +3640,7 @@ DEFINE_LUA_FUNCTION(input_getcurrentinputstatus, "")
|
|||
s32 y (point.y);
|
||||
|
||||
UnscaleScreenCoords(x,y);
|
||||
ToDSScreenRelativeCoords(x,y,true);
|
||||
ToDSScreenRelativeCoords(x,y,1);
|
||||
|
||||
lua_pushinteger(L, x);
|
||||
lua_setfield(L, -2, "xmouse");
|
||||
|
|
|
@ -727,8 +727,6 @@ void _CDECL_ FCEUI_SaveMovie(const char *fname, std::wstring author, int flag, s
|
|||
assert(nds.touchX == input.touch.touchX && nds.touchY == input.touch.touchY);
|
||||
assert((mr.touch.x << 4) == nds.touchX && (mr.touch.y << 4) == nds.touchY);
|
||||
|
||||
currMovieData.truncateAt(currFrameCounter);
|
||||
|
||||
mr.dump(&currMovieData, osRecordingMovie,currMovieData.records.size());
|
||||
currMovieData.records.push_back(mr);
|
||||
|
||||
|
@ -912,6 +910,7 @@ bool mov_loadstate(EMUFILE* fp, int size)
|
|||
// #endif
|
||||
|
||||
currMovieData.rerecordCount = currRerecordCount;
|
||||
currMovieData.truncateAt(currFrameCounter);
|
||||
|
||||
openRecordingMovie(curMovieFilename);
|
||||
if(!osRecordingMovie)
|
||||
|
|
|
@ -216,10 +216,10 @@ void HK_LCDsMode(int)
|
|||
doLCDsLayout();
|
||||
}
|
||||
|
||||
extern void LCDsSwap();
|
||||
extern void LCDsSwap(int);
|
||||
void HK_LCDsSwap(int)
|
||||
{
|
||||
LCDsSwap();
|
||||
LCDsSwap(-1);
|
||||
}
|
||||
|
||||
void HK_Reset(int, bool justPressed) {ResetGame();}
|
||||
|
|
|
@ -504,8 +504,9 @@ void UnscaleScreenCoords(s32& x, s32& y)
|
|||
|
||||
// input x,y should be windows client-space coords already at 1x scaling.
|
||||
// output is in pixels relative to the top-left of the chosen screen.
|
||||
// (-1 == top screen, 1 == bottom screen, 0 == absolute vertically aligned)
|
||||
// the gap between screens (if any) is subtracted away from the output y.
|
||||
void ToDSScreenRelativeCoords(s32& x, s32& y, bool bottomScreen)
|
||||
void ToDSScreenRelativeCoords(s32& x, s32& y, int whichScreen)
|
||||
{
|
||||
s32 tx=x, ty=y;
|
||||
|
||||
|
@ -536,26 +537,46 @@ void ToDSScreenRelativeCoords(s32& x, s32& y, bool bottomScreen)
|
|||
y = 192;
|
||||
else if(y > 191)
|
||||
y = 191;
|
||||
|
||||
// finally, make it relative to the correct screen
|
||||
if((bottomScreen) && (video.swap == 0))
|
||||
y -= 192;
|
||||
}
|
||||
else
|
||||
if (video.layout == 1)
|
||||
|
||||
// finally, make it relative to the correct screen
|
||||
if (video.layout == 0 || video.layout == 2)
|
||||
{
|
||||
if(whichScreen)
|
||||
{
|
||||
if (video.swap == 0)
|
||||
x = tx - 255;
|
||||
bool topOnTop = (video.swap == 0) || (video.swap == 2 && !MainScreen.offset) || (video.swap == 3 && MainScreen.offset);
|
||||
bool bottom = (whichScreen > 0);
|
||||
if(topOnTop)
|
||||
y += bottom ? -192 : 0;
|
||||
else
|
||||
x = tx;
|
||||
//INFO("X=%i, Y=%i (tx = %i, ty = %i)\n", x, y, tx, ty);
|
||||
y += (y < 192) ? (bottom ? 0 : 192) : (bottom ? 0 : -192);
|
||||
}
|
||||
}
|
||||
else if (video.layout == 1) // side-by-side
|
||||
{
|
||||
if(whichScreen)
|
||||
{
|
||||
bool topOnTop = (video.swap == 0) || (video.swap == 2 && !MainScreen.offset) || (video.swap == 3 && MainScreen.offset);
|
||||
bool bottom = (whichScreen > 0);
|
||||
if(topOnTop)
|
||||
x += bottom ? -256 : 0;
|
||||
else
|
||||
x += (x < 256) ? (bottom ? 0 : 256) : (bottom ? 0 : -256);
|
||||
}
|
||||
else
|
||||
if (video.layout == 2)
|
||||
{
|
||||
if(x >= 256)
|
||||
{
|
||||
x = tx;
|
||||
//INFO("X=%i, Y=%i (tx = %i, ty = %i)\n", x, y, tx, ty);
|
||||
x -= 256;
|
||||
y += 192;
|
||||
}
|
||||
else if(x < 0)
|
||||
{
|
||||
x += 256;
|
||||
y -= 192;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// END Rotation definitions
|
||||
|
@ -953,16 +974,21 @@ template<typename T, int bpp> static void doRotate(void* dst)
|
|||
}
|
||||
|
||||
void UpdateWndRects(HWND hwnd);
|
||||
void FixAspectRatio();
|
||||
|
||||
void LCDsSwap()
|
||||
void LCDsSwap(int swapVal)
|
||||
{
|
||||
video.swap = !video.swap;
|
||||
MainWindow->checkMenu(ID_LCDS_SWAP, !video.swap);
|
||||
if(swapVal == -1) swapVal = video.swap ^ 1; // -1 means to flip the existing setting
|
||||
if(swapVal < 0 || swapVal > 3) swapVal = 0;
|
||||
if(osd && !(swapVal & video.swap & 1)) osd->swapScreens = !osd->swapScreens; // 1-frame fixup
|
||||
video.swap = swapVal;
|
||||
WritePrivateProfileInt("Video", "LCDsSwap", video.swap, IniName);
|
||||
}
|
||||
|
||||
void doLCDsLayout()
|
||||
{
|
||||
osd->singleScreen = (video.layout == 2);
|
||||
|
||||
RECT rc = { 0 };
|
||||
int oldheight, oldwidth;
|
||||
int newheight, newwidth;
|
||||
|
@ -1078,6 +1104,7 @@ void doLCDsLayout()
|
|||
WritePrivateProfileInt("Video", "LCDsLayout", video.layout, IniName);
|
||||
SetMinWindowSize();
|
||||
MainWindow->setClientSize(newwidth, newheight);
|
||||
FixAspectRatio();
|
||||
UpdateWndRects(MainWindow->getHWnd());
|
||||
}
|
||||
|
||||
|
@ -1116,10 +1143,40 @@ static void DD_DoDisplay()
|
|||
|
||||
lpBackSurface->Unlock((LPRECT)ddsd.lpSurface);
|
||||
|
||||
if (video.layout != 2)
|
||||
RECT* dstRects [2] = {&MainScreenRect, &SubScreenRect};
|
||||
RECT* srcRects [2];
|
||||
|
||||
if(video.swap == 0)
|
||||
{
|
||||
// Main screen
|
||||
if(lpPrimarySurface->Blt(&MainScreenRect, lpBackSurface, (video.swap == 0)?&MainScreenSrcRect:&SubScreenSrcRect, DDBLT_WAIT, 0) == DDERR_SURFACELOST)
|
||||
srcRects[0] = &MainScreenSrcRect;
|
||||
srcRects[1] = &SubScreenSrcRect;
|
||||
if(osd) osd->swapScreens = false;
|
||||
}
|
||||
else if(video.swap == 1)
|
||||
{
|
||||
srcRects[0] = &SubScreenSrcRect;
|
||||
srcRects[1] = &MainScreenSrcRect;
|
||||
if(osd) osd->swapScreens = true;
|
||||
}
|
||||
else if(video.swap == 2)
|
||||
{
|
||||
srcRects[0] = (MainScreen.offset) ? &SubScreenSrcRect : &MainScreenSrcRect;
|
||||
srcRects[1] = (MainScreen.offset) ? &MainScreenSrcRect : &SubScreenSrcRect;
|
||||
if(osd) osd->swapScreens = (MainScreen.offset != 0);
|
||||
}
|
||||
else if(video.swap == 3)
|
||||
{
|
||||
srcRects[0] = (MainScreen.offset) ? &MainScreenSrcRect : &SubScreenSrcRect;
|
||||
srcRects[1] = (MainScreen.offset) ? &SubScreenSrcRect : &MainScreenSrcRect;
|
||||
if(osd) osd->swapScreens = (SubScreen.offset != 0);
|
||||
}
|
||||
|
||||
for(int i = 0; i < 2; i++)
|
||||
{
|
||||
if(i && video.layout == 2)
|
||||
break;
|
||||
|
||||
if(lpPrimarySurface->Blt(dstRects[i], lpBackSurface, srcRects[i], DDBLT_WAIT, 0) == DDERR_SURFACELOST)
|
||||
{
|
||||
LOG("DirectDraw buffers is lost\n");
|
||||
if(IDirectDrawSurface7_Restore(lpPrimarySurface) == DD_OK)
|
||||
|
@ -1127,14 +1184,6 @@ static void DD_DoDisplay()
|
|||
}
|
||||
}
|
||||
|
||||
// Sub screen
|
||||
if(lpPrimarySurface->Blt(video.layout == 2?&MainScreenRect:&SubScreenRect, lpBackSurface, (video.swap == 0)?&SubScreenSrcRect:&MainScreenSrcRect, DDBLT_WAIT, 0) == DDERR_SURFACELOST)
|
||||
{
|
||||
LOG("DirectDraw buffers is lost\n");
|
||||
if(IDirectDrawSurface7_Restore(lpPrimarySurface) == DD_OK)
|
||||
IDirectDrawSurface7_Restore(lpBackSurface);
|
||||
}
|
||||
|
||||
if (video.layout == 1) return;
|
||||
if (video.layout == 2) return;
|
||||
|
||||
|
@ -2104,7 +2153,6 @@ int _main()
|
|||
video.layout = video.layout_old = 0;
|
||||
}
|
||||
video.swap = GetPrivateProfileInt("Video", "LCDsSwap", 0, IniName);
|
||||
if (video.swap > 1) video.swap = 1;
|
||||
|
||||
CommonSettings.hud.FpsDisplay = GetPrivateProfileBool("Display","Display Fps", false, IniName);
|
||||
CommonSettings.hud.FrameCounterDisplay = GetPrivateProfileBool("Display","FrameCounter", false, IniName);
|
||||
|
@ -2287,6 +2335,8 @@ int _main()
|
|||
NDS_Init ();
|
||||
#endif
|
||||
|
||||
osd->singleScreen = (video.layout == 2);
|
||||
|
||||
/*
|
||||
* Activate the GDB stubs
|
||||
* This has to come after the NDS_Init where the cpus are set up.
|
||||
|
@ -2517,7 +2567,9 @@ void UpdateWndRects(HWND hwnd)
|
|||
RECT rc;
|
||||
|
||||
int wndWidth, wndHeight;
|
||||
int defHeight = (video.height + video.screengap);
|
||||
int defHeight = video.height;
|
||||
if(video.layout == 0)
|
||||
defHeight += video.screengap;
|
||||
float ratio;
|
||||
int oneScreenHeight, gapHeight;
|
||||
|
||||
|
@ -3365,7 +3417,11 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||
MainWindow->checkMenu(ID_LCDS_VERTICAL, ((video.layout==0)));
|
||||
MainWindow->checkMenu(ID_LCDS_HORIZONTAL, ((video.layout==1)));
|
||||
MainWindow->checkMenu(ID_LCDS_ONE, ((video.layout==2)));
|
||||
MainWindow->checkMenu(ID_LCDS_SWAP, video.swap);
|
||||
// LCDs swap
|
||||
MainWindow->checkMenu(ID_LCDS_NOSWAP, video.swap == 0);
|
||||
MainWindow->checkMenu(ID_LCDS_SWAP, video.swap == 1);
|
||||
MainWindow->checkMenu(ID_LCDS_MAINGPU, video.swap == 2);
|
||||
MainWindow->checkMenu(ID_LCDS_SUBGPU, video.swap == 3);
|
||||
//Force Maintain Ratio
|
||||
MainWindow->checkMenu(IDC_FORCERATIO, ((ForceRatio)));
|
||||
//Screen rotation
|
||||
|
@ -3833,13 +3889,13 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||
|
||||
if(HudEditorMode)
|
||||
{
|
||||
ToDSScreenRelativeCoords(x,y,false);
|
||||
ToDSScreenRelativeCoords(x,y,0);
|
||||
EditHud(x,y, &Hud);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((video.layout == 2) && (video.swap == 1)) return 0;
|
||||
ToDSScreenRelativeCoords(x,y,true);
|
||||
if ((video.layout == 2) && ((video.swap == 0) || (video.swap == 2 && !MainScreen.offset) || (video.swap == 3 && MainScreen.offset))) return 0;
|
||||
ToDSScreenRelativeCoords(x,y,1);
|
||||
if(x<0) x = 0; else if(x>255) x = 255;
|
||||
if(y<0) y = 0; else if(y>192) y = 192;
|
||||
NDS_setTouchPos(x, y);
|
||||
|
@ -4456,8 +4512,17 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||
doLCDsLayout();
|
||||
return 0;
|
||||
|
||||
case ID_LCDS_NOSWAP:
|
||||
LCDsSwap(0);
|
||||
return 0;
|
||||
case ID_LCDS_SWAP:
|
||||
LCDsSwap();
|
||||
LCDsSwap(1);
|
||||
return 0;
|
||||
case ID_LCDS_MAINGPU:
|
||||
LCDsSwap(2);
|
||||
return 0;
|
||||
case ID_LCDS_SUBGPU:
|
||||
LCDsSwap(3);
|
||||
return 0;
|
||||
|
||||
case ID_VIEW_FRAMECOUNTER:
|
||||
|
|
|
@ -708,6 +708,9 @@
|
|||
#define ID_LCDS_HORIZONTAL 40056
|
||||
#define ID_LCDS_ONE 40057
|
||||
#define ID_LCDS_SWAP 40058
|
||||
#define ID_LCDS_NOSWAP 40059
|
||||
#define ID_LCDS_MAINGPU 40060
|
||||
#define ID_LCDS_SUBGPU 40061
|
||||
#define IDC_LABEL_UP 50000
|
||||
#define IDC_LABEL_RIGHT 50001
|
||||
#define IDC_LABEL_LEFT 50002
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue