Skip to content

Commit

Permalink
Merge branch 'xenia-canary:canary_experimental' into Custom
Browse files Browse the repository at this point in the history
  • Loading branch information
backgamon authored Dec 25, 2023
2 parents 80bc9a3 + e0f0dc7 commit 87f5051
Show file tree
Hide file tree
Showing 8 changed files with 282 additions and 33 deletions.
42 changes: 42 additions & 0 deletions src/xenia/app/emulator_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,14 @@ void EmulatorWindow::EmulatorWindowListener::OnKeyDown(ui::KeyEvent& e) {
emulator_window_.OnKeyDown(e);
}

void EmulatorWindow::EmulatorWindowListener::OnMouseDown(ui::MouseEvent& e) {
emulator_window_.OnMouseDown(e);
}

void EmulatorWindow::EmulatorWindowListener::OnMouseUp(ui::MouseEvent& e) {
emulator_window_.OnMouseUp(e);
}

void EmulatorWindow::DisplayConfigGameConfigLoadCallback::PostGameConfigLoad() {
emulator_window_.ApplyDisplayConfigForCvars();
}
Expand Down Expand Up @@ -864,6 +872,40 @@ void EmulatorWindow::OnKeyDown(ui::KeyEvent& e) {
e.set_handled(true);
}

void EmulatorWindow::OnMouseDown(const ui::MouseEvent& e) {
ToggleFullscreenOnDoubleClick();
}

void EmulatorWindow::OnMouseUp(const ui::MouseEvent& e) {
last_mouse_up = steady_clock::now();
}

void EmulatorWindow::ToggleFullscreenOnDoubleClick() {
// this function tests if user has double clicked.
// if double click was achieved the fullscreen gets toggled
const auto now = steady_clock::now(); // current mouse event time
const int16_t mouse_down_max_threshold = 250;
const int16_t mouse_up_max_threshold = 250;
const int16_t mouse_up_down_max_delta = 100;
// max delta to prevent 'chaining' of double clicks with next mouse events

const auto last_mouse_down_delta = diff_in_ms(now, last_mouse_down);
if (last_mouse_down_delta >= mouse_down_max_threshold) {
last_mouse_down = now;
return;
}

const auto last_mouse_up_delta = diff_in_ms(now, last_mouse_up);
const auto mouse_event_deltas = diff_in_ms(last_mouse_up, last_mouse_down);
if (last_mouse_up_delta >= mouse_up_max_threshold) {
return;
}

if (mouse_event_deltas < mouse_up_down_max_delta) {
ToggleFullscreen();
}
}

