示例#1
0
文件: cellPad.cpp 项目: mob41/rpcs3
s32 cellPadPeriphGetInfo(vm::ptr<CellPadPeriphInfo> info)
{
	sys_io.trace("cellPadPeriphGetInfo(info=*0x%x)", info);

	const auto handler = fxm::get<PadHandlerBase>();

	if (!handler)
		return CELL_PAD_ERROR_UNINITIALIZED;

	const PadInfo& rinfo = handler->GetInfo();

	info->max_connect = rinfo.max_connect;
	info->now_connect = rinfo.now_connect;
	info->system_info = rinfo.system_info;

	std::vector<Pad>& pads = handler->GetPads();

	// TODO: Support other types of controllers
	for (u32 i = 0; i < CELL_PAD_MAX_PORT_NUM; ++i)
	{
		if (i >= pads.size())
			break;

		info->port_status[i] = pads[i].m_port_status;
		info->port_setting[i] = pads[i].m_port_setting;
		info->device_capability[i] = pads[i].m_device_capability;
		info->device_type[i] = pads[i].m_device_type;
		info->pclass_type[i] = CELL_PAD_PCLASS_TYPE_STANDARD;
		info->pclass_profile[i] = 0x0;
	}

	return CELL_OK;
}
示例#2
0
error_code sys_event_queue_tryreceive(u32 equeue_id, vm::ptr<sys_event_t> event_array, s32 size, vm::ptr<u32> number)
{
	sys_event.trace("sys_event_queue_tryreceive(equeue_id=0x%x, event_array=*0x%x, size=%d, number=*0x%x)", equeue_id, event_array, size, number);

	const auto queue = idm::get<lv2_obj, lv2_event_queue>(equeue_id);

	if (!queue)
	{
		return CELL_ESRCH;
	}

	if (queue->type != SYS_PPU_QUEUE)
	{
		return CELL_EINVAL;
	}

	semaphore_lock lock(queue->mutex);

	s32 count = 0;

	while (queue->sq.empty() && count < size && !queue->events.empty())
	{
		auto& dest = event_array[count++];
		auto event = queue->events.front();
		queue->events.pop_front();

		std::tie(dest.source, dest.data1, dest.data2, dest.data3) = event;
	}

	*number = count;

	return CELL_OK;
}
示例#3
0
s32 sys_spu_thread_group_yield(u32 id)
{
	sys_spu.trace("sys_spu_thread_group_yield(id=0x%x)", id);

	LV2_LOCK;

	const auto group = idm::get<lv2_spu_group_t>(id);

	if (!group)
	{
		return CELL_ESRCH;
	}

	if (group->type & SYS_SPU_THREAD_GROUP_TYPE_EXCLUSIVE_NON_CONTEXT) // this check may be inaccurate
	{
		return CELL_OK;
	}

	if (group->state != SPU_THREAD_GROUP_STATUS_RUNNING)
	{
		return CELL_ESTAT;
	}

	// SPU_THREAD_GROUP_STATUS_READY state is not used, so this function does nothing

	return CELL_OK;
}
示例#4
0
文件: cellFs.cpp 项目: 4iDragon/rpcs3
s32 cellFsClosedir(u32 fd)
{
	cellFs.trace("cellFsClosedir(fd=0x%x)", fd);

	// call the syscall
	return sys_fs_closedir(fd);
}
示例#5
0
error_code cellVideoOutGetState(u32 videoOut, u32 deviceIndex, vm::ptr<CellVideoOutState> state)
{
	cellSysutil.trace("cellVideoOutGetState(videoOut=%d, deviceIndex=%d, state=*0x%x)", videoOut, deviceIndex, state);

	if (deviceIndex) return CELL_VIDEO_OUT_ERROR_DEVICE_NOT_FOUND;

	switch (videoOut)
	{
	case CELL_VIDEO_OUT_PRIMARY:
		state->state = CELL_VIDEO_OUT_OUTPUT_STATE_ENABLED;
		state->colorSpace = CELL_VIDEO_OUT_COLOR_SPACE_RGB;
		state->displayMode.resolutionId = g_video_out_resolution_id.at(g_cfg.video.resolution); // TODO
		state->displayMode.scanMode = CELL_VIDEO_OUT_SCAN_MODE_PROGRESSIVE;
		state->displayMode.conversion = CELL_VIDEO_OUT_DISPLAY_CONVERSION_NONE;
		state->displayMode.aspect = g_video_out_aspect_id.at(g_cfg.video.aspect_ratio); // TODO
		state->displayMode.refreshRates = CELL_VIDEO_OUT_REFRESH_RATE_59_94HZ;
		return CELL_OK;

	case CELL_VIDEO_OUT_SECONDARY:
		*state = { CELL_VIDEO_OUT_OUTPUT_STATE_DISABLED }; // ???
		return CELL_OK;
	}

	return CELL_VIDEO_OUT_ERROR_UNSUPPORTED_VIDEO_OUT;
}
示例#6
0
文件: cellFs.cpp 项目: 4iDragon/rpcs3
s32 cellFsRead(u32 fd, vm::ptr<void> buf, u64 nbytes, vm::ptr<u64> nread)
{
	cellFs.trace("cellFsRead(fd=0x%x, buf=0x%x, nbytes=0x%llx, nread=0x%x)", fd, buf, nbytes, nread);

	// call the syscall
	return sys_fs_read(fd, buf, nbytes, nread ? nread : vm::var<u64>{});
}
示例#7
0
文件: cellFs.cpp 项目: 4iDragon/rpcs3
ppu_error_code cellFsWriteWithOffset(u32 fd, u64 offset, vm::cptr<void> buf, u64 data_size, vm::ptr<u64> nwrite)
{
	cellFs.trace("cellFsWriteWithOffset(fd=%d, offset=0x%llx, buf=*0x%x, data_size=0x%llx, nwrite=*0x%x)", fd, offset, buf, data_size, nwrite);

	if (!buf)
	{
		if (nwrite) *nwrite = 0;
		return CELL_EFAULT;
	}

	if (fd - 3 > 252)
	{
		if (nwrite) *nwrite = 0;
		return CELL_EBADF;
	}

	vm::var<lv2_file_op_rw> arg;

	arg->_vtable = vm::cast(0xfa8b0000); // Intentionally wrong (provide correct vtable if necessary)
	
	arg->op = 0x8000000b;
	arg->fd = fd;
	arg->buf = vm::const_ptr_cast<void>(buf);
	arg->offset = offset;
	arg->size = data_size;

	// Call the syscall
	const s32 rc = sys_fs_fcntl(fd, 0x8000000b, arg, arg.size());

	// Write size written
	if (nwrite) *nwrite = rc && rc != CELL_EFSSPECIFIC ? 0 : arg->out_size.value();

	return NOT_AN_ERROR(rc ? rc : arg->out_code.value());
}
示例#8
0
error_code cellPadGetCapabilityInfo(u32 port_no, vm::ptr<CellPadCapabilityInfo> info)
{
	sys_io.trace("cellPadGetCapabilityInfo(port_no=%d, data_addr:=0x%x)", port_no, info.addr());

	const auto handler = fxm::get<pad_thread>();

	if (!handler)
		return CELL_PAD_ERROR_UNINITIALIZED;

	if (port_no >= CELL_MAX_PADS || !info)
		return CELL_PAD_ERROR_INVALID_PARAMETER;

	const auto& pads = handler->GetPads();

	if (port_no >= pads.size() || port_no >= handler->GetInfo().max_connect)
		return CELL_PAD_ERROR_NO_DEVICE;

	const auto pad = pads[port_no];

	if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
		return CELL_PAD_ERROR_NO_DEVICE;

	// Should return the same as device capability mask, psl1ght has it backwards in pad->h
	info->info[port_no] = pad->m_device_capability;

	return CELL_OK;
}
示例#9
0
error_code cellPadSetPortSetting(u32 port_no, u32 port_setting)
{
	sys_io.trace("cellPadSetPortSetting(port_no=%d, port_setting=0x%x)", port_no, port_setting);

	const auto handler = fxm::get<pad_thread>();

	if (!handler)
		return CELL_PAD_ERROR_UNINITIALIZED;

	if (port_no >= CELL_MAX_PADS)
		return CELL_PAD_ERROR_INVALID_PARAMETER;

	const auto& pads = handler->GetPads();

	// CELL_PAD_ERROR_NO_DEVICE is not returned in this case.
	// TODO: Set the setting regardless
	if (port_no >= pads.size() || port_no >= handler->GetInfo().max_connect)
		return CELL_OK;

	const auto pad = pads[port_no];
	pad->m_port_setting = port_setting;

	// can also return CELL_PAD_ERROR_UNSUPPORTED_GAMEPAD

	return CELL_OK;
}
示例#10
0
error_code cellPadGetInfo(vm::ptr<CellPadInfo> info)
{
	sys_io.trace("cellPadGetInfo(info=*0x%x)", info);

	const auto handler = fxm::get<pad_thread>();

	if (!handler)
		return CELL_PAD_ERROR_UNINITIALIZED;

	if (!info)
		return CELL_PAD_ERROR_INVALID_PARAMETER;

	std::memset(info.get_ptr(), 0, sizeof(CellPadInfo));

	const PadInfo& rinfo = handler->GetInfo();
	info->max_connect = rinfo.max_connect;
	info->now_connect = rinfo.now_connect;
	info->system_info = rinfo.system_info;

	const auto& pads = handler->GetPads();

	for (u32 i = 0; i < CELL_MAX_PADS; ++i)
	{
		if (i >= pads.size())
			break;

		info->status[i] = pads[i]->m_port_status;
		pads[i]->m_port_status &= ~CELL_PAD_STATUS_ASSIGN_CHANGES;
		info->product_id[i] = 0x0268;
		info->vendor_id[i] = 0x054C;
	}

	return CELL_OK;
}
示例#11
0
error_code cellPadGetInfo2(vm::ptr<CellPadInfo2> info)
{
	sys_io.trace("cellPadGetInfo2(info=*0x%x)", info);

	const auto handler = fxm::get<pad_thread>();

	if (!handler)
		return CELL_PAD_ERROR_UNINITIALIZED;

	if (!info)
		return CELL_PAD_ERROR_INVALID_PARAMETER;

	std::memset(info.get_ptr(), 0, sizeof(CellPadInfo2));

	const PadInfo& rinfo = handler->GetInfo();
	info->max_connect = rinfo.max_connect;
	info->now_connect = rinfo.now_connect;
	info->system_info = rinfo.system_info;

	const auto& pads = handler->GetPads();

	for (u32 i = 0; i < CELL_PAD_MAX_PORT_NUM; ++i)
	{
		if (i >= pads.size())
			break;

		info->port_status[i] = pads[i]->m_port_status;
		pads[i]->m_port_status &= ~CELL_PAD_STATUS_ASSIGN_CHANGES;
		info->port_setting[i] = pads[i]->m_port_setting;
		info->device_capability[i] = pads[i]->m_device_capability;
		info->device_type[i] = pads[i]->m_device_type;
	}

	return CELL_OK;
}
示例#12
0
error_code cellPadSetActDirect(u32 port_no, vm::ptr<CellPadActParam> param)
{
	sys_io.trace("cellPadSetActDirect(port_no=%d, param=*0x%x)", port_no, param);

	const auto handler = fxm::get<pad_thread>();

	if (!handler)
		return CELL_PAD_ERROR_UNINITIALIZED;

	if (port_no >= CELL_MAX_PADS || !param)
		return CELL_PAD_ERROR_INVALID_PARAMETER;

	const auto& pads = handler->GetPads();

	if (port_no >= pads.size() || port_no >= handler->GetInfo().max_connect)
		return CELL_PAD_ERROR_NO_DEVICE;

	const auto pad = pads[port_no];

	if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
		return CELL_PAD_ERROR_NO_DEVICE;

	// TODO: find out if this is checked here or later or at all
	if (!(pad->m_device_capability & CELL_PAD_CAPABILITY_ACTUATOR))
		return CELL_PAD_ERROR_UNSUPPORTED_GAMEPAD;

	// make sure reserved bits are 0. Looks like this happens after checking the pad status
	for (int i = 0; i < 6; i++)
		if (param->reserved[i])
			return CELL_PAD_ERROR_INVALID_PARAMETER;

	handler->SetRumble(port_no, param->motor[1], param->motor[0] > 0);

	return CELL_OK;
}
示例#13
0
error_code cellPadPeriphGetData(u32 port_no, vm::ptr<CellPadPeriphData> data)
{
	sys_io.trace("cellPadPeriphGetData(port_no=%d, data=*0x%x)", port_no, data);
	const auto handler = fxm::get<pad_thread>();

	if (!handler)
		return CELL_PAD_ERROR_UNINITIALIZED;

	// port_no can only be 0-6 in this function
	if (port_no >= CELL_PAD_MAX_PORT_NUM || !data)
		return CELL_PAD_ERROR_INVALID_PARAMETER;

	const auto& pads = handler->GetPads();

	if (port_no >= pads.size() || port_no >= handler->GetInfo().max_connect)
		return CELL_PAD_ERROR_NO_DEVICE;

	const auto pad = pads[port_no];

	if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
		return CELL_PAD_ERROR_NO_DEVICE;

	// todo: support for 'unique' controllers, which goes in offsets 24+ in padData
	data->pclass_type = CELL_PAD_PCLASS_TYPE_STANDARD;
	data->pclass_profile = 0x0;

	return cellPadGetData(port_no, vm::get_addr(&data->cellpad_data));
}
示例#14
0
s32 cellSysutilCheckCallback(ppu_thread& ppu)
{
	cellSysutil.trace("cellSysutilCheckCallback()");

	const auto cbm = fxm::get_always<sysutil_cb_manager>();

	while (true)
	{
		std::lock_guard<std::mutex> lock(cbm->mutex);

		if (cbm->registered.empty())
		{
			break;
		}

		const auto func = std::move(cbm->registered.front());

		cbm->registered.pop();

		if (s32 res = func(ppu))
		{
			return res;
		}
	}

	return CELL_OK;
}
示例#15
0
s32 cellMouseGetData(u32 port_no, vm::ptr<CellMouseData> data)
{
	sys_io.trace("cellMouseGetData(port_no=%d, data=*0x%x)", port_no, data);

	const auto handler = fxm::get<MouseHandlerBase>();

	if (!handler)
	{
		return CELL_MOUSE_ERROR_UNINITIALIZED;
	}

	if (port_no >= handler->GetMice().size())
	{
		return CELL_MOUSE_ERROR_NO_DEVICE;
	}
	
	MouseData& current_data = handler->GetData(port_no);
	data->update = current_data.update;
	data->buttons = current_data.buttons;
	data->x_axis = current_data.x_axis;
	data->y_axis = current_data.y_axis;
	data->wheel = current_data.wheel;
	data->tilt = current_data.tilt;

	current_data.update = CELL_MOUSE_DATA_NON;
	current_data.x_axis = 0;
	current_data.y_axis = 0;
	current_data.wheel = 0;

	return CELL_OK;
}
示例#16
0
error_code cellPadSetSensorMode(u32 port_no, u32 mode)
{
	sys_io.trace("cellPadSetSensorMode(port_no=%d, mode=%d)", port_no, mode);

	const auto handler = fxm::get<pad_thread>();

	if (!handler)
		return CELL_PAD_ERROR_UNINITIALIZED;

	if (port_no >= CELL_MAX_PADS)
		return CELL_PAD_ERROR_INVALID_PARAMETER;

	const auto& pads = handler->GetPads();

	// CELL_PAD_ERROR_NO_DEVICE is not returned in this case.
	// TODO: Set the setting regardless
	if (port_no >= pads.size() || port_no >= handler->GetInfo().max_connect)
		return CELL_OK;

	const auto pad = pads[port_no];

	// TODO: find out if this is checked here or later or at all
	if (!(pad->m_device_capability & CELL_PAD_CAPABILITY_SENSOR_MODE))
		return CELL_PAD_ERROR_UNSUPPORTED_GAMEPAD;

	if (mode)
		pad->m_port_setting |= CELL_PAD_SETTING_SENSOR_ON;
	else
		pad->m_port_setting &= ~CELL_PAD_SETTING_SENSOR_ON;

	return CELL_OK;
}
示例#17
0
文件: cellFs.cpp 项目: 4iDragon/rpcs3
s32 cellFsFtruncate(u32 fd, u64 size)
{
	cellFs.trace("cellFsFtruncate(fd=0x%x, size=0x%llx)", fd, size);

	// call the syscall
	return sys_fs_ftruncate(fd, size);
}
示例#18
0
s32 sys_io_3733EA3C(u32 port_no, vm::ptr<u32> device_type, vm::ptr<CellPadData> data)
{
	// Used by the ps1 emulator built into the firmware
	// Seems to call the same function that getdataextra does
	sys_io.trace("sys_io_3733EA3C(port_no=%d, device_type=*0x%x, data=*0x%x)", port_no, device_type, data);
	return cellPadGetDataExtra(port_no, device_type, data);
}
示例#19
0
文件: cellFs.cpp 项目: 4iDragon/rpcs3
ppu_error_code cellFsReadWithOffset(u32 fd, u64 offset, vm::ptr<void> buf, u64 buffer_size, vm::ptr<u64> nread)
{
	cellFs.trace("cellFsReadWithOffset(fd=%d, offset=0x%llx, buf=*0x%x, buffer_size=0x%llx, nread=*0x%x)", fd, offset, buf, buffer_size, nread);

	if (fd - 3 > 252)
	{
		if (nread) *nread = 0;
		return CELL_EBADF;
	}

	vm::var<lv2_file_op_rw> arg;

	arg->_vtable = vm::cast(0xfa8a0000); // Intentionally wrong (provide correct vtable if necessary)
	
	arg->op = 0x8000000a;
	arg->fd = fd;
	arg->buf = buf;
	arg->offset = offset;
	arg->size = buffer_size;

	// Call the syscall
	const s32 rc = sys_fs_fcntl(fd, 0x8000000a, arg, arg.size());

	// Write size read
	if (nread) *nread = rc && rc != CELL_EFSSPECIFIC ? 0 : arg->out_size.value();

	return NOT_AN_ERROR(rc ? rc : arg->out_code.value());
}
示例#20
0
error_code sys_memory_get_page_attribute(u32 addr, vm::ptr<sys_page_attr_t> attr)
{
	sys_memory.trace("sys_memory_get_page_attribute(addr=0x%x, attr=*0x%x)", addr, attr);

	if (!vm::check_addr(addr))
	{
		return CELL_EINVAL;
	}

	if (!vm::check_addr(attr.addr(), attr.size()))
	{
		return CELL_EFAULT;
	}

	attr->attribute = 0x40000ull; // SYS_MEMORY_PROT_READ_WRITE (TODO)
	attr->access_right = 0xFull; // SYS_MEMORY_ACCESS_RIGHT_ANY (TODO)

	if (vm::check_addr(addr, 1, vm::page_1m_size))
	{
		attr->page_size = 0x100000;
	}
	else if (vm::check_addr(addr, 1, vm::page_64k_size))
	{
		attr->page_size = 0x10000;
	}
	else
	{
		attr->page_size = 4096;
	}
	
	return CELL_OK;
}
示例#21
0
文件: cellFs.cpp 项目: 4iDragon/rpcs3
s32 cellFsWrite(u32 fd, vm::cptr<void> buf, u64 nbytes, vm::ptr<u64> nwrite)
{
	cellFs.trace("cellFsWrite(fd=0x%x, buf=*0x%x, nbytes=0x%llx, nwrite=*0x%x)", fd, buf, nbytes, nwrite);

	// call the syscall
	return sys_fs_write(fd, buf, nbytes, nwrite ? nwrite : vm::var<u64>{});
}
示例#22
0
error_code sys_event_queue_tryreceive(u32 equeue_id, vm::ptr<sys_event_t> event_array, s32 size, vm::ptr<u32> number)
{
	sys_event.trace("sys_event_queue_tryreceive(equeue_id=0x%x, event_array=*0x%x, size=%d, number=*0x%x)", equeue_id, event_array, size, number);

	const u32 count = ::narrow<u32>(size, "sys_event_queue_tryreceive");

	const auto queue = idm::get<lv2_event_queue>(equeue_id);

	if (!queue)
	{
		return CELL_ESRCH;
	}

	if (queue->type != SYS_PPU_QUEUE)
	{
		return CELL_EINVAL;
	}

	u32 result = 0;

	lv2_lock lock{queue};

	while (queue->waiters.empty() && result < count && queue->events.size())
	{
		event_array[result++].tie() = queue->events.front();
		queue->events.pop_front();
	}

	*number = result;

	return CELL_OK;
}
示例#23
0
文件: cellFs.cpp 项目: 4iDragon/rpcs3
s32 cellFsFstat(u32 fd, vm::ptr<CellFsStat> sb)
{
	cellFs.trace("cellFsFstat(fd=0x%x, sb=*0x%x)", fd, sb);

	// call the syscall
	return sys_fs_fstat(fd, sb);
}
示例#24
0
error_code sys_event_port_send(u32 eport_id, u64 data1, u64 data2, u64 data3)
{
	sys_event.trace("sys_event_port_send(eport_id=0x%x, data1=0x%llx, data2=0x%llx, data3=0x%llx)", eport_id, data1, data2, data3);

	const auto port = idm::get<lv2_event_port>(eport_id, [](lv2_event_port& port)
	{
		lv2_lock lock{port};

		return port.queue.lock();
	});

	if (!port)
	{
		return CELL_ESRCH;
	}

	if (!port.value)
	{
		return CELL_ENOTCONN;
	}

	if (!port.value->push(port->name ? port->name : (u64)process_getpid() << 32 | eport_id, data1, data2, data3))
	{
		return CELL_EBUSY;
	}

	return CELL_OK;
}
示例#25
0
error_code sys_lwmutex_destroy(ppu_thread& ppu, vm::ptr<sys_lwmutex_t> lwmutex)
{
	sysPrxForUser.trace("sys_lwmutex_destroy(lwmutex=*0x%x)", lwmutex);

	if (g_cfg.core.hle_lwmutex)
	{
		return sys_mutex_destroy(lwmutex->sleep_queue);
	}

	// check to prevent recursive locking in the next call
	if (lwmutex->vars.owner.load() == ppu.id)
	{
		return CELL_EBUSY;
	}

	// attempt to lock the mutex
	if (error_code res = sys_lwmutex_trylock(ppu, lwmutex))
	{
		return res;
	}

	// call the syscall
	if (error_code res = _sys_lwmutex_destroy(lwmutex->sleep_queue))
	{
		// unlock the mutex if failed
		sys_lwmutex_unlock(ppu, lwmutex);

		return res;
	}

	// deleting succeeded
	lwmutex->vars.owner.release(lwmutex_dead);

	return CELL_OK;
}
示例#26
0
s32 sys_timer_sleep(u32 sleep_time)
{
	sys_timer.trace("sys_timer_sleep(sleep_time=%d)", sleep_time);

	const u64 start_time = get_system_time();

	const u64 useconds = sleep_time * 1000000ull;

	u64 passed;

	while (useconds > (passed = get_system_time() - start_time) + 1000)
	{
		CHECK_EMU_STATUS;

		std::this_thread::sleep_for(1ms);
	}
	
	if (useconds > passed)
	{
		std::this_thread::sleep_for(std::chrono::microseconds(useconds - passed));
	}

	CHECK_EMU_STATUS;
	return CELL_OK;
}
示例#27
0
文件: cellSsl.cpp 项目: DHrpcs3/rpcs3
s32 cellSslCertificateLoader(u64 flag, vm::ptr<char> buffer, u32 size, vm::ptr<u32> required)
{
	cellSsl.trace("cellSslCertificateLoader(flag=%llu, buffer=0x%x, size=%zu, required=0x%x)", flag, buffer, size, required);

	const std::bitset<58> flagBits(flag);
	const std::string certPath = vfs::get("/dev_flash/") + "data/cert/";

	if (required)
	{
		*required = 0;
		for (int i = 1; i <= flagBits.size(); i++)
		{
			if (!flagBits[i-1])
				continue;
			// If we're loading cert 6 (the baltimore cert), then we need set that we're loading the 'normal' set of certs.
			*required += (u32)(getCert(certPath, i, flagBits[BaltimoreCert-1]).size());
		}
	}
	else
	{
		std::string final;
		for (int i = 1; i <= flagBits.size(); i++)
		{
			if (!flagBits[i-1])
				continue;
			// If we're loading cert 6 (the baltimore cert), then we need set that we're loading the 'normal' set of certs.
			final.append(getCert(certPath, i, flagBits[BaltimoreCert-1]));
		}

		memset(buffer.get_ptr(), '\0', size - 1);
		memcpy(buffer.get_ptr(), final.c_str(), final.size());
	}
示例#28
0
error_code cellKbRead(u32 port_no, vm::ptr<CellKbData> data)
{
	sys_io.trace("cellKbRead(port_no=%d, data=*0x%x)", port_no, data);

	const auto handler = fxm::get<KeyboardHandlerBase>();

	if (!handler)
		return CELL_KB_ERROR_UNINITIALIZED;

	const std::vector<Keyboard>& keyboards = handler->GetKeyboards();

	if (port_no >= keyboards.size())
		return CELL_KB_ERROR_INVALID_PARAMETER;

	KbData& current_data = handler->GetData(port_no);
	data->led = current_data.led;
	data->mkey = current_data.mkey;
	data->len = std::min((u32)current_data.len, CELL_KB_MAX_KEYCODES);

	for (s32 i=0; i<current_data.len; i++)
	{
		data->keycode[i] = current_data.keycode[i];
	}

	current_data.len = 0;
	
	return CELL_OK;
}
示例#29
0
s32 sys_spu_thread_write_snr(u32 id, u32 number, u32 value)
{
	sys_spu.trace("sys_spu_thread_write_snr(id=0x%x, number=%d, value=0x%x)", id, number, value);

	LV2_LOCK;

	const auto thread = idm::get<SPUThread>(id);

	if (!thread)
	{
		return CELL_ESRCH;
	}

	if (number > 1)
	{
		return CELL_EINVAL;
	}

	const auto group = thread->tg.lock();

	if (!group)
	{
		throw EXCEPTION("Invalid SPU thread group");
	}

	//if (group->state < SPU_THREAD_GROUP_STATUS_WAITING || group->state > SPU_THREAD_GROUP_STATUS_RUNNING) // ???
	//{
	//	return CELL_ESTAT;
	//}

	thread->push_snr(number, value);

	return CELL_OK;
}
示例#30
0
文件: cellPad.cpp 项目: mob41/rpcs3
s32 cellPadSetSensorMode(u32 port_no, u32 mode)
{
	sys_io.trace("cellPadSetSensorMode(port_no=%d, mode=%d)", port_no, mode);

	const auto handler = fxm::get<PadHandlerBase>();

	if (!handler)
		return CELL_PAD_ERROR_UNINITIALIZED;

	if (mode != 0 && mode != 1)
		return CELL_PAD_ERROR_INVALID_PARAMETER;

	const PadInfo& rinfo = handler->GetInfo();

	if (port_no >= rinfo.max_connect)
		return CELL_PAD_ERROR_INVALID_PARAMETER;
	if (port_no >= rinfo.now_connect)
		return CELL_PAD_ERROR_NO_DEVICE;

	std::vector<Pad>& pads = handler->GetPads();

	if (mode)
		pads[port_no].m_port_setting |= CELL_PAD_SETTING_SENSOR_ON;
	else
		pads[port_no].m_port_setting &= ~CELL_PAD_SETTING_SENSOR_ON;

	return CELL_OK;
}