Initial CControllerRecorder imp (very WIP)

This commit is contained in:
Phillip Stephens 2021-05-29 00:41:52 -07:00
parent fe965cde0e
commit 4cfc4e78ec
Signed by: Antidote
GPG Key ID: F8BEE4C83DACA60D
7 changed files with 145 additions and 13 deletions

View File

@ -0,0 +1,50 @@
#include "Runtime/Input/CControllerRecorder.hpp"
#include "Runtime/Graphics/CGraphics.hpp"
#include "Runtime/CArchitectureQueue.hpp"
#include "Runtime/CArchitectureMessage.hpp"
namespace metaforce {
bool CControllerRecorder::ProcessInput(const CFinalInput& in, s32 frame, CArchitectureQueue& queue) {
if (m_mode == EMode::Record) {
m_finalInputs[frame] = in;
return false;
} else {
SetMode(EMode::Record);
}
if (m_mode == EMode::Play && m_finalInputs.find(frame) != m_finalInputs.end()) {
queue.Push(MakeMsg::CreateUserInput(EArchMsgTarget::Game, m_finalInputs[frame]));
return true;
}
return false;
}
void CControllerRecorder::SetMode(EMode mode) {
EMode oldMode = m_mode;
m_mode = mode;
if (m_mode == EMode::Record && oldMode != EMode::Record) {
m_initialState = *g_GameState;
} else if (oldMode == EMode::Record && m_mode == EMode::None) {
//auto w = athena::io::FileWriter("/home/antidote/Documents/test.inp");
//PutTo(w);
} else if (oldMode == EMode::None && m_mode == EMode::Play) {
m_oldGameStatePtr = g_GameState;
g_GameState = &m_initialState;
} else if (oldMode == EMode::Play && m_mode == EMode::None) {
}
}
void CControllerRecorder::PutTo(COutputStream& out) {
out.writeUint32Big(1); // Version
m_initialState.WriteBackupBuf();
auto& buf = m_initialState.BackupBuf();
out.writeUint32Big(buf.size());
out.writeBytes(buf.data(), buf.size());
out.writeUint32Big(m_finalInputs.size());
for (auto pair : m_finalInputs) {
out.writeUint32Big(pair.first);
pair.second.PutTo(out);
}
}
}

View File

@ -0,0 +1,28 @@
#pragma once
#include "Runtime/Input/CFinalInput.hpp"
#include "Runtime/CGameState.hpp"
namespace metaforce {
class CArchitectureQueue;
class CControllerRecorder {
public:
enum class EMode {
None,
Record,
Play
};
private:
std::map<int, CFinalInput> m_finalInputs; // frame -> input
EMode m_mode = EMode::None;
CGameState m_initialState;
const CGameState* m_oldGameStatePtr = nullptr;
public:
CControllerRecorder() = default;
bool ProcessInput(const CFinalInput& in, s32 frame, CArchitectureQueue& queue);
void SetMode(EMode mode);
void PutTo(COutputStream& out);
};
} // namespace metaforce

View File

@ -162,4 +162,51 @@ CFinalInput CFinalInput::ScaleAnalogueSticks(float leftDiv, float rightDiv) cons
ret.m_rightMul = 1.f / rightDiv; ret.m_rightMul = 1.f / rightDiv;
return ret; return ret;
} }
void CFinalInput::PutTo(COutputStream& out) {
out.writeFloatBig(x0_dt);
out.writeFloatBig(x4_controllerIdx);
out.writeFloatBig(x8_anaLeftX);
out.writeFloatBig(xc_anaLeftY);
out.writeFloatBig(x10_anaRightX);
out.writeFloatBig(x14_anaRightY);
out.writeFloatBig(x18_anaLeftTrigger);
out.writeFloatBig(x1c_anaRightTrigger);
out.writeBool(x20_enableAnaLeftXP);
out.writeBool(x20_enableAnaLeftNegXP);
out.writeBool(x21_enableAnaLeftYP);
out.writeBool(x21_enableAnaLeftNegYP);
out.writeBool(x22_enableAnaRightXP);
out.writeBool(x22_enableAnaRightNegXP);
out.writeBool(x23_enableAnaRightYP);
out.writeBool(x23_enableAnaRightNegYP);
out.writeBool(x24_anaLeftTriggerP);
out.writeBool(x28_anaRightTriggerP);
out.writeBool(x2c_b24_A);
out.writeBool(x2c_b25_B);
out.writeBool(x2c_b26_X);
out.writeBool(x2c_b27_Y);
out.writeBool(x2c_b28_Z);
out.writeBool(x2c_b29_L);
out.writeBool(x2c_b30_R);
out.writeBool(x2c_b31_DPUp);
out.writeBool(x2d_b24_DPRight);
out.writeBool(x2d_b25_DPDown);
out.writeBool(x2d_b26_DPLeft);
out.writeBool(x2d_b27_Start);
out.writeBool(x2d_b28_PA);
out.writeBool(x2d_b29_PB);
out.writeBool(x2d_b30_PX);
out.writeBool(x2d_b31_PY);
out.writeBool(x2e_b25_PL);
out.writeBool(x2e_b26_PR);
out.writeBool(x2e_b27_PDPUp);
out.writeBool(x2e_b28_PDPRight);
out.writeBool(x2e_b29_PDPDown);
out.writeBool(x2e_b30_PDPLeft);
out.writeBool(x2e_b31_PStart);
out.writeBytes(m_PCharKeys.data(), m_PCharKeys.size() - 1);
out.writeBytes(m_PSpecialKeys.data(), m_PSpecialKeys.size() - 1);
out.writeBytes(m_PMouseButtons.data(), m_PMouseButtons.size() - 1);
}
} // namespace metaforce } // namespace metaforce

View File

@ -171,6 +171,7 @@ struct CFinalInput {
float AMouseButton(boo::EMouseButton k) const { return DMouseButton(k) ? 1.f : 0.f; } float AMouseButton(boo::EMouseButton k) const { return DMouseButton(k) ? 1.f : 0.f; }
const std::optional<CKeyboardMouseControllerData>& GetKBM() const { return m_kbm; } const std::optional<CKeyboardMouseControllerData>& GetKBM() const { return m_kbm; }
void PutTo(COutputStream& out);
}; };
} // namespace metaforce } // namespace metaforce

View File

@ -28,13 +28,15 @@ void CInputGenerator::Update(float dt, CArchitectureQueue& queue) {
input |= kbInput; input |= kbInput;
kbUsed = true; kbUsed = true;
} }
queue.Push(MakeMsg::CreateUserInput(EArchMsgTarget::Game, input)); if (!m_recorder.ProcessInput(input, CGraphics::GetFrameCounter(), queue)) {
queue.Push(MakeMsg::CreateUserInput(EArchMsgTarget::Game, input));
}
} }
} }
/* Send straight keyboard input if no first controller present */ /* Send straight keyboard input if no first controller present */
if (!kbUsed) if (!kbUsed && !m_recorder.ProcessInput(kbInput, CGraphics::GetFrameCounter(), queue)) {
queue.Push(MakeMsg::CreateUserInput(EArchMsgTarget::Game, kbInput)); queue.Push(MakeMsg::CreateUserInput(EArchMsgTarget::Game, kbInput));
}
} }
} // namespace metaforce } // namespace metaforce

View File

@ -5,6 +5,8 @@
#include <mutex> #include <mutex>
#include "Runtime/Input/CFinalInput.hpp" #include "Runtime/Input/CFinalInput.hpp"
#include "Runtime/Input/CControllerRecorder.hpp"
#include "Runtime/Input/CKeyboardMouseController.hpp" #include "Runtime/Input/CKeyboardMouseController.hpp"
#include <boo/boo.hpp> #include <boo/boo.hpp>
@ -33,7 +35,7 @@ class CInputGenerator : public boo::DeviceFinder {
} }
bool m_firstFrame = true; bool m_firstFrame = true;
CControllerRecorder m_recorder;
public: public:
CInputGenerator(float leftDiv, float rightDiv) CInputGenerator(float leftDiv, float rightDiv)
: boo::DeviceFinder({dev_typeid(DolphinSmashAdapter)}), m_leftDiv(leftDiv), m_rightDiv(rightDiv) {} : boo::DeviceFinder({dev_typeid(DolphinSmashAdapter)}), m_leftDiv(leftDiv), m_rightDiv(rightDiv) {}
@ -180,6 +182,7 @@ public:
/* This is where the game thread enters */ /* This is where the game thread enters */
void Update(float dt, CArchitectureQueue& queue); void Update(float dt, CArchitectureQueue& queue);
void SetRecordMode(CControllerRecorder::EMode mode) { m_recorder.SetMode(mode); };
}; };
} // namespace metaforce } // namespace metaforce

View File

@ -1,12 +1,13 @@
set(INPUT_SOURCES set(INPUT_SOURCES
IController.hpp IController.hpp
CKeyboardMouseController.hpp CKeyboardMouseController.hpp
ControlMapper.hpp ControlMapper.cpp ControlMapper.hpp ControlMapper.cpp
CInputGenerator.hpp CInputGenerator.cpp CInputGenerator.hpp CInputGenerator.cpp
CFinalInput.hpp CFinalInput.cpp CFinalInput.hpp CFinalInput.cpp
CRumbleManager.hpp CRumbleManager.cpp CRumbleManager.hpp CRumbleManager.cpp
CRumbleGenerator.hpp CRumbleGenerator.cpp CRumbleGenerator.hpp CRumbleGenerator.cpp
CRumbleVoice.hpp CRumbleVoice.cpp CRumbleVoice.hpp CRumbleVoice.cpp
RumbleFxTable.hpp RumbleFxTable.cpp) RumbleFxTable.hpp RumbleFxTable.cpp
CControllerRecorder.hpp CControllerRecorder.cpp)
runtime_add_list(Input INPUT_SOURCES) runtime_add_list(Input INPUT_SOURCES)