Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for bot input over EXI interface #329

Draft
wants to merge 1 commit into
base: slippi
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions Source/Core/Core/HW/EXI_DeviceSlippi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
//#include "Core/PatchEngine.h"
#include "Core/PowerPC/PowerPC.h"

#include "InputCommon/ControllerInterface/ControllerInterface.h"

// Not clean but idk a better way atm
#include "DolphinWX/Frame.h"
#include "DolphinWX/Main.h"
Expand Down Expand Up @@ -2944,6 +2946,35 @@ void CEXISlippi::prepareDelayResponse()
}
}

void CEXISlippi::prepareOverwriteInputs()
{
m_read_queue.clear();
// If blocking pipe input is configured, this will block until pipe input is sent for this frame
g_controller_interface.UpdateInput();
std::map<int, SlippiPad> pads = g_controller_interface.GetSlippiPads();

// Insert the pads
for (int i = 1; i <= 4; i++)
{
if (pads.count(i-1) != 0)
{
// Do overwrite this port
m_read_queue.push_back(1);
for (int j = 0; j < SLIPPI_PAD_DATA_SIZE; j++)
{
m_read_queue.push_back(pads[i-1].padBuf[j]);
}
}
else
{
// Don't overwrite this port
m_read_queue.push_back(0);
appendWordToBuffer(&m_read_queue, 0);
appendWordToBuffer(&m_read_queue, 0);
}
}
}

void CEXISlippi::DMAWrite(u32 _uAddr, u32 _uSize)
{
u8 *memPtr = Memory::GetPointer(_uAddr);
Expand Down Expand Up @@ -3092,6 +3123,9 @@ void CEXISlippi::DMAWrite(u32 _uAddr, u32 _uSize)
case CMD_GET_DELAY:
prepareDelayResponse();
break;
case CMD_OVERWRITE_INPUTS:
prepareOverwriteInputs();
break;
default:
writeToFileAsync(&memPtr[bufLoc], payloadLen + 1, "");
m_slippiserver->write(&memPtr[bufLoc], payloadLen + 1);
Expand Down
3 changes: 3 additions & 0 deletions Source/Core/Core/HW/EXI_DeviceSlippi.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ class CEXISlippi : public IEXIDevice
CMD_GCT_LENGTH = 0xD3,
CMD_GCT_LOAD = 0xD4,
CMD_GET_DELAY = 0xD5,
CMD_OVERWRITE_INPUTS = 0xD6,
CMD_PREMADE_TEXT_LENGTH = 0xE1,
CMD_PREMADE_TEXT_LOAD = 0xE2,
};
Expand Down Expand Up @@ -135,6 +136,7 @@ class CEXISlippi : public IEXIDevice
{CMD_GCT_LENGTH, 0x0},
{CMD_GCT_LOAD, 0x4},
{CMD_GET_DELAY, 0x0},
{CMD_OVERWRITE_INPUTS, 0x0},
{CMD_PREMADE_TEXT_LENGTH, 0x2},
{CMD_PREMADE_TEXT_LOAD, 0x2},
};
Expand Down Expand Up @@ -212,6 +214,7 @@ class CEXISlippi : public IEXIDevice
void prepareGctLength();
void prepareGctLoad(u8 *payload);
void prepareDelayResponse();
void prepareOverwriteInputs();
void preparePremadeTextLength(u8 *payload);
void preparePremadeTextLoad(u8 *payload);

