Skip to content

Commit

Permalink
[XAM] Changes to settings handling
Browse files Browse the repository at this point in the history
- 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
Gliniak committed Feb 18, 2024
1 parent f6b5424 commit ecbd696
Show file tree
Hide file tree
Showing 4 changed files with 446 additions and 266 deletions.
234 changes: 234 additions & 0 deletions src/xenia/kernel/util/xuserdata.h
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
Loading

0 comments on commit ecbd696

Please sign in to comment.