diff --git a/rpcs3/Emu/Cell/Modules/cellKey2char.cpp b/rpcs3/Emu/Cell/Modules/cellKey2char.cpp index fe3d9ebbf1..3505dad943 100644 --- a/rpcs3/Emu/Cell/Modules/cellKey2char.cpp +++ b/rpcs3/Emu/Cell/Modules/cellKey2char.cpp @@ -1,7 +1,6 @@ -#include "stdafx.h" +#include "stdafx.h" #include "Emu/Cell/PPUModule.h" - - +#include "cellKb.h" LOG_CHANNEL(cellKey2char); @@ -16,6 +15,20 @@ enum CellKey2CharError : u32 CELL_K2C_ERROR_OTHER = 0x80121306, }; +// Modes +enum +{ + CELL_KEY2CHAR_MODE_ENGLISH = 0, + CELL_KEY2CHAR_MODE_NATIVE = 1, + CELL_KEY2CHAR_MODE_NATIVE2 = 2 +}; + +// Constants +enum +{ + SCE_KEY2CHAR_HANDLE_SIZE = 128 +}; + struct CellKey2CharKeyData { be_t led; @@ -23,6 +36,11 @@ struct CellKey2CharKeyData be_t keycode; }; +struct CellKey2CharHandle +{ + u8 data[SCE_KEY2CHAR_HANDLE_SIZE]; +}; + template<> void fmt_class_string::format(std::string& out, u64 arg) { @@ -42,33 +60,126 @@ void fmt_class_string::format(std::string& out, u64 arg) }); } -error_code cellKey2CharOpen(vm::ptr handle) +error_code cellKey2CharOpen(vm::ptr handle) { cellKey2char.todo("cellKey2CharOpen(handle=*0x%x)", handle); + + if (!handle) + return CELL_K2C_ERROR_INVALID_HANDLE; + + if (handle->data[8] != 0) + return CELL_K2C_ERROR_ALREADY_INITIALIZED; + + // TODO + return CELL_OK; } -error_code cellKey2CharClose(vm::ptr handle) +error_code cellKey2CharClose(vm::ptr handle) { cellKey2char.todo("cellKey2CharClose(handle=*0x%x)", handle); + + if (!handle) + return CELL_K2C_ERROR_INVALID_HANDLE; + + if (handle->data[8] == 0) + return CELL_K2C_ERROR_UNINITIALIZED; + + // TODO + return CELL_OK; } -error_code cellKey2CharGetChar(vm::ptr handle, vm::ptr kdata, vm::pptr charCode, vm::ptr charNum, vm::ptr processed) +error_code cellKey2CharGetChar(vm::ptr handle, vm::ptr kdata, vm::pptr charCode, vm::ptr charNum, vm::ptr processed) { cellKey2char.todo("cellKey2CharGetChar(handle=*0x%x, kdata=*0x%x, charCode=**0x%x, charNum=*0x%x, processed=*0x%x)", handle, kdata, charCode, charNum, processed); + + if (!handle) + return CELL_K2C_ERROR_INVALID_HANDLE; + + if (handle->data[8] == 0) + return CELL_K2C_ERROR_UNINITIALIZED; + + if (!charCode || !kdata || !kdata->keycode) + return CELL_K2C_ERROR_INVALID_PARAMETER; + + if (handle->data[0] == 255) + { + if (false /* some check for CELL_OK */) + return CELL_K2C_ERROR_OTHER; + } + return CELL_OK; } -error_code cellKey2CharSetMode(vm::ptr handle, s32 mode) +error_code cellKey2CharSetMode(vm::ptr handle, s32 mode) { cellKey2char.todo("cellKey2CharSetMode(handle=*0x%x, mode=0x%x)", handle, mode); + + if (!handle) + return CELL_K2C_ERROR_INVALID_HANDLE; + + if (handle->data[8] == 0) + return CELL_K2C_ERROR_UNINITIALIZED; + + if (mode > CELL_KEY2CHAR_MODE_NATIVE2) + return CELL_K2C_ERROR_INVALID_PARAMETER; + + if (handle->data[0] == 255) + return CELL_K2C_ERROR_OTHER; + + const s32 mapping = handle->data[1]; + + switch (mode) + { + case CELL_KEY2CHAR_MODE_ENGLISH: + // TODO: set mode to alphanumeric + break; + case CELL_KEY2CHAR_MODE_NATIVE: + switch (mapping) + { + case CELL_KB_MAPPING_106: // Japanese + // TODO: set mode to kana + break; + case CELL_KB_MAPPING_RUSSIAN_RUSSIA: + // TODO: set mode to Cyrillic + break; + case CELL_KB_MAPPING_KOREAN_KOREA: + // TODO: set mode to Hangul + break; + case CELL_KB_MAPPING_CHINESE_TRADITIONAL: + // TODO: set mode to Bopofomo + break; + default: + break; + } + break; + case CELL_KEY2CHAR_MODE_NATIVE2: + if (mapping == CELL_KB_MAPPING_CHINESE_TRADITIONAL) + { + // TODO: set mode to Cangjie + } + break; + default: + break; // Unreachable + } + return CELL_OK; } -error_code cellKey2CharSetArrangement(vm::ptr handle, s32 arrange) +error_code cellKey2CharSetArrangement(vm::ptr handle, s32 arrange) { cellKey2char.todo("cellKey2CharSetArrangement(handle=*0x%x, arrange=0x%x)", handle, arrange); + + if (!handle) + return CELL_K2C_ERROR_INVALID_HANDLE; + + if (handle->data[8] == 0) + return CELL_K2C_ERROR_UNINITIALIZED; + + if (arrange < CELL_KB_MAPPING_101 || arrange > CELL_KB_MAPPING_TURKISH_TURKEY) + return CELL_K2C_ERROR_INVALID_PARAMETER; + return CELL_OK; }