Merge pull request #1488 from mgaver/master

OSK Localizable Update
This commit is contained in:
Henrik Rydgård 2013-04-24 04:04:22 -07:00
commit 957ccc0c6d
2 changed files with 442 additions and 95 deletions

View File

@ -1,4 +1,4 @@
// Copyright (c) 2012- PPSSPP Project.
// Copyright (c) 2012- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@ -30,8 +30,8 @@
#include <math.h>
#endif
const int numKeyCols[OSK_KEYBOARD_COUNT] = {12, 12, 13, 13};
const int numKeyRows[OSK_KEYBOARD_COUNT] = {4, 4, 5, 5};
const int numKeyCols[OSK_KEYBOARD_COUNT] = {12, 12, 13, 13, 12, 12, 12};
const int numKeyRows[OSK_KEYBOARD_COUNT] = {4, 4, 5, 5, 5, 4, 4};
// Japanese(Kana) diacritics
static const wchar_t diacritics[2][103] =
@ -43,9 +43,20 @@ static const wchar_t diacritics[2][103] =
// Korean(Hangul) consonant
static const wchar_t kor_cons[] = L"ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ";
// Korean(Hangul) bowels, Some bowels are not used, them will be spacing
// Korean(Hangul) vowels, Some bowels are not used, them will be spacing
static const wchar_t kor_vowel[] = L"ㅏㅐㅑㅒㅓㅔㅕㅖㅗ ㅛㅜ ㅠㅡ ㅣ";
// Korean(Hangul) vowel Combination key
const int kor_vowelCom[] = {0,8,9,1,8,10,20,8,11,4,13,14,5,13,15,20,13,16,20,18,19};
// Korean(Hangul) last consonant(diacritics)
static const wchar_t kor_lcons[] = L"ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅅㅆㅇㅈㅊㅋㅌㅍㅎ";
// Korean(Hangul) last consonant Combination key
const int kor_lconsCom[] = {18,0,2,21,3,4,26,3,5,0,7,8,15,7,9,16,7,10,18,7,11,24,7,12,25,7,13,26,7,14,18,16,17};
// Korean(Hangul) last consonant Separation key
const int kor_lconsSpr[] = {2,1,9,4,4,12,5,4,18,8,8,0,9,8,6,10,8,7,11,8,9,12,8,16,13,8,17,14,8,18,17,17,9};
static const wchar_t oskKeys[OSK_KEYBOARD_COUNT][5][14] =
{
@ -79,22 +90,28 @@ static const wchar_t oskKeys[OSK_KEYBOARD_COUNT][5][14] =
{L"エケセテネヘメ レ ェ ˚"},
{L"オコソトノホモヨルンォョ "},
},
/*
{
// Korean(Hangul) Lowercase
// Korean(Hangul)
{L"1234567890-+"},
{L"ㅃㅉㄸㄲㅆ!@#$%^&"},
{L"ㅂㅈㄷㄱㅅㅛㅕㅑㅐㅔ[]"},
{L"ㅁㄴㅇㄹㅎㅗㅓㅏㅣ;@~"},
{L"ㅋㅌㅊㅍㅠㅜㅡ<>/?|"},
},
{
// Korean(Hangul) Uppercase
{L"!@#$%^&*()_+"},
{L"ㅃㅉㄸㄲㅆㅛㅕㅑㅒㅖ{}"},
{L"ㅁㄴㅇㄹㅎㅗㅓㅏㅣ:\"`"},
{L"ㅋㅌㅊㅍㅠㅜㅡ<>/?|"},
// Russian Lowercase
{L"1234567890-+"},
{L"йцукенгшщзхъ"},
{L"фывапролджэё"},
{L"ячсмитьбю/?|"},
},
{
// Russian Uppercase
{L"!@#$%^&*()_+"},
{L"ЙЦУКЕНГШЩЗХЪ"},
{L"ФЫВАПРОЛДЖЭЁ"},
{L"ЯЧСМИТЬБЮ/?|"},
},
*/
};
@ -122,13 +139,10 @@ void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const u32 em_address)
{
if (c < 0x80)
*string++ = c;
else if (c < 0x800)
{
else if (c < 0x800) {
*string++ = 0xC0 | (c >> 6);
*string++ = 0x80 | (c & 0x3F);
}
else
{
} else {
*string++ = 0xE0 | (c >> 12);
*string++ = 0x80 | ((c >> 6) & 0x3F);
*string++ = 0x80 | (c & 0x3F);
@ -148,13 +162,10 @@ void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, wchar_t* input)
{
if (c < 0x80)
*string++ = c;
else if (c < 0x800)
{
else if (c < 0x800) {
*string++ = 0xC0 | (c >> 6);
*string++ = 0x80 | (c & 0x3F);
}
else
{
} else {
*string++ = 0xE0 | (c >> 12);
*string++ = 0x80 | ((c >> 6) & 0x3F);
*string++ = 0x80 | (c & 0x3F);
@ -164,7 +175,6 @@ void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, wchar_t* input)
_string = stringBuffer;
}
int PSPOskDialog::Init(u32 oskPtr)
{
// Ignore if already running
@ -204,6 +214,8 @@ int PSPOskDialog::Init(u32 oskPtr)
ConvertUCS2ToUTF8(oskIntext, oskData.intextPtr);
ConvertUCS2ToUTF8(oskOuttext, oskData.outtextPtr);
i_level = 0;
inputChars = L"";
u16 *src = (u16 *) Memory::GetPointer(oskData.intextPtr);
@ -224,7 +236,249 @@ int PSPOskDialog::Init(u32 oskPtr)
return 0;
}
std::wstring PSPOskDialog::CombinationString()
std::wstring PSPOskDialog::CombinationKorean(bool isInput)
{
std::wstring string;
isCombinated = true;
int selectedRow = selectedChar / numKeyCols[currentKeyboard];
int selectedCol = selectedChar % numKeyCols[currentKeyboard];
if(inputChars.size() == 0) {
wchar_t sw = oskKeys[currentKeyboard][selectedRow][selectedCol];
if (inputChars.size() < FieldMaxLength()) {
string += sw;
i_value[0] = GetIndex(kor_cons, sw);
if(i_value[0] != -1 && isInput == true)
i_level = 1;
} else {
isCombinated = false;
}
} else {
for(u32 i = 0; i < inputChars.size(); i++) {
if(i + 1 == inputChars.size()) {
wchar_t sw = oskKeys[currentKeyboard][selectedRow][selectedCol];
if(i_level == 0) {
string += inputChars[i];
if (inputChars.size() < FieldMaxLength()) {
string += sw;
i_value[0] = GetIndex(kor_cons, sw);
if(i_value[0] != -1 && isInput == true)
i_level = 1;
} else {
isCombinated = false;
}
} else if(i_level == 1) {
i_value[1] = GetIndex(kor_vowel, sw);
if(i_value[1] == -1) {
string += inputChars[i];
if (inputChars.size() < FieldMaxLength()) {
string += sw;
if(isInput == true) {
i_value[0] = GetIndex(kor_cons, sw);
if(i_value[0] != -1)
i_level = 1;
else
i_level = 0;
}
} else {
isCombinated = false;
}
} else {
u16 code = 0xAC00 + i_value[0] * 0x24C + i_value[1] * 0x1C;
string += code;
if(isInput == true) {
i_level = 2;
}
}
} else if(i_level == 2) {
u32 tmp = GetIndex(kor_vowel, sw);
if(tmp != -1) {
int tmp2 = -1;
for(int j = 0; j < sizeof(kor_vowelCom) / 4; j+=3) {
if(kor_vowelCom[j] == tmp && kor_vowelCom[j + 1] == i_value[1]) {
tmp2 = kor_vowelCom[j + 2];
break;
}
}
if(tmp2 != -1) {
if(isInput == true) {
i_value[1] = tmp2;
}
u16 code = 0xAC00 + i_value[0] * 0x24C + tmp2 * 0x1C;
string += code;
} else {
string += inputChars[i];
if (inputChars.size() < FieldMaxLength()) {
string += sw;
if(isInput == true) {
i_level = 0;
}
} else {
isCombinated = false;
}
}
} else {
u32 tmp = GetIndex(kor_lcons, sw);
if(tmp == -1) {
string += inputChars[i];
if (inputChars.size() < FieldMaxLength()) {
string += sw;
if(isInput == true) {
i_value[0] = GetIndex(kor_cons, sw);
if(i_value[0] != -1)
i_level = 1;
else
i_level = 0;
}
} else {
isCombinated = false;
}
} else {
u16 code = 0xAC00 + i_value[0] * 0x24C + i_value[1] * 0x1C + tmp + 1;
string += code;
if(isInput == true) {
i_level = 3;
i_value[2] = tmp;
}
}
}
} else if(i_level == 3) {
u32 tmp = GetIndex(kor_lcons, sw);
if(tmp != -1) {
int tmp2 = -1;
for(int j = 0; j < sizeof(kor_lconsCom) / 4; j+=3) {
if(kor_lconsCom[j] == tmp && kor_lconsCom[j + 1] == i_value[2]) {
tmp2 = kor_lconsCom[j + 2];
break;
}
}
if(tmp2 != -1) {
if(isInput == true) {
i_value[2] = tmp2;
}
u16 code = 0xAC00 + i_value[0] * 0x24C + tmp2 * 0x1C + i_value[2] + 1;
string += code;
} else {
string += inputChars[i];
if (inputChars.size() < FieldMaxLength()) {
string += sw;
if(isInput == true) {
i_value[0] = GetIndex(kor_cons, sw);
if(i_value[0] != -1)
i_level = 1;
else
i_level = 0;
}
} else {
isCombinated = false;
}
}
} else {
u32 tmp = GetIndex(kor_vowel, sw);
if(tmp == -1) {
string += inputChars[i];
if (inputChars.size() < FieldMaxLength()) {
string += sw;
if(isInput == true) {
i_value[0] = GetIndex(kor_cons, sw);
if(i_value[0] != -1)
i_level = 1;
else
i_level = 0;
}
} else {
isCombinated = false;
}
} else {
if (inputChars.size() < FieldMaxLength()) {
int tmp2 = -1;
for(int j = 0; j < sizeof(kor_lconsSpr) / 4; j+=3) {
if(kor_lconsSpr[j] == i_value[2]) {
tmp2 = j;
break;
}
}
if(tmp2 != -1) {
u16 code = 0xAC00 + i_value[0] * 0x24C + i_value[1] * 0x1C + kor_lconsSpr[tmp2 + 1];
string += code;
code = 0xAC00 + kor_lconsSpr[tmp2 + 2] * 0x24C + tmp * 0x1C;
string += code;
if(isInput == true) {
i_value[0] = kor_lconsSpr[tmp2 + 2];
i_value[1] = tmp;
i_level = 2;
}
} else {
u32 tmp2 = GetIndex(kor_cons, kor_lcons[i_value[2]]);
if(tmp2 != -1) {
u16 code = 0xAC00 + i_value[0] * 0x24C + i_value[1] * 0x1C;
string += code;
code = 0xAC00 + tmp2 * 0x24C + tmp * 0x1C;
string += code;
if(isInput == true) {
i_value[0] = tmp2;
i_value[1] = tmp;
i_level = 2;
}
} else {
string += inputChars[i];
string += sw;
if(isInput == true) {
i_level = 0;
}
}
}
} else {
string += inputChars[i];
isCombinated = false;
}
}
}
}
} else {
string += inputChars[i];
}
}
}
return string;
}
std::wstring PSPOskDialog::CombinationString(bool isInput)
{
std::wstring string;
@ -233,77 +487,159 @@ std::wstring PSPOskDialog::CombinationString()
int selectedRow = selectedChar / numKeyCols[currentKeyboard];
int selectedCol = selectedChar % numKeyCols[currentKeyboard];
if(oskKeys[currentKeyboard][selectedRow][selectedCol] == L'˝')
if(currentKeyboard == OSK_KEYBOARD_KOREAN)
{
for(u32 i = 0; i < inputChars.size(); i++)
{
if(i + 1 == inputChars.size())
{
for(u32 j = 0; j < wcslen(diacritics[0]); j+=2)
{
if(inputChars[i] == diacritics[0][j])
{
string += diacritics[0][j + 1];
isCombinated = true;
break;
}
}
if(isCombinated == false)
{
string += inputChars[i];
}
}
else
{
string += inputChars[i];
}
}
}
else if(oskKeys[currentKeyboard][selectedRow][selectedCol] == L'˚')
{
for(u32 i = 0; i < inputChars.size(); i++)
{
if(i + 1 == inputChars.size())
{
for(u32 j = 0; j < wcslen(diacritics[1]); j+=2)
{
if(inputChars[i] == diacritics[1][j])
{
string += diacritics[1][j + 1];
isCombinated = true;
break;
}
}
if(isCombinated == false)
{
string += inputChars[i];
}
}
else
{
string += inputChars[i];
}
}
string = CombinationKorean(isInput);
}
else
{
for(u32 i = 0; i < inputChars.size(); i++)
if(isInput == true)
{
string += inputChars[i];
i_level = 0;
}
if (string.size() < FieldMaxLength())
if(oskKeys[currentKeyboard][selectedRow][selectedCol] == L'˝')
{
string += oskKeys[currentKeyboard][selectedRow][selectedCol];
for(u32 i = 0; i < inputChars.size(); i++)
{
if(i + 1 == inputChars.size())
{
for(u32 j = 0; j < wcslen(diacritics[0]); j+=2)
{
if(inputChars[i] == diacritics[0][j])
{
string += diacritics[0][j + 1];
isCombinated = true;
break;
}
}
if(isCombinated == false)
{
string += inputChars[i];
}
}
else
{
string += inputChars[i];
}
}
}
else if(oskKeys[currentKeyboard][selectedRow][selectedCol] == L'˚')
{
for(u32 i = 0; i < inputChars.size(); i++)
{
if(i + 1 == inputChars.size())
{
for(u32 j = 0; j < wcslen(diacritics[1]); j+=2)
{
if(inputChars[i] == diacritics[1][j])
{
string += diacritics[1][j + 1];
isCombinated = true;
break;
}
}
if(isCombinated == false)
{
string += inputChars[i];
}
}
else
{
string += inputChars[i];
}
}
}
else
{
for(u32 i = 0; i < inputChars.size(); i++)
{
string += inputChars[i];
}
if (string.size() < FieldMaxLength())
{
string += oskKeys[currentKeyboard][selectedRow][selectedCol];
}
isCombinated = true;
}
isCombinated = true;
}
return string;
}
void PSPOskDialog::RemoveKorean()
{
if(i_level == 1)
{
i_level = 0;
}
else if(i_level == 2)
{
int tmp = -1;
for(int i = 2; i < sizeof(kor_vowelCom) / 4; i+=3)
{
if(kor_vowelCom[i] == i_value[1])
{
tmp = kor_vowelCom[i - 1];
break;
}
}
if(tmp != -1)
{
i_value[1] = tmp;
u16 code = 0xAC00 + i_value[0] * 0x24C + i_value[1] * 0x1C;
inputChars += code;
}
else
{
i_level = 1;
inputChars += kor_cons[i_value[0]];;
}
}
else if(i_level == 3)
{
int tmp = -1;
for(int i = 2; i < sizeof(kor_lconsCom) / 4; i+=3)
{
if(kor_lconsCom[i] == i_value[2])
{
tmp = kor_vowelCom[i - 1];
break;
}
}
if(tmp != -1)
{
i_value[2] = tmp;
u16 code = 0xAC00 + i_value[0] * 0x24C + i_value[1] * 0x1C + i_value[2] + 1;
inputChars += code;
}
else
{
i_level = 2;
u16 code = 0xAC00 + i_value[0] * 0x24C + i_value[1] * 0x1C;
inputChars += code;
}
}
}
u32 PSPOskDialog::GetIndex(const wchar_t* src, wchar_t ch)
{
for(u32 i = 0; i < wcslen(src); i++)
{
if(src[i] == ch)
{
return i;
}
}
return -1;
}
u32 PSPOskDialog::FieldMaxLength()
{
if (oskData.outtextlimit > oskData.outtextlength - 1 || oskData.outtextlimit == 0)
@ -311,7 +647,6 @@ u32 PSPOskDialog::FieldMaxLength()
return oskData.outtextlimit;
}
void PSPOskDialog::RenderKeyboard()
{
int selectedRow = selectedChar / numKeyCols[currentKeyboard];
@ -334,7 +669,7 @@ void PSPOskDialog::RenderKeyboard()
std::wstring result;
result = CombinationString();
result = CombinationString(false);
for (u32 i = 0; i < limit; ++i)
{
@ -343,7 +678,7 @@ void PSPOskDialog::RenderKeyboard()
{
temp[0] = result[i];
ConvertUCS2ToUTF8(buffer, temp);
PPGeDrawText(buffer.c_str(), previewLeftSide + (i * characterWidth), 40.0f, PPGE_ALIGN_CENTER, 0.5f, color);
PPGeDrawText(buffer.c_str(), previewLeftSide + (i * characterWidth), 40.0f, PPGE_ALIGN_HCENTER, 0.5f, color);
}
else
{
@ -360,21 +695,21 @@ void PSPOskDialog::RenderKeyboard()
ConvertUCS2ToUTF8(buffer, temp);
PPGeDrawText(buffer.c_str(), previewLeftSide + (i * characterWidth), 40.0f, PPGE_ALIGN_CENTER, 0.5f, color);
PPGeDrawText(buffer.c_str(), previewLeftSide + (i * characterWidth), 40.0f, PPGE_ALIGN_HCENTER, 0.5f, color);
// Also draw the underline for the same reason.
color = CalcFadedColor(0xFFFFFFFF);
PPGeDrawText("_", previewLeftSide + (i * characterWidth), 40.0f, PPGE_ALIGN_CENTER, 0.5f, color);
PPGeDrawText("_", previewLeftSide + (i * characterWidth), 40.0f, PPGE_ALIGN_HCENTER, 0.5f, color);
}
else
{
ConvertUCS2ToUTF8(buffer, temp);
PPGeDrawText(buffer.c_str(), previewLeftSide + (i * characterWidth), 40.0f, PPGE_ALIGN_CENTER, 0.5f, color);
PPGeDrawText(buffer.c_str(), previewLeftSide + (i * characterWidth), 40.0f, PPGE_ALIGN_HCENTER, 0.5f, color);
}
}
else
{
PPGeDrawText("_", previewLeftSide + (i * characterWidth), 40.0f, PPGE_ALIGN_CENTER, 0.5f, color);
PPGeDrawText("_", previewLeftSide + (i * characterWidth), 40.0f, PPGE_ALIGN_HCENTER, 0.5f, color);
}
}
}
@ -454,8 +789,8 @@ int PSPOskDialog::Update()
selectedChar = (selectedChar + (numKeyCols[currentKeyboard] * numKeyRows[currentKeyboard])) % (numKeyCols[currentKeyboard] * numKeyRows[currentKeyboard]);
if (IsButtonPressed(CTRL_CROSS))
{
inputChars = CombinationString();
{
inputChars = CombinationString(true);
}
else if (IsButtonPressed(CTRL_SELECT))
{
@ -477,7 +812,13 @@ int PSPOskDialog::Update()
else if (IsButtonPressed(CTRL_CIRCLE))
{
if (inputChars.size() > 0)
{
inputChars.resize(inputChars.size() - 1);
if(i_level != 0)
{
RemoveKorean();
}
}
}
else if (IsButtonPressed(CTRL_START))
{

View File

@ -146,9 +146,9 @@ enum OskKeyboardDisplay
OSK_KEYBOARD_LATIN_UPPERCASE,
OSK_KEYBOARD_HIRAGANA,
OSK_KEYBOARD_KATAKANA,
/* OSK_KEYBOARD_KOREAN_LOWERCASE,
OSK_KEYBOARD_KOREAN_UPPERCASE,
*/
OSK_KEYBOARD_KOREAN,
OSK_KEYBOARD_RUSSIAN_LOWERCASE,
OSK_KEYBOARD_RUSSIAN_UPPERCASE,
// TODO: Something to do native?
OSK_KEYBOARD_COUNT
};
@ -167,9 +167,12 @@ private:
void ConvertUCS2ToUTF8(std::string& _string, wchar_t* input);
void RenderKeyboard();
std::wstring CombinationString(); // for Japanese, Korean
std::wstring CombinationString(bool isInput); // for Japanese, Korean
std::wstring CombinationKorean(bool isInput); // for Korea
void RemoveKorean(); // for Korean character removal
u32 FieldMaxLength();
u32 GetIndex(const wchar_t* src, wchar_t ch);
SceUtilityOskParams *oskParams;
SceUtilityOskData oskData;
@ -181,5 +184,8 @@ private:
std::wstring inputChars;
OskKeyboardDisplay currentKeyboard;
bool isCombinated;
int i_level; // for Korean Keyboard support
int i_value[3]; // for Korean Keyboard support
};