rosalina menu: add scrolling, cpad and inputredir support (note: no ZL/ZR due to technical reasons)

This commit is contained in:
TuxSH 2020-05-14 21:05:27 +01:00
parent 6417720d7d
commit 22db3445a0
5 changed files with 87 additions and 89 deletions

View File

@ -45,7 +45,8 @@
#define BUTTON_X (1 << 10)
#define BUTTON_Y (1 << 11)
#define DEFAULT_MENU_COMBO (BUTTON_L1 | BUTTON_DOWN | BUTTON_SELECT)
#define DEFAULT_MENU_COMBO (BUTTON_L1 | BUTTON_DOWN | BUTTON_SELECT)
#define DIRECTIONAL_KEYS (BUTTON_DOWN | BUTTON_UP | BUTTON_LEFT | BUTTON_RIGHT)
#define CORE_APPLICATION 0
#define CORE_SYSTEM 1
@ -75,10 +76,10 @@ extern Handle terminationRequestEvent;
extern u32 menuCombo;
u32 waitInputWithTimeout(u32 msec);
u32 waitInputWithTimeout(s32 msec);
u32 waitInput(void);
u32 waitComboWithTimeout(u32 msec);
u32 waitComboWithTimeout(s32 msec);
u32 waitCombo(void);
MyThread *menuCreateThread(void);

View File

@ -27,6 +27,7 @@
#pragma once
#include <3ds/svc.h>
#include <3ds/srv.h>
#include <3ds/result.h>
#include "csvc.h"
@ -56,4 +57,10 @@ static inline void *decodeArmBranch(const void *src)
return (void *)((const u8 *)src + 8 + off);
}
static inline bool isServiceUsable(const char *name)
{
bool r;
return R_SUCCEEDED(srvIsServiceRegistered(&r, name)) && r;
}
Result OpenProcessByName(const char *name, Handle *h);

View File

@ -36,7 +36,6 @@
#include "gdb/server.h"
#include "pmdbgext.h"
#define MAP_BASE 0x10000000
#define SYSCOREVER (*(vu32 *)0x1FF80010)
#define APPMEMTYPE (*(vu32 *)0x1FF80030)
@ -249,8 +248,10 @@ void HBLDR_HandleCommands(void *ctx)
break;
}
// note: mappableFree doesn't do anything
u32 tmp = 0;
res = svcControlMemoryEx(&tmp, MAP_BASE, 0, totalSize, MEMOP_ALLOC | flags, MEMPERM_READ | MEMPERM_WRITE, true);
u32 *addr = mappableAlloc(totalSize);
res = svcControlMemoryEx(&tmp, (u32)addr, 0, totalSize, MEMOP_ALLOC | flags, MEMPERM_READ | MEMPERM_WRITE, true);
if (R_FAILED(res))
{
IFile_Close(&file);
@ -258,12 +259,12 @@ void HBLDR_HandleCommands(void *ctx)
break;
}
Handle hCodeset = Ldr_CodesetFrom3dsx(name, (u32*)MAP_BASE, baseAddr, &file, tid);
Handle hCodeset = Ldr_CodesetFrom3dsx(name, addr, baseAddr, &file, tid);
IFile_Close(&file);
if (!hCodeset)
{
svcControlMemory(&tmp, MAP_BASE, 0, totalSize, MEMOP_FREE, 0);
svcControlMemory(&tmp, (u32)addr, 0, totalSize, MEMOP_FREE, 0);
error(cmdbuf, MAKERESULT(RL_PERMANENT, RS_INTERNAL, RM_LDR, RD_NOT_FOUND));
break;
}

View File

