Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 2 additions & 0 deletions code/dc2/opencloud2.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
<ClInclude Include="movie.h" />
<ClInclude Include="npc.h" />
<ClInclude Include="object_anime.h" />
<ClInclude Include="pad_control.h" />
<ClInclude Include="pot.h" />
<ClInclude Include="quest.h" />
<ClInclude Include="rain.h" />
Expand Down Expand Up @@ -123,6 +124,7 @@
<ClCompile Include="movie.cc" />
<ClCompile Include="npc.cc" />
<ClCompile Include="object_anime.cc" />
<ClCompile Include="pad_control.cc" />
<ClCompile Include="pot.cc" />
<ClCompile Include="quest.cc" />
<ClCompile Include="rain.cc" />
Expand Down
2 changes: 2 additions & 0 deletions code/dc2/opencloud2.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
<ClCompile Include="character_func.cc" />
<ClCompile Include="object_anime.cc" />
<ClCompile Include="editmap.cc" />
<ClCompile Include="pad_control.cc" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="camera.h" />
Expand Down Expand Up @@ -197,6 +198,7 @@
<ClInclude Include="character_func.h" />
<ClInclude Include="object_anime.h" />
<ClInclude Include="editmap.h" />
<ClInclude Include="pad_control.h" />
</ItemGroup>
<ItemGroup>
<None Include="opencloud2.exports.props" />
Expand Down
87 changes: 87 additions & 0 deletions code/dc2/pad_control.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#include "common/debug.h"
#include "common/log.h"

#include "dc2/pad_control.h"

#include "host/host_interface_dwm.h"

set_log_channel("pad_control");

// 002ED3E0
// Clears all recorded actions
void CPadControl::Reset()
{
log_trace("CPadControl::{}()", __func__);

m_buttons.clear();
m_analog.clear();
}

// 002ED460
// Registers up to two buttons for a particular action
// TODO: Accept a vector for an arbitrary number of buttons
void CPadControl::RegisterBtn(const std::string_view& action_name, host::pad_handler::buttons btn1, host::pad_handler::buttons btn2)
{
log_trace("CPadControl::{}({}, {:#X}, {:#X})", __func__, action_name, std::to_underlying(btn1), std::to_underlying(btn2));

m_buttons[action_name.data()] = {
.m_value = false,
.m_input_key = btn1 | btn2
};
}

// 002ED4A0
// Registers an axis for a particular aciton
void CPadControl::RegisterAnalog(const std::string_view& action_name, EPadAxis axis)
{
log_trace("CPadControl::{}({}, {})", __func__, action_name, std::to_underlying(axis));

m_analog[action_name.data()] = {
.m_value = 0.0f,
.m_input_axis = axis
};
}

// 002ED4E0
// Checks the button value for a particular action
bool CPadControl::Btn(const std::string_view& action_name)
{
log_trace("CPadControl::{}({})", __func__, action_name);

if (!m_buttons.contains(action_name.data()))
{
return false;
}

return m_buttons[action_name.data()].m_value;
}

// 002ED520
// Checks the analog value for a particular action
f32 CPadControl::Analog(const std::string_view& action_name)
{
log_trace("CPadControl::{}({})", __func__, action_name);

if (!m_analog.contains(action_name.data()))
{
return 0.0f;
}

return m_analog[action_name.data()].m_value;
}

// 002ED550
// Updates each action's button pressed/analog value
void CPadControl::Update()
{
log_trace("CPadControl::{}()", __func__);

for (auto& button : m_buttons)
{
// Update recorded values for buttons
button.second.m_value = g_host_interface->pad_button_any_pressed(button.second.m_input_key);
}

// TODO: Check analog values
todo;
}
84 changes: 84 additions & 0 deletions code/dc2/pad_control.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#pragma once
#include <unordered_map>
#include <vector>

#include "common/types.h"

#include "host/pad_handler.h"

/*
* CPadControl creates an abstraction by allowing the programmer to register
* raw inputs for a particular action the player may perform, then get the value
* of the inputs by checking the action.
*
* For example, a simple usage may look something like this:
*
* PadCtrl.RegisterBtn("photo-take", SQUARE);
* ...
* PadCtrl.Update();
* ...
* if (PadCtrl.Btn("photo_take"))
* {
* // The user is pressing the button associated with taking a photo
* }
* else
* {
* // The user is not pressing the button associated with taking a photo
* }
*
* Note that the second argument for RegisterBtn need not necessarily be SQUARE,
* but could come from some other source like a settings file. Therefore,
* the action "photo-take" could be associated with any number of arbitrary
* inputs, but the programmer does not have to worry about the raw inputs.
*
* NOTE: This MVP is designed only for gamepads, at the moment.
*/

enum class EPadAxis
{
_1 = 1,
_2 = 2,
_3 = 3,
_4 = 4,
};

struct PAD_ANALOG
{
f32 m_value{ 0.0f };
EPadAxis m_input_axis{};
};

struct PAD_BUTTON
{
bool m_value{ false };
host::pad_handler::buttons m_input_key{};
};

class CPadControl
{
public:

// 002ED3E0
void Reset();

// 002ED460
void RegisterBtn(const std::string_view& action_name, host::pad_handler::buttons btn1, host::pad_handler::buttons btn2 = host::pad_handler::buttons::none);

// 002ED4A0
void RegisterAnalog(const std::string_view& action_name, EPadAxis axis);

// 002ED4E0
bool Btn(const std::string_view& action_name);

// 002ED520
f32 Analog(const std::string_view& action_name);

// 002ED550
void Update();

private:
std::unordered_map<std::string, PAD_BUTTON> m_buttons{};
std::unordered_map<std::string, PAD_ANALOG> m_analog{};
};

extern std::unique_ptr<CPadControl> PadCtrl = std::make_unique<CPadControl>();
1 change: 1 addition & 0 deletions code/host/pad_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace host
public:
enum class buttons : u32
{
none = 0,
dpad_up = 1 << 0,
dpad_down = 1 << 1,
dpad_left = 1 << 2,
Expand Down