Merge pull request #2044 from unknownbrackets/mem-pointers

Use PSPPointer in a few more places
This commit is contained in:
Henrik Rydgård 2013-06-03 00:19:42 -07:00
commit 1d0d13509c
6 changed files with 171 additions and 112 deletions

View File

@ -124,34 +124,15 @@ PSPOskDialog::PSPOskDialog() : PSPDialog() {
PSPOskDialog::~PSPOskDialog() {
}
void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const u32 em_address)
void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const PSPPointer<wchar_t> em_address)
{
char stringBuffer[2048];
char *string = stringBuffer;
if (em_address == 0)
if (!em_address.Valid())
{
_string = "";
return;
}
u16 *src = (u16 *) Memory::GetPointer(em_address);
int c;
while (c = *src++)
{
if (c < 0x80)
*string++ = c;
else if (c < 0x800) {
*string++ = 0xC0 | (c >> 6);
*string++ = 0x80 | (c & 0x3F);
} else {
*string++ = 0xE0 | (c >> 12);
*string++ = 0x80 | ((c >> 6) & 0x3F);
*string++ = 0x80 | (c & 0x3F);
}
}
*string++ = '\0';
_string = stringBuffer;
ConvertUCS2ToUTF8(_string, &em_address[0]);
}
void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, wchar_t* input)
@ -160,7 +141,7 @@ void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, wchar_t* input)
char *string = stringBuffer;
int c;
while (c = *input++)
while ((c = *input++) != 0)
{
if (c < 0x80)
*string++ = c;
@ -189,16 +170,16 @@ int PSPOskDialog::Init(u32 oskPtr)
return -1;
}
oskParams = Memory::GetStruct<SceUtilityOskParams>(oskPtr);
oskParams = oskPtr;
if (oskParams->base.size != sizeof(SceUtilityOskParams))
{
ERROR_LOG(HLE, "sceUtilityOskInitStart: invalid size (%d)", oskParams->base.size);
return SCE_ERROR_UTILITY_INVALID_PARAM_SIZE;
}
// Also seems to crash.
if (!Memory::IsValidAddress(oskParams->fieldPtr))
if (!oskParams->fields.Valid())
{
ERROR_LOG_REPORT(HLE, "sceUtilityOskInitStart: invalid field data (%08x)", oskParams->fieldPtr);
ERROR_LOG_REPORT(HLE, "sceUtilityOskInitStart: invalid field data (%08x)", oskParams->fields.ptr);
return -1;
}
@ -211,26 +192,19 @@ int PSPOskDialog::Init(u32 oskPtr)
selectedChar = 0;
currentKeyboard = OSK_KEYBOARD_LATIN_LOWERCASE;
Memory::ReadStruct(oskParams->fieldPtr, &oskData);
ConvertUCS2ToUTF8(oskDesc, oskData.descPtr);
ConvertUCS2ToUTF8(oskIntext, oskData.intextPtr);
ConvertUCS2ToUTF8(oskOuttext, oskData.outtextPtr);
ConvertUCS2ToUTF8(oskDesc, oskParams->fields[0].desc);
ConvertUCS2ToUTF8(oskIntext, oskParams->fields[0].intext);
ConvertUCS2ToUTF8(oskOuttext, oskParams->fields[0].outtext);
i_level = 0;
inputChars = L"";
if (oskData.intextPtr) {
u16 *src = (u16 *) Memory::GetPointer(oskData.intextPtr);
if (oskParams->fields[0].intext.Valid()) {
auto src = oskParams->fields[0].intext;
int c;
while (c = *src++)
{
while ((c = *src++) != 0)
inputChars += c;
if(c == 0x00)
{
break;
}
}
}
// Eat any keys pressed before the dialog inited.
@ -307,10 +281,10 @@ std::wstring PSPOskDialog::CombinationKorean(bool isInput)
}
}
} else if(i_level == 2) {
u32 tmp = GetIndex(kor_vowel, sw);
int tmp = GetIndex(kor_vowel, sw);
if(tmp != -1) {
int tmp2 = -1;
for(int j = 0; j < sizeof(kor_vowelCom) / 4; j+=3) {
for(size_t 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;
@ -337,7 +311,7 @@ std::wstring PSPOskDialog::CombinationKorean(bool isInput)
}
}
} else {
u32 tmp = GetIndex(kor_lcons, sw);
int tmp = GetIndex(kor_lcons, sw);
if(tmp == -1) {
string += inputChars[i];
@ -367,10 +341,10 @@ std::wstring PSPOskDialog::CombinationKorean(bool isInput)
}
}
} else if(i_level == 3) {
u32 tmp = GetIndex(kor_lcons, sw);
int tmp = GetIndex(kor_lcons, sw);
if(tmp != -1) {
int tmp2 = -1;
for(int j = 0; j < sizeof(kor_lconsCom) / 4; j+=3) {
for(size_t 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;
@ -402,7 +376,7 @@ std::wstring PSPOskDialog::CombinationKorean(bool isInput)
}
}
} else {
u32 tmp = GetIndex(kor_vowel, sw);
int tmp = GetIndex(kor_vowel, sw);
if(tmp == -1) {
string += inputChars[i];
if (inputChars.size() < FieldMaxLength()) {
@ -422,9 +396,9 @@ std::wstring PSPOskDialog::CombinationKorean(bool isInput)
} else {
if (inputChars.size() < FieldMaxLength()) {
int tmp2 = -1;
for(int j = 0; j < sizeof(kor_lconsSpr) / 4; j+=3) {
for(size_t j = 0; j < sizeof(kor_lconsSpr) / 4; j+=3) {
if(kor_lconsSpr[j] == i_value[2]) {
tmp2 = j;
tmp2 = (int)j;
break;
}
}
@ -441,7 +415,7 @@ std::wstring PSPOskDialog::CombinationKorean(bool isInput)
i_level = 2;
}
} else {
u32 tmp2 = GetIndex(kor_cons, kor_lcons[i_value[2]]);
int tmp2 = GetIndex(kor_cons, kor_lcons[i_value[2]]);
if(tmp2 != -1) {
u16 code = 0xAC00 + i_value[0] * 0x24C + i_value[1] * 0x1C;
@ -583,7 +557,7 @@ void PSPOskDialog::RemoveKorean()
else if(i_level == 2)
{
int tmp = -1;
for(int i = 2; i < sizeof(kor_vowelCom) / 4; i+=3)
for(size_t i = 2; i < sizeof(kor_vowelCom) / 4; i+=3)
{
if(kor_vowelCom[i] == i_value[1])
{
@ -607,7 +581,7 @@ void PSPOskDialog::RemoveKorean()
else if(i_level == 3)
{
int tmp = -1;
for(int i = 2; i < sizeof(kor_lconsCom) / 4; i+=3)
for(size_t i = 2; i < sizeof(kor_lconsCom) / 4; i+=3)
{
if(kor_lconsCom[i] == i_value[2])
{
@ -631,9 +605,9 @@ void PSPOskDialog::RemoveKorean()
}
}
u32 PSPOskDialog::GetIndex(const wchar_t* src, wchar_t ch)
int PSPOskDialog::GetIndex(const wchar_t* src, wchar_t ch)
{
for(u32 i = 0; i < wcslen(src); i++)
for(int i = 0, end = (int)wcslen(src); i < end; i++)
{
if(src[i] == ch)
{
@ -646,9 +620,9 @@ u32 PSPOskDialog::GetIndex(const wchar_t* src, wchar_t ch)
u32 PSPOskDialog::FieldMaxLength()
{
if (oskData.outtextlimit > oskData.outtextlength - 1 || oskData.outtextlimit == 0)
return oskData.outtextlength - 1;
return oskData.outtextlimit;
if (oskParams->fields[0].outtextlimit > oskParams->fields[0].outtextlength - 1 || oskParams->fields[0].outtextlimit == 0)
return oskParams->fields[0].outtextlength - 1;
return oskParams->fields[0].outtextlimit;
}
void PSPOskDialog::RenderKeyboard()
@ -835,33 +809,21 @@ int PSPOskDialog::Update()
status = SCE_UTILITY_STATUS_SHUTDOWN;
}
for (u32 i = 0; i < oskData.outtextlength; ++i)
wchar_t *outText = oskParams->fields[0].outtext;
for (u32 i = 0, end = oskParams->fields[0].outtextlength; i < end; ++i)
{
u16 value = 0;
if (i < inputChars.size())
value = inputChars[i];
Memory::Write_U16(value, oskData.outtextPtr + (2 * i));
outText[i] = inputChars[i];
outText[i] = value;
}
oskParams->base.result = 0;
oskData.result = PSP_UTILITY_OSK_RESULT_CHANGED;
Memory::WriteStruct(oskParams->fieldPtr, &oskData);
oskParams->fields[0].result = PSP_UTILITY_OSK_RESULT_CHANGED;
return 0;
}
template <typename T>
static void DoBasePointer(PointerWrap &p, T **ptr)
{
u32 addr = *ptr == NULL ? 0 : (u8 *) *ptr - Memory::base;
p.Do(addr);
if (addr == 0)
*ptr = NULL;
else
*ptr = Memory::GetStruct<T>(addr);
}
int PSPOskDialog::Shutdown(bool force)
{
if (status != SCE_UTILITY_STATUS_FINISHED && !force)
@ -875,8 +837,7 @@ int PSPOskDialog::Shutdown(bool force)
void PSPOskDialog::DoState(PointerWrap &p)
{
PSPDialog::DoState(p);
DoBasePointer(p, &oskParams);
p.Do(oskData);
p.Do(oskParams);
p.Do(oskDesc);
p.Do(oskIntext);
p.Do(oskOuttext);

View File

@ -94,7 +94,7 @@ enum SceUtilityOskInputType
/**
* OSK Field data
*/
typedef struct _SceUtilityOskData
struct SceUtilityOskData
{
/** Unknown. Pass 0. */
int unk_00;
@ -111,19 +111,18 @@ typedef struct _SceUtilityOskData
/** Unknown. Pass 0. */
int unk_24;
/** Description text */
u32 descPtr;
PSPPointer<wchar_t> desc;
/** Initial text */
u32 intextPtr;
PSPPointer<wchar_t> intext;
// Length, in unsigned shorts, including the terminator.
u32 outtextlength;
/** Pointer to the output text */
u32 outtextPtr;
PSPPointer<wchar_t> outtext;
/** Result. One of ::SceUtilityOskResult */
int result;
// Number of characters to allow, not including terminator (if less than outtextlength - 1.)
u32 outtextlimit;
} SceUtilityOskData;
};
// Parameters to sceUtilityOskInitStart
struct SceUtilityOskParams
@ -132,7 +131,7 @@ struct SceUtilityOskParams
// Number of fields.
int fieldCount;
// Pointer to an array of fields (see SceUtilityOskData.)
u32 fieldPtr;
PSPPointer<SceUtilityOskData> fields;
SceUtilityOskState state;
// Maybe just padding?
int unk_60;
@ -164,7 +163,7 @@ public:
virtual int Shutdown(bool force = false);
virtual void DoState(PointerWrap &p);
private:
void ConvertUCS2ToUTF8(std::string& _string, const u32 em_address);
void ConvertUCS2ToUTF8(std::string& _string, const PSPPointer<wchar_t> em_address);
void ConvertUCS2ToUTF8(std::string& _string, wchar_t* input);
void RenderKeyboard();
@ -173,10 +172,9 @@ private:
void RemoveKorean(); // for Korean character removal
u32 FieldMaxLength();
u32 GetIndex(const wchar_t* src, wchar_t ch);
int GetIndex(const wchar_t* src, wchar_t ch);
SceUtilityOskParams *oskParams;
SceUtilityOskData oskData;
PSPPointer<SceUtilityOskParams> oskParams;
std::string oskDesc;
std::string oskIntext;
std::string oskOuttext;

View File

@ -844,13 +844,13 @@ int SavedataParam::GetFilesList(SceUtilitySavedataParam *param)
return SCE_UTILITY_SAVEDATA_ERROR_RW_BAD_STATUS;
}
if (!Memory::IsValidAddress(param->fileListAddr)) {
ERROR_LOG_REPORT(HLE, "SavedataParam::GetFilesList(): bad fileList address %08x", param->fileListAddr);
if (!param->fileList.Valid()) {
ERROR_LOG_REPORT(HLE, "SavedataParam::GetFilesList(): bad fileList address %08x", param->fileList.ptr);
// Should crash.
return -1;
}
auto fileList = Memory::GetStruct<SceUtilitySavedataFileListInfo>(param->fileListAddr);
auto &fileList = param->fileList;
if (fileList->secureEntries.Valid() && fileList->maxSecureEntries > 99) {
ERROR_LOG_REPORT(HLE, "SavedataParam::GetFilesList(): too many secure entries, %d", fileList->maxSecureEntries);
return SCE_UTILITY_SAVEDATA_ERROR_RW_BAD_PARAMS;

View File

@ -186,7 +186,7 @@ struct SceUtilitySavedataParam
u32 idListAddr;
// Function 12 FILES
u32 fileListAddr;
PSPPointer<SceUtilitySavedataFileListInfo> fileList;
// Function 22 GETSIZES
u32 sizeAddr;

View File

@ -82,22 +82,6 @@ struct Mutex : public KernelObject
};
struct NativeLwMutex
{
SceSize size;
char name[KERNELOBJECT_MAX_NAME_LENGTH + 1];
SceUInt attr;
SceUID uid;
u32 workareaPtr;
int initialCount;
// Not kept up to date.
int currentCount;
// Not kept up to date.
SceUID lockThread;
// Not kept up to date.
int numWaitThreads;
};
struct NativeLwMutexWorkarea
{
int lockLevel;
@ -120,6 +104,22 @@ struct NativeLwMutexWorkarea
}
};
struct NativeLwMutex
{
SceSize size;
char name[KERNELOBJECT_MAX_NAME_LENGTH + 1];
SceUInt attr;
SceUID uid;
PSPPointer<NativeLwMutexWorkarea> workarea;
int initialCount;
// Not kept up to date.
int currentCount;
// Not kept up to date.
SceUID lockThread;
// Not kept up to date.
int numWaitThreads;
};
struct LwMutex : public KernelObject
{
const char *GetName() {return nm.name;}
@ -732,7 +732,7 @@ int sceKernelCreateLwMutex(u32 workareaPtr, const char *name, u32 attr, int init
mutex->nm.name[KERNELOBJECT_MAX_NAME_LENGTH] = 0;
mutex->nm.attr = attr;
mutex->nm.uid = id;
mutex->nm.workareaPtr = workareaPtr;
mutex->nm.workarea = workareaPtr;
mutex->nm.initialCount = initialCount;
auto workarea = Memory::GetStruct<NativeLwMutexWorkarea>(workareaPtr);
workarea->init();
@ -990,8 +990,7 @@ void __KernelLwMutexEndCallback(SceUID threadID, SceUID prevCallbackId, u32 &ret
// TODO: Don't wake up if __KernelCurHasReadyCallbacks()?
// Attempt to unlock.
auto workarea = Memory::GetStruct<NativeLwMutexWorkarea>(mutex->nm.workareaPtr);
if (mutex->nm.lockThread == -1 && __KernelUnlockLwMutexForThread(mutex, workarea, threadID, error, 0))
if (mutex->nm.lockThread == -1 && __KernelUnlockLwMutexForThread(mutex, mutex->nm.workarea, threadID, error, 0))
return;
// We only check if it timed out if it couldn't unlock.
@ -1150,7 +1149,7 @@ int __KernelReferLwMutexStatus(SceUID uid, u32 infoPtr)
if (Memory::Read_U32(infoPtr) != 0)
{
auto workarea = Memory::GetStruct<NativeLwMutexWorkarea>(m->nm.workareaPtr);
auto workarea = m->nm.workarea;
u32 error;
for (auto iter = m->waitingThreads.begin(); iter != m->waitingThreads.end(); ++iter)

View File

@ -269,17 +269,82 @@ struct PSPPointer
{
u32 ptr;
T &operator*() const
inline T &operator*() const
{
return *(T *)(Memory::base + ptr);
}
T &operator[](int i) const
inline T &operator[](int i) const
{
return *((T *)(Memory::base + ptr) + i);
}
T *operator->() const
inline T *operator->() const
{
return (T *)(Memory::base + ptr);
}
inline PSPPointer<T> operator+(int i) const
{
PSPPointer other;
other.ptr = ptr + i * sizeof(T);
return other;
}
inline PSPPointer<T> &operator=(u32 p)
{
ptr = p;
return *this;
}
inline PSPPointer<T> &operator+=(int i)
{
ptr = ptr + i * sizeof(T);
return *this;
}
inline PSPPointer<T> operator-(int i) const
{
PSPPointer other;
other.ptr = ptr - i * sizeof(T);
return other;
}
inline PSPPointer<T> &operator-=(int i)
{
ptr = ptr - i * sizeof(T);
return *this;
}
inline PSPPointer<T> &operator++()
{
ptr += sizeof(T);
return *this;
}
inline PSPPointer<T> operator++(int i)
{
PSPPointer<T> other;
other.ptr = ptr;
ptr += sizeof(T);
return other;
}
inline PSPPointer<T> &operator--()
{
ptr -= sizeof(T);
return *this;
}
inline PSPPointer<T> operator--(int i)
{
PSPPointer<T> other;
other.ptr = ptr;
ptr -= sizeof(T);
return other;
}
inline operator T*()
{
return (T *)(Memory::base + ptr);
}
@ -290,5 +355,41 @@ struct PSPPointer
}
};
template <typename T>
inline bool operator==(const PSPPointer<T> &lhs, const PSPPointer<T> &rhs)
{
return lhs.ptr == rhs.ptr;
}
template <typename T>
inline bool operator!=(const PSPPointer<T> &lhs, const PSPPointer<T> &rhs)
{
return lhs.ptr != rhs.ptr;
}
template <typename T>
inline bool operator<(const PSPPointer<T> &lhs, const PSPPointer<T> &rhs)
{
return lhs.ptr < rhs.ptr;
}
template <typename T>
inline bool operator>(const PSPPointer<T> &lhs, const PSPPointer<T> &rhs)
{
return lhs.ptr > rhs.ptr;
}
template <typename T>
inline bool operator<=(const PSPPointer<T> &lhs, const PSPPointer<T> &rhs)
{
return lhs.ptr <= rhs.ptr;
}
template <typename T>
inline bool operator>=(const PSPPointer<T> &lhs, const PSPPointer<T> &rhs)
{
return lhs.ptr >= rhs.ptr;
}
#endif