@ -111,6 +111,7 @@ void initSystem(void)
s64 out;
Result res;
__sync_init();
mappableInit(0x10000000, 0x14000000);
isN3DS = svcGetSystemInfo(&out, 0x10001, 0) == 0;
@ -156,16 +157,14 @@ void initSystem(void)
bool terminationRequest = false;
Handle terminationRequestEvent;
extern bool isHidInitialized;
static void handleTermNotification(u32 notificationId)
{
(void)notificationId;
// Termination request
terminationRequest = true;
svcSignalEvent(terminationRequestEvent);
}
static void relinquishConnectionSessions(u32 notificationId)
static void handlePreTermNotification(u32 notificationId)
{
(void)notificationId;
// Might be subject to a race condition, but heh.
@ -183,6 +182,13 @@ static void relinquishConnectionSessions(u32 notificationId)
isConnectionForced = false;
SysConfigMenu_UpdateStatus(true);
}
if (isHidInitialized)
hidExit();
// Termination request
terminationRequest = true;
svcSignalEvent(terminationRequestEvent);
}
static void handleNextApplicationDebuggedByForce(u32 notificationId)
@ -205,9 +211,9 @@ static const ServiceManagerServiceEntry services[] = {
static const ServiceManagerNotificationEntry notifications[] = {
{ 0x100 , handleTermNotification },
//{ 0x103 , relinquishConnectionSessions }, // Sleep mode entry <=== causes issues
//{ 0x103 , handlePreTermNotification }, // Sleep mode entry <=== causes issues
{ 0x1000, handleNextApplicationDebuggedByForce },
{ 0x2000, relinquishConnectionSessions },
{ 0x2000, handlePreTermNotification },
{ 0x3000, handleRestartHbAppNotification },
{ 0x000, NULL },
};
@ -240,6 +246,7 @@ int main(void)
TaskRunner_Terminate();
MyThread_Join(menuThread, -1LL);
MyThread_Join(taskRunnerThread, -1LL);
MyThread_Join(errDispThread, -1LL);

View File

@ -36,92 +36,76 @@
#include "menus/cheats.h"
#include "minisoc.h"
u32 waitInputWithTimeout(u32 msec)
bool isHidInitialized = false;
// libctru redefinition:
bool hidShouldUseIrrst(void)
{
bool pressedKey = false;
u32 key = 0;
u32 n = 0;
// ir:rst exposes only two sessions :(
return false;
}
//Wait for no keys to be pressed
while(HID_PAD && !terminationRequest && (msec == 0 || n < msec))
{
svcSleepThread(1 * 1000 * 1000LL);
n++;
}
static u32 convertHidKeys(u32 keys)
{
u32 buttons = keys & 0xFFF;
if(terminationRequest || (msec != 0 && n >= msec))
return 0;
// Transform Circle Pad and C-stick into directional keys
if (keys & KEY_LEFT) buttons |= BUTTON_LEFT;
if (keys & KEY_RIGHT) buttons |= BUTTON_RIGHT;
if (keys & KEY_UP) buttons |= BUTTON_UP;
if (keys & KEY_DOWN) buttons |= BUTTON_DOWN;
return buttons;
}
u32 waitInputWithTimeout(s32 msec)
{
s32 n = 0;
u32 keys;
do
{
//Wait for a key to be pressed
while(!HID_PAD && !terminationRequest && (msec == 0 || n < msec))
{
svcSleepThread(1 * 1000 * 1000LL);
n++;
}
svcSleepThread(1 * 1000 * 1000LL);
if (!isHidInitialized || terminationRequest) break;
n += 1;
if(terminationRequest || (msec != 0 && n >= msec))
return 0;
hidScanInput();
keys = convertHidKeys(hidKeysDown()) | (convertHidKeys(hidKeysDownRepeat()) & DIRECTIONAL_KEYS);
} while (keys == 0 && !terminationRequest && isHidInitialized && n < msec);
key = HID_PAD;
//Make sure it's pressed
for(u32 i = 0x26000; i > 0; i --)
{
if(key != HID_PAD) break;
if(i == 1) pressedKey = true;
}
}
while(!pressedKey);
return key;
return keys;
}
u32 waitInput(void)
{
return waitInputWithTimeout(0);
return waitInputWithTimeout(-1);
}
u32 waitComboWithTimeout(u32 msec)
u32 waitComboWithTimeout(s32 msec)
{
u32 key = 0;
u32 n = 0;
s32 n = 0;
u32 keys;
//Wait for no keys to be pressed
while(HID_PAD && !terminationRequest && (msec == 0 || n < msec))
{
svcSleepThread(1 * 1000 * 1000LL);
n++;
}
if(terminationRequest || (msec != 0 && n >= msec))
return 0;
hidScanInput();
keys = convertHidKeys(hidKeysHeld());
do
{
svcSleepThread(1 * 1000 * 1000LL);
n++;
if (!isHidInitialized || terminationRequest) break;
n += 1;
hidScanInput();
keys = convertHidKeys(hidKeysHeld());
} while (keys == 0 && !terminationRequest && isHidInitialized && n < msec);
u32 tempKey = HID_PAD;
for(u32 i = 0x26000; i > 0; i--)
{
if(tempKey != HID_PAD) break;
if(i == 1) key = tempKey;
}
}
while((!key || HID_PAD) && !terminationRequest && (msec == 0 || n < msec));
if(terminationRequest || (msec != 0 && n >= msec))
return 0;
return key;
return keys;
}
u32 waitCombo(void)
{
return waitComboWithTimeout(0);
return waitComboWithTimeout(-1);
}
static MyThread menuThread;
@ -149,28 +133,26 @@ void menuThreadMain(void)
else
N3DSMenu_UpdateStatus();
bool isAcURegistered = false;
while (!isServiceUsable("ac:u") || !isServiceUsable("hid:USER"))
svcSleepThread(500 * 1000 * 1000LL);
hidInit(); // assume this doesn't fail
hidSetRepeatParameters(250, 100);
isHidInitialized = true;
while(!terminationRequest)
{
if((HID_PAD & menuCombo) == menuCombo)
{
if (!isAcURegistered)
isAcURegistered = R_SUCCEEDED(srvIsServiceRegistered(&isAcURegistered, "ac:u"))
&& isAcURegistered;
u32 keys = waitComboWithTimeout(1);
Cheat_ApplyCheats();
if (isAcURegistered)
{
menuEnter();
if(isN3DS) N3DSMenu_UpdateStatus();
menuShow(&rosalinaMenu);
menuLeave();
}
}
else
if((keys & menuCombo) == menuCombo)
{
Cheat_ApplyCheats();
menuEnter();
if(isN3DS) N3DSMenu_UpdateStatus();
menuShow(&rosalinaMenu);
menuLeave();
}
svcSleepThread(50 * 1000 * 1000LL);
}
}