#pragma once
#include "Common/Input/InputState.h"
#include "Core/KeyMap.h"
#include <functional>
#include <cstring>
#include <mutex>
class ControlMapper {
public:
void Update(double now);
bool Key(const KeyInput &key, bool *pauseTrigger);
void Axis(const AxisInput *axes, size_t count);
void SetCallbacks(
std::function<void(VirtKey, bool)> onVKey,
std::function<void(VirtKey, float)> onVKeyAnalog,
std::function<void(uint32_t, uint32_t)> updatePSPButtons,
std::function<void(int, float, float)> setPSPAnalog,
std::function<void(int, float, float)> setRawAnalog);
void PSPKey(int deviceId, int pspKeyCode, int flags);
void ToggleSwapAxes();
void ForceReleaseVKey(int vkey);
void ReleaseAll();
void GetDebugString(char *buffer, size_t bufSize) const;
struct InputSample {
float value;
double timestamp;
};
private:
bool UpdatePSPState(const InputMapping &changedMapping, double now);
float MapAxisValue(float value, int vkId, const InputMapping &mapping, const InputMapping &changedMapping, bool *oppositeTouched);
void SwapMappingIfEnabled(uint32_t *vkey);
void SetPSPAxis(int deviceId, int stick, char axis, float value);
void UpdateAnalogOutput(int stick);
void onVKey(VirtKey vkey, bool down);
void onVKeyAnalog(int deviceId, VirtKey vkey, float value);
void UpdateCurInputAxis(const InputMapping &mapping, float value, double timestamp);
float GetDeviceAxisThreshold(int device, const InputMapping &mapping);
float virtKeys_[VIRTKEY_COUNT]{};
bool virtKeyOn_[VIRTKEY_COUNT]{};
float rawAxisValue_[JOYSTICK_AXIS_MAX]{};
double deviceTimestamps_[(size_t)DEVICE_ID_COUNT]{};
int lastNonDeadzoneDeviceID_[2]{};
float history_[2][2]{};
float converted_[2][2]{};
bool autoRotatingAnalogCW_ = false;
bool autoRotatingAnalogCCW_ = false;
bool swapAxes_ = false;
std::mutex mutex_;
std::map<InputMapping, InputSample> curInput_;
std::function<void(VirtKey, bool)> onVKey_;
std::function<void(VirtKey, float)> onVKeyAnalog_;
std::function<void(uint32_t, uint32_t)> updatePSPButtons_;
std::function<void(int, float, float)> setPSPAnalog_;
std::function<void(int, float, float)> setRawAnalog_;
};
void ConvertAnalogStick(float x, float y, float *outX, float *outY);
float GetDeviceAxisThreshold(int device, const InputMapping &mapping);