Expand Down
6 changes: 6 additions & 0 deletions Source/Core/Core/Slippi/SlippiPad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
// TODO: Confirm the default and padding values are right
static u8 emptyPad[SLIPPI_PAD_FULL_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

SlippiPad::SlippiPad()
{
this->frame = 0;
memcpy(this->padBuf, emptyPad, SLIPPI_PAD_FULL_SIZE);
}

SlippiPad::SlippiPad(int32_t frame)
{
this->frame = frame;
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/Slippi/SlippiPad.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
class SlippiPad
{
public:
SlippiPad();
SlippiPad(int32_t frame);
SlippiPad(int32_t frame, u8* padBuf);
SlippiPad(int32_t frame, u8 playerIdx, u8 *padBuf);
Expand All @@ -17,4 +18,3 @@ class SlippiPad
u8 playerIdx;
u8 padBuf[SLIPPI_PAD_FULL_SIZE];
};

Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
#include "InputCommon/ControllerInterface/Pipes/Pipes.h"
#endif

#include "InputCommon/InputConfig.h"
#include "InputCommon/ControllerEmu.h"
#include "Core/HW/GCPad.h"

using namespace ciface::ExpressionParser;

namespace
Expand Down Expand Up @@ -237,6 +241,40 @@ void ControllerInterface::InvokeHotplugCallbacks() const
callback();
}

std::map<int, SlippiPad> ControllerInterface::GetSlippiPads()
{
std::map<int, SlippiPad> pads;
// Loop through all input devices
{
std::lock_guard<std::mutex> lk(m_devices_mutex);

for (u32 i = 0; i < m_devices.size(); i++)
{
std::shared_ptr<ciface::Core::Device> d = m_devices[i];
if (d->GetSource() == "Pipe")
{
ciface::Pipes::PipeDevice* x = (ciface::Pipes::PipeDevice*)d.get();

// Find which controller this device is attached to
for(int j = 0; j < 4; j++)
{
const auto device_type = SConfig::GetInstance().m_SIDevice[j];
if (device_type == 6) //TODO
{
ciface::Core::DeviceQualifier device = Pad::GetConfig()->GetController(j)->default_device;
if (device.name == d->GetName())
{
pads[j] = (x)->GetSlippiPad();
}
}
}
}
}
}

return pads;
}

//
// InputReference :: State
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <string>
#include <vector>

#include "Core/Slippi/SlippiPad.h"
#include "Common/CommonTypes.h"
#include "Common/Thread.h"
#include "InputCommon/ControllerInterface/Device.h"
Expand Down Expand Up @@ -127,6 +128,7 @@ class ControllerInterface : public ciface::Core::DeviceContainer

void RegisterHotplugCallback(std::function<void(void)> callback);
void InvokeHotplugCallbacks() const;
std::map<int, SlippiPad> GetSlippiPads();

private:
std::vector<std::function<void()>> m_hotplug_callbacks;
Expand Down
110 changes: 109 additions & 1 deletion Source/Core/InputCommon/ControllerInterface/Pipes/Pipes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,31 @@ void PipeDevice::AddAxis(const std::string& name, double value)

void PipeDevice::SetAxis(const std::string& entry, double value)
{
if (entry.compare("MAIN X") == 0)
{
m_current_pad.padBuf[2] = u8 ((value * 255) + 128) % 256;
}
if (entry.compare("MAIN Y") == 0)
{
m_current_pad.padBuf[3] = u8 ((value * 255) + 128) % 256;
}
if (entry.compare("C X") == 0)
{
m_current_pad.padBuf[4] = u8 ((value * 255) + 128) % 256;
}
if (entry.compare("C Y") == 0)
{
m_current_pad.padBuf[5] = u8 ((value * 255) + 128) % 256;
}
if (entry.compare("L") == 0)
{
m_current_pad.padBuf[6] = u8 (value * 256);
}
if (entry.compare("R") == 0)
{
m_current_pad.padBuf[7] = u8 (value * 256);
}

value = MathUtil::Clamp(value, 0.0, 1.0);
double hi = std::max(0.0, value - 0.5) * 2.0;
double lo = (0.5 - std::min(0.5, value)) * 2.0;
Expand All @@ -239,6 +264,7 @@ bool PipeDevice::ParseCommand(const std::string& command)
return false;
if (tokens[0] == "PRESS" || tokens[0] == "RELEASE")
{
SetButtonState(tokens[1], tokens[0]);
auto search = m_buttons.find(tokens[1]);
if (search != m_buttons.end())
search->second->SetState(tokens[0] == "PRESS" ? 1.0 : 0.0);
Expand All @@ -248,7 +274,7 @@ bool PipeDevice::ParseCommand(const std::string& command)
if (tokens.size() == 3)
{
double value = StringToDouble(tokens[2]);
SetAxis(tokens[1], (value / 2.0) + 0.5);
SetAxis(tokens[1], value);
}
else if (tokens.size() == 4)
{
Expand All @@ -260,5 +286,87 @@ bool PipeDevice::ParseCommand(const std::string& command)
}
return false;
}

SlippiPad PipeDevice::GetSlippiPad()
{
return m_current_pad;
}

void PipeDevice::SetButtonState(const std::string& button, const std::string& press)
{
u8 mask = 0x00;
int index = 0;
bool is_press = press == "PRESS";

if (button.compare("A") == 0)
{
mask = 0x01;
index = 0;
}
if (button.compare("B") == 0)
{
mask = 0x02;
index = 0;
}
if (button.compare("X") == 0)
{
mask = 0x04;
index = 0;
}
if (button.compare("Y") == 0)
{
mask = 0x08;
index = 0;
}
if (button.compare("L") == 0)
{
mask = 0x40;
index = 1;
}
if (button.compare("R") == 0)
{
mask = 0x20;
index = 1;
}
if (button.compare("START") == 0)
{
mask = 0x10;
index = 0;
}
if (button.compare("D_LEFT") == 0)
{
mask = 0x01;
index = 1;
}
if (button.compare("D_RIGHT") == 0)
{
mask = 0x02;
index = 1;
}
if (button.compare("D_DOWN") == 0)
{
mask = 0x04;
index = 1;
}
if (button.compare("D_UP") == 0)
{
mask = 0x08;
index = 1;
}
if (button.compare("Z") == 0)
{
mask = 0x10;
index = 1;
}
if (is_press)
{
m_current_pad.padBuf[index] |= mask;
}
else
{
m_current_pad.padBuf[index] &= ~(mask);
}
}

}
}
5 changes: 5 additions & 0 deletions Source/Core/InputCommon/ControllerInterface/Pipes/Pipes.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include <unistd.h>
#endif

#include "Core/Slippi/SlippiPad.h"

extern bool g_needInputForFrame;

namespace ciface
Expand Down Expand Up @@ -47,6 +49,7 @@ class PipeDevice : public Core::Device
void UpdateInput() override;
std::string GetName() const override { return m_name; }
std::string GetSource() const override { return "Pipe"; }
SlippiPad GetSlippiPad();
private:
class PipeInput : public Input
{
Expand All @@ -64,12 +67,14 @@ class PipeDevice : public Core::Device
bool ParseCommand(const std::string& command);
void SetAxis(const std::string& entry, double value);
s32 readFromPipe(PIPE_FD file_descriptor, char *in_buffer, size_t size);
void SetButtonState(const std::string& button, const std::string& press);

const PIPE_FD m_fd;
const std::string m_name;
std::string m_buf;
std::map<std::string, PipeInput*> m_buttons;
std::map<std::string, PipeInput*> m_axes;
SlippiPad m_current_pad;
};
}
}