mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-27 16:05:29 +03:00
Add String Support to IPC Push/Pop
This commit does some minor renaming/reordering in IPC and adds support for strings to IPC Push/Pop. It also fixes a tiny regression with the frametime display.
This commit is contained in:
parent
63154d05d1
commit
925d05d049
@ -62,7 +62,7 @@ namespace skyline::gpu {
|
||||
if (frameTimestamp) {
|
||||
auto now = util::GetTimeNs();
|
||||
|
||||
frametime = static_cast<u32>((now - frameTimestamp) / (constant::NsInSecond / 100)); // frametime / 100 is the real ms value, this is to retain the first two decimals
|
||||
frametime = static_cast<u32>((now - frameTimestamp) / 10000); // frametime / 100 is the real ms value, this is to retain the first two decimals
|
||||
fps = static_cast<u16>(constant::NsInSecond / (now - frameTimestamp));
|
||||
|
||||
frameTimestamp = now;
|
||||
|
@ -143,7 +143,7 @@ namespace skyline::kernel::ipc {
|
||||
memset(tls, 0, constant::TlsIpcSize);
|
||||
|
||||
auto header = reinterpret_cast<CommandHeader *>(pointer);
|
||||
header->rawSize = static_cast<u32>((sizeof(PayloadHeader) + argVec.size() + (domainObjects.size() * sizeof(KHandle)) + constant::IpcPaddingSum + (isDomain ? sizeof(DomainHeaderRequest) : 0)) / sizeof(u32)); // Size is in 32-bit units because Nintendo
|
||||
header->rawSize = static_cast<u32>((sizeof(PayloadHeader) + payload.size() + (domainObjects.size() * sizeof(KHandle)) + constant::IpcPaddingSum + (isDomain ? sizeof(DomainHeaderRequest) : 0)) / sizeof(u32)); // Size is in 32-bit units because Nintendo
|
||||
header->handleDesc = (!copyHandles.empty() || !moveHandles.empty());
|
||||
pointer += sizeof(CommandHeader);
|
||||
|
||||
@ -174,15 +174,15 @@ namespace skyline::kernel::ipc {
|
||||
pointer += sizeof(DomainHeaderResponse);
|
||||
}
|
||||
|
||||
auto payload = reinterpret_cast<PayloadHeader *>(pointer);
|
||||
payload->magic = util::MakeMagic<u32>("SFCO"); // SFCO is the magic in IPC responses
|
||||
payload->version = 1;
|
||||
payload->value = errorCode;
|
||||
auto payloadHeader = reinterpret_cast<PayloadHeader *>(pointer);
|
||||
payloadHeader->magic = util::MakeMagic<u32>("SFCO"); // SFCO is the magic in IPC responses
|
||||
payloadHeader->version = 1;
|
||||
payloadHeader->value = errorCode;
|
||||
pointer += sizeof(PayloadHeader);
|
||||
|
||||
if (!argVec.empty())
|
||||
std::memcpy(pointer, argVec.data(), argVec.size());
|
||||
pointer += argVec.size();
|
||||
if (!payload.empty())
|
||||
std::memcpy(pointer, payload.data(), payload.size());
|
||||
pointer += payload.size();
|
||||
|
||||
if (isDomain) {
|
||||
for (auto &domainObject : domainObjects) {
|
||||
@ -191,6 +191,6 @@ namespace skyline::kernel::ipc {
|
||||
}
|
||||
}
|
||||
|
||||
state.logger->Debug("Output: Raw Size: {}, Command ID: 0x{:X}, Copy Handles: {}, Move Handles: {}", u32(header->rawSize), u32(payload->value), copyHandles.size(), moveHandles.size());
|
||||
state.logger->Debug("Output: Raw Size: {}, Command ID: 0x{:X}, Copy Handles: {}, Move Handles: {}", u32(header->rawSize), u32(payloadHeader->value), copyHandles.size(), moveHandles.size());
|
||||
}
|
||||
}
|
||||
|
@ -281,6 +281,16 @@ namespace skyline {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This returns a std::string_view from the payload
|
||||
* @param size The length of the string (0 means the string is null terminated)
|
||||
*/
|
||||
inline std::string_view PopString(size_t size = 0) {
|
||||
auto view = size ? std::string_view(reinterpret_cast<const char*>(payloadOffset), size) : std::string_view(reinterpret_cast<const char*>(payloadOffset));
|
||||
payloadOffset += view.length();
|
||||
return view;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This skips an object to pop off the top
|
||||
* @tparam ValueType The type of the object to skip
|
||||
@ -296,8 +306,8 @@ namespace skyline {
|
||||
*/
|
||||
class IpcResponse {
|
||||
private:
|
||||
std::vector<u8> argVec; //!< This holds all of the contents to be pushed to the payload
|
||||
const DeviceState &state; //!< The state of the device
|
||||
std::vector<u8> payload; //!< This holds all of the contents to be pushed to the payload
|
||||
|
||||
public:
|
||||
bool nWrite{}; //!< This is to signal the IPC handler to not write this, as it will be manually written
|
||||
@ -320,12 +330,22 @@ namespace skyline {
|
||||
*/
|
||||
template<typename ValueType>
|
||||
inline void Push(const ValueType &value) {
|
||||
argVec.reserve(argVec.size() + sizeof(ValueType));
|
||||
auto item = reinterpret_cast<const u8 *>(&value);
|
||||
for (uint index = 0; sizeof(ValueType) > index; index++) {
|
||||
argVec.push_back(*item);
|
||||
item++;
|
||||
}
|
||||
auto size = payload.size();
|
||||
payload.resize(size + sizeof(ValueType));
|
||||
|
||||
std::memcpy(payload.data() + size, reinterpret_cast<const u8 *>(&value), sizeof(ValueType));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes a string to the payload
|
||||
* @param string The string to write to the payload
|
||||
*/
|
||||
template<>
|
||||
inline void Push(const std::string &string) {
|
||||
auto size = payload.size();
|
||||
payload.resize(size + string.size());
|
||||
|
||||
std::memcpy(payload.data() + size, string.data(), string.size());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -12,7 +12,7 @@ namespace skyline::service::sm {
|
||||
void IUserInterface::Initialize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
|
||||
|
||||
void IUserInterface::GetService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
std::string serviceName(reinterpret_cast<char *>(request.cmdArg));
|
||||
std::string serviceName(request.PopString());
|
||||
|
||||
if (serviceName.empty()) {
|
||||
response.errorCode = constant::status::ServiceInvName;
|
||||
|
@ -41,7 +41,7 @@ namespace skyline::service::visrv {
|
||||
}
|
||||
|
||||
void IApplicationDisplayService::OpenDisplay(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
std::string displayName(reinterpret_cast<char *>(request.cmdArg));
|
||||
std::string displayName(request.PopString());
|
||||
state.logger->Debug("Setting display as: {}", displayName);
|
||||
state.os->serviceManager.GetService<hosbinder::IHOSBinderDriver>(Service::hosbinder_IHOSBinderDriver)->SetDisplay(displayName);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user