From ae6011b0e2ab8e0323c1516c0b5e140d4f893be1 Mon Sep 17 00:00:00 2001 From: Gliniak Date: Sun, 24 Mar 2024 18:31:11 +0100 Subject: [PATCH] [Kernel] Added initial support for Property also added unfinished classes for Filters and Contexts --- src/xenia/kernel/util/property.cc | 104 ++++++++++++++++++++++++++ src/xenia/kernel/util/property.h | 105 +++++++++++++++++++++++++++ src/xenia/kernel/xam/apps/xgi_app.cc | 3 +- 3 files changed, 211 insertions(+), 1 deletion(-) create mode 100644 src/xenia/kernel/util/property.cc create mode 100644 src/xenia/kernel/util/property.h diff --git a/src/xenia/kernel/util/property.cc b/src/xenia/kernel/util/property.cc new file mode 100644 index 000000000..03443ba14 --- /dev/null +++ b/src/xenia/kernel/util/property.cc @@ -0,0 +1,104 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2024 Xenia Canary. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include "xenia/kernel/util/property.h" +#include "xenia/base/logging.h" + +namespace xe { +namespace kernel { + +Property::Property(uint32_t property_id, uint32_t value_size, + uint8_t* value_ptr) { + property_id_.value = property_id; + data_type_ = static_cast(property_id_.type); + + value_size_ = value_size; + value_.resize(value_size); + + memcpy(value_.data(), value_ptr, value_size); +} + +Property::Property(const uint8_t* serialized_data, size_t data_size) { + if (data_size < 8) { + XELOGW("Property::Property lacks information. Skipping!"); + return; + } + + memcpy(&property_id_, serialized_data, sizeof(property_id_)); + data_type_ = static_cast(property_id_.type); + + memcpy(&value_size_, serialized_data + 4, sizeof(value_size_)); + + value_.resize(value_size_); + memcpy(value_.data(), serialized_data + 8, value_size_); +} + +Property::~Property(){}; + +std::vector Property::Serialize() { + std::vector serialized_property; + serialized_property.resize(sizeof(property_id_) + sizeof(value_size_) + + value_.size()); + + size_t offset = 0; + memcpy(serialized_property.data(), &property_id_, sizeof(property_id_)); + offset += sizeof(property_id_); + + memcpy(serialized_property.data() + offset, &value_size_, + sizeof(value_size_)); + + offset += sizeof(value_size_); + + memcpy(serialized_property.data() + offset, value_.data(), value_.size()); + + return serialized_property; +} + +void Property::Write(Memory* memory, XUSER_PROPERTY* property) { + property->property_id = property_id_.value; + property->data.type = data_type_; + + switch (data_type_) { + case X_USER_DATA_TYPE::WSTRING: + property->data.binary.size = value_size_; + break; + case X_USER_DATA_TYPE::CONTENT: + case X_USER_DATA_TYPE::BINARY: + property->data.binary.size = value_size_; + // Property pointer must be valid at this point! + memcpy(memory->TranslateVirtual(property->data.binary.ptr), value_.data(), + value_size_); + break; + case X_USER_DATA_TYPE::INT32: + memcpy(reinterpret_cast(&property->data.s32), value_.data(), + value_size_); + break; + case X_USER_DATA_TYPE::INT64: + memcpy(reinterpret_cast(&property->data.s64), value_.data(), + value_size_); + break; + case X_USER_DATA_TYPE::DOUBLE: + memcpy(reinterpret_cast(&property->data.f64), value_.data(), + value_size_); + break; + case X_USER_DATA_TYPE::FLOAT: + memcpy(reinterpret_cast(&property->data.f32), value_.data(), + value_size_); + break; + case X_USER_DATA_TYPE::DATETIME: + memcpy(reinterpret_cast(&property->data.filetime), + value_.data(), value_size_); + break; + default: + break; + } +} + +} // namespace kernel +} // namespace xe \ No newline at end of file diff --git a/src/xenia/kernel/util/property.h b/src/xenia/kernel/util/property.h new file mode 100644 index 000000000..e4553f549 --- /dev/null +++ b/src/xenia/kernel/util/property.h @@ -0,0 +1,105 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2024 Xenia Canary. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_KERNEL_UTIL_PROPERTY_H_ +#define XENIA_KERNEL_UTIL_PROPERTY_H_ + +#include "xenia/base/byte_stream.h" +#include "xenia/kernel/util/xuserdata.h" +#include "xenia/memory.h" +#include "xenia/xbox.h" + +namespace xe { +namespace kernel { + +struct XUSER_PROPERTY { + xe::be property_id; + X_USER_DATA data; +}; + +struct XUSER_STATS_COLUMN { + xe::be column_ordinal; + X_USER_DATA data; +}; + +class Property { + public: + Property(uint32_t property_id, uint32_t value_size, uint8_t* value_ptr); + Property(const uint8_t* serialized_data, size_t data_size); + ~Property(); + + bool IsValid() const { return property_id_.value != 0; } + std::vector Serialize(); + + void Write(Memory* memory, XUSER_PROPERTY* property); + uint32_t GetSize() const { return value_size_; } + + bool RequiresPointer() const { + return static_cast(property_id_.type) == + X_USER_DATA_TYPE::CONTENT || + static_cast(property_id_.type) == + X_USER_DATA_TYPE::WSTRING || + static_cast(property_id_.type) == + X_USER_DATA_TYPE::BINARY; + } + + private: + AttributeKey property_id_ = {}; + X_USER_DATA_TYPE data_type_ = X_USER_DATA_TYPE::UNSET; + + uint32_t value_size_ = 0; + std::vector value_; +}; + +class Filter { + public: + enum class ComparationOperator : uint16_t { + Equals = 0, + LeftGreater = 1, + LeftGreaterEqual = 2, + RightGreater = 3, + RightGreaterEqual = 4, + }; + + enum class Type : uint32_t { + Attribute = 0, + Parameter = 1, + }; + + Filter(uint32_t left_side_id, uint32_t right_side_id, uint32_t op); + + private: + uint32_t left_side_id_; + Type left_side_type_; + + uint32_t right_side_id_; + Type right_side_type_; + + ComparationOperator op_; +}; + +/* +class Context { + public: + Context(uint32_t id); + ~Context(); + + private: + AttributeKey property_id_ = {}; + + uint32_t stringId = 0; + std::string friendly_name = ""; + uint32_t default_value = 0; + uint32_t max_value = 0; +};*/ + +} // namespace kernel +} // namespace xe + +#endif \ No newline at end of file diff --git a/src/xenia/kernel/xam/apps/xgi_app.cc b/src/xenia/kernel/xam/apps/xgi_app.cc index b15e3c459..6eb329a9e 100644 --- a/src/xenia/kernel/xam/apps/xgi_app.cc +++ b/src/xenia/kernel/xam/apps/xgi_app.cc @@ -11,6 +11,7 @@ #include "xenia/base/logging.h" #include "xenia/base/threading.h" +#include "xenia/kernel/util/property.h" namespace xe { namespace kernel { @@ -71,7 +72,7 @@ X_HRESULT XgiApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, const util::XdbfGameData title_xdbf = kernel_state_->title_xdbf(); if (title_xdbf.is_valid()) { - const auto property = title_xdbf.GetContext(property_id); + const auto property = title_xdbf.GetProperty(property_id); const XLanguage title_language = title_xdbf.GetExistingLanguage( static_cast(XLanguage::kEnglish)); const std::string desc =