From 4bc06562d63acc6128c8f6299fb734aa14b04120 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 22 Dec 2012 22:41:51 -0800 Subject: [PATCH 1/8] Move OSK inputChars to global, fixes release crash. Also, assorted potential crash fixes / etc. --- Core/Dialog/PSPOskDialog.cpp | 71 ++++++++++++++++++++++-------------- Core/Dialog/PSPOskDialog.h | 1 - 2 files changed, 44 insertions(+), 28 deletions(-) diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index 55bbe101cc..d0eba108d4 100644 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -30,6 +30,8 @@ const char oskKeys[NUMKEYROWS][KEYSPERROW] = {'Z','X','C','V','B','N','M',',','.','/','?','\\','\0'}, }; +char inputChars[255]; // must be a better way of doing this... + PSPOskDialog::PSPOskDialog() : PSPDialog() { @@ -81,6 +83,13 @@ int PSPOskDialog::Init(u32 oskPtr) HackyGetStringWide(oskOuttext, oskData.outtextPtr); Memory::WriteStruct(oskParams.SceUtilityOskDataPtr, &oskData); Memory::WriteStruct(oskPtr, &oskParams); + + if (oskData.outtextlimit >= sizeof(inputChars)) + { + // TODO: Check actual behavior. + ERROR_LOG(HLE, "OskDialog requested %d characters, failing", oskData.outtextlimit); + return -1; + } } else { @@ -97,37 +106,36 @@ void PSPOskDialog::RenderKeyboard() int selectedExtra = selectedChar % (KEYSPERROW-1); char SelectedLine[KEYSPERROW]; + char temp[2]; + temp[1] = '\0'; + + int limit = oskData.outtextlimit; + // TODO: Test more thoroughly. Encountered a game where this was 0. + if (limit <= 0) + limit = 16; + PPGeDrawText(oskDesc.c_str(), 480/2, 20, PPGE_ALIGN_CENTER, 0.5f, 0xFFFFFFFF); - for (int i=0; i 0) + { + inputChars[currentInputChar] = 0x00; + currentInputChar--; + } } else if (IsButtonPressed(CTRL_START)) { @@ -224,7 +241,7 @@ void PSPOskDialog::Update() status = SCE_UTILITY_STATUS_SHUTDOWN; } - for (int i=0; i Date: Sat, 22 Dec 2012 22:57:56 -0800 Subject: [PATCH 2/8] Oops, forgot to add one here. --- Core/Dialog/PSPOskDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index d0eba108d4..e4cc8331cb 100644 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -104,7 +104,7 @@ void PSPOskDialog::RenderKeyboard() { int selectedRow = selectedChar / (KEYSPERROW-1); int selectedExtra = selectedChar % (KEYSPERROW-1); - char SelectedLine[KEYSPERROW]; + char SelectedLine[KEYSPERROW + 1]; char temp[2]; temp[1] = '\0'; From f2cb19d7ba076e65520af8e4ec009b49d4174f91 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 23 Dec 2012 08:52:51 -0800 Subject: [PATCH 3/8] Switch OSK to using a std::string buffer. Back as a class member, hurray. --- Core/Dialog/PSPOskDialog.cpp | 41 +++++++++++------------------------- Core/Dialog/PSPOskDialog.h | 3 +-- 2 files changed, 13 insertions(+), 31 deletions(-) diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index e4cc8331cb..a6cfbf9201 100644 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -30,8 +30,6 @@ const char oskKeys[NUMKEYROWS][KEYSPERROW] = {'Z','X','C','V','B','N','M',',','.','/','?','\\','\0'}, }; -char inputChars[255]; // must be a better way of doing this... - PSPOskDialog::PSPOskDialog() : PSPDialog() { @@ -69,10 +67,9 @@ int PSPOskDialog::Init(u32 oskPtr) memset(&oskParams, 0, sizeof(oskParams)); memset(&oskData, 0, sizeof(oskData)); // TODO: should this be init'd to oskIntext? - memset(inputChars, 0x00, sizeof(inputChars)); + inputChars.clear(); oskParamsAddr = oskPtr; selectedChar = 0; - currentInputChar = 0; if (Memory::IsValidAddress(oskPtr)) { @@ -83,13 +80,6 @@ int PSPOskDialog::Init(u32 oskPtr) HackyGetStringWide(oskOuttext, oskData.outtextPtr); Memory::WriteStruct(oskParams.SceUtilityOskDataPtr, &oskData); Memory::WriteStruct(oskPtr, &oskParams); - - if (oskData.outtextlimit >= sizeof(inputChars)) - { - // TODO: Check actual behavior. - ERROR_LOG(HLE, "OskDialog requested %d characters, failing", oskData.outtextlimit); - return -1; - } } else { @@ -118,9 +108,9 @@ void PSPOskDialog::RenderKeyboard() for (int i = 0; i < limit; ++i) { u32 color = 0xFFFFFFFF; - if (inputChars[i] != 0) + if (i < inputChars.size()) temp[0] = inputChars[i]; - else if (currentInputChar == i) + else if (i == inputChars.size()) { temp[0] = oskKeys[selectedRow][selectedExtra]; color = 0xFF3060FF; @@ -212,23 +202,13 @@ void PSPOskDialog::Update() // TODO : Dialogs should take control over input and not send them to the game while displaying if (IsButtonPressed(CTRL_CROSS)) { - if (currentInputChar < limit) - { - inputChars[currentInputChar]= oskKeys[selectedRow][selectedExtra]; - currentInputChar++; - } - else - { - currentInputChar = limit; // just in case - } + if (inputChars.size() < limit) + inputChars += oskKeys[selectedRow][selectedExtra]; } else if (IsButtonPressed(CTRL_CIRCLE)) { - if (currentInputChar > 0) - { - inputChars[currentInputChar] = 0x00; - currentInputChar--; - } + if (inputChars.size() > 0) + inputChars.resize(inputChars.size() - 1); } else if (IsButtonPressed(CTRL_START)) { @@ -243,10 +223,13 @@ void PSPOskDialog::Update() for (int i = 0; i < limit; ++i) { - Memory::Write_U16(0x0000^inputChars[i],oskData.outtextPtr + (2*i)); + u16 value = 0; + if (i < inputChars.size()) + value = 0x0000 ^ inputChars[i]; + Memory::Write_U16(value, oskData.outtextPtr + (2 * i)); } - oskData.outtextlength = currentInputChar; + oskData.outtextlength = inputChars.size(); oskParams.base.result= 0; oskData.result = PSP_UTILITY_OSK_RESULT_CHANGED; Memory::WriteStruct(oskParams.SceUtilityOskDataPtr, &oskData); diff --git a/Core/Dialog/PSPOskDialog.h b/Core/Dialog/PSPOskDialog.h index 76ea15c1c3..9939923499 100644 --- a/Core/Dialog/PSPOskDialog.h +++ b/Core/Dialog/PSPOskDialog.h @@ -157,8 +157,7 @@ private: std::string oskOuttext; int oskParamsAddr; - int currentInputChar; int selectedChar; - + std::string inputChars; }; From 1c4409e082b2d235c3a844fdebf26315bb772b13 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 23 Dec 2012 08:59:34 -0800 Subject: [PATCH 4/8] Naive fix for repeat rate issues in OSK. Not sure if the latch should actually be consumed but makes sense. Needs tests. --- Core/Dialog/PSPOskDialog.cpp | 10 +++++----- Core/HLE/sceCtrl.cpp | 7 +++++++ Core/HLE/sceCtrl.h | 3 ++- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index a6cfbf9201..3400c80dbe 100644 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -108,7 +108,7 @@ void PSPOskDialog::RenderKeyboard() for (int i = 0; i < limit; ++i) { u32 color = 0xFFFFFFFF; - if (i < inputChars.size()) + if (i < (int) inputChars.size()) temp[0] = inputChars[i]; else if (i == inputChars.size()) { @@ -146,7 +146,7 @@ void PSPOskDialog::RenderKeyboard() void PSPOskDialog::Update() { - buttons = __CtrlPeekButtons(); + buttons = __CtrlReadLatch(); int selectedRow = selectedChar / (KEYSPERROW-1); int selectedExtra = selectedChar % (KEYSPERROW-1); @@ -179,7 +179,7 @@ void PSPOskDialog::Update() } else if (IsButtonPressed(CTRL_DOWN)) { - selectedChar -=10; + selectedChar -= 10; } else if (IsButtonPressed(CTRL_LEFT)) { @@ -202,7 +202,7 @@ void PSPOskDialog::Update() // TODO : Dialogs should take control over input and not send them to the game while displaying if (IsButtonPressed(CTRL_CROSS)) { - if (inputChars.size() < limit) + if ((int) inputChars.size() < limit) inputChars += oskKeys[selectedRow][selectedExtra]; } else if (IsButtonPressed(CTRL_CIRCLE)) @@ -224,7 +224,7 @@ void PSPOskDialog::Update() for (int i = 0; i < limit; ++i) { u16 value = 0; - if (i < inputChars.size()) + if (i < (int) inputChars.size()) value = 0x0000 ^ inputChars[i]; Memory::Write_U16(value, oskData.outtextPtr + (2 * i)); } diff --git a/Core/HLE/sceCtrl.cpp b/Core/HLE/sceCtrl.cpp index 73e03def9d..bbcde95559 100644 --- a/Core/HLE/sceCtrl.cpp +++ b/Core/HLE/sceCtrl.cpp @@ -125,6 +125,13 @@ u32 __CtrlPeekButtons() return ctrlCurrent.buttons; } +u32 __CtrlReadLatch() +{ + u32 ret = latch.btnMake; + __CtrlResetLatch(); + return ret; +} + // Functions so that the rest of the emulator can control what the sceCtrl interface should return // to the game: diff --git a/Core/HLE/sceCtrl.h b/Core/HLE/sceCtrl.h index 2f658d73c0..dcb465f305 100644 --- a/Core/HLE/sceCtrl.h +++ b/Core/HLE/sceCtrl.h @@ -40,4 +40,5 @@ void __CtrlButtonUp(u32 buttonBit); void __CtrlSetAnalog(float x, float y); // For use by internal UI like MsgDialog -u32 __CtrlPeekButtons(); \ No newline at end of file +u32 __CtrlPeekButtons(); +u32 __CtrlReadLatch(); \ No newline at end of file From 64d8763d0a5c8244e649764fb76a88863ec3f7dd Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 23 Dec 2012 09:05:01 -0800 Subject: [PATCH 5/8] Fix left/right/up/down wrapping issues in OSK. --- Core/Dialog/PSPOskDialog.cpp | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index 3400c80dbe..a4feb82cde 100644 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -20,9 +20,9 @@ #include "../HLE/sceCtrl.h" #define NUMKEYROWS 4 -#define KEYSPERROW 13 -#define NUMBEROFVALIDCHARS 44 -const char oskKeys[NUMKEYROWS][KEYSPERROW] = +#define KEYSPERROW 12 +#define NUMBEROFVALIDCHARS (KEYSPERROW * NUMKEYROWS) +const char oskKeys[NUMKEYROWS][KEYSPERROW + 1] = { {'1','2','3','4','5','6','7','8','9','0','-','+','\0'}, {'Q','W','E','R','T','Y','U','I','O','P','[',']','\0'}, @@ -92,8 +92,8 @@ int PSPOskDialog::Init(u32 oskPtr) void PSPOskDialog::RenderKeyboard() { - int selectedRow = selectedChar / (KEYSPERROW-1); - int selectedExtra = selectedChar % (KEYSPERROW-1); + int selectedRow = selectedChar / KEYSPERROW; + int selectedExtra = selectedChar % KEYSPERROW; char SelectedLine[KEYSPERROW + 1]; char temp[2]; @@ -147,8 +147,8 @@ void PSPOskDialog::RenderKeyboard() void PSPOskDialog::Update() { buttons = __CtrlReadLatch(); - int selectedRow = selectedChar / (KEYSPERROW-1); - int selectedExtra = selectedChar % (KEYSPERROW-1); + int selectedRow = selectedChar / KEYSPERROW; + int selectedExtra = selectedChar % KEYSPERROW; int limit = oskData.outtextlimit; // TODO: Test more thoroughly. Encountered a game where this was 0. @@ -175,11 +175,11 @@ void PSPOskDialog::Update() if (IsButtonPressed(CTRL_UP)) { - selectedChar += 10; + selectedChar -= KEYSPERROW; } else if (IsButtonPressed(CTRL_DOWN)) { - selectedChar -= 10; + selectedChar += KEYSPERROW; } else if (IsButtonPressed(CTRL_LEFT)) { @@ -190,14 +190,7 @@ void PSPOskDialog::Update() selectedChar++; } - if (selectedChar < 0) - { - selectedChar = NUMBEROFVALIDCHARS; - } - if (selectedChar > NUMBEROFVALIDCHARS) - { - selectedChar = 0; - } + selectedChar = (selectedChar + NUMBEROFVALIDCHARS) % NUMBEROFVALIDCHARS; // TODO : Dialogs should take control over input and not send them to the game while displaying if (IsButtonPressed(CTRL_CROSS)) From c89c46cbf9fb2bba542dbe6c3b1528a3508a1357 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 23 Dec 2012 09:21:10 -0800 Subject: [PATCH 6/8] Center and space out the OSK. --- Core/Dialog/PSPOskDialog.cpp | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index a4feb82cde..b636fd7013 100644 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -94,7 +94,6 @@ void PSPOskDialog::RenderKeyboard() { int selectedRow = selectedChar / KEYSPERROW; int selectedExtra = selectedChar % KEYSPERROW; - char SelectedLine[KEYSPERROW + 1]; char temp[2]; temp[1] = '\0'; @@ -104,6 +103,9 @@ void PSPOskDialog::RenderKeyboard() if (limit <= 0) limit = 16; + const float keyboardLeftSide = (480.0f - (16.0f * KEYSPERROW)) / 2.0f; + float previewLeftSide = (480.0f - (16.0f * limit)) / 2.0f; + PPGeDrawText(oskDesc.c_str(), 480/2, 20, PPGE_ALIGN_CENTER, 0.5f, 0xFFFFFFFF); for (int i = 0; i < limit; ++i) { @@ -118,29 +120,23 @@ void PSPOskDialog::RenderKeyboard() else temp[0] = '_'; - PPGeDrawText(temp, 20.0f + (i * 16.0f), 40, NULL, 0.5f, color); + PPGeDrawText(temp, previewLeftSide + (i * 16.0f), 40.0f, NULL, 0.5f, color); } - for (int row = 0; row < NUMKEYROWS; row++) + for (int row = 0; row < NUMKEYROWS; ++row) { - u32 color = 0xFFFFFFFF; - if (selectedRow == row) - color = 0xFF7f7f7f; - PPGeDrawText(oskKeys[row], 20.0f, 70.0f + (25.0f * row), NULL, 0.6f, color); - } - for (int selectedItemCounter = 0; selectedItemCounter < KEYSPERROW; selectedItemCounter++ ) - { - if (selectedItemCounter!=selectedExtra) + for (int col = 0; col < KEYSPERROW; ++col) { - SelectedLine[selectedItemCounter] = oskKeys[selectedRow][selectedItemCounter]; - } - else - { - SelectedLine[selectedItemCounter] = '_'; - } - } + u32 color = 0xFFFFFFFF; + if (selectedRow == row && col == selectedExtra) + color = 0xFF7f7f7f; - SelectedLine[KEYSPERROW] = '\0'; - PPGeDrawText(SelectedLine, 20, 71.0f + (25.0f * selectedRow), NULL, 0.6f, 0xFFFFFFFF); + temp[0] = oskKeys[row][col]; + PPGeDrawText(temp, keyboardLeftSide + (16.0f * col), 70.0f + (25.0f * row), NULL, 0.6f, color); + + if (selectedRow == row && col == selectedExtra) + PPGeDrawText("_", keyboardLeftSide + (16.0f * col), 70.0f + (25.0f * row), NULL, 0.6f, 0xFFFFFFFF); + } + } } From bfcf6e3aca8d58f349769eaa72b15b70e660b22d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 23 Dec 2012 09:23:01 -0800 Subject: [PATCH 7/8] Stop always selecting the first char in OSK. --- Core/Dialog/PSPOskDialog.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index b636fd7013..a7380c510f 100644 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -86,6 +86,9 @@ int PSPOskDialog::Init(u32 oskPtr) return -1; } + // Eat any keys pressed before the dialog inited. + __CtrlReadLatch(); + return 0; } From 7c35b145eaa8536f32cc5a3aa3937fe77d27d3b9 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 23 Dec 2012 09:25:42 -0800 Subject: [PATCH 8/8] Make the OSK go left/right like SNES/etc. ones. --- Core/Dialog/PSPOskDialog.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index a7380c510f..f2d186c5a5 100644 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -183,10 +183,14 @@ void PSPOskDialog::Update() else if (IsButtonPressed(CTRL_LEFT)) { selectedChar--; + if (((selectedChar + KEYSPERROW) % KEYSPERROW) == KEYSPERROW - 1) + selectedChar += KEYSPERROW; } else if (IsButtonPressed(CTRL_RIGHT)) { selectedChar++; + if ((selectedChar % KEYSPERROW) == 0) + selectedChar -= KEYSPERROW; } selectedChar = (selectedChar + NUMBEROFVALIDCHARS) % NUMBEROFVALIDCHARS;