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;
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

View File

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

View File

@ -28,13 +28,15 @@ void CInputGenerator::Update(float dt, CArchitectureQueue& queue) {
input |= kbInput;
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 */
if (!kbUsed)
if (!kbUsed && !m_recorder.ProcessInput(kbInput, CGraphics::GetFrameCounter(), queue)) {
queue.Push(MakeMsg::CreateUserInput(EArchMsgTarget::Game, kbInput));
}
}
} // namespace metaforce

View File

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

View File

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