int cellGameBootCheck(mem32_t type, mem32_t attributes, mem_ptr_t<CellGameContentSize> size, mem_list_ptr_t<u8> dirName) { cellGame.Warning("cellGameBootCheck(type_addr=0x%x, attributes_addr=0x%x, size_addr=0x%x, dirName_addr=0x%x)", type.GetAddr(), attributes.GetAddr(), size.GetAddr(), dirName.GetAddr()); if (!type.IsGood() || !attributes.IsGood() || !size.IsGood() || !dirName.IsGood()) { cellGame.Warning("cellGameBootCheck returns CELL_GAME_ERROR_PARAM. As a result size->hddFreeSizeKB may be 0."); return CELL_GAME_ERROR_PARAM; } // TODO: Only works for HDD games type = CELL_GAME_GAMETYPE_HDD; attributes = 0; size->hddFreeSizeKB = 40000000; //40 GB, TODO: Use the free space of the computer's HDD where RPCS3 is being run. size->sizeKB = CELL_GAME_SIZEKB_NOTCALC; size->sysSizeKB = 0; // TODO: Locate the PARAM.SFO. The following path may be wrong. vfsFile f("/app_home/PARAM.SFO"); PSFLoader psf(f); if(!psf.Load(false)) return CELL_GAME_ERROR_FAILURE; std::string titleId = psf.GetString("TITLE_ID"); Memory.WriteString(dirName.GetAddr(), titleId); return CELL_OK; }
int cellSysutilGetSystemParamString(s32 id, mem_list_ptr_t<u8> buf, u32 bufsize) { cellSysutil.Log("cellSysutilGetSystemParamString(id=%d, buf_addr=0x%x, bufsize=%d)", id, buf.GetAddr(), bufsize); if (!buf.IsGood()) return CELL_EFAULT; memset(buf, 0, bufsize); switch(id) { case CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME: cellSysutil.Warning("cellSysutilGetSystemParamString: CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME"); memcpy(buf, "Unknown", 8); //for example break; case CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME: cellSysutil.Warning("cellSysutilGetSystemParamString: CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME"); memcpy(buf, "Unknown", 8); break; default: return CELL_EINVAL; } return CELL_OK; }
int cellGameGetParamString(u32 id, mem_list_ptr_t<u8> buf, u32 bufsize) { cellGame.Warning("cellGameGetParamString(id=%d, buf_addr=0x%x, bufsize=%d)", id, buf.GetAddr(), bufsize); if(!buf.IsGood()) return CELL_GAME_ERROR_PARAM; // TODO: Locate the PARAM.SFO. The following path is in most cases wrong. vfsFile f("/app_home/PARAM.SFO"); PSFLoader psf(f); if(!psf.Load(false)) return CELL_GAME_ERROR_FAILURE; switch(id) { // WARNING: Is there any difference between all these "CELL_GAME_PARAMID_TITLE*" IDs? case CELL_GAME_PARAMID_TITLE: case CELL_GAME_PARAMID_TITLE_DEFAULT: case CELL_GAME_PARAMID_TITLE_JAPANESE: case CELL_GAME_PARAMID_TITLE_ENGLISH: case CELL_GAME_PARAMID_TITLE_FRENCH: case CELL_GAME_PARAMID_TITLE_SPANISH: case CELL_GAME_PARAMID_TITLE_GERMAN: case CELL_GAME_PARAMID_TITLE_ITALIAN: case CELL_GAME_PARAMID_TITLE_DUTCH: case CELL_GAME_PARAMID_TITLE_PORTUGUESE: case CELL_GAME_PARAMID_TITLE_RUSSIAN: case CELL_GAME_PARAMID_TITLE_KOREAN: case CELL_GAME_PARAMID_TITLE_CHINESE_T: case CELL_GAME_PARAMID_TITLE_CHINESE_S: case CELL_GAME_PARAMID_TITLE_FINNISH: case CELL_GAME_PARAMID_TITLE_SWEDISH: case CELL_GAME_PARAMID_TITLE_DANISH: case CELL_GAME_PARAMID_TITLE_NORWEGIAN: case CELL_GAME_PARAMID_TITLE_POLISH: case CELL_GAME_PARAMID_TITLE_PORTUGUESE_BRAZIL: case CELL_GAME_PARAMID_TITLE_ENGLISH_UK: Memory.WriteString(buf.GetAddr(), psf.m_info.name.Left(bufsize)); break; case CELL_GAME_PARAMID_TITLE_ID: Memory.WriteString(buf.GetAddr(), psf.m_info.serial.Left(bufsize)); break; case CELL_GAME_PARAMID_VERSION: Memory.WriteString(buf.GetAddr(), psf.m_info.fw.Left(bufsize)); break; case CELL_GAME_PARAMID_APP_VER: Memory.WriteString(buf.GetAddr(), psf.m_info.app_ver.Left(bufsize)); break; default: return CELL_GAME_ERROR_INVALID_ID; } return CELL_OK; }
int cellGameContentPermit(mem_list_ptr_t<u8> contentInfoPath, mem_list_ptr_t<u8> usrdirPath) { cellGame.Warning("cellGameContentPermit(contentInfoPath_addr=0x%x, usrdirPath_addr=0x%x)", contentInfoPath.GetAddr(), usrdirPath.GetAddr()); if (!contentInfoPath.IsGood() || !usrdirPath.IsGood()) return CELL_GAME_ERROR_PARAM; // TODO: Locate the PARAM.SFO. The following path may be wrong. vfsFile f("/app_home/PARAM.SFO"); PSFLoader psf(f); if(!psf.Load(false)) return CELL_GAME_ERROR_FAILURE; std::string titleId = psf.GetString("TITLE_ID"); // TODO: Only works for HDD games Memory.WriteString(contentInfoPath.GetAddr(), "/dev_hdd0/game/"+titleId); Memory.WriteString(usrdirPath.GetAddr(), "/dev_hdd0/game/"+titleId+"/USRDIR"); return CELL_OK; }
int cellGameBootCheck(mem32_t type, mem32_t attributes, mem_ptr_t<CellGameContentSize> size, mem_list_ptr_t<u8> dirName) { cellGame.Warning("cellGameBootCheck(type_addr=0x%x, attributes_addr=0x%x, size_addr=0x%x, dirName_addr=0x%x)", type.GetAddr(), attributes.GetAddr(), size.GetAddr(), dirName.GetAddr()); if (!type.IsGood() || !attributes.IsGood() || !size.IsGood() || !dirName.IsGood()) return CELL_GAME_ERROR_PARAM; type = CELL_GAME_GAMETYPE_DISC; attributes = 0; size->hddFreeSizeKB = 40000000; //40 GB, TODO: Use the free space of the computer's HDD where RPCS3 is being run. size->sizeKB = CELL_GAME_SIZEKB_NOTCALC; size->sysSizeKB = 0; //TODO: dirName return CELL_OK; }
int cellMsgDialogProgressBarSetMsg(u32 progressBarIndex, mem_list_ptr_t<u8> msgString) { if (!msgString.IsGood()) { cellSysutil->Error("cellMsgDialogProgressBarSetMsg(progressBarIndex=%d, msgString_addr=0x%x): CELL_EFAULT", progressBarIndex, msgString.GetAddr()); return CELL_EFAULT; } cellSysutil->Warning("cellMsgDialogProgressBarSetMsg(progressBarIndex=%d, msgString_addr=0x%x): '%s'", progressBarIndex, msgString.GetAddr(), msgString.GetString()); if (g_msg_dialog_state != msgDialogOpen) { return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED; } if (progressBarIndex >= (u32)(bool)m_gauge1 + (u32)(bool)m_gauge2) { return CELL_MSGDIALOG_ERROR_PARAM; } std::string text(msgString.GetString()); wxGetApp().CallAfter([text, progressBarIndex]() { if (g_msg_dialog && !Emu.IsStopped()) { if (progressBarIndex == 0 && m_text1) m_text1->SetLabelText(fmt::FromUTF8(text)); if (progressBarIndex == 1 && m_text2) m_text2->SetLabelText(fmt::FromUTF8(text)); g_msg_dialog->Layout(); g_msg_dialog->Fit(); } }); return CELL_OK; }
int cellMsgDialogOpen2(u32 type, mem_list_ptr_t<u8> msgString, mem_func_ptr_t<CellMsgDialogCallback> callback, u32 userData, u32 extParam) { cellSysutil->Warning("cellMsgDialogOpen2(type=0x%x, msgString_addr=0x%x, callback_addr=0x%x, userData=0x%x, extParam=0x%x)", type, msgString.GetAddr(), callback.GetAddr(), userData, extParam); if (!msgString.IsGood() || !callback.IsGood()) { return CELL_EFAULT; } //type |= CELL_MSGDIALOG_TYPE_PROGRESSBAR_SINGLE; //type |= CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO; MsgDialogState old = msgDialogNone; if (!g_msg_dialog_state.compare_exchange_strong(old, msgDialogOpen)) { return CELL_SYSUTIL_ERROR_BUSY; } thread t("MsgDialog thread", [=]() { switch (type & CELL_MSGDIALOG_TYPE_SE_TYPE) { case CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL: LOG_WARNING(Log::HLE, "%s", msgString.GetString()); break; case CELL_MSGDIALOG_TYPE_SE_TYPE_ERROR: LOG_ERROR(Log::HLE, "%s", msgString.GetString()); break; } switch (type & CELL_MSGDIALOG_TYPE_SE_MUTE) // TODO { case CELL_MSGDIALOG_TYPE_SE_MUTE_OFF: break; case CELL_MSGDIALOG_TYPE_SE_MUTE_ON: break; } switch (type & CELL_MSGDIALOG_TYPE_BG) // TODO { case CELL_MSGDIALOG_TYPE_BG_INVISIBLE: break; case CELL_MSGDIALOG_TYPE_BG_VISIBLE: break; } switch (type & CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR) // TODO { case CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR_NO: break; default: break; } u64 status = CELL_MSGDIALOG_BUTTON_NONE; volatile bool m_signal = false; wxGetApp().CallAfter([&]() { wxWindow* parent = nullptr; // TODO: align it better m_gauge1 = nullptr; m_gauge2 = nullptr; m_text1 = nullptr; m_text2 = nullptr; wxButton* m_button_ok = nullptr; wxButton* m_button_yes = nullptr; wxButton* m_button_no = nullptr; g_msg_dialog = new wxDialog(parent, wxID_ANY, type & CELL_MSGDIALOG_TYPE_SE_TYPE ? "" : "Error", wxDefaultPosition, wxDefaultSize); g_msg_dialog->SetExtraStyle(g_msg_dialog->GetExtraStyle() | wxWS_EX_TRANSIENT); wxSizer* sizer1 = new wxBoxSizer(wxVERTICAL); wxStaticText* m_text = new wxStaticText(g_msg_dialog, wxID_ANY, wxString(msgString.GetString(), wxConvUTF8)); sizer1->Add(m_text, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 16); switch (type & CELL_MSGDIALOG_TYPE_PROGRESSBAR) { case CELL_MSGDIALOG_TYPE_PROGRESSBAR_DOUBLE: m_gauge2 = new wxGauge(g_msg_dialog, wxID_ANY, 100, wxDefaultPosition, wxSize(300, -1), wxGA_HORIZONTAL | wxGA_SMOOTH); m_text2 = new wxStaticText(g_msg_dialog, wxID_ANY, ""); m_text2->SetAutoLayout(true); case CELL_MSGDIALOG_TYPE_PROGRESSBAR_SINGLE: m_gauge1 = new wxGauge(g_msg_dialog, wxID_ANY, 100, wxDefaultPosition, wxSize(300, -1), wxGA_HORIZONTAL | wxGA_SMOOTH); m_text1 = new wxStaticText(g_msg_dialog, wxID_ANY, ""); m_text1->SetAutoLayout(true); case CELL_MSGDIALOG_TYPE_PROGRESSBAR_NONE: break; } if (m_gauge1) { sizer1->Add(m_text1, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 8); sizer1->Add(m_gauge1, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT, 16); m_gauge1->SetValue(0); } if (m_gauge2) { sizer1->Add(m_text2, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 8); sizer1->Add(m_gauge2, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT, 16); m_gauge2->SetValue(0); } wxBoxSizer* buttons = new wxBoxSizer(wxHORIZONTAL); switch (type & CELL_MSGDIALOG_TYPE_BUTTON_TYPE) { case CELL_MSGDIALOG_TYPE_BUTTON_TYPE_NONE: break; case CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO: m_button_yes = new wxButton(g_msg_dialog, wxID_YES); buttons->Add(m_button_yes, 0, wxALIGN_CENTER_HORIZONTAL | wxRIGHT, 8); m_button_no = new wxButton(g_msg_dialog, wxID_NO); buttons->Add(m_button_no, 0, wxALIGN_CENTER_HORIZONTAL, 16); sizer1->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 16); break; case CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK: m_button_ok = new wxButton(g_msg_dialog, wxID_OK); buttons->Add(m_button_ok, 0, wxALIGN_CENTER_HORIZONTAL, 16); sizer1->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 16); break; } sizer1->AddSpacer(16); g_msg_dialog->SetSizerAndFit(sizer1); g_msg_dialog->Centre(wxBOTH); g_msg_dialog->Show(); g_msg_dialog->Enable(); g_msg_dialog->Bind(wxEVT_BUTTON, [&](wxCommandEvent& event) { status = (event.GetId() == wxID_NO) ? CELL_MSGDIALOG_BUTTON_NO : CELL_MSGDIALOG_BUTTON_YES /* OK */; g_msg_dialog->Hide(); m_wait_until = get_system_time(); g_msg_dialog_state = msgDialogClose; }); g_msg_dialog->Bind(wxEVT_CLOSE_WINDOW, [&](wxCloseEvent& event) { if (type & CELL_MSGDIALOG_TYPE_DISABLE_CANCEL) { } else { status = CELL_MSGDIALOG_BUTTON_ESCAPE; g_msg_dialog->Hide(); m_wait_until = get_system_time(); g_msg_dialog_state = msgDialogClose; } }); m_signal = true; }); while (!m_signal) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); } while (g_msg_dialog_state == msgDialogOpen || get_system_time() < m_wait_until) { if (Emu.IsStopped()) { g_msg_dialog_state = msgDialogAbort; break; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); } if (callback && (g_msg_dialog_state != msgDialogAbort)) callback.async(status, userData); wxGetApp().CallAfter([&]() { delete g_msg_dialog; g_msg_dialog = nullptr; }); g_msg_dialog_state = msgDialogNone; }); t.detach(); return CELL_OK; }