-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Fixed incorrect X_USER_PROFILE_SETTING structure - Added X_USER_PROFILE_SETTING_HEADER based on entries from console - Removed X_USER_PROFILE_SETTING_DATA in favor of X_USER_DATA X_USER_DATA is used also in Properties in exactly the same way - Removed is_set in favor of X_USER_PROFILE_SETTING_SOURCE
- Loading branch information
Showing
4 changed files
with
446 additions
and
266 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,234 @@ | ||
/** | ||
****************************************************************************** | ||
* Xenia : Xbox 360 Emulator Research Project * | ||
****************************************************************************** | ||
* Copyright 2024 Ben Vanik. All rights reserved. * | ||
* Released under the BSD license - see LICENSE in the root for more details. * | ||
****************************************************************************** | ||
*/ | ||
|
||
#ifndef XENIA_KERNEL_UTIL_XUSERDATA_H_ | ||
#define XENIA_KERNEL_UTIL_XUSERDATA_H_ | ||
|
||
#include "xenia/base/byte_stream.h" | ||
#include "xenia/xbox.h" | ||
|
||
namespace xe { | ||
namespace kernel { | ||
|
||
enum class X_USER_DATA_TYPE : uint8_t { | ||
CONTENT = 0, | ||
INT32 = 1, | ||
INT64 = 2, | ||
DOUBLE = 3, | ||
WSTRING = 4, | ||
FLOAT = 5, | ||
BINARY = 6, | ||
DATETIME = 7, | ||
UNSET = 0xFF, | ||
}; | ||
|
||
struct X_USER_DATA { | ||
X_USER_DATA_TYPE type; | ||
|
||
union { | ||
be<int32_t> s32; | ||
be<int64_t> s64; | ||
be<uint32_t> u32; | ||
be<double> f64; | ||
struct { | ||
be<uint32_t> size; | ||
be<uint32_t> ptr; | ||
} unicode; | ||
be<float> f32; | ||
struct { | ||
be<uint32_t> size; | ||
be<uint32_t> ptr; | ||
} binary; | ||
be<uint64_t> filetime; | ||
}; | ||
}; | ||
static_assert_size(X_USER_DATA, 16); | ||
|
||
class DataByteStream : public ByteStream { | ||
public: | ||
DataByteStream(uint32_t ptr, uint8_t* data, size_t data_length, | ||
size_t offset = 0) | ||
: ByteStream(data, data_length, offset), ptr_(ptr) {} | ||
|
||
uint32_t ptr() const { return static_cast<uint32_t>(ptr_ + offset()); } | ||
|
||
private: | ||
uint32_t ptr_; | ||
}; | ||
|
||
class UserData { | ||
public: | ||
union Key { | ||
uint32_t value; | ||
struct { | ||
uint32_t id : 14; | ||
uint32_t unk : 2; | ||
uint32_t size : 12; | ||
uint32_t type : 4; | ||
}; | ||
}; | ||
|
||
UserData(){}; | ||
UserData(X_USER_DATA_TYPE type) { data_.type = type; } | ||
|
||
virtual void Append(X_USER_DATA* data, DataByteStream* stream) { | ||
data->type = data_.type; | ||
} | ||
|
||
virtual std::vector<uint8_t> Serialize() const { | ||
return std::vector<uint8_t>(); | ||
} | ||
virtual void Deserialize(std::vector<uint8_t>) {} | ||
|
||
private: | ||
X_USER_DATA data_ = {}; | ||
}; | ||
|
||
class Int32UserData : public UserData { | ||
public: | ||
Int32UserData(int32_t value) | ||
: UserData(X_USER_DATA_TYPE::INT32), value_(value) {} | ||
void Append(X_USER_DATA* data, DataByteStream* stream) override { | ||
UserData::Append(data, stream); | ||
data->s32 = value_; | ||
} | ||
|
||
private: | ||
int32_t value_; | ||
}; | ||
|
||
class Uint32UserData : public UserData { | ||
public: | ||
Uint32UserData(uint32_t value) | ||
: UserData(X_USER_DATA_TYPE::INT32), value_(value) {} | ||
void Append(X_USER_DATA* data, DataByteStream* stream) override { | ||
UserData::Append(data, stream); | ||
data->u32 = value_; | ||
} | ||
|
||
private: | ||
uint32_t value_; | ||
}; | ||
|
||
class Int64UserData : public UserData { | ||
public: | ||
Int64UserData(int64_t value) | ||
: UserData(X_USER_DATA_TYPE::INT64), value_(value) {} | ||
void Append(X_USER_DATA* data, DataByteStream* stream) override { | ||
UserData::Append(data, stream); | ||
data->s64 = value_; | ||
} | ||
|
||
private: | ||
int64_t value_; | ||
}; | ||
|
||
class FloatUserData : public UserData { | ||
public: | ||
FloatUserData(float value) | ||
: UserData(X_USER_DATA_TYPE::FLOAT), value_(value) {} | ||
|
||
void Append(X_USER_DATA* data, DataByteStream* stream) override { | ||
UserData::Append(data, stream); | ||
data->f32 = value_; | ||
} | ||
|
||
private: | ||
float value_; | ||
}; | ||
|
||
class DoubleUserData : public UserData { | ||
public: | ||
DoubleUserData(double value) | ||
: UserData(X_USER_DATA_TYPE::DOUBLE), value_(value) {} | ||
void Append(X_USER_DATA* data, DataByteStream* stream) override { | ||
UserData::Append(data, stream); | ||
data->f64 = value_; | ||
} | ||
|
||
private: | ||
double value_; | ||
}; | ||
|
||
class UnicodeUserData : public UserData { | ||
public: | ||
UnicodeUserData(const std::u16string& value) | ||
: UserData(X_USER_DATA_TYPE::WSTRING), value_(value) {} | ||
void Append(X_USER_DATA* data, DataByteStream* stream) override { | ||
UserData::Append(data, stream); | ||
|
||
if (value_.empty()) { | ||
data->unicode.size = 0; | ||
data->unicode.ptr = 0; | ||
return; | ||
} | ||
|
||
size_t count = value_.size() + 1; | ||
size_t size = 2 * count; | ||
assert_true(size <= std::numeric_limits<uint32_t>::max()); | ||
data->unicode.size = static_cast<uint32_t>(size); | ||
data->unicode.ptr = stream->ptr(); | ||
auto buffer = | ||
reinterpret_cast<uint16_t*>(&stream->data()[stream->offset()]); | ||
stream->Advance(size); | ||
copy_and_swap(buffer, (uint16_t*)value_.data(), count); | ||
} | ||
|
||
private: | ||
std::u16string value_; | ||
}; | ||
|
||
class BinaryUserData : public UserData { | ||
public: | ||
BinaryUserData(const std::vector<uint8_t>& value) | ||
: UserData(X_USER_DATA_TYPE::BINARY), value_(value) {} | ||
void Append(X_USER_DATA* data, DataByteStream* stream) override { | ||
UserData::Append(data, stream); | ||
|
||
if (value_.empty()) { | ||
data->binary.size = 0; | ||
data->binary.ptr = 0; | ||
return; | ||
} | ||
|
||
size_t size = value_.size(); | ||
assert_true(size <= std::numeric_limits<uint32_t>::max()); | ||
data->binary.size = static_cast<uint32_t>(size); | ||
data->binary.ptr = stream->ptr(); | ||
stream->Write(value_.data(), size); | ||
} | ||
|
||
std::vector<uint8_t> Serialize() const override { | ||
return std::vector<uint8_t>(value_.data(), value_.data() + value_.size()); | ||
} | ||
|
||
void Deserialize(std::vector<uint8_t> data) override { value_ = data; } | ||
|
||
private: | ||
std::vector<uint8_t> value_; | ||
}; | ||
|
||
class DateTimeUserData : public UserData { | ||
public: | ||
DateTimeUserData(int64_t value) | ||
: UserData(X_USER_DATA_TYPE::DATETIME), value_(value) {} | ||
|
||
void Append(X_USER_DATA* data, DataByteStream* stream) override { | ||
UserData::Append(data, stream); | ||
data->filetime = value_; | ||
} | ||
|
||
private: | ||
int64_t value_; | ||
}; | ||
|
||
} // namespace kernel | ||
} // namespace xe | ||
|
||
#endif |
Oops, something went wrong.