Ejemplo n.º 1
0
void fsAioRead(u32 fd, mem_ptr_t<CellFsAio> aio, int xid, mem_func_ptr_t<void (*)(mem_ptr_t<CellFsAio> xaio, int error, int xid, u64 size)> func)
{
	while (g_FsAioReadCur != xid)
	{
		std::this_thread::sleep_for(std::chrono::milliseconds(1));
		if (Emu.IsStopped())
		{
			LOG_WARNING(HLE, "fsAioRead() aborted");
			return;
		}
	}

	vfsFileBase* orig_file;
	if(!sys_fs->CheckId(fd, orig_file)) return;

	u64 nbytes = aio->size;
	u32 buf_addr = aio->buf_addr;

	u32 error = CELL_OK;

	vfsStream& file = *(vfsStream*)orig_file;
	const u64 old_pos = file.Tell();
	file.Seek((u64)aio->offset);

	// TODO: use code from cellFsRead or something

	u64 res = 0;
	if (nbytes != (u32)nbytes)
	{
		error = CELL_ENOMEM;
	}
	else
	{
		res = nbytes ? file.Read(Memory.GetMemFromAddr(buf_addr), nbytes) : 0;
	}

	file.Seek(old_pos);

	if (Ini.HLELogging.GetValue())
		LOG_NOTICE(HLE, "*** fsAioRead(fd=%d, offset=0x%llx, buf_addr=0x%x, size=0x%x, error=0x%x, res=0x%x, xid=0x%x [%s])",
			fd, (u64)aio->offset, buf_addr, (u64)aio->size, error, res, xid, orig_file->GetPath().c_str());

	if (func) // start callback thread
	{
		func.async(aio, error, xid, res);
	}

	g_FsAioReadCur++;
}
Ejemplo n.º 2
0
void fsAioRead(u32 fd, mem_ptr_t<CellFsAio> aio, int xid, mem_func_ptr_t<void (*)(mem_ptr_t<CellFsAio> xaio, int error, int xid, u64 size)> func)
{
	while (g_FsAioReadCur != xid)
	{
		Sleep(1);
		if (Emu.IsStopped())
		{
			ConLog.Warning("fsAioRead() aborted");
			return;
		}
	}

	vfsFileBase* orig_file;
	if(!sys_fs.CheckId(fd, orig_file)) return;

	std::string path = orig_file->GetPath();
	std::string::size_type first_slash = path.find('/');
	if (first_slash == std::string::npos)
	{
		path = "";
	}
	else
	{
		path = path.substr(first_slash+1,std::string::npos);
	}

	u64 nbytes = aio->size;
	u32 buf_addr = aio->buf_addr;

	u32 res = 0;
	u32 error = CELL_OK;

	vfsStream& file = *(vfsStream*)orig_file;
	const u64 old_pos = file.Tell();
	file.Seek((u64)aio->offset);

	u32 count = nbytes;
	if (nbytes != (u64)count)
	{
		error = CELL_ENOMEM;
		goto fin;
	}

	if (!Memory.IsGoodAddr(buf_addr))
	{
		error = CELL_EFAULT;
		goto fin;
	}

	if (count) if (u32 frag = buf_addr & 4095) // memory page fragment
	{
		u32 req = min(count, 4096 - frag);
		u32 read = file.Read(Memory + buf_addr, req);
		buf_addr += req;
		res += read;
		count -= req;
		if (read < req) goto fin;
	}

	for (u32 pages = count / 4096; pages > 0; pages--) // full pages
	{
		if (!Memory.IsGoodAddr(buf_addr)) goto fin; // ??? (probably EFAULT)
		u32 read = file.Read(Memory + buf_addr, 4096);
		buf_addr += 4096;
		res += read;
		count -= 4096;
		if (read < 4096) goto fin;
	}

	if (count) // last fragment
	{
		if (!Memory.IsGoodAddr(buf_addr)) goto fin;
		res += file.Read(Memory + buf_addr, count);
	}

fin:
	file.Seek(old_pos);

	ConLog.Warning("*** fsAioRead(fd=%d, offset=0x%llx, buf_addr=0x%x, size=0x%x, error=0x%x, res=0x%x, xid=0x%x [%s])",
		fd, (u64)aio->offset, buf_addr, (u64)aio->size, error, res, xid, path.c_str());

	if (func) // start callback thread
	{
		func.async(aio, error, xid, res);
	}

	/*CPUThread& thr = Emu.GetCallbackThread();
	while (thr.IsAlive())
	{
		Sleep(1);
		if (Emu.IsStopped())
		{
			ConLog.Warning("fsAioRead() aborted");
			break;
		}
	}*/

	g_FsAioReadCur++;
}
Ejemplo n.º 3
0
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;
}