swkbd: add swkbd callbacks & refactor

This commit is contained in:
SSimco 2026-05-09 16:35:14 +03:00
parent 54f043c0f2
commit e43871fa8a
5 changed files with 64 additions and 29 deletions

View File

@ -965,7 +965,7 @@ void LatteRenderTarget_copyToBackbuffer(LatteTextureView* textureView, bool isPa
g_renderer->HandleScreenshotRequest(textureView, isPadView);
if (!g_renderer->ImguiBegin(!isPadView))
return;
swkbd_render(!isPadView);
swkbd::render(!isPadView);
nn::erreula::render(!isPadView);
LatteOverlay_render(isPadView);
g_renderer->ImguiEnd();
@ -1004,7 +1004,7 @@ void LatteRenderTarget_itHLECopyColorBufferToScanBuffer(MPTR colorBufferPtr, uin
isDRCPrimary = !isDRCPrimary;
togglePressedLast = togglePressed;
bool showDRC = swkbd_hasKeyboardInputHook() == false && (isDRCPrimary ^ altScreenRequested);
bool showDRC = swkbd::hasKeyboardInputHook() == false && (isDRCPrimary ^ altScreenRequested);
if ((renderTarget & RENDER_TARGET_DRC) && g_renderer->IsPadWindowActive())
LatteRenderTarget_copyToBackbuffer(texView, true);

View File

@ -1,3 +1,4 @@
#include "OS/libs/swkbd/swkbd.h"
#include "Cafe/OS/common/OSCommon.h"
#include "Cafe/HW/Latte/ISA/RegDefines.h"
#include "Cafe/OS/libs/gx2/GX2.h"
@ -91,6 +92,13 @@ typedef struct
swkbdInternalState_t* swkbdInternalState = NULL;
std::shared_ptr<swkbd::swkbdCallbacks> g_swkbdCallbacks;
void swkbd::setSwkbdCallbacks(std::shared_ptr<swkbd::swkbdCallbacks> swkbdCallbacks)
{
g_swkbdCallbacks = std::move(swkbdCallbacks);
}
void swkbdExport_SwkbdCreate(PPCInterpreter_t* hCPU)
{
cemuLog_logDebug(LogType::Force, "swkbd.SwkbdCreate(0x{:08x},0x{:08x},0x{:08x},0x{:08x})", hCPU->gpr[3], hCPU->gpr[4], hCPU->gpr[5], hCPU->gpr[6]);
@ -235,6 +243,9 @@ void swkbdExport_SwkbdAppearInputForm(PPCInterpreter_t* hCPU)
swkbdInternalState->formStringBuffer[0] = '\0';
swkbdInternalState->formStringLength = 0;
}
if (g_swkbdCallbacks)
g_swkbdCallbacks->showSoftwareKeyboard({swkbdInternalState->formStringBuffer, swkbdInternalState->formStringBuffer + swkbdInternalState->formStringLength}, swkbdInternalState->maxTextLength);
osLib_returnFromFunction(hCPU, 1);
}
@ -257,6 +268,11 @@ void swkbdExport_SwkbdAppearKeyboard(PPCInterpreter_t* hCPU)
swkbdInternalState->formStringBuffer[0] = '\0';
swkbdInternalState->formStringLength = 0;
swkbdInternalState->keyboardArg = *keyboardArg;
if (g_swkbdCallbacks)
{
sint32 maxLength = std::max(swkbdInternalState->keyboardArg.receiverArg.stringBufSize - 1, 0);
g_swkbdCallbacks->showSoftwareKeyboard({swkbdInternalState->formStringBuffer, swkbdInternalState->formStringBuffer + swkbdInternalState->formStringLength}, maxLength);
}
osLib_returnFromFunction(hCPU, 1);
}
@ -264,6 +280,8 @@ void swkbdExport_SwkbdDisappearInputForm(PPCInterpreter_t* hCPU)
{
debug_printf("SwkbdDisappearInputForm__3RplFv LR: %08x\n", hCPU->spr.LR);
swkbdInternalState->isActive = false;
if (g_swkbdCallbacks)
g_swkbdCallbacks->hideSoftwareKeyboard();
osLib_returnFromFunction(hCPU, 1);
}
@ -271,6 +289,8 @@ void swkbdExport_SwkbdDisappearKeyboard(PPCInterpreter_t* hCPU)
{
debug_printf("SwkbdDisappearKeyboard__3RplFv LR: %08x\n", hCPU->spr.LR);
swkbdInternalState->isActive = false;
if (g_swkbdCallbacks)
g_swkbdCallbacks->hideSoftwareKeyboard();
osLib_returnFromFunction(hCPU, 1);
}
@ -292,7 +312,7 @@ void swkbdExport_SwkbdIsDecideOkButton(PPCInterpreter_t* hCPU)
osLib_returnFromFunction(hCPU, 0);
}
typedef struct
typedef struct
{
uint32be ukn00;
uint32be ukn04;
@ -349,8 +369,7 @@ void swkbdExport_SwkbdIsNeedCalcSubThreadPredict(PPCInterpreter_t* hCPU)
osLib_returnFromFunction(hCPU, r?1:0);
}
void swkbd_keyInput(uint32 keyCode);
void swkbd_render(bool mainWindow)
void swkbd::render(bool mainWindow)
{
// only render if active
if( swkbdInternalState == NULL || swkbdInternalState->isActive == false)
@ -438,13 +457,13 @@ void swkbd_render(bool mainWindow)
if (ImGui::Button(key, { *key == ' ' ? 537 : (button_len + 5), 0}))
{
if (strcmp(key, _utf8WrapperPtr(ICON_FA_ARROW_CIRCLE_LEFT)) == 0)
swkbd_keyInput(8);
swkbd::keyInput(BACKSPACE_KEYCODE);
else if (strcmp(key, _utf8WrapperPtr(ICON_FA_ARROW_UP)) == 0)
swkbdInternalState->shiftActivated = !swkbdInternalState->shiftActivated;
else if (strcmp(key, _utf8WrapperPtr(ICON_FA_CHECK)) == 0)
swkbd_keyInput(13);
swkbd::keyInput(RETURN_KEYCODE);
else
swkbd_keyInput(*key);
swkbd::keyInput(*key);
}
ImGui::SameLine();
@ -470,13 +489,13 @@ void swkbd_render(bool mainWindow)
if (ImGui::Button(key, { *key == ' ' ? 537 : (button_len + 5), 0 }))
{
if (strcmp(key, _utf8WrapperPtr(ICON_FA_ARROW_CIRCLE_LEFT)) == 0)
swkbd_keyInput(8);
swkbd::keyInput(BACKSPACE_KEYCODE);
else if (strcmp(key, _utf8WrapperPtr(ICON_FA_ARROW_UP)) == 0)
swkbdInternalState->shiftActivated = !swkbdInternalState->shiftActivated;
else if (strcmp(key, _utf8WrapperPtr(ICON_FA_CHECK)) == 0)
swkbd_keyInput(13);
swkbd::keyInput(RETURN_KEYCODE);
else
swkbd_keyInput(*key);
swkbd::keyInput(*key);
}
ImGui::SameLine();
@ -492,7 +511,7 @@ void swkbd_render(bool mainWindow)
if (io.NavInputs[ImGuiNavInput_Cancel] > 0)
{
if(!swkbdInternalState->cancelState)
swkbd_keyInput(8); // backspace
swkbd::keyInput(BACKSPACE_KEYCODE);
swkbdInternalState->cancelState = true;
}
else
@ -501,7 +520,7 @@ void swkbd_render(bool mainWindow)
if (io.NavInputs[ImGuiNavInput_Input] > 0)
{
if (!swkbdInternalState->returnState)
swkbd_keyInput(13); // return
swkbd::keyInput(RETURN_KEYCODE);
swkbdInternalState->returnState = true;
}
else
@ -511,7 +530,7 @@ void swkbd_render(bool mainWindow)
ImGui::PopStyleColor();
}
bool swkbd_hasKeyboardInputHook()
bool swkbd::hasKeyboardInputHook()
{
return swkbdInternalState != NULL && swkbdInternalState->isActive;
}
@ -564,9 +583,9 @@ void swkbd_inputStringChanged()
}
}
void swkbd_keyInput(uint32 keyCode)
void swkbd::keyInput(uint32 keyCode)
{
if (keyCode == 8 || keyCode == 127) // backspace || backwards delete
if (keyCode == BACKSPACE_KEYCODE || keyCode == BACKWARDS_DELETE_KEYCODE)
{
if (swkbdInternalState->formStringLength > 0)
swkbdInternalState->formStringLength--;
@ -574,7 +593,7 @@ void swkbd_keyInput(uint32 keyCode)
swkbd_inputStringChanged();
return;
}
else if (keyCode == 13) // return
else if (keyCode == RETURN_KEYCODE)
{
swkbd_finishInput();
return;
@ -593,7 +612,7 @@ void swkbd_keyInput(uint32 keyCode)
{
// allowed
}
else if (keyCode < 32)
else if (keyCode < CONTROL_KEYCODE)
{
// control key
return;

View File

@ -1,10 +1,26 @@
#include "Cafe/OS/RPL/COSModule.h"
#pragma once
void swkbd_render(bool mainWindow);
bool swkbd_hasKeyboardInputHook();
void swkbd_keyInput(uint32 keyCode);
#include "Cafe/OS/RPL/COSModule.h"
namespace swkbd
{
constexpr uint32 BACKSPACE_KEYCODE = 8;
constexpr uint32 BACKWARDS_DELETE_KEYCODE = 127;
constexpr uint32 RETURN_KEYCODE = 13;
constexpr uint32 CONTROL_KEYCODE = 32;
class swkbdCallbacks
{
public:
virtual void showSoftwareKeyboard(const std::string& initialText, sint32 maxLength) = 0;
virtual void hideSoftwareKeyboard() = 0;
};
void setSwkbdCallbacks(std::shared_ptr<swkbdCallbacks> callbacks);
void render(bool mainWindow);
bool hasKeyboardInputHook();
void keyInput(uint32 keyCode);
COSModule* GetModule();
}
} // namespace swkbd

View File

@ -1452,7 +1452,7 @@ void MainWindow::OnKeyUp(wxKeyEvent& event)
{
event.Skip();
if (swkbd_hasKeyboardInputHook())
if (swkbd::hasKeyboardInputHook())
return;
HotkeySettings::CaptureInput(event);
@ -1481,8 +1481,8 @@ void MainWindow::OnKeyDown(wxKeyEvent& event)
void MainWindow::OnChar(wxKeyEvent& event)
{
if (swkbd_hasKeyboardInputHook())
swkbd_keyInput(event.GetUnicodeKey());
if (swkbd::hasKeyboardInputHook())
swkbd::keyInput(event.GetUnicodeKey());
// event.Skip();
}

View File

@ -163,7 +163,7 @@ void PadViewFrame::OnKeyUp(wxKeyEvent& event)
{
event.Skip();
if (swkbd_hasKeyboardInputHook())
if (swkbd::hasKeyboardInputHook())
return;
const auto code = event.GetKeyCode();
@ -187,8 +187,8 @@ void PadViewFrame::OnGesturePan(wxPanGestureEvent& event)
void PadViewFrame::OnChar(wxKeyEvent& event)
{
if (swkbd_hasKeyboardInputHook())
swkbd_keyInput(event.GetUnicodeKey());
if (swkbd::hasKeyboardInputHook())
swkbd::keyInput(event.GetUnicodeKey());
event.Skip();
}