Dependency injection for apu/gpu/hid.
This commit is contained in:
parent
9a6c5c5c74
commit
5834a42ef3
|
@ -17,11 +17,103 @@
|
|||
#include "xenia/emulator.h"
|
||||
#include "xenia/ui/file_picker.h"
|
||||
|
||||
// Available audio systems:
|
||||
#include "xenia/apu/nop/nop_audio_system.h"
|
||||
#if XE_PLATFORM_WIN32
|
||||
#include "xenia/apu/xaudio2/xaudio2_audio_system.h"
|
||||
#endif // XE_PLATFORM_WIN32
|
||||
|
||||
// Available graphics systems:
|
||||
#include "xenia/gpu/gl4/gl4_graphics_system.h"
|
||||
|
||||
// Available input drivers:
|
||||
#include "xenia/hid/nop/nop_hid.h"
|
||||
#if XE_PLATFORM_WIN32
|
||||
#include "xenia/hid/winkey/winkey_hid.h"
|
||||
#include "xenia/hid/xinput/xinput_hid.h"
|
||||
#endif // XE_PLATFORM_WIN32
|
||||
|
||||
DEFINE_string(apu, "any", "Audio system. Use: [any, nop, xaudio2]");
|
||||
DEFINE_string(gpu, "any", "Graphics system. Use: [any, gl4]");
|
||||
DEFINE_string(hid, "any", "Input system. Use: [any, nop, winkey, xinput]");
|
||||
|
||||
DEFINE_string(target, "", "Specifies the target .xex or .iso to execute.");
|
||||
|
||||
namespace xe {
|
||||
namespace app {
|
||||
|
||||
std::unique_ptr<apu::AudioSystem> CreateAudioSystem(cpu::Processor* processor) {
|
||||
if (FLAGS_apu.compare("nop") == 0) {
|
||||
return apu::nop::NopAudioSystem::Create(processor);
|
||||
#if XE_PLATFORM_WIN32
|
||||
} else if (FLAGS_apu.compare("xaudio2") == 0) {
|
||||
return apu::xaudio2::XAudio2AudioSystem::Create(processor);
|
||||
#endif // XE_PLATFORM_WIN32
|
||||
} else {
|
||||
// Create best available.
|
||||
std::unique_ptr<apu::AudioSystem> best;
|
||||
|
||||
#if XE_PLATFORM_WIN32
|
||||
best = apu::xaudio2::XAudio2AudioSystem::Create(processor);
|
||||
if (best) {
|
||||
return best;
|
||||
}
|
||||
#endif // XE_PLATFORM_WIN32
|
||||
|
||||
// Fallback to nop.
|
||||
return apu::nop::NopAudioSystem::Create(processor);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<gpu::GraphicsSystem> CreateGraphicsSystem() {
|
||||
if (FLAGS_gpu.compare("gl4") == 0) {
|
||||
return std::unique_ptr<gpu::GraphicsSystem>(
|
||||
new xe::gpu::gl4::GL4GraphicsSystem());
|
||||
} else {
|
||||
// Create best available.
|
||||
std::unique_ptr<gpu::GraphicsSystem> best;
|
||||
|
||||
best = std::unique_ptr<gpu::GraphicsSystem>(
|
||||
new xe::gpu::gl4::GL4GraphicsSystem());
|
||||
if (best) {
|
||||
return best;
|
||||
}
|
||||
|
||||
// Nothing!
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<hid::InputDriver>> CreateInputDrivers(
|
||||
ui::Window* window) {
|
||||
std::vector<std::unique_ptr<hid::InputDriver>> drivers;
|
||||
if (FLAGS_hid.compare("nop") == 0) {
|
||||
drivers.emplace_back(xe::hid::nop::Create(window));
|
||||
#if XE_PLATFORM_WIN32
|
||||
} else if (FLAGS_hid.compare("winkey") == 0) {
|
||||
drivers.emplace_back(xe::hid::winkey::Create(window));
|
||||
} else if (FLAGS_hid.compare("xinput") == 0) {
|
||||
drivers.emplace_back(xe::hid::xinput::Create(window));
|
||||
#endif // XE_PLATFORM_WIN32
|
||||
} else {
|
||||
#if XE_PLATFORM_WIN32
|
||||
auto xinput_driver = xe::hid::xinput::Create(window);
|
||||
if (xinput_driver) {
|
||||
drivers.emplace_back(std::move(xinput_driver));
|
||||
}
|
||||
auto winkey_driver = xe::hid::winkey::Create(window);
|
||||
if (winkey_driver) {
|
||||
drivers.emplace_back(std::move(winkey_driver));
|
||||
}
|
||||
#endif // XE_PLATFORM_WIN32
|
||||
if (drivers.empty()) {
|
||||
// Fallback to nop if none created.
|
||||
drivers.emplace_back(xe::hid::nop::Create(window));
|
||||
}
|
||||
}
|
||||
return drivers;
|
||||
}
|
||||
|
||||
int xenia_main(const std::vector<std::wstring>& args) {
|
||||
Profiler::Initialize();
|
||||
Profiler::ThreadEnter("main");
|
||||
|
@ -34,7 +126,9 @@ int xenia_main(const std::vector<std::wstring>& args) {
|
|||
|
||||
// Setup and initialize all subsystems. If we can't do something
|
||||
// (unsupported system, memory issues, etc) this will fail early.
|
||||
X_STATUS result = emulator->Setup(emulator_window->window());
|
||||
X_STATUS result =
|
||||
emulator->Setup(emulator_window->window(), CreateAudioSystem,
|
||||
CreateGraphicsSystem, CreateInputDrivers);
|
||||
if (XFAILED(result)) {
|
||||
XELOGE("Failed to setup emulator: %.8X", result);
|
||||
return 1;
|
||||
|
|
|
@ -9,6 +9,4 @@
|
|||
|
||||
#include "xenia/apu/apu_flags.h"
|
||||
|
||||
DEFINE_string(apu, "any", "Audio system. Use: [any, nop, xaudio2]");
|
||||
|
||||
DEFINE_bool(mute, false, "Mutes all audio output.");
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
|
||||
#include <gflags/gflags.h>
|
||||
|
||||
DECLARE_string(apu);
|
||||
|
||||
DECLARE_bool(mute);
|
||||
|
||||
#endif // XENIA_APU_APU_FLAGS_H_
|
||||
|
|
|
@ -20,11 +20,6 @@
|
|||
#include "xenia/base/threading.h"
|
||||
#include "xenia/cpu/thread_state.h"
|
||||
|
||||
#include "xenia/apu/nop/nop_audio_system.h"
|
||||
#if XE_PLATFORM_WIN32
|
||||
#include "xenia/apu/xaudio2/xaudio2_audio_system.h"
|
||||
#endif // XE_PLATFORM_WIN32
|
||||
|
||||
// As with normal Microsoft, there are like twelve different ways to access
|
||||
// the audio APIs. Early games use XMA*() methods almost exclusively to touch
|
||||
// decoders. Later games use XAudio*() and direct memory writes to the XMA
|
||||
|
@ -40,29 +35,6 @@
|
|||
namespace xe {
|
||||
namespace apu {
|
||||
|
||||
std::unique_ptr<AudioSystem> AudioSystem::Create(cpu::Processor* processor) {
|
||||
if (FLAGS_apu.compare("nop") == 0) {
|
||||
return nop::NopAudioSystem::Create(processor);
|
||||
#if XE_PLATFORM_WIN32
|
||||
} else if (FLAGS_apu.compare("xaudio2") == 0) {
|
||||
return xaudio2::XAudio2AudioSystem::Create(processor);
|
||||
#endif // WIN32
|
||||
} else {
|
||||
// Create best available.
|
||||
std::unique_ptr<AudioSystem> best;
|
||||
|
||||
#if XE_PLATFORM_WIN32
|
||||
best = xaudio2::XAudio2AudioSystem::Create(processor);
|
||||
if (best) {
|
||||
return best;
|
||||
}
|
||||
#endif // XE_PLATFORM_WIN32
|
||||
|
||||
// Fallback to nop.
|
||||
return nop::NopAudioSystem::Create(processor);
|
||||
}
|
||||
}
|
||||
|
||||
AudioSystem::AudioSystem(cpu::Processor* processor)
|
||||
: memory_(processor->memory()),
|
||||
processor_(processor),
|
||||
|
|
|
@ -30,8 +30,6 @@ class AudioSystem {
|
|||
public:
|
||||
virtual ~AudioSystem();
|
||||
|
||||
static std::unique_ptr<AudioSystem> Create(cpu::Processor* processor);
|
||||
|
||||
Memory* memory() const { return memory_; }
|
||||
cpu::Processor* processor() const { return processor_; }
|
||||
XmaDecoder* xma_decoder() const { return xma_decoder_.get(); }
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "xenia/base/string.h"
|
||||
#include "xenia/cpu/backend/code_cache.h"
|
||||
#include "xenia/gpu/graphics_system.h"
|
||||
#include "xenia/hid/input_driver.h"
|
||||
#include "xenia/hid/input_system.h"
|
||||
#include "xenia/kernel/kernel_state.h"
|
||||
#include "xenia/kernel/xam/xam_module.h"
|
||||
|
@ -68,7 +69,14 @@ Emulator::~Emulator() {
|
|||
ExceptionHandler::Uninstall(Emulator::ExceptionCallbackThunk, this);
|
||||
}
|
||||
|
||||
X_STATUS Emulator::Setup(ui::Window* display_window) {
|
||||
X_STATUS Emulator::Setup(
|
||||
ui::Window* display_window,
|
||||
std::function<std::unique_ptr<apu::AudioSystem>(cpu::Processor*)>
|
||||
audio_system_factory,
|
||||
std::function<std::unique_ptr<gpu::GraphicsSystem>()>
|
||||
graphics_system_factory,
|
||||
std::function<std::vector<std::unique_ptr<hid::InputDriver>>(ui::Window*)>
|
||||
input_driver_factory) {
|
||||
X_STATUS result = X_STATUS_UNSUCCESSFUL;
|
||||
|
||||
display_window_ = display_window;
|
||||
|
@ -111,13 +119,15 @@ X_STATUS Emulator::Setup(ui::Window* display_window) {
|
|||
}
|
||||
|
||||
// Initialize the APU.
|
||||
audio_system_ = xe::apu::AudioSystem::Create(processor_.get());
|
||||
if (!audio_system_) {
|
||||
return X_STATUS_NOT_IMPLEMENTED;
|
||||
if (audio_system_factory) {
|
||||
audio_system_ = audio_system_factory(processor_.get());
|
||||
if (!audio_system_) {
|
||||
return X_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the GPU.
|
||||
graphics_system_ = xe::gpu::GraphicsSystem::Create();
|
||||
graphics_system_ = graphics_system_factory();
|
||||
if (!graphics_system_) {
|
||||
return X_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
@ -127,10 +137,16 @@ X_STATUS Emulator::Setup(ui::Window* display_window) {
|
|||
});
|
||||
|
||||
// Initialize the HID.
|
||||
input_system_ = xe::hid::InputSystem::Create(display_window_);
|
||||
input_system_ = std::make_unique<xe::hid::InputSystem>(display_window_);
|
||||
if (!input_system_) {
|
||||
return X_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
if (input_driver_factory) {
|
||||
auto input_drivers = input_driver_factory(display_window_);
|
||||
for (size_t i = 0; i < input_drivers.size(); ++i) {
|
||||
input_system_->AddDriver(std::move(input_drivers[i]));
|
||||
}
|
||||
}
|
||||
|
||||
result = input_system_->Setup();
|
||||
if (result) {
|
||||
|
@ -150,9 +166,11 @@ X_STATUS Emulator::Setup(ui::Window* display_window) {
|
|||
return result;
|
||||
}
|
||||
|
||||
result = audio_system_->Setup(kernel_state_.get());
|
||||
if (result) {
|
||||
return result;
|
||||
if (audio_system_) {
|
||||
result = audio_system_->Setup(kernel_state_.get());
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// HLE kernel modules.
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#ifndef XENIA_EMULATOR_H_
|
||||
#define XENIA_EMULATOR_H_
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
#include "xenia/base/exception_handler.h"
|
||||
|
@ -32,6 +33,7 @@ namespace gpu {
|
|||
class GraphicsSystem;
|
||||
} // namespace gpu
|
||||
namespace hid {
|
||||
class InputDriver;
|
||||
class InputSystem;
|
||||
} // namespace hid
|
||||
namespace ui {
|
||||
|
@ -68,7 +70,14 @@ class Emulator {
|
|||
|
||||
kernel::KernelState* kernel_state() const { return kernel_state_.get(); }
|
||||
|
||||
X_STATUS Setup(ui::Window* display_window);
|
||||
X_STATUS Setup(
|
||||
ui::Window* display_window,
|
||||
std::function<std::unique_ptr<apu::AudioSystem>(cpu::Processor*)>
|
||||
audio_system_factory,
|
||||
std::function<std::unique_ptr<gpu::GraphicsSystem>()>
|
||||
graphics_system_factory,
|
||||
std::function<std::vector<std::unique_ptr<hid::InputDriver>>(ui::Window*)>
|
||||
input_driver_factory);
|
||||
|
||||
X_STATUS LaunchPath(std::wstring path);
|
||||
X_STATUS LaunchXexFile(std::wstring path);
|
||||
|
|
|
@ -24,10 +24,6 @@ namespace xe {
|
|||
namespace gpu {
|
||||
namespace gl4 {
|
||||
|
||||
std::unique_ptr<GraphicsSystem> Create() {
|
||||
return std::make_unique<GL4GraphicsSystem>();
|
||||
}
|
||||
|
||||
std::unique_ptr<ui::GraphicsContext> GL4GraphicsSystem::CreateContext(
|
||||
ui::Window* target_window) {
|
||||
// Setup the GL control that actually does the drawing.
|
||||
|
|
|
@ -30,6 +30,10 @@ using namespace xe::gpu::xenos;
|
|||
|
||||
class GL4TraceViewer : public TraceViewer {
|
||||
public:
|
||||
std::unique_ptr<gpu::GraphicsSystem> CreateGraphicsSystem() override {
|
||||
return std::unique_ptr<gpu::GraphicsSystem>(new GL4GraphicsSystem());
|
||||
}
|
||||
|
||||
uintptr_t GetColorRenderTarget(uint32_t pitch, MsaaSamples samples,
|
||||
uint32_t base,
|
||||
ColorRenderTargetFormat format) override {
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
|
||||
#include "xenia/gpu/gpu_flags.h"
|
||||
|
||||
DEFINE_string(gpu, "any", "Graphics system. Use: [any, gl4]");
|
||||
|
||||
DEFINE_string(trace_gpu_prefix, "scratch/gpu/gpu_trace_",
|
||||
"Prefix path for GPU trace files.");
|
||||
DEFINE_bool(trace_gpu_stream, false, "Trace all GPU packets.");
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
|
||||
#include <gflags/gflags.h>
|
||||
|
||||
DECLARE_string(gpu);
|
||||
|
||||
DECLARE_string(trace_gpu_prefix);
|
||||
DECLARE_bool(trace_gpu_stream);
|
||||
|
||||
|
|
|
@ -21,27 +21,6 @@
|
|||
namespace xe {
|
||||
namespace gpu {
|
||||
|
||||
namespace gl4 {
|
||||
std::unique_ptr<GraphicsSystem> Create();
|
||||
} // namespace gl4
|
||||
|
||||
std::unique_ptr<GraphicsSystem> GraphicsSystem::Create() {
|
||||
if (FLAGS_gpu.compare("gl4") == 0) {
|
||||
return xe::gpu::gl4::Create();
|
||||
} else {
|
||||
// Create best available.
|
||||
std::unique_ptr<GraphicsSystem> best;
|
||||
|
||||
best = xe::gpu::gl4::Create();
|
||||
if (best) {
|
||||
return best;
|
||||
}
|
||||
|
||||
// Nothing!
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
GraphicsSystem::GraphicsSystem() : vsync_worker_running_(false) {}
|
||||
|
||||
GraphicsSystem::~GraphicsSystem() = default;
|
||||
|
|
|
@ -34,7 +34,6 @@ class GraphicsSystem {
|
|||
public:
|
||||
virtual ~GraphicsSystem();
|
||||
|
||||
static std::unique_ptr<GraphicsSystem> Create();
|
||||
virtual std::unique_ptr<ui::GraphicsContext> CreateContext(
|
||||
ui::Window* target_window) = 0;
|
||||
|
||||
|
|
|
@ -66,7 +66,9 @@ bool TraceViewer::Setup() {
|
|||
|
||||
// Create the emulator but don't initialize so we can setup the window.
|
||||
emulator_ = std::make_unique<Emulator>(L"");
|
||||
X_STATUS result = emulator_->Setup(window_.get());
|
||||
X_STATUS result =
|
||||
emulator_->Setup(window_.get(), nullptr,
|
||||
[this]() { return CreateGraphicsSystem(); }, nullptr);
|
||||
if (XFAILED(result)) {
|
||||
XELOGE("Failed to setup emulator: %.8X", result);
|
||||
return false;
|
||||
|
|
|
@ -44,6 +44,8 @@ class TraceViewer {
|
|||
protected:
|
||||
TraceViewer();
|
||||
|
||||
virtual std::unique_ptr<gpu::GraphicsSystem> CreateGraphicsSystem() = 0;
|
||||
|
||||
void DrawMultilineString(const std::string& str);
|
||||
|
||||
virtual uintptr_t GetColorRenderTarget(
|
||||
|
|
|
@ -22,12 +22,51 @@
|
|||
#include "xenia/ui/imgui_drawer.h"
|
||||
#include "xenia/ui/window.h"
|
||||
|
||||
// Available input drivers:
|
||||
#include "xenia/hid/nop/nop_hid.h"
|
||||
#if XE_PLATFORM_WIN32
|
||||
#include "xenia/hid/winkey/winkey_hid.h"
|
||||
#include "xenia/hid/xinput/xinput_hid.h"
|
||||
#endif // XE_PLATFORM_WIN32
|
||||
|
||||
DEFINE_string(hid, "any", "Input system. Use: [any, nop, winkey, xinput]");
|
||||
|
||||
namespace xe {
|
||||
namespace hid {
|
||||
|
||||
std::unique_ptr<xe::ui::ImGuiDrawer> imgui_drawer_;
|
||||
std::unique_ptr<xe::hid::InputSystem> input_system_;
|
||||
|
||||
std::vector<std::unique_ptr<hid::InputDriver>> CreateInputDrivers(
|
||||
ui::Window* window) {
|
||||
std::vector<std::unique_ptr<hid::InputDriver>> drivers;
|
||||
if (FLAGS_hid.compare("nop") == 0) {
|
||||
drivers.emplace_back(xe::hid::nop::Create(window));
|
||||
#if XE_PLATFORM_WIN32
|
||||
} else if (FLAGS_hid.compare("winkey") == 0) {
|
||||
drivers.emplace_back(xe::hid::winkey::Create(window));
|
||||
} else if (FLAGS_hid.compare("xinput") == 0) {
|
||||
drivers.emplace_back(xe::hid::xinput::Create(window));
|
||||
#endif // XE_PLATFORM_WIN32
|
||||
} else {
|
||||
#if XE_PLATFORM_WIN32
|
||||
auto xinput_driver = xe::hid::xinput::Create(window);
|
||||
if (xinput_driver) {
|
||||
drivers.emplace_back(std::move(xinput_driver));
|
||||
}
|
||||
auto winkey_driver = xe::hid::winkey::Create(window);
|
||||
if (winkey_driver) {
|
||||
drivers.emplace_back(std::move(winkey_driver));
|
||||
}
|
||||
#endif // XE_PLATFORM_WIN32
|
||||
if (drivers.empty()) {
|
||||
// Fallback to nop if none created.
|
||||
drivers.emplace_back(xe::hid::nop::Create(window));
|
||||
}
|
||||
}
|
||||
return drivers;
|
||||
}
|
||||
|
||||
std::unique_ptr<xe::ui::GraphicsContext> CreateDemoContext(
|
||||
xe::ui::Window* window) {
|
||||
return xe::ui::gl::GLContext::Create(window);
|
||||
|
@ -70,7 +109,11 @@ int hid_demo_main(const std::vector<std::wstring>& args) {
|
|||
imgui_drawer_->SetupDefaultInput();
|
||||
|
||||
// Initialize input system and all drivers.
|
||||
input_system_ = xe::hid::InputSystem::Create(window.get());
|
||||
input_system_ = std::make_unique<xe::hid::InputSystem>(window.get());
|
||||
auto drivers = CreateInputDrivers(window.get());
|
||||
for (size_t i = 0; i < drivers.size(); ++i) {
|
||||
input_system_->AddDriver(std::move(drivers[i]));
|
||||
}
|
||||
});
|
||||
|
||||
window->on_painting.AddListener([&](xe::ui::UIEvent* e) {
|
||||
|
|
|
@ -8,5 +8,3 @@
|
|||
*/
|
||||
|
||||
#include "xenia/hid/hid_flags.h"
|
||||
|
||||
DEFINE_string(hid, "any", "Input system. Use: [any, nop, winkey, xinput]");
|
||||
|
|
|
@ -12,6 +12,4 @@
|
|||
|
||||
#include <gflags/gflags.h>
|
||||
|
||||
DECLARE_string(hid);
|
||||
|
||||
#endif // XENIA_HID_HID_FLAGS_H_
|
||||
|
|
|
@ -12,8 +12,7 @@
|
|||
namespace xe {
|
||||
namespace hid {
|
||||
|
||||
InputDriver::InputDriver(InputSystem* input_system)
|
||||
: input_system_(input_system) {}
|
||||
InputDriver::InputDriver(xe::ui::Window* window) : window_(window) {}
|
||||
|
||||
InputDriver::~InputDriver() = default;
|
||||
|
||||
|
|
|
@ -13,6 +13,12 @@
|
|||
#include "xenia/hid/input.h"
|
||||
#include "xenia/xbox.h"
|
||||
|
||||
namespace xe {
|
||||
namespace ui {
|
||||
class Window;
|
||||
} // namespace ui
|
||||
} // namespace xe
|
||||
|
||||
namespace xe {
|
||||
namespace hid {
|
||||
|
||||
|
@ -33,9 +39,9 @@ class InputDriver {
|
|||
X_INPUT_KEYSTROKE* out_keystroke) = 0;
|
||||
|
||||
protected:
|
||||
explicit InputDriver(InputSystem* input_system);
|
||||
explicit InputDriver(xe::ui::Window* window);
|
||||
|
||||
InputSystem* input_system_ = nullptr;
|
||||
xe::ui::Window* window_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace hid
|
||||
|
|
|
@ -13,54 +13,9 @@
|
|||
#include "xenia/hid/hid_flags.h"
|
||||
#include "xenia/hid/input_driver.h"
|
||||
|
||||
#include "xenia/hid/nop/nop_hid.h"
|
||||
#if XE_PLATFORM_WIN32
|
||||
#include "xenia/hid/winkey/winkey_hid.h"
|
||||
#include "xenia/hid/xinput/xinput_hid.h"
|
||||
#endif // XE_PLATFORM_WIN32
|
||||
|
||||
namespace xe {
|
||||
namespace hid {
|
||||
|
||||
std::unique_ptr<InputSystem> InputSystem::Create(xe::ui::Window* window) {
|
||||
std::unique_ptr<InputSystem> input_system(new InputSystem(window));
|
||||
|
||||
if (FLAGS_hid.compare("nop") == 0) {
|
||||
input_system->AddDriver(xe::hid::nop::Create(input_system.get()));
|
||||
#if XE_PLATFORM_WIN32
|
||||
} else if (FLAGS_hid.compare("winkey") == 0) {
|
||||
input_system->AddDriver(xe::hid::winkey::Create(input_system.get()));
|
||||
} else if (FLAGS_hid.compare("xinput") == 0) {
|
||||
input_system->AddDriver(xe::hid::xinput::Create(input_system.get()));
|
||||
#endif // WIN32
|
||||
} else {
|
||||
// Create all available.
|
||||
bool any_created = false;
|
||||
|
||||
// NOTE: in any mode we create as many as we can, falling back to nop.
|
||||
|
||||
#if XE_PLATFORM_WIN32
|
||||
auto xinput_driver = xe::hid::xinput::Create(input_system.get());
|
||||
if (xinput_driver) {
|
||||
input_system->AddDriver(std::move(xinput_driver));
|
||||
any_created = true;
|
||||
}
|
||||
auto winkey_driver = xe::hid::winkey::Create(input_system.get());
|
||||
if (winkey_driver) {
|
||||
input_system->AddDriver(std::move(winkey_driver));
|
||||
any_created = true;
|
||||
}
|
||||
#endif // WIN32
|
||||
|
||||
// Fallback to nop if none created.
|
||||
if (!any_created) {
|
||||
input_system->AddDriver(xe::hid::nop::Create(input_system.get()));
|
||||
}
|
||||
}
|
||||
|
||||
return input_system;
|
||||
}
|
||||
|
||||
InputSystem::InputSystem(xe::ui::Window* window) : window_(window) {}
|
||||
|
||||
InputSystem::~InputSystem() = default;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "xenia/hid/input.h"
|
||||
#include "xenia/hid/input_driver.h"
|
||||
#include "xenia/xbox.h"
|
||||
|
||||
namespace xe {
|
||||
|
@ -25,14 +26,11 @@ class Window;
|
|||
namespace xe {
|
||||
namespace hid {
|
||||
|
||||
class InputDriver;
|
||||
|
||||
class InputSystem {
|
||||
public:
|
||||
explicit InputSystem(xe::ui::Window* window);
|
||||
~InputSystem();
|
||||
|
||||
static std::unique_ptr<InputSystem> Create(xe::ui::Window* window);
|
||||
|
||||
xe::ui::Window* window() const { return window_; }
|
||||
|
||||
X_STATUS Setup();
|
||||
|
@ -47,8 +45,6 @@ class InputSystem {
|
|||
X_INPUT_KEYSTROKE* out_keystroke);
|
||||
|
||||
private:
|
||||
explicit InputSystem(xe::ui::Window* window);
|
||||
|
||||
xe::ui::Window* window_ = nullptr;
|
||||
|
||||
std::vector<std::unique_ptr<InputDriver>> drivers_;
|
||||
|
|
|
@ -15,8 +15,8 @@ namespace xe {
|
|||
namespace hid {
|
||||
namespace nop {
|
||||
|
||||
std::unique_ptr<InputDriver> Create(InputSystem* input_system) {
|
||||
return std::make_unique<NopInputDriver>(input_system);
|
||||
std::unique_ptr<InputDriver> Create(xe::ui::Window* window) {
|
||||
return std::make_unique<NopInputDriver>(window);
|
||||
}
|
||||
|
||||
} // namespace nop
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace xe {
|
|||
namespace hid {
|
||||
namespace nop {
|
||||
|
||||
std::unique_ptr<InputDriver> Create(InputSystem* input_system);
|
||||
std::unique_ptr<InputDriver> Create(xe::ui::Window* window);
|
||||
|
||||
} // namespace nop
|
||||
} // namespace hid
|
||||
|
|
|
@ -15,10 +15,9 @@ namespace xe {
|
|||
namespace hid {
|
||||
namespace nop {
|
||||
|
||||
NopInputDriver::NopInputDriver(InputSystem* input_system)
|
||||
: InputDriver(input_system) {}
|
||||
NopInputDriver::NopInputDriver(xe::ui::Window* window) : InputDriver(window) {}
|
||||
|
||||
NopInputDriver::~NopInputDriver() {}
|
||||
NopInputDriver::~NopInputDriver() = default;
|
||||
|
||||
X_STATUS NopInputDriver::Setup() { return X_STATUS_SUCCESS; }
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace nop {
|
|||
|
||||
class NopInputDriver : public InputDriver {
|
||||
public:
|
||||
explicit NopInputDriver(InputSystem* input_system);
|
||||
explicit NopInputDriver(xe::ui::Window* window);
|
||||
~NopInputDriver() override;
|
||||
|
||||
X_STATUS Setup() override;
|
||||
|
|
|
@ -15,8 +15,8 @@ namespace xe {
|
|||
namespace hid {
|
||||
namespace winkey {
|
||||
|
||||
std::unique_ptr<InputDriver> Create(InputSystem* input_system) {
|
||||
return std::make_unique<WinKeyInputDriver>(input_system);
|
||||
std::unique_ptr<InputDriver> Create(xe::ui::Window* window) {
|
||||
return std::make_unique<WinKeyInputDriver>(window);
|
||||
}
|
||||
|
||||
} // namespace winkey
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace xe {
|
|||
namespace hid {
|
||||
namespace winkey {
|
||||
|
||||
std::unique_ptr<InputDriver> Create(InputSystem* input_system);
|
||||
std::unique_ptr<InputDriver> Create(xe::ui::Window* window);
|
||||
|
||||
} // namespace winkey
|
||||
} // namespace hid
|
||||
|
|
|
@ -19,10 +19,10 @@ namespace xe {
|
|||
namespace hid {
|
||||
namespace winkey {
|
||||
|
||||
WinKeyInputDriver::WinKeyInputDriver(InputSystem* input_system)
|
||||
: InputDriver(input_system), packet_number_(1) {
|
||||
WinKeyInputDriver::WinKeyInputDriver(xe::ui::Window* window)
|
||||
: InputDriver(window), packet_number_(1) {
|
||||
// Register a key listener.
|
||||
input_system_->window()->on_key_down.AddListener([this](ui::KeyEvent* evt) {
|
||||
window_->on_key_down.AddListener([this](ui::KeyEvent* evt) {
|
||||
auto global_lock = global_critical_region_.Acquire();
|
||||
|
||||
KeyEvent key;
|
||||
|
@ -32,7 +32,7 @@ WinKeyInputDriver::WinKeyInputDriver(InputSystem* input_system)
|
|||
key.repeat_count = evt->repeat_count();
|
||||
key_events_.push(key);
|
||||
});
|
||||
input_system_->window()->on_key_up.AddListener([this](ui::KeyEvent* evt) {
|
||||
window_->on_key_up.AddListener([this](ui::KeyEvent* evt) {
|
||||
auto global_lock = global_critical_region_.Acquire();
|
||||
|
||||
KeyEvent key;
|
||||
|
@ -89,7 +89,7 @@ X_RESULT WinKeyInputDriver::GetState(uint32_t user_index,
|
|||
int16_t thumb_rx = 0;
|
||||
int16_t thumb_ry = 0;
|
||||
|
||||
if (input_system_->window()->has_focus()) {
|
||||
if (window_->has_focus()) {
|
||||
if (IS_KEY_TOGGLED(VK_CAPITAL)) {
|
||||
// dpad toggled
|
||||
if (IS_KEY_DOWN(0x41)) {
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace winkey {
|
|||
|
||||
class WinKeyInputDriver : public InputDriver {
|
||||
public:
|
||||
explicit WinKeyInputDriver(InputSystem* input_system);
|
||||
explicit WinKeyInputDriver(xe::ui::Window* window);
|
||||
~WinKeyInputDriver() override;
|
||||
|
||||
X_STATUS Setup() override;
|
||||
|
|
|
@ -15,8 +15,8 @@ namespace xe {
|
|||
namespace hid {
|
||||
namespace xinput {
|
||||
|
||||
std::unique_ptr<InputDriver> Create(InputSystem* input_system) {
|
||||
return std::make_unique<XInputInputDriver>(input_system);
|
||||
std::unique_ptr<InputDriver> Create(xe::ui::Window* window) {
|
||||
return std::make_unique<XInputInputDriver>(window);
|
||||
}
|
||||
|
||||
} // namespace xinput
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace xe {
|
|||
namespace hid {
|
||||
namespace xinput {
|
||||
|
||||
std::unique_ptr<InputDriver> Create(InputSystem* input_system);
|
||||
std::unique_ptr<InputDriver> Create(xe::ui::Window* window);
|
||||
|
||||
} // namespace xinput
|
||||
} // namespace hid
|
||||
|
|
|
@ -19,8 +19,8 @@ namespace xe {
|
|||
namespace hid {
|
||||
namespace xinput {
|
||||
|
||||
XInputInputDriver::XInputInputDriver(InputSystem* input_system)
|
||||
: InputDriver(input_system) {
|
||||
XInputInputDriver::XInputInputDriver(xe::ui::Window* window)
|
||||
: InputDriver(window) {
|
||||
XInputEnable(TRUE);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace xinput {
|
|||
|
||||
class XInputInputDriver : public InputDriver {
|
||||
public:
|
||||
explicit XInputInputDriver(InputSystem* input_system);
|
||||
explicit XInputInputDriver(xe::ui::Window* window);
|
||||
~XInputInputDriver() override;
|
||||
|
||||
X_STATUS Setup() override;
|
||||
|
|
Loading…
Reference in New Issue