Merge pull request #434 from Xele02/master

PSPMsgDialog return value
This commit is contained in:
Henrik Rydgård 2013-01-17 14:47:13 -08:00
commit 53b0a87de3
2 changed files with 153 additions and 122 deletions

View File

@ -22,7 +22,7 @@
PSPMsgDialog::PSPMsgDialog()
: PSPDialog()
, display(DS_NONE)
, flag(0)
{
}
@ -42,7 +42,10 @@ int PSPMsgDialog::Init(unsigned int paramAddr)
{
return 0;
}
Memory::ReadStruct(messageDialogAddr, &messageDialog);
int size = Memory::Read_U32(paramAddr);
memset(&messageDialog,0,sizeof(messageDialog));
// Only copy the right size to support different request format
Memory::Memcpy(&messageDialog,paramAddr,size);
// debug info
int optionsNotCoded = ((messageDialog.options | SCE_UTILITY_MSGDIALOG_DEBUG_OPTION_CODED) ^ SCE_UTILITY_MSGDIALOG_DEBUG_OPTION_CODED);
@ -51,22 +54,68 @@ int PSPMsgDialog::Init(unsigned int paramAddr)
ERROR_LOG(HLE,"PSPMsgDialog options not coded : 0x%08x",optionsNotCoded);
}
yesnoChoice = 1;
if (messageDialog.type == 0) // number
flag = 0;
// Check request invalidity
if(messageDialog.type == 0 && !(messageDialog.errorNum & 0x80000000))
{
INFO_LOG(HLE, "MsgDialog: %08x", messageDialog.errorNum);
display = DS_ERROR;
flag |= DS_ERROR;
messageDialog.result = SCE_UTILITY_MSGDIALOG_ERROR_ERRORCODEINVALID;
}
else
else if(size == SCE_UTILITY_MSGDIALOG_SIZE_V2 && messageDialog.type == 1)
{
INFO_LOG(HLE, "MsgDialog: %s", messageDialog.string);
display = DS_MESSAGE;
if(messageDialog.options & SCE_UTILITY_MSGDIALOG_OPTION_YESNO)
display = DS_YESNO;
if(messageDialog.options & SCE_UTILITY_MSGDIALOG_OPTION_OK)
display = DS_OK;
unsigned int validOp = SCE_UTILITY_MSGDIALOG_OPTION_TEXT |
SCE_UTILITY_MSGDIALOG_OPTION_YESNO |
SCE_UTILITY_MSGDIALOG_OPTION_DEFAULT_NO;
if((messageDialog.options | validOp) ^ validOp)
{
flag |= DS_ERROR;
messageDialog.result = SCE_UTILITY_MSGDIALOG_ERROR_BADOPTION;
}
}
else if(size == SCE_UTILITY_MSGDIALOG_SIZE_V3)
{
if((messageDialog.options & SCE_UTILITY_MSGDIALOG_OPTION_DEFAULT_NO) &&
!(messageDialog.options & SCE_UTILITY_MSGDIALOG_OPTION_YESNO))
{
flag |= DS_ERROR;
messageDialog.result = SCE_UTILITY_MSGDIALOG_ERROR_BADOPTION;
}
}
if(flag == 0)
{
yesnoChoice = 1;
if(messageDialog.type == 1)
flag |= DS_MSG;
if(messageDialog.type == 0)
flag |= DS_ERRORMSG;
if((messageDialog.options & SCE_UTILITY_MSGDIALOG_OPTION_YESNO) &&
((size == SCE_UTILITY_MSGDIALOG_SIZE_V3) ||
(size == SCE_UTILITY_MSGDIALOG_SIZE_V2 && messageDialog.type == 1)))
flag |= DS_YESNO;
if(messageDialog.options & SCE_UTILITY_MSGDIALOG_OPTION_DEFAULT_NO)
{
yesnoChoice = 0;
flag |= DS_DEFNO;
}
if((messageDialog.options & SCE_UTILITY_MSGDIALOG_OPTION_OK) && (size == SCE_UTILITY_MSGDIALOG_SIZE_V3))
{
yesnoChoice = 1;
flag |= DS_OK;
}
if((flag & DS_YESNO) || (flag & DS_OK))
flag |= DS_VALIDBUTTON;
if(!((messageDialog.options & SCE_UTILITY_MSGDIALOG_OPTION_NOCANCEL) && (size == SCE_UTILITY_MSGDIALOG_SIZE_V3)))
flag |= DS_CANCELBUTTON;
if(messageDialog.options & SCE_UTILITY_MSGDIALOG_OPTION_NOSOUND)
flag |= DS_NOSOUND;
}
if (flag & DS_ERRORMSG) {
snprintf(msgText, 512, "Error code: %08x", messageDialog.errorNum);
} else {
strncpy(msgText, messageDialog.string, 512);
}
status = SCE_UTILITY_STATUS_INITIALIZE;
@ -77,8 +126,8 @@ int PSPMsgDialog::Init(unsigned int paramAddr)
void PSPMsgDialog::DisplayBack()
{
PPGeDrawImage(cancelButtonImg, 250, 220, 20, 20, 0, 0xFFFFFFFF);
PPGeDrawText("Back", 270, 220, PPGE_ALIGN_LEFT, 0.5f, 0xFFFFFFFF);
PPGeDrawImage(cancelButtonImg, 290, 220, 20, 20, 0, 0xFFFFFFFF);
PPGeDrawText("Back", 320, 220, PPGE_ALIGN_LEFT, 0.5f, 0xFFFFFFFF);
}
void PSPMsgDialog::DisplayYesNo()
@ -96,12 +145,16 @@ void PSPMsgDialog::DisplayYesNo()
yesnoChoice = 0;
}
}
void PSPMsgDialog::DisplayEnterBack()
void PSPMsgDialog::DisplayOk()
{
PPGeDrawText("OK", 250, 150, PPGE_ALIGN_LEFT, 0.5f, 0xFF0000FF);
}
void PSPMsgDialog::DisplayEnter()
{
PPGeDrawImage(okButtonImg, 200, 220, 20, 20, 0, 0xFFFFFFFF);
PPGeDrawText("Enter", 230, 220, PPGE_ALIGN_LEFT, 0.5f, 0xFFFFFFFF);
PPGeDrawImage(cancelButtonImg, 290, 220, 20, 20, 0, 0xFFFFFFFF);
PPGeDrawText("Back", 320, 220, PPGE_ALIGN_LEFT, 0.5f, 0xFFFFFFFF);
}
int PSPMsgDialog::Update()
@ -117,115 +170,74 @@ int PSPMsgDialog::Update()
return 0;
}
const char *text;
if (messageDialog.type == 0) {
char temp[256];
sprintf(temp, "Error code: %08x", messageDialog.errorNum);
text = temp;
} else {
text = messageDialog.string;
}
buttons = __CtrlPeekButtons();
okButtonImg = I_CIRCLE;
cancelButtonImg = I_CROSS;
okButtonFlag = CTRL_CIRCLE;
cancelButtonFlag = CTRL_CROSS;
if(messageDialog.common.buttonSwap == 1)
if((flag & DS_ERROR))
{
okButtonImg = I_CROSS;
cancelButtonImg = I_CIRCLE;
okButtonFlag = CTRL_CROSS;
cancelButtonFlag = CTRL_CIRCLE;
status = SCE_UTILITY_STATUS_FINISHED;
}
switch(display)
else
{
case DS_MESSAGE:
StartDraw();
buttons = __CtrlPeekButtons();
DisplayMessage(text);
okButtonImg = I_CIRCLE;
cancelButtonImg = I_CROSS;
okButtonFlag = CTRL_CIRCLE;
cancelButtonFlag = CTRL_CROSS;
if(messageDialog.common.buttonSwap == 1)
{
okButtonImg = I_CROSS;
cancelButtonImg = I_CIRCLE;
okButtonFlag = CTRL_CROSS;
cancelButtonFlag = CTRL_CIRCLE;
}
// TODO : Dialogs should take control over input and not send them to the game while displaying
DisplayBack();
if (IsButtonPressed(cancelButtonFlag))
{
status = SCE_UTILITY_STATUS_FINISHED;
messageDialog.buttonPressed = 0;
}
EndDraw();
break;
case DS_ERROR:
StartDraw();
StartDraw();
DisplayMessage(text);
if((flag & DS_MSG) || (flag & DS_ERRORMSG))
DisplayMessage(msgText);
// TODO : Dialogs should take control over input and not send them to the game while displaying
DisplayBack();
if (IsButtonPressed(cancelButtonFlag))
{
status = SCE_UTILITY_STATUS_FINISHED;
messageDialog.buttonPressed = 3;
}
EndDraw();
break;
case DS_YESNO:
StartDraw();
DisplayMessage(text);
if(flag & DS_YESNO)
DisplayYesNo();
if(flag & DS_OK)
DisplayOk();
// TODO : Dialogs should take control over input and not send them to the game while displaying
DisplayEnterBack();
if (IsButtonPressed(cancelButtonFlag))
if(flag & DS_VALIDBUTTON)
DisplayEnter();
if(flag & DS_CANCELBUTTON)
DisplayBack();
// TODO : Dialogs should take control over input and not send them to the game while displaying
if (IsButtonPressed(cancelButtonFlag) && (flag & DS_CANCELBUTTON))
{
status = SCE_UTILITY_STATUS_FINISHED;
if(messageDialog.common.size == SCE_UTILITY_MSGDIALOG_SIZE_V3 ||
((messageDialog.common.size == SCE_UTILITY_MSGDIALOG_SIZE_V2) && (flag & DS_YESNO)))
messageDialog.buttonPressed = 3;
else
messageDialog.buttonPressed = 0;
}
else if(IsButtonPressed(okButtonFlag) && (flag & DS_VALIDBUTTON))
{
status = SCE_UTILITY_STATUS_FINISHED;
if(yesnoChoice == 0)
{
status = SCE_UTILITY_STATUS_FINISHED;
messageDialog.buttonPressed = 3;
messageDialog.buttonPressed = 2;
}
else if (IsButtonPressed(okButtonFlag))
{
if(yesnoChoice == 0)
{
status = SCE_UTILITY_STATUS_FINISHED;
messageDialog.buttonPressed = 2;
}
else
{
status = SCE_UTILITY_STATUS_FINISHED;
messageDialog.buttonPressed = 1;
}
}
EndDraw();
break;
case DS_OK:
StartDraw();
DisplayMessage(text);
// TODO : Dialogs should take control over input and not send them to the game while displaying
DisplayEnterBack();
if (IsButtonPressed(cancelButtonFlag))
{
status = SCE_UTILITY_STATUS_FINISHED;
messageDialog.buttonPressed = 3;
}
else if (IsButtonPressed(okButtonFlag))
else
{
status = SCE_UTILITY_STATUS_FINISHED;
messageDialog.buttonPressed = 1;
}
EndDraw();
break;
default:
status = SCE_UTILITY_STATUS_FINISHED;
return 0;
break;
}
EndDraw();
lastButtons = buttons;
}
lastButtons = buttons;
Memory::WriteStruct(messageDialogAddr, &messageDialog);
Memory::Memcpy(messageDialogAddr,&messageDialog,messageDialog.common.size);
return 0;
}
@ -237,9 +249,10 @@ int PSPMsgDialog::Shutdown()
void PSPMsgDialog::DoState(PointerWrap &p)
{
PSPDialog::DoState(p);
p.Do(display);
p.Do(flag);
p.Do(messageDialog);
p.Do(messageDialogAddr);
p.Do(msgText);
p.Do(yesnoChoice);
p.Do(okButtonImg);
p.Do(cancelButtonImg);

View File

@ -19,13 +19,22 @@
#include "PSPDialog.h"
#define SCE_UTILITY_MSGDIALOG_OPTION_ERROR 0 // Do nothing
#define SCE_UTILITY_MSGDIALOG_OPTION_ERROR 0x00000000
#define SCE_UTILITY_MSGDIALOG_OPTION_TEXT 0x00000001
#define SCE_UTILITY_MSGDIALOG_OPTION_NOSOUND 0x00000002
#define SCE_UTILITY_MSGDIALOG_OPTION_YESNO 0x00000010
#define SCE_UTILITY_MSGDIALOG_OPTION_OK 0x00000020
#define SCE_UTILITY_MSGDIALOG_OPTION_NOCANCEL 0x00000080
#define SCE_UTILITY_MSGDIALOG_OPTION_DEFAULT_NO 0x00000100
#define SCE_UTILITY_MSGDIALOG_DEBUG_OPTION_CODED 0x00000131 // OR of all options coded to display warning
#define SCE_UTILITY_MSGDIALOG_SIZE_V1 572
#define SCE_UTILITY_MSGDIALOG_SIZE_V2 580
#define SCE_UTILITY_MSGDIALOG_SIZE_V3 708
#define SCE_UTILITY_MSGDIALOG_DEBUG_OPTION_CODED 0x000001B3 // OR of all options coded to display warning
#define SCE_UTILITY_MSGDIALOG_ERROR_BADOPTION 0x80110501
#define SCE_UTILITY_MSGDIALOG_ERROR_ERRORCODEINVALID 0x80110502
struct pspMessageDialog
{
@ -34,8 +43,12 @@ struct pspMessageDialog
int type;
unsigned int errorNum;
char string[512];
// End of request V1 (Size 572)
unsigned int options;
unsigned int buttonPressed; // 0=?, 1=Yes/OK, 2=No, 3=Back
unsigned int buttonPressed;
// End of request V2 (Size 580)
int unknown[32];
// End of request V3 (Size 708)
};
@ -52,23 +65,28 @@ public:
private :
void DisplayBack();
void DisplayYesNo();
void DisplayEnterBack();
void DisplayEnter();
void DisplayOk();
enum DisplayState
enum Flags
{
DS_NONE,
DS_MESSAGE,
DS_ERROR,
DS_YESNO,
DS_OK
DS_MSG = 0x1,
DS_ERRORMSG = 0x2,
DS_YESNO = 0x4,
DS_DEFNO = 0x8,
DS_OK = 0x10,
DS_VALIDBUTTON = 0x20,
DS_CANCELBUTTON = 0x40,
DS_NOSOUND = 0x80,
DS_ERROR = 0x100
};
DisplayState display;
u32 flag;
pspMessageDialog messageDialog;
int messageDialogAddr;
char msgText[512];
int yesnoChoice;
int okButtonImg;