void EmulatorWindow::FileDrop(const std::filesystem::path& path) {
if (!emulator_initialized_) {
return;
Expand Down
20 changes: 19 additions & 1 deletion src/xenia/app/emulator_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ struct RecentTitleEntry {

class EmulatorWindow {
public:
using steady_clock = std::chrono::steady_clock; // stdlib steady clock

enum : size_t {
// The UI is on top of the game and is open in special cases, so
// lowest-priority.
Expand All @@ -57,7 +59,17 @@ class EmulatorWindow {
std::unique_ptr<xe::threading::Thread> Gamepad_HotKeys_Listener;

int32_t selected_title_index = -1;


static constexpr int64_t diff_in_ms(
const steady_clock::time_point t1,
const steady_clock::time_point t2) noexcept {
using ms = std::chrono::milliseconds;
return std::chrono::duration_cast<ms>(t1 - t2).count();
}

steady_clock::time_point last_mouse_up = steady_clock::now();
steady_clock::time_point last_mouse_down = steady_clock::now();

Emulator* emulator() const { return emulator_; }
ui::WindowedAppContext& app_context() const { return app_context_; }
ui::Window* window() const { return window_.get(); }
Expand Down Expand Up @@ -131,6 +143,9 @@ class EmulatorWindow {

void OnKeyDown(ui::KeyEvent& e) override;

void OnMouseDown(ui::MouseEvent& e) override;
void OnMouseUp(ui::MouseEvent& e) override;

private:
EmulatorWindow& emulator_window_;
};
Expand Down Expand Up @@ -184,7 +199,10 @@ class EmulatorWindow {
void ApplyDisplayConfigForCvars();

void OnKeyDown(ui::KeyEvent& e);
void OnMouseDown(const ui::MouseEvent& e);
void ToggleFullscreenOnDoubleClick();
void FileDrop(const std::filesystem::path& filename);
void OnMouseUp(const ui::MouseEvent& e);
void FileOpen();
void FileClose();
void InstallContent();
Expand Down
20 changes: 20 additions & 0 deletions src/xenia/emulator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1042,6 +1042,26 @@ X_STATUS Emulator::CompleteLaunch(const std::filesystem::path& path,
}
XELOGI("----------------- END OF ACHIEVEMENTS ----------------");

XELOGI("-------------------- PROPERTIES --------------------");
const std::vector<kernel::util::XdbfPropertyTableEntry> properties_list =
db.GetProperties();

for (const kernel::util::XdbfPropertyTableEntry& entry :
properties_list) {
std::string label = db.GetStringTableEntry(language, entry.string_id);
XELOGI("{:08X} - {} - {}", entry.id, label, entry.data_size);
}
XELOGI("----------------- END OF PROPERTIES ----------------");

XELOGI("-------------------- CONTEXTS --------------------");
const std::vector<kernel::util::XdbfContextTableEntry> contexts_list =
db.GetContexts();

for (const kernel::util::XdbfContextTableEntry& entry : contexts_list) {
std::string label = db.GetStringTableEntry(language, entry.string_id);
XELOGI("{:08X} - {} - {}", entry.id, label, entry.unk2);
}
XELOGI("----------------- END OF CONTEXTS ----------------");
auto icon_block = db.icon();
if (icon_block) {
display_window_->SetIcon(icon_block.buffer, icon_block.size);
Expand Down
54 changes: 28 additions & 26 deletions src/xenia/kernel/achievement_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,36 +36,38 @@ void AchievementManager::EarnAchievement(uint64_t xuid, uint32_t title_id,
ui::ImGuiDrawer* imgui_drawer = emulator->imgui_drawer();

const util::XdbfGameData title_xdbf = kernel_state()->title_xdbf();
const std::vector<util::XdbfAchievementTableEntry> achievements =
title_xdbf.GetAchievements();
const util::XdbfAchievementTableEntry achievement =
title_xdbf.GetAchievement(achievement_id);

if (!achievement.id) {
return;
}

const XLanguage title_language = title_xdbf.GetExistingLanguage(
static_cast<XLanguage>(cvars::user_language));

for (const util::XdbfAchievementTableEntry& entry : achievements) {
if (entry.id == achievement_id) {
const std::string label =
title_xdbf.GetStringTableEntry(title_language, entry.label_id);
const std::string desc =
title_xdbf.GetStringTableEntry(title_language, entry.description_id);

XELOGI("Achievement unlocked: {}", label);
const std::string description =
fmt::format("{}G - {}", entry.gamerscore, label);

unlocked_achievements[achievement_id] = Clock::QueryHostSystemTime();
// Even if we disable popup we still should store info that this
// achievement was earned.
if (!cvars::show_achievement_notification) {
continue;
}

app_context.CallInUIThread([imgui_drawer, description]() {
new xe::ui::AchievementNotificationWindow(
imgui_drawer, "Achievement unlocked", description, 0,
kernel_state()->notification_position_);
});
}
const std::string label =
title_xdbf.GetStringTableEntry(title_language, achievement.label_id);
const std::string desc = title_xdbf.GetStringTableEntry(
title_language, achievement.description_id);

XELOGI("Achievement unlocked: {}", label);

unlocked_achievements[achievement_id] = Clock::QueryHostSystemTime();
// Even if we disable popup we still should store info that this
// achievement was earned.
if (!cvars::show_achievement_notification) {
return;
}

const std::string description =
fmt::format("{}G - {}", achievement.gamerscore, label);

app_context.CallInUIThread([imgui_drawer, description]() {
new xe::ui::AchievementNotificationWindow(
imgui_drawer, "Achievement unlocked", description, 0,
kernel_state()->notification_position_);
});
}

bool AchievementManager::IsAchievementUnlocked(uint32_t achievement_id) {
Expand Down
92 changes: 88 additions & 4 deletions src/xenia/kernel/util/xdbf_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@ constexpr fourcc_t kXdbfSignatureXdbf = make_fourcc("XDBF");
constexpr fourcc_t kXdbfSignatureXstc = make_fourcc("XSTC");
constexpr fourcc_t kXdbfSignatureXstr = make_fourcc("XSTR");
constexpr fourcc_t kXdbfSignatureXach = make_fourcc("XACH");
constexpr fourcc_t kXdbfSignatureXprp = make_fourcc("XPRP");
constexpr fourcc_t kXdbfSignatureXcxt = make_fourcc("XCXT");

constexpr uint64_t kXdbfIdTitle = 0x8000;
constexpr uint64_t kXdbfIdXstc = 0x58535443;
constexpr uint64_t kXdbfIdXach = 0x58414348;
constexpr uint64_t kXdbfIdXprp = 0x58505250;
constexpr uint64_t kXdbfIdXctx = 0x58435854;

XdbfWrapper::XdbfWrapper(const uint8_t* data, size_t data_size)
: data_(data), data_size_(data_size) {
Expand Down Expand Up @@ -69,11 +73,11 @@ std::string XdbfWrapper::GetStringTableEntry(XLanguage language,
}

auto xstr_head =
reinterpret_cast<const XdbfSectionHeader*>(language_block.buffer);
reinterpret_cast<const XdbfXstrSectionHeader*>(language_block.buffer);
assert_true(xstr_head->magic == kXdbfSignatureXstr);
assert_true(xstr_head->version == 1);

const uint8_t* ptr = language_block.buffer + sizeof(XdbfSectionHeader);
const uint8_t* ptr = language_block.buffer + sizeof(XdbfXstrSectionHeader);
for (uint16_t i = 0; i < xstr_head->count; ++i) {
auto entry = reinterpret_cast<const XdbfStringTableEntry*>(ptr);
ptr += sizeof(XdbfStringTableEntry);
Expand All @@ -95,11 +99,11 @@ std::vector<XdbfAchievementTableEntry> XdbfWrapper::GetAchievements() const {
}

auto xach_head =
reinterpret_cast<const XdbfSectionHeader*>(achievement_table.buffer);
reinterpret_cast<const XdbfXachSectionHeader*>(achievement_table.buffer);
assert_true(xach_head->magic == kXdbfSignatureXach);
assert_true(xach_head->version == 1);

const uint8_t* ptr = achievement_table.buffer + sizeof(XdbfSectionHeader);
const uint8_t* ptr = achievement_table.buffer + sizeof(XdbfXachSectionHeader);
for (uint16_t i = 0; i < xach_head->count; ++i) {
auto entry = reinterpret_cast<const XdbfAchievementTableEntry*>(ptr);
ptr += sizeof(XdbfAchievementTableEntry);
Expand All @@ -108,6 +112,86 @@ std::vector<XdbfAchievementTableEntry> XdbfWrapper::GetAchievements() const {
return achievements;
}

std::vector<XdbfPropertyTableEntry> XdbfWrapper::GetProperties() const {
std::vector<XdbfPropertyTableEntry> properties;

auto property_table = GetEntry(XdbfSection::kMetadata, kXdbfIdXprp);
if (!property_table) {
return properties;
}

auto xprp_head =
reinterpret_cast<const XdbfXprpSectionHeader*>(property_table.buffer);
assert_true(xprp_head->magic == kXdbfSignatureXprp);
assert_true(xprp_head->version == 1);

const uint8_t* ptr = property_table.buffer + sizeof(XdbfXprpSectionHeader);
for (uint16_t i = 0; i < xprp_head->count; ++i) {
auto entry = reinterpret_cast<const XdbfPropertyTableEntry*>(ptr);
ptr += sizeof(XdbfPropertyTableEntry);
properties.push_back(*entry);
}
return properties;
}

std::vector<XdbfContextTableEntry> XdbfWrapper::GetContexts() const {
std::vector<XdbfContextTableEntry> contexts;

auto contexts_table = GetEntry(XdbfSection::kMetadata, kXdbfIdXctx);
if (!contexts_table) {
return contexts;
}

auto xcxt_head =
reinterpret_cast<const XdbfXcxtSectionHeader*>(contexts_table.buffer);
assert_true(xcxt_head->magic == kXdbfSignatureXcxt);
assert_true(xcxt_head->version == 1);

const uint8_t* ptr = contexts_table.buffer + sizeof(XdbfXcxtSectionHeader);
for (uint16_t i = 0; i < xcxt_head->count; ++i) {
auto entry = reinterpret_cast<const XdbfContextTableEntry*>(ptr);
ptr += sizeof(XdbfContextTableEntry);
contexts.push_back(*entry);
}
return contexts;
}

XdbfAchievementTableEntry XdbfWrapper::GetAchievement(const uint32_t id) const {
const auto achievements = GetAchievements();

for (const auto& entry : achievements) {
if (entry.id != id) {
continue;
}
return entry;
}
return {};
}

XdbfPropertyTableEntry XdbfWrapper::GetProperty(const uint32_t id) const {
const auto properties = GetProperties();

for (const auto& entry : properties) {
if (entry.id != id) {
continue;
}
return entry;
}
return {};
}

XdbfContextTableEntry XdbfWrapper::GetContext(const uint32_t id) const {
const auto contexts = GetContexts();

for (const auto& entry : contexts) {
if (entry.id != id) {
continue;
}
return entry;
}
return {};
}

XLanguage XdbfGameData::GetExistingLanguage(XLanguage language_to_check) const {
// A bit of a hack. Check if title in specific language exist.
// If it doesn't then for sure language is not supported.
Expand Down
Loading

0 comments on commit 87f5051

Please sign in to comment.