mirror of
https://github.com/LumaTeam/Luma3DS.git
synced 2026-02-22 01:44:38 +00:00
rosalina: add qtm calibration submenu
Also steal qtm handle b/c of limitiations (max 3 sessions total)
This commit is contained in:
parent
2aa2013318
commit
1c737d499f
@ -69,7 +69,7 @@ extern u32 menuCombo;
|
|||||||
extern bool isHidInitialized;
|
extern bool isHidInitialized;
|
||||||
extern bool isQtmInitialized;
|
extern bool isQtmInitialized;
|
||||||
extern u32 mcuFwVersion;
|
extern u32 mcuFwVersion;
|
||||||
extern u8 mcuInfoTable[9];
|
extern u8 mcuInfoTable[10];
|
||||||
extern bool mcuInfoTableRead;
|
extern bool mcuInfoTableRead;
|
||||||
extern const char *topScreenType;
|
extern const char *topScreenType;
|
||||||
extern const char *bottomScreenType;
|
extern const char *bottomScreenType;
|
||||||
|
|||||||
@ -38,3 +38,5 @@ void N3DSMenu_ChangeClockRate(void);
|
|||||||
void N3DSMenu_EnableDisableL2Cache(void);
|
void N3DSMenu_EnableDisableL2Cache(void);
|
||||||
|
|
||||||
void N3DSMenu_ToggleSs3d(void);
|
void N3DSMenu_ToggleSs3d(void);
|
||||||
|
void N3DSMenu_TestBarrierPositions(void);
|
||||||
|
void N3DSMenu_Ss3dCalibration(void);
|
||||||
|
|||||||
@ -206,7 +206,7 @@ static void handlePreTermNotification(u32 notificationId)
|
|||||||
if (isHidInitialized)
|
if (isHidInitialized)
|
||||||
hidExit();
|
hidExit();
|
||||||
if (isQtmInitialized)
|
if (isQtmInitialized)
|
||||||
qtmExit();
|
svcCloseHandle(*qtmGetSessionHandle()); // qtmExit();
|
||||||
|
|
||||||
// Termination request
|
// Termination request
|
||||||
menuShouldExit = true;
|
menuShouldExit = true;
|
||||||
|
|||||||
@ -44,7 +44,7 @@ u32 menuCombo = 0;
|
|||||||
bool isHidInitialized = false;
|
bool isHidInitialized = false;
|
||||||
bool isQtmInitialized = false;
|
bool isQtmInitialized = false;
|
||||||
u32 mcuFwVersion = 0;
|
u32 mcuFwVersion = 0;
|
||||||
u8 mcuInfoTable[9] = {0};
|
u8 mcuInfoTable[10] = {0};
|
||||||
bool mcuInfoTableRead = false;
|
bool mcuInfoTableRead = false;
|
||||||
|
|
||||||
const char *topScreenType = NULL;
|
const char *topScreenType = NULL;
|
||||||
@ -289,9 +289,17 @@ static void menuInitializeQtm(void)
|
|||||||
if (isQtmInitialized)
|
if (isQtmInitialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Open last remaining qtm:sp session (out of 3) on >= 9.3,
|
// Steal QTM handle from GSP, because there is a limit of 3 sessions (or 2 before 9.3) for ALL qtm services
|
||||||
// or one of the two qtm:s handles below 9.3
|
Handle qtmHandle = 0;
|
||||||
isQtmInitialized = R_SUCCEEDED(qtmInit(GET_VERSION_MINOR(osGetKernelVersion()) >= 48 ? QTM_SERVICE_SYSTEM_PROCESS : QTM_SERVICE_SYSTEM));
|
for (int i = 0; i < 20 && !qtmIsInitialized(); i++)
|
||||||
|
{
|
||||||
|
if (R_SUCCEEDED(svcControlService(SERVICEOP_STEAL_CLIENT_SESSION, &qtmHandle, "qtm:sp")))
|
||||||
|
*qtmGetSessionHandle() = qtmHandle;
|
||||||
|
else
|
||||||
|
svcSleepThread(100 * 100 * 1000LL);
|
||||||
|
}
|
||||||
|
|
||||||
|
isQtmInitialized = qtmIsInitialized();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u32 menuAdvanceCursor(u32 pos, u32 numItems, s32 displ)
|
static inline u32 menuAdvanceCursor(u32 pos, u32 numItems, s32 displ)
|
||||||
@ -335,6 +343,7 @@ void menuThreadMain(void)
|
|||||||
{
|
{
|
||||||
while (!isServiceUsable("qtm:u"))
|
while (!isServiceUsable("qtm:u"))
|
||||||
svcSleepThread(250 * 1000 * 1000LL);
|
svcSleepThread(250 * 1000 * 1000LL);
|
||||||
|
menuInitializeQtm();
|
||||||
N3DSMenu_UpdateStatus();
|
N3DSMenu_UpdateStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,8 +354,6 @@ void menuThreadMain(void)
|
|||||||
|
|
||||||
menuReadScreenTypes();
|
menuReadScreenTypes();
|
||||||
|
|
||||||
menuInitializeQtm();
|
|
||||||
|
|
||||||
while(!preTerminationRequested)
|
while(!preTerminationRequested)
|
||||||
{
|
{
|
||||||
svcSleepThread(50 * 1000 * 1000LL);
|
svcSleepThread(50 * 1000 * 1000LL);
|
||||||
|
|||||||
@ -25,19 +25,27 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <3ds.h>
|
#include <3ds.h>
|
||||||
|
#include <math.h>
|
||||||
#include "fmt.h"
|
#include "fmt.h"
|
||||||
#include "menus/n3ds.h"
|
#include "menus/n3ds.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
|
#include "n3ds.h"
|
||||||
|
#include "draw.h"
|
||||||
|
|
||||||
static char clkRateBuf[128 + 1];
|
static char clkRateBuf[128 + 1];
|
||||||
|
|
||||||
|
static QtmCalibrationData lastQtmCal = {0};
|
||||||
|
static bool qtmCalRead = false;
|
||||||
|
|
||||||
Menu N3DSMenu = {
|
Menu N3DSMenu = {
|
||||||
"New 3DS menu",
|
"New 3DS menu",
|
||||||
{
|
{
|
||||||
{ "Enable L2 cache", METHOD, .method = &N3DSMenu_EnableDisableL2Cache },
|
{ "Enable L2 cache", METHOD, .method = &N3DSMenu_EnableDisableL2Cache },
|
||||||
{ clkRateBuf, METHOD, .method = &N3DSMenu_ChangeClockRate },
|
{ clkRateBuf, METHOD, .method = &N3DSMenu_ChangeClockRate },
|
||||||
{ "Temporarily disable Super-Stable 3D", METHOD, .method = &N3DSMenu_ToggleSs3d, .visibility = &N3DSMenu_CheckNotN2dsXl },
|
{ "Temporarily disable Super-Stable 3D", METHOD, .method = &N3DSMenu_ToggleSs3d, .visibility = &N3DSMenu_CheckNotN2dsXl },
|
||||||
|
{ "Test parallax barrier positions", METHOD, .method = &N3DSMenu_TestBarrierPositions, .visibility = &N3DSMenu_CheckNotN2dsXl },
|
||||||
|
{ "Super-Stable 3D calibration", METHOD, .method = &N3DSMenu_Ss3dCalibration, .visibility = &N3DSMenu_CheckNotN2dsXl },
|
||||||
{},
|
{},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -49,7 +57,7 @@ static QtmStatus lastUpdatedQtmStatus;
|
|||||||
bool N3DSMenu_CheckNotN2dsXl(void)
|
bool N3DSMenu_CheckNotN2dsXl(void)
|
||||||
{
|
{
|
||||||
// Also check if qtm could be initialized
|
// Also check if qtm could be initialized
|
||||||
return isQtmInitialized && mcuInfoTableRead && mcuInfoTable[9] != 5 && !qtmUnavailableAndNotBlacklisted;
|
return isQtmInitialized && mcuInfoTableRead && mcuInfoTable[9] < 5 && !qtmUnavailableAndNotBlacklisted;
|
||||||
}
|
}
|
||||||
|
|
||||||
void N3DSMenu_UpdateStatus(void)
|
void N3DSMenu_UpdateStatus(void)
|
||||||
@ -116,3 +124,171 @@ void N3DSMenu_ToggleSs3d(void)
|
|||||||
|
|
||||||
N3DSMenu_UpdateStatus();
|
N3DSMenu_UpdateStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void N3DSMenu_TestBarrierPositions(void)
|
||||||
|
{
|
||||||
|
Draw_Lock();
|
||||||
|
Draw_ClearFramebuffer();
|
||||||
|
Draw_FlushFramebuffer();
|
||||||
|
Draw_Unlock();
|
||||||
|
|
||||||
|
u8 pos = 0;
|
||||||
|
QTMS_DisableAutoBarrierControl(); // assume it doesn't fail
|
||||||
|
QTMS_GetCurrentBarrierPosition(&pos);
|
||||||
|
|
||||||
|
u32 pressed = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Draw_Lock();
|
||||||
|
|
||||||
|
Draw_DrawString(10, 10, COLOR_TITLE, "New 3DS menu");
|
||||||
|
u32 posY = Draw_DrawString(10, 30, COLOR_WHITE, "Use left/right to adjust the barrier's position.\n\n");
|
||||||
|
posY = Draw_DrawString(10, posY, COLOR_WHITE, "Each position corresponds to 5.2mm horizontal eye\nmovement (assuming ideal viewing conditions).\n\n");
|
||||||
|
posY = Draw_DrawString(10, posY, COLOR_WHITE, "Once you figure out the ideal central position, you\ncan then use it in the calibration submenu.\n\n");
|
||||||
|
posY = Draw_DrawString(10, posY, COLOR_WHITE, "Auto-barrier adjustment behavior is restored on\nexit.\n\n");
|
||||||
|
|
||||||
|
posY = Draw_DrawFormattedString(10, posY, COLOR_WHITE, "Barrier position: %2hhu\n", pos);
|
||||||
|
|
||||||
|
Draw_FlushFramebuffer();
|
||||||
|
pressed = waitInputWithTimeout(1000);
|
||||||
|
|
||||||
|
if (pressed & KEY_LEFT)
|
||||||
|
{
|
||||||
|
pos = pos > 11 ? 11 : pos; // pos is 13 when SS3D is disabled/camera is in use
|
||||||
|
pos = (12 + pos - 1) % 12;
|
||||||
|
QTMS_SetBarrierPosition(pos);
|
||||||
|
}
|
||||||
|
else if (pressed & KEY_RIGHT)
|
||||||
|
{
|
||||||
|
pos = pos > 11 ? 11 : pos; // pos is 13 when SS3D is disabled/camera is in use
|
||||||
|
pos = (pos + 1) % 12;
|
||||||
|
QTMS_SetBarrierPosition(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
Draw_Unlock();
|
||||||
|
} while(!menuShouldExit && !(pressed & KEY_B));
|
||||||
|
|
||||||
|
QTMS_EnableAutoBarrierControl();
|
||||||
|
}
|
||||||
|
|
||||||
|
void N3DSMenu_Ss3dCalibration(void)
|
||||||
|
{
|
||||||
|
Draw_Lock();
|
||||||
|
Draw_ClearFramebuffer();
|
||||||
|
Draw_FlushFramebuffer();
|
||||||
|
Draw_Unlock();
|
||||||
|
|
||||||
|
u8 currentPos;
|
||||||
|
QtmTrackingData trackingData = {0};
|
||||||
|
|
||||||
|
if (R_FAILED(QTMS_GetCurrentBarrierPosition(¤tPos)))
|
||||||
|
currentPos = 13;
|
||||||
|
|
||||||
|
bool calReadFailed = false;
|
||||||
|
|
||||||
|
if (!qtmCalRead)
|
||||||
|
{
|
||||||
|
cfguInit();
|
||||||
|
calReadFailed = R_FAILED(CFG_GetConfigInfoBlk8(sizeof(QtmCalibrationData), QTM_CAL_CFG_BLK_ID, &lastQtmCal));
|
||||||
|
cfguExit();
|
||||||
|
if (!calReadFailed)
|
||||||
|
qtmCalRead = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool trackingDisabled = currentPos == 13;
|
||||||
|
|
||||||
|
if (currentPos < 12)
|
||||||
|
QTMS_EnableAutoBarrierControl(); // assume this doesn't fail
|
||||||
|
|
||||||
|
u32 pressed = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (!trackingDisabled)
|
||||||
|
{
|
||||||
|
QTMS_GetCurrentBarrierPosition(¤tPos);
|
||||||
|
QTMU_GetTrackingData(&trackingData);
|
||||||
|
}
|
||||||
|
|
||||||
|
Draw_Lock();
|
||||||
|
|
||||||
|
Draw_DrawString(10, 10, COLOR_TITLE, "New 3DS menu");
|
||||||
|
u32 posY = 30;
|
||||||
|
|
||||||
|
if (trackingDisabled)
|
||||||
|
posY = Draw_DrawString(10, posY, COLOR_WHITE, "SS3D disabled or camera in use.\nPress B to exit this menu.\n");
|
||||||
|
else if (calReadFailed)
|
||||||
|
posY = Draw_DrawString(10, posY, COLOR_WHITE, "Failed to read calibration data.\nPress B to exit this menu.\n");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
posY = Draw_DrawString(10, posY, COLOR_WHITE, "Right/Left: +- 1\n");
|
||||||
|
posY = Draw_DrawString(10, posY, COLOR_WHITE, "Up/Down: +- 0.1\n");
|
||||||
|
posY = Draw_DrawString(10, posY, COLOR_WHITE, "R/L: +- 0.01\n");
|
||||||
|
posY = Draw_DrawString(10, posY, COLOR_WHITE, "A: save to system config\n");
|
||||||
|
posY = Draw_DrawString(10, posY, COLOR_WHITE, "Y: reload last saved calibration\n");
|
||||||
|
posY = Draw_DrawString(10, posY, COLOR_WHITE, "B: exit this menu\n\n");
|
||||||
|
|
||||||
|
char calStr[16];
|
||||||
|
floatToString(calStr, lastQtmCal.centerBarrierPosition, 2, true);
|
||||||
|
posY = Draw_DrawFormattedString(10, posY, COLOR_WHITE, "Center position: %-5s\n\n", calStr);
|
||||||
|
|
||||||
|
posY = Draw_DrawFormattedString(10, posY, COLOR_WHITE, "Current barrier position: %-2hhu\n", currentPos);
|
||||||
|
posY = Draw_DrawFormattedString(10, posY, COLOR_WHITE, "Current eye distance: %-2d cm\n", (int)roundf(qtmEstimateEyeToCameraDistance(&trackingData) / 10.0f));
|
||||||
|
posY = Draw_DrawFormattedString(10, posY, COLOR_WHITE, "Optimal eye distance: %-2d cm\n", (int)roundf(lastQtmCal.viewingDistance / 10.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
Draw_FlushFramebuffer();
|
||||||
|
pressed = waitInputWithTimeout(15);
|
||||||
|
|
||||||
|
if (!calReadFailed)
|
||||||
|
{
|
||||||
|
if (pressed & KEY_LEFT)
|
||||||
|
{
|
||||||
|
lastQtmCal.centerBarrierPosition = fmodf(12.0f + lastQtmCal.centerBarrierPosition - 1.0f, 12.0f);
|
||||||
|
QTMS_SetCalibrationData(&lastQtmCal, false);
|
||||||
|
}
|
||||||
|
else if (pressed & KEY_RIGHT)
|
||||||
|
{
|
||||||
|
lastQtmCal.centerBarrierPosition = fmodf(lastQtmCal.centerBarrierPosition + 1.0f, 12.0f);
|
||||||
|
QTMS_SetCalibrationData(&lastQtmCal, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pressed & KEY_DOWN)
|
||||||
|
{
|
||||||
|
lastQtmCal.centerBarrierPosition = fmodf(12.0f + lastQtmCal.centerBarrierPosition - 0.1f, 12.0f);
|
||||||
|
QTMS_SetCalibrationData(&lastQtmCal, false);
|
||||||
|
}
|
||||||
|
else if (pressed & KEY_UP)
|
||||||
|
{
|
||||||
|
lastQtmCal.centerBarrierPosition = fmodf(lastQtmCal.centerBarrierPosition + 0.1f, 12.0f);
|
||||||
|
QTMS_SetCalibrationData(&lastQtmCal, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pressed & KEY_L)
|
||||||
|
{
|
||||||
|
lastQtmCal.centerBarrierPosition = fmodf(12.0f + lastQtmCal.centerBarrierPosition - 0.01f, 12.0f);
|
||||||
|
QTMS_SetCalibrationData(&lastQtmCal, false);
|
||||||
|
}
|
||||||
|
else if (pressed & KEY_R)
|
||||||
|
{
|
||||||
|
lastQtmCal.centerBarrierPosition = fmodf(lastQtmCal.centerBarrierPosition + 0.01f, 12.0f);
|
||||||
|
QTMS_SetCalibrationData(&lastQtmCal, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pressed & KEY_A)
|
||||||
|
QTMS_SetCalibrationData(&lastQtmCal, true);
|
||||||
|
|
||||||
|
if (pressed & KEY_Y)
|
||||||
|
{
|
||||||
|
cfguInit();
|
||||||
|
calReadFailed = R_FAILED(CFG_GetConfigInfoBlk8(sizeof(QtmCalibrationData), QTM_CAL_CFG_BLK_ID, &lastQtmCal));
|
||||||
|
cfguExit();
|
||||||
|
qtmCalRead = !calReadFailed;
|
||||||
|
if (qtmCalRead)
|
||||||
|
QTMS_SetCalibrationData(&lastQtmCal, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Draw_Unlock();
|
||||||
|
} while(!menuShouldExit && !(pressed & KEY_B));
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user