diff --git a/src/Cafe/HW/Latte/Core/LatteRenderTarget.cpp b/src/Cafe/HW/Latte/Core/LatteRenderTarget.cpp index 79b2d694..9db0c2c6 100644 --- a/src/Cafe/HW/Latte/Core/LatteRenderTarget.cpp +++ b/src/Cafe/HW/Latte/Core/LatteRenderTarget.cpp @@ -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); diff --git a/src/Cafe/OS/libs/swkbd/swkbd.cpp b/src/Cafe/OS/libs/swkbd/swkbd.cpp index 4e82783a..2553da56 100644 --- a/src/Cafe/OS/libs/swkbd/swkbd.cpp +++ b/src/Cafe/OS/libs/swkbd/swkbd.cpp @@ -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 g_swkbdCallbacks; + +void swkbd::setSwkbdCallbacks(std::shared_ptr 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; diff --git a/src/Cafe/OS/libs/swkbd/swkbd.h b/src/Cafe/OS/libs/swkbd/swkbd.h index db466ea6..20f2792f 100644 --- a/src/Cafe/OS/libs/swkbd/swkbd.h +++ b/src/Cafe/OS/libs/swkbd/swkbd.h @@ -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 callbacks); + + void render(bool mainWindow); + bool hasKeyboardInputHook(); + void keyInput(uint32 keyCode); + COSModule* GetModule(); -} +} // namespace swkbd diff --git a/src/gui/wxgui/MainWindow.cpp b/src/gui/wxgui/MainWindow.cpp index e1e88ff8..9bcce0b3 100644 --- a/src/gui/wxgui/MainWindow.cpp +++ b/src/gui/wxgui/MainWindow.cpp @@ -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(); } diff --git a/src/gui/wxgui/PadViewFrame.cpp b/src/gui/wxgui/PadViewFrame.cpp index ca213849..deffb1da 100644 --- a/src/gui/wxgui/PadViewFrame.cpp +++ b/src/gui/wxgui/PadViewFrame.cpp @@ -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(); }