[UI] Notification & Custom Font Support

This commit is contained in:
Gliniak
2023-02-28 12:55:29 +01:00
committed by Radosław Gliński
parent 069d33c03f
commit 0ec65be5ff
14 changed files with 4953 additions and 55 deletions

View File

@@ -0,0 +1,63 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2023 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "achievement_manager.h"
#include "xenia/emulator.h"
#include "xenia/gpu/graphics_system.h"
#include "xenia/kernel/kernel_state.h"
#include "xenia/kernel/util/shim_utils.h"
#include "xenia/ui/imgui_notification.h"
DEFINE_bool(show_achievement_notification, true,
"Show achievement notification on screen.", "UI");
namespace xe {
namespace kernel {
AchievementManager::AchievementManager(){};
void AchievementManager::EarnAchievement(uint64_t xuid, uint32_t title_id,
uint32_t achievement_id) {
const Emulator* emulator = kernel_state()->emulator();
ui::WindowedAppContext& app_context =
kernel_state()->emulator()->display_window()->app_context();
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();
for (const util::XdbfAchievementTableEntry& entry : achievements) {
if (entry.id == achievement_id) {
const std::string label = title_xdbf.GetStringTableEntry(
title_xdbf.default_language(), entry.label_id);
const std::string desc = title_xdbf.GetStringTableEntry(
title_xdbf.default_language(), entry.description_id);
XELOGI("Achievement unlocked: {}", label);
const std::string description =
fmt::format("{}G - {}", entry.gamerscore, label);
// 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_);
});
}
}
}
} // namespace kernel
} // namespace xe

View File

@@ -0,0 +1,36 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2023 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_KERNEL_ACHIEVEMENT_MANAGER_H_
#define XENIA_KERNEL_ACHIEVEMENT_MANAGER_H_
#include <string>
#include <vector>
#include "xenia/xbox.h"
namespace xe {
namespace kernel {
class AchievementManager {
public:
AchievementManager();
void EarnAchievement(uint64_t xuid, uint32_t title_id,
uint32_t achievement_id);
private:
// void Load();
// void Save();
};
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_ACHIEVEMENT_MANAGER_H_

View File

@@ -52,6 +52,7 @@ KernelState::KernelState(Emulator* emulator)
file_system_ = emulator->file_system();
app_manager_ = std::make_unique<xam::AppManager>();
achievement_manager_ = std::make_unique<AchievementManager>();
user_profiles_.emplace(0, std::make_unique<xam::UserProfile>(0));
auto content_root = emulator_->content_root();

View File

@@ -30,6 +30,7 @@
#include "xenia/memory.h"
#include "xenia/vfs/virtual_file_system.h"
#include "xenia/xbox.h"
#include "achievement_manager.h"
namespace xe {
class ByteStream;
@@ -103,6 +104,9 @@ class KernelState {
util::XdbfGameData title_xdbf() const;
util::XdbfGameData module_xdbf(object_ref<UserModule> exec_module) const;
AchievementManager* achievement_manager() const {
return achievement_manager_.get();
}
xam::AppManager* app_manager() const { return app_manager_.get(); }
xam::ContentManager* content_manager() const {
return content_manager_.get();
@@ -229,6 +233,7 @@ class KernelState {
bool Save(ByteStream* stream);
bool Restore(ByteStream* stream);
uint32_t notification_position_ = 0;
private:
void LoadKernelModule(object_ref<KernelModule> kernel_module);
@@ -240,6 +245,7 @@ class KernelState {
std::unique_ptr<xam::AppManager> app_manager_;
std::unique_ptr<xam::ContentManager> content_manager_;
std::map<uint8_t, std::unique_ptr<xam::UserProfile>> user_profiles_;
std::unique_ptr<AchievementManager> achievement_manager_;
xe::global_critical_region global_critical_region_;

View File

@@ -17,6 +17,11 @@ namespace kernel {
namespace xam {
namespace apps {
struct X_XUSER_ACHIEVEMENT {
xe::be<uint32_t> user_idx;
xe::be<uint32_t> achievement_id;
};
XgiApp::XgiApp(KernelState* kernel_state) : App(kernel_state, 0xFB) {}
// http://mb.mirage.org/bugzilla/xliveless/main.c
@@ -55,6 +60,13 @@ X_HRESULT XgiApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
uint32_t achievements_ptr = xe::load_and_swap<uint32_t>(buffer + 4);
XELOGD("XGIUserWriteAchievements({:08X}, {:08X})", achievement_count,
achievements_ptr);
auto* achievement =
(X_XUSER_ACHIEVEMENT*)memory_->TranslateVirtual(achievements_ptr);
for (uint32_t i = 0; i < achievement_count; i++, achievement++) {
kernel_state_->achievement_manager()->EarnAchievement(
achievement->user_idx, 0, achievement->achievement_id);
}
return X_E_SUCCESS;
}
case 0x000B0010: {

View File

@@ -98,6 +98,7 @@ dword_result_t XNotifyDelayUI_entry(dword_t delay_ms) {
DECLARE_XAM_EXPORT1(XNotifyDelayUI, kNone, kStub);
void XNotifyPositionUI_entry(dword_t position) {
kernel_state()->notification_position_ = position;
// Ignored.
}
DECLARE_XAM_EXPORT1(XNotifyPositionUI, kNone, kStub);