mirror of https://github.com/AxioDL/metaforce.git
Initial port configuration (needs cleanup)
This commit is contained in:
parent
f8d9207aaa
commit
10d4bbf297
|
@ -89,6 +89,7 @@ set(RUNTIME_SOURCES_B
|
|||
Streams/ContainerReaders.hpp
|
||||
Streams/CTextInStream.hpp Streams/CTextInStream.cpp
|
||||
Streams/CTextOutStream.hpp Streams/CTextOutStream.cpp
|
||||
Streams/CFileOutStream.hpp Streams/CFileOutStream.cpp
|
||||
CGameAllocator.hpp CGameAllocator.cpp
|
||||
CMemoryCardSys.hpp CMemoryCardSys.cpp
|
||||
CScannableObjectInfo.hpp CScannableObjectInfo.cpp
|
||||
|
|
|
@ -1,15 +1,64 @@
|
|||
#include "Runtime/ImGuiControllerConfig.hpp"
|
||||
|
||||
#include "Runtime/Streams/CFileOutStream.hpp"
|
||||
#include "Runtime/Streams/ContainerReaders.hpp"
|
||||
#include "Runtime/Streams/ContainerWriters.hpp"
|
||||
|
||||
#include "aurora/pad.hpp"
|
||||
#include "aurora/aurora.hpp"
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
namespace metaforce {
|
||||
ImGuiControllerConfig::Button::Button(CInputStream& in)
|
||||
: button(in.Get<s32>())
|
||||
, uvX(in.Get<u32>())
|
||||
, uvY(in.Get<u32>())
|
||||
, width(in.Get<u32>())
|
||||
, height(in.Get<u32>())
|
||||
, offX(in.Get<float>())
|
||||
, offY(in.Get<float>()) {}
|
||||
|
||||
void ImGuiControllerConfig::Button::PutTo(COutputStream& out) const {
|
||||
out.Put(button);
|
||||
out.Put(uvX);
|
||||
out.Put(uvY);
|
||||
out.Put(width);
|
||||
out.Put(height);
|
||||
out.Put(offX);
|
||||
out.Put(offY);
|
||||
}
|
||||
|
||||
ImGuiControllerConfig::ControllerAtlas::ControllerAtlas(CInputStream& in) : name(in.Get<std::string>()) {
|
||||
u32 vidPidCount = in.Get<u32>();
|
||||
vidPids.reserve(vidPidCount);
|
||||
|
||||
for (u32 i = 0; i < vidPidCount; ++i) {
|
||||
u16 vid = static_cast<u16>(in.Get<s16>());
|
||||
u16 pid = static_cast<u16>(in.Get<s16>());
|
||||
vidPids.emplace_back(vid, pid);
|
||||
}
|
||||
|
||||
atlasFile = in.Get<std::string>();
|
||||
read_vector(buttons, in);
|
||||
};
|
||||
|
||||
void ImGuiControllerConfig::ControllerAtlas::PutTo(COutputStream& out) const {
|
||||
out.Put(name);
|
||||
out.Put(static_cast<u32>(vidPids.size()));
|
||||
for (const auto& vidPid : vidPids) {
|
||||
out.Put(vidPid.first);
|
||||
out.Put(vidPid.second);
|
||||
}
|
||||
|
||||
write_vector(buttons, out);
|
||||
}
|
||||
|
||||
void ImGuiControllerConfig::show(bool& visible) {
|
||||
|
||||
/** TODO:
|
||||
* - Implement multiple controllers
|
||||
* - Implement setting controller ports
|
||||
* - Implement setting controller ports (except for the GameCube adapter, which is hard coded)
|
||||
* - Implement fancy graphical UI
|
||||
*/
|
||||
|
||||
|
@ -18,56 +67,127 @@ void ImGuiControllerConfig::show(bool& visible) {
|
|||
}
|
||||
|
||||
if (m_pendingMapping != nullptr) {
|
||||
s32 nativeButton = PADGetNativeButtonPressed(0);
|
||||
s32 nativeButton = PADGetNativeButtonPressed(m_pendingPort);
|
||||
if (nativeButton != -1) {
|
||||
m_pendingMapping->nativeButton = nativeButton;
|
||||
m_pendingMapping = nullptr;
|
||||
m_pendingPort = -1;
|
||||
PADBlockInput(false);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> controllers;
|
||||
controllers.push_back("None");
|
||||
for (u32 i = 0; i < PADCount(); ++i) {
|
||||
controllers.push_back(fmt::format(FMT_STRING("{}-{}"), PADGetNameForControllerIndex(i), i));
|
||||
}
|
||||
|
||||
m_pendingValid = false;
|
||||
if (ImGui::Begin("Controller Config", &visible)) {
|
||||
ImGui::Text("%s", PADGetName(0));
|
||||
u32 buttonCount = 0;
|
||||
PADButtonMapping* mapping = PADGetButtonMappings(0, &buttonCount);
|
||||
if (mapping != nullptr) {
|
||||
for (u32 i = 0; i < buttonCount; ++i) {
|
||||
bool pressed = ImGui::Button(PADGetButtonName(mapping[i].padButton));
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%s", PADGetNativeButtonName(mapping[i].nativeButton));
|
||||
|
||||
if (pressed && m_pendingMapping == nullptr) {
|
||||
m_pendingMapping = &mapping[i];
|
||||
PADBlockInput(true);
|
||||
if (ImGui::CollapsingHeader("Ports")) {
|
||||
for (u32 i = 0; i < 4; ++i) {
|
||||
ImGui::PushID(fmt::format(FMT_STRING("PortConf-{}"), i).c_str());
|
||||
s32 index = PADGetIndexForPort(i);
|
||||
int sel = 0;
|
||||
std::string name = "None";
|
||||
const char* tmpName = PADGetName(i);
|
||||
bool changed = false;
|
||||
if (tmpName != nullptr) {
|
||||
name = fmt::format(FMT_STRING("{}-{}"), tmpName, index);
|
||||
}
|
||||
if (ImGui::BeginCombo(fmt::format(FMT_STRING("Port {}"), i + 1).c_str(), name.c_str())) {
|
||||
for (u32 j = 0; const auto& s : controllers) {
|
||||
if (ImGui::Selectable(s.c_str(), name == s)) {
|
||||
sel = j;
|
||||
changed = true;
|
||||
}
|
||||
++j;
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if (m_pendingMapping == &mapping[i]) {
|
||||
ImGui::SameLine();
|
||||
ImGui::Text(" - Waiting for button...");
|
||||
if (changed) {
|
||||
if (sel > 0) {
|
||||
PADSetPortForIndex(sel - 1, i);
|
||||
} else if (sel == 0) {
|
||||
PADClearPort(i);
|
||||
}
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
if (ImGui::BeginTabBar("Controllers")) {
|
||||
for (u32 i = 0; i < 4; ++i) {
|
||||
if (ImGui::BeginTabItem(fmt::format(FMT_STRING("Port {}"), i + 1).c_str())) {
|
||||
ImGui::PushID(fmt::format(FMT_STRING("Port_{}"), i + 1).c_str());
|
||||
/* If the tab is changed while pending for input, cancel the pending port */
|
||||
if (m_pendingMapping != nullptr && m_pendingPort != i) {
|
||||
m_pendingMapping = nullptr;
|
||||
m_pendingValid = false;
|
||||
m_pendingPort = -1;
|
||||
}
|
||||
u32 vid, pid;
|
||||
PADGetVidPid(i, &vid, &pid);
|
||||
if (vid == 0 && pid == 0) {
|
||||
ImGui::EndTabItem();
|
||||
ImGui::PopID();
|
||||
continue;
|
||||
}
|
||||
ImGui::Text("%s", PADGetName(i));
|
||||
u32 buttonCount = 0;
|
||||
PADButtonMapping* mapping = PADGetButtonMappings(i, &buttonCount);
|
||||
if (mapping != nullptr) {
|
||||
for (u32 m = 0; m < buttonCount; ++m) {
|
||||
const char* padName = PADGetButtonName(mapping[m].padButton);
|
||||
if (padName == nullptr) {
|
||||
continue;
|
||||
}
|
||||
ImGui::PushID(padName);
|
||||
bool pressed = ImGui::Button(padName);
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%s", PADGetNativeButtonName(mapping[m].nativeButton));
|
||||
|
||||
if (ImGui::CollapsingHeader("Dead-zones")) {
|
||||
PADDeadZones* deadZones = PADGetDeadZones(0);
|
||||
ImGui::Checkbox("Use Dead-zones", &deadZones->useDeadzones);
|
||||
s32 tmp = deadZones->stickDeadZone;
|
||||
if (ImGui::DragInt("Left Stick", &tmp)) {
|
||||
deadZones->stickDeadZone = tmp;
|
||||
}
|
||||
tmp = deadZones->substickDeadZone;
|
||||
if (ImGui::DragInt("Right Stick", &tmp)) {
|
||||
deadZones->substickDeadZone = tmp;
|
||||
}
|
||||
ImGui::Checkbox("Emulate Triggers", &deadZones->emulateTriggers);
|
||||
tmp = deadZones->leftTriggerActivationZone;
|
||||
if (ImGui::DragInt("Left Trigger Activation", &tmp)) {
|
||||
deadZones->leftTriggerActivationZone = tmp;
|
||||
}
|
||||
tmp = deadZones->rightTriggerActivationZone;
|
||||
if (ImGui::DragInt("Right Trigger Activation", &tmp)) {
|
||||
deadZones->rightTriggerActivationZone = tmp;
|
||||
if (pressed && m_pendingMapping == nullptr) {
|
||||
m_pendingMapping = &mapping[m];
|
||||
m_pendingPort = i;
|
||||
PADBlockInput(true);
|
||||
}
|
||||
|
||||
if (m_pendingMapping == &mapping[m]) {
|
||||
m_pendingValid = true;
|
||||
ImGui::SameLine();
|
||||
ImGui::Text(" - Waiting for button...");
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::CollapsingHeader("Dead-zones")) {
|
||||
PADDeadZones* deadZones = PADGetDeadZones(i);
|
||||
ImGui::Checkbox("Use Dead-zones", &deadZones->useDeadzones);
|
||||
float tmp = static_cast<float>(deadZones->stickDeadZone * 100.f) / 32767.f;
|
||||
if (ImGui::DragFloat("Left Stick", &tmp, 0.5f, 0.f, 100.f, "%.3f%%")) {
|
||||
deadZones->stickDeadZone = static_cast<u16>((tmp / 100.f) * 32767);
|
||||
}
|
||||
tmp = static_cast<float>(deadZones->substickDeadZone * 100.f) / 32767.f;
|
||||
if (ImGui::DragFloat("Right Stick", &tmp, 0.5f, 0.f, 100.f, "%.3f%%")) {
|
||||
deadZones->substickDeadZone = static_cast<u16>((tmp / 100.f) * 32767);
|
||||
}
|
||||
ImGui::Checkbox("Emulate Triggers", &deadZones->emulateTriggers);
|
||||
tmp = static_cast<float>(deadZones->leftTriggerActivationZone * 100.f) / 32767.f;
|
||||
if (ImGui::DragFloat("Left Trigger Activation", &tmp, 0.5f, 0.f, 100.f, "%.3f%%")) {
|
||||
deadZones->leftTriggerActivationZone = static_cast<u16>((tmp / 100.f) * 32767);
|
||||
}
|
||||
tmp = static_cast<float>(deadZones->rightTriggerActivationZone * 100.f) / 32767.f;
|
||||
if (ImGui::DragFloat("Right Trigger Activation", &tmp, 0.5f, 0.f, 100.f, "%.3f%%")) {
|
||||
deadZones->rightTriggerActivationZone = static_cast<u16>((tmp / 100.f) * 32767);
|
||||
}
|
||||
}
|
||||
ImGui::PopID();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
@ -96,6 +216,23 @@ void ImGuiControllerConfig::showEditor(bool& visible) {
|
|||
}
|
||||
|
||||
if (ImGui::Begin("Controller Atlas Editor", &visible)) {
|
||||
/* TODO: Atlas editor */
|
||||
ImGui::Separator();
|
||||
if (ImGui::Button("Save Controller Database")) {
|
||||
CFileOutStream out("ControllerAtlases.ctrdb");
|
||||
out.WriteUint32(SLITTLE('CTDB'));
|
||||
out.WriteUint32(1); // Version
|
||||
write_vector(m_controllerAtlases, out);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Export") && m_currentAtlas != nullptr) {
|
||||
CFileOutStream out("test.ctratlas");
|
||||
out.Put(SLITTLE('CTRA'));
|
||||
out.Put(1); // Version
|
||||
out.Put(*m_currentAtlas);
|
||||
}
|
||||
|
||||
/* TODO: Import logic */
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "Runtime/GCNTypes.hpp"
|
||||
#include "Runtime/Streams/CInputStream.hpp"
|
||||
#include "Runtime/Streams/COutputStream.hpp"
|
||||
#include "aurora/pad.hpp"
|
||||
|
||||
#include <array>
|
||||
|
@ -11,20 +13,28 @@
|
|||
namespace metaforce {
|
||||
class ImGuiControllerConfig {
|
||||
struct Button {
|
||||
u32 button; // the SDL button this entry corresponds to
|
||||
u32 uvX; // Offset if icon image in atlas from left (in pixels)
|
||||
u32 uvY; // Offset if icon image in atlas from top (in pixels)
|
||||
u32 width; // Width of button image (in pixels)
|
||||
u32 height; // Height of button image (in pixels)
|
||||
float offX; // Offset from left of config window
|
||||
float offY; // Offset from top of config window
|
||||
s32 button = -1; // the SDL button this entry corresponds to
|
||||
u32 uvX = 0; // Offset if icon image in atlas from left (in pixels)
|
||||
u32 uvY = 0; // Offset if icon image in atlas from top (in pixels)
|
||||
u32 width = 32; // Width of button image (in pixels)
|
||||
u32 height = 32; // Height of button image (in pixels)
|
||||
float offX = 0.f; // Offset from left of config window
|
||||
float offY = 0.f; // Offset from top of config window
|
||||
|
||||
Button() = default;
|
||||
explicit Button(CInputStream& in);
|
||||
void PutTo(COutputStream& in) const;
|
||||
};
|
||||
|
||||
struct ControllerMapping {
|
||||
struct ControllerAtlas {
|
||||
std::string name;
|
||||
std::pair<u32, u32> vidPid;
|
||||
std::vector<std::pair<u16, u16>> vidPids;
|
||||
std::string atlasFile; // Path to atlas relative to controller definition
|
||||
std::vector<Button> buttons;
|
||||
|
||||
ControllerAtlas() = default;
|
||||
explicit ControllerAtlas(CInputStream& in);
|
||||
void PutTo(COutputStream& out) const;
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -34,9 +44,12 @@ private:
|
|||
void showEditor(bool& visible);
|
||||
|
||||
PADButtonMapping* m_pendingMapping = nullptr;
|
||||
s32 m_pendingPort = 0;
|
||||
bool m_pendingValid = false;
|
||||
bool m_editorVisible = false;
|
||||
|
||||
std::array<ControllerMapping*, 4> m_controllers;
|
||||
std::vector<ControllerMapping> m_mappings;
|
||||
|
||||
ControllerAtlas* m_currentAtlas = nullptr;
|
||||
std::vector<ControllerAtlas> m_controllerAtlases;
|
||||
};
|
||||
} // namespace metaforce
|
|
@ -30,8 +30,11 @@ void CInputGenerator::Update(float dt, CArchitectureQueue& queue) {
|
|||
if (i == 0) {
|
||||
firstController = true;
|
||||
}
|
||||
m_lastInput = CFinalInput(i, dt, cont, xc_leftDiv, x10_rightDiv);
|
||||
queue.Push(MakeMsg::CreateUserInput(EArchMsgTarget::Game, m_lastInput));
|
||||
auto tmp = CFinalInput(i, dt, cont, xc_leftDiv, x10_rightDiv);
|
||||
if (i == 0) {
|
||||
m_lastInput = tmp;
|
||||
}
|
||||
queue.Push(MakeMsg::CreateUserInput(EArchMsgTarget::Game, tmp));
|
||||
++availSlot;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
#include "Runtime/Streams/CFileOutStream.hpp"
|
||||
|
||||
namespace metaforce {
|
||||
CFileOutStream::CFileOutStream(std::string_view name, u32 blockLen) : COutputStream(blockLen) {
|
||||
m_file = fopen(name.data(), "wbe");
|
||||
}
|
||||
|
||||
CFileOutStream::~CFileOutStream() {
|
||||
Flush();
|
||||
if (m_file) {
|
||||
fclose(m_file);
|
||||
}
|
||||
}
|
||||
|
||||
void CFileOutStream::Write(const u8* ptr, u32 len) {
|
||||
if (!m_file) {
|
||||
return;
|
||||
}
|
||||
fwrite(ptr, 1, len, m_file);
|
||||
}
|
||||
} // namespace metaforce
|
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include "Runtime/Streams/COutputStream.hpp"
|
||||
#include <cstdio>
|
||||
|
||||
namespace metaforce {
|
||||
class CFileOutStream final : public COutputStream {
|
||||
FILE* m_file;
|
||||
public:
|
||||
explicit CFileOutStream(std::string_view name, u32 blockLen = 4096);
|
||||
virtual ~CFileOutStream();
|
||||
|
||||
protected:
|
||||
void Write(const u8* ptr, u32 len);
|
||||
};
|
||||
} // namespace metaforce
|
|
@ -97,9 +97,15 @@ struct PADButtonMapping {
|
|||
PAD::BUTTON padButton;
|
||||
};
|
||||
|
||||
s32 PADGetCount();
|
||||
void PADGetVidPid(u32 idx, u32* vid, u32* pid);
|
||||
const char* PADGetName(u32 idx);
|
||||
/* Returns the total number of controllers */
|
||||
u32 PADCount();
|
||||
/* Returns the controller name for the given index into the controller map */
|
||||
const char* PADGetNameForControllerIndex(u32 idx);
|
||||
void PADSetPortForIndex(u32 index, s32 port);
|
||||
s32 PADGetIndexForPort(u32 port);
|
||||
void PADGetVidPid(u32 port, u32* vid, u32* pid);
|
||||
void PADClearPort(u32 port);
|
||||
const char* PADGetName(u32 port);
|
||||
void PADSetButtonMapping(u32 port, PADButtonMapping mapping);
|
||||
void PADSetAllButtonMappings(u32 port, PADButtonMapping buttons[12]);
|
||||
PADButtonMapping* PADGetButtonMappings(u32 port, u32* buttonCount);
|
||||
|
|
|
@ -22,7 +22,7 @@ struct GameController {
|
|||
PADDeadZones m_deadZones;
|
||||
u16 m_vid = 0;
|
||||
u16 m_pid = 0;
|
||||
std::array<PADButtonMapping, 12> m_mapping;
|
||||
std::array<PADButtonMapping, 12> m_mapping{};
|
||||
bool m_mappingLoaded = false;
|
||||
constexpr bool operator==(const GameController& other) const {
|
||||
return m_controller == other.m_controller && m_index == other.m_index;
|
||||
|
@ -37,20 +37,24 @@ GameController* get_controller_for_player(u32 player) noexcept {
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* If we don't have a controller assigned to this port use the first unassigned controller */
|
||||
if (!g_GameControllers.empty()) {
|
||||
int32_t availIndex = -1;
|
||||
for (const auto& controller : g_GameControllers) {
|
||||
if (player_index(controller.second.m_index) == -1) {
|
||||
availIndex = controller.second.m_index;
|
||||
GameController* ct = nullptr;
|
||||
for (auto& controller : g_GameControllers) {
|
||||
if (player_index(controller.first) == -1) {
|
||||
availIndex = controller.first;
|
||||
ct = &controller.second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (availIndex != -1) {
|
||||
set_player_index(g_GameControllers.begin()->second.m_index, player);
|
||||
return get_controller_for_player(player);
|
||||
set_player_index(availIndex, player);
|
||||
return ct;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -389,6 +393,71 @@ static const std::array<PADButtonMapping, 12> mDefaultButtons{{
|
|||
void PADSetSpec(s32 spec) {}
|
||||
void PADInit() {}
|
||||
|
||||
aurora::input::GameController* __PADGetControllerForIndex(u32 idx) {
|
||||
if (idx >= aurora::input::g_GameControllers.size()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
u32 tmp = 0;
|
||||
auto iter = aurora::input::g_GameControllers.begin();
|
||||
while (tmp < idx) {
|
||||
++iter;
|
||||
++tmp;
|
||||
}
|
||||
if (iter == aurora::input::g_GameControllers.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &iter->second;
|
||||
}
|
||||
|
||||
u32 PADCount() { return aurora::input::g_GameControllers.size(); }
|
||||
|
||||
const char* PADGetNameForControllerIndex(u32 idx) {
|
||||
auto* ctrl = __PADGetControllerForIndex(idx);
|
||||
if (ctrl == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return SDL_GameControllerName(ctrl->m_controller);
|
||||
}
|
||||
|
||||
void PADSetPortForIndex(u32 idx, s32 port) {
|
||||
auto* ctrl = __PADGetControllerForIndex(idx);
|
||||
auto* dest = aurora::input::get_controller_for_player(port);
|
||||
if (ctrl == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (dest != nullptr) {
|
||||
SDL_GameControllerSetPlayerIndex(dest->m_controller, -1);
|
||||
}
|
||||
SDL_GameControllerSetPlayerIndex(ctrl->m_controller, port);
|
||||
}
|
||||
|
||||
s32 PADGetIndexForPort(u32 port) {
|
||||
auto* ctrl = aurora::input::get_controller_for_player(port);
|
||||
if (ctrl == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
s32 index = 0;
|
||||
for (auto iter = aurora::input::g_GameControllers.begin(); iter != aurora::input::g_GameControllers.end();
|
||||
++iter, ++index) {
|
||||
if (&iter->second == ctrl) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
void PADClearPort(u32 port) {
|
||||
auto* ctrl = aurora::input::get_controller_for_player(port);
|
||||
if (ctrl == nullptr) {
|
||||
return;
|
||||
}
|
||||
SDL_GameControllerSetPlayerIndex(ctrl->m_controller, -1);
|
||||
}
|
||||
|
||||
void __PADLoadMapping(aurora::input::GameController* controller) {
|
||||
s32 playerIndex = SDL_GameControllerGetPlayerIndex(controller->m_controller);
|
||||
if (playerIndex == -1) {
|
||||
|
@ -402,11 +471,9 @@ void __PADLoadMapping(aurora::input::GameController* controller) {
|
|||
|
||||
controller->m_mappingLoaded = true;
|
||||
|
||||
FILE* file =
|
||||
fopen(fmt::format(FMT_STRING("{}/{}_{:04X}_{:04X}.controller"), basePath,
|
||||
aurora::input::controller_name(controller->m_index), controller->m_vid, controller->m_pid)
|
||||
.c_str(),
|
||||
"rbe");
|
||||
auto path = fmt::format(FMT_STRING("{}/{}_{:04X}_{:04X}.controller"), basePath, PADGetName(playerIndex),
|
||||
controller->m_vid, controller->m_pid);
|
||||
FILE* file = fopen(path.c_str(), "rbe");
|
||||
if (file == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
@ -434,7 +501,7 @@ void __PADLoadMapping(aurora::input::GameController* controller) {
|
|||
}
|
||||
|
||||
fread(&controller->m_deadZones, 1, sizeof(PADDeadZones), file);
|
||||
fread(&controller->m_mapping, 1, sizeof(PADButtonMapping), file);
|
||||
fread(&controller->m_mapping, 1, sizeof(PADButtonMapping) * controller->m_mapping.size(), file);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
|
@ -455,9 +522,6 @@ u32 PADRead(PAD::Status* status) {
|
|||
|
||||
if (!controller->m_mappingLoaded) {
|
||||
__PADLoadMapping(controller);
|
||||
#ifndef NDEBUG
|
||||
PADSerializeMappings();
|
||||
#endif
|
||||
}
|
||||
status[i].xa_err = PAD::ERR_NONE;
|
||||
std::for_each(controller->m_mapping.begin(), controller->m_mapping.end(),
|
||||
|
@ -563,7 +627,7 @@ void PADControlAllMotors(const u32* commands) {
|
|||
}
|
||||
|
||||
u32 SIProbe(s32 chan) {
|
||||
auto *const controller = aurora::input::get_controller_for_player(chan);
|
||||
auto* const controller = aurora::input::get_controller_for_player(chan);
|
||||
if (controller == nullptr) {
|
||||
return SI::ERROR_NO_RESPONSE;
|
||||
}
|
||||
|
@ -735,26 +799,10 @@ void PADClampCircle(PAD::Status* status) {
|
|||
}
|
||||
}
|
||||
|
||||
s32 PADGetCount() { return aurora::input::g_GameControllers.size(); }
|
||||
|
||||
aurora::input::GameController* __PADGetController(s32 idx) {
|
||||
auto iter = aurora::input::g_GameControllers.begin();
|
||||
s32 i = 0;
|
||||
for (; aurora::input::g_GameControllers.begin() != aurora::input::g_GameControllers.end() && i < idx; ++iter, ++i) {}
|
||||
if (iter == aurora::input::g_GameControllers.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &iter->second;
|
||||
}
|
||||
|
||||
void PADGetVidPid(u32 idx, u32* vid, u32* pid) {
|
||||
void PADGetVidPid(u32 port, u32* vid, u32* pid) {
|
||||
*vid = 0;
|
||||
*pid = 0;
|
||||
if (idx < 0 || idx >= aurora::input::g_GameControllers.size()) {
|
||||
return;
|
||||
}
|
||||
auto* controller = __PADGetController(idx);
|
||||
auto* controller = aurora::input::get_controller_for_player(port);
|
||||
if (controller == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
@ -763,8 +811,8 @@ void PADGetVidPid(u32 idx, u32* vid, u32* pid) {
|
|||
*pid = controller->m_pid;
|
||||
}
|
||||
|
||||
const char* PADGetName(u32 idx) {
|
||||
auto* controller = __PADGetController(idx);
|
||||
const char* PADGetName(u32 port) {
|
||||
auto* controller = aurora::input::get_controller_for_player(port);
|
||||
if (controller == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -916,6 +964,4 @@ void PADRestoreDefaultMapping(u32 port) {
|
|||
controller->m_mapping = mDefaultButtons;
|
||||
}
|
||||
|
||||
void PADBlockInput(bool block) {
|
||||
gBlockPAD = block;
|
||||
}
|
||||
void PADBlockInput(bool block) { gBlockPAD = block; }
|
Loading…
Reference in New Issue