HAxis sos
This commit is contained in:
171
Source/UnrealProject/External/Events.hpp
vendored
Normal file
171
Source/UnrealProject/External/Events.hpp
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
enum class EventCode : uint8_t
|
||||
{
|
||||
PlayerSpawn = 0,
|
||||
PlayerUpdate,
|
||||
PlayerDie,
|
||||
PlayerCast,
|
||||
PlayerHealth,
|
||||
PlayerMana,
|
||||
PlayerMaxHealth,
|
||||
PlayerMaxMana,
|
||||
PlayerDealDamage,
|
||||
PlayerLevel,
|
||||
SessionEnd,
|
||||
|
||||
MetaEvents = 64,
|
||||
|
||||
MapData,
|
||||
MapImage,
|
||||
PlayerName,
|
||||
PlayerTeam,
|
||||
AbilityName,
|
||||
};
|
||||
|
||||
struct PlayerSpawn
|
||||
{
|
||||
PlayerSpawn() = default;
|
||||
PlayerSpawn(uint32_t time, uint8_t player, float playerX, float playerY) : event(EventCode::PlayerSpawn), time(time), player(player), playerX(playerX), playerY(playerY) {}
|
||||
EventCode event;
|
||||
uint32_t time;
|
||||
uint8_t player;
|
||||
float playerX;
|
||||
float playerY;
|
||||
};
|
||||
struct PlayerUpdate
|
||||
{
|
||||
PlayerUpdate() = default;
|
||||
PlayerUpdate(uint32_t time, uint8_t player, float playerX, float playerY) : event(EventCode::PlayerUpdate), time(time), player(player), playerX(playerX), playerY(playerY) {}
|
||||
EventCode event;
|
||||
uint32_t time;
|
||||
uint8_t player;
|
||||
float playerX;
|
||||
float playerY;
|
||||
};
|
||||
struct PlayerDie
|
||||
{
|
||||
PlayerDie() = default;
|
||||
PlayerDie(uint32_t time, uint8_t player, uint8_t source) : event(EventCode::PlayerDie), time(time), player(player), source(source) {}
|
||||
EventCode event;
|
||||
uint32_t time;
|
||||
uint8_t player;
|
||||
uint8_t source;
|
||||
};
|
||||
struct PlayerCast
|
||||
{
|
||||
PlayerCast() = default;
|
||||
PlayerCast(uint32_t time, uint8_t player, uint32_t ability) : event(EventCode::PlayerCast), time(time), player(player), ability(ability) {}
|
||||
EventCode event;
|
||||
uint32_t time;
|
||||
uint8_t player;
|
||||
uint32_t ability;
|
||||
};
|
||||
struct PlayerHealth
|
||||
{
|
||||
PlayerHealth() = default;
|
||||
PlayerHealth(uint32_t time, uint8_t player, int32_t health) : event(EventCode::PlayerHealth), time(time), player(player), health(health) {}
|
||||
EventCode event;
|
||||
uint32_t time;
|
||||
uint8_t player;
|
||||
int32_t health;
|
||||
};
|
||||
struct PlayerMana
|
||||
{
|
||||
PlayerMana() = default;
|
||||
PlayerMana(uint32_t time, uint8_t player, int32_t mana) : event(EventCode::PlayerMana), time(time), player(player), mana(mana) {}
|
||||
EventCode event;
|
||||
uint32_t time;
|
||||
uint8_t player;
|
||||
int32_t mana;
|
||||
};
|
||||
struct PlayerMaxHealth
|
||||
{
|
||||
PlayerMaxHealth() = default;
|
||||
PlayerMaxHealth(uint32_t time, uint8_t player, int32_t maxHealth) : event(EventCode::PlayerMaxHealth), time(time), player(player), maxHealth(maxHealth) {}
|
||||
EventCode event;
|
||||
uint32_t time;
|
||||
uint8_t player;
|
||||
int32_t maxHealth;
|
||||
};
|
||||
struct PlayerMaxMana
|
||||
{
|
||||
PlayerMaxMana() = default;
|
||||
PlayerMaxMana(uint32_t time, uint8_t player, int32_t maxMana) : event(EventCode::PlayerMaxMana), time(time), player(player), maxMana(maxMana) {}
|
||||
EventCode event;
|
||||
uint32_t time;
|
||||
uint8_t player;
|
||||
int32_t maxMana;
|
||||
};
|
||||
struct PlayerDealDamage
|
||||
{
|
||||
PlayerDealDamage() = default;
|
||||
PlayerDealDamage(uint32_t time, uint8_t player, uint32_t ability, int32_t damage) : event(EventCode::PlayerDealDamage), time(time), player(player), ability(ability), damage(damage) {}
|
||||
EventCode event;
|
||||
uint32_t time;
|
||||
uint8_t player;
|
||||
uint32_t ability;
|
||||
int32_t damage;
|
||||
};
|
||||
struct PlayerLevel
|
||||
{
|
||||
PlayerLevel() = default;
|
||||
PlayerLevel(uint32_t time, uint8_t player, uint8_t level) : event(EventCode::PlayerLevel), time(time), player(player), level(level) {}
|
||||
EventCode event;
|
||||
uint32_t time;
|
||||
uint8_t player;
|
||||
uint8_t level;
|
||||
};
|
||||
struct SessionEnd
|
||||
{
|
||||
SessionEnd() = default;
|
||||
SessionEnd(uint32_t time) : event(EventCode::SessionEnd), time(time) {}
|
||||
EventCode event;
|
||||
uint32_t time;
|
||||
};
|
||||
|
||||
struct MapData
|
||||
{
|
||||
MapData() = default;
|
||||
MapData(float minX, float maxX, float minY, float maxY) : event(EventCode::MapData), minX(minX), maxX(maxX), minY(minY), maxY(maxY) {}
|
||||
EventCode event;
|
||||
float minX;
|
||||
float maxX;
|
||||
float minY;
|
||||
float maxY;
|
||||
};
|
||||
struct MapImage
|
||||
{
|
||||
MapImage() = default;
|
||||
MapImage(uint32_t width, uint32_t height) : event(EventCode::MapImage), width(width), height(height) {}
|
||||
EventCode event;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
};
|
||||
struct PlayerName
|
||||
{
|
||||
PlayerName() = default;
|
||||
PlayerName(uint8_t player, uint16_t length) : event(EventCode::PlayerName), player(player), length(length) {}
|
||||
EventCode event;
|
||||
uint8_t player;
|
||||
uint16_t length;
|
||||
};
|
||||
struct PlayerTeam
|
||||
{
|
||||
PlayerTeam() = default;
|
||||
PlayerTeam(uint8_t player, uint8_t team) : event(EventCode::PlayerTeam), player(player), team(team) {}
|
||||
EventCode event;
|
||||
uint8_t player;
|
||||
uint8_t team;
|
||||
};
|
||||
struct AbilityName
|
||||
{
|
||||
AbilityName() = default;
|
||||
AbilityName(uint32_t ability, uint16_t length) : event(EventCode::AbilityName), ability(ability), length(length) {}
|
||||
EventCode event;
|
||||
uint32_t ability;
|
||||
uint16_t length;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
96
Source/UnrealProject/External/HeatMapMetrics.cpp
vendored
Normal file
96
Source/UnrealProject/External/HeatMapMetrics.cpp
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
// Project Lab - NHTV Igad
|
||||
|
||||
#include "UnrealProject.h"
|
||||
|
||||
#if PLATFORM_SPECIFIC_WIN == 0
|
||||
|
||||
#include "HeatMapMetrics.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
float HeatMapMetrics::s_timeMap[3][512][512];
|
||||
|
||||
void HeatMapMetrics::ResetMap()
|
||||
{
|
||||
memset(&s_timeMap, 0, sizeof(s_timeMap));
|
||||
}
|
||||
|
||||
void HeatMapMetrics::AddTime(FVector2D position, float time, size_t team)
|
||||
{
|
||||
position *= 512.0f;
|
||||
s_timeMap[team][(int)position.Y][(int)position.X] += time;
|
||||
}
|
||||
|
||||
void HeatMapMetrics::ExportToFile()
|
||||
{
|
||||
char* envPath;
|
||||
size_t envPathSize;
|
||||
getenv_s(&envPathSize, NULL, 0, "APPDATA");
|
||||
if (envPathSize == 0)
|
||||
{
|
||||
TERROR("APPDATA does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
envPath = (char*)malloc(envPathSize * sizeof(char));
|
||||
if (!envPath)
|
||||
{
|
||||
TERROR("Failed to allocate memory.");
|
||||
return;
|
||||
}
|
||||
|
||||
getenv_s(&envPathSize, envPath, envPathSize, "APPDATA");
|
||||
|
||||
|
||||
string path = envPath;
|
||||
|
||||
free(envPath);
|
||||
|
||||
path.append("\\Haxis\\HaxisHeatmap");
|
||||
path.append(m_GetCurrentDateTime());
|
||||
path.append(".HME");
|
||||
fstream fs;
|
||||
fs.open(path.c_str(), fstream::out | fstream::binary);
|
||||
if (!fs.is_open())
|
||||
{
|
||||
TERROR("failed to export metrics");
|
||||
return;
|
||||
}
|
||||
|
||||
fs.write((char*)&s_timeMap[0][0][0], sizeof(s_timeMap));
|
||||
|
||||
fs.close();
|
||||
}
|
||||
|
||||
void HeatMapMetrics::m_RetrieveCurrentTM(std::tm& a_TM)
|
||||
{
|
||||
time_t currentTime = time(0);
|
||||
localtime_s(&a_TM, ¤tTime);
|
||||
}
|
||||
string HeatMapMetrics::m_GetCurrentTime()
|
||||
{
|
||||
tm tstruct;
|
||||
char buffer[80];
|
||||
m_RetrieveCurrentTM(tstruct);
|
||||
strftime(buffer, sizeof(buffer), "(%H:%M:%S) ", &tstruct);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
string HeatMapMetrics::m_GetCurrentDateTime()
|
||||
{
|
||||
tm tstruct;
|
||||
char buffer[80];
|
||||
m_RetrieveCurrentTM(tstruct);
|
||||
strftime(buffer, sizeof(buffer), "%Y-%m-%d_%H-%M-%S", &tstruct);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
#endif
|
||||
27
Source/UnrealProject/External/HeatMapMetrics.h
vendored
Normal file
27
Source/UnrealProject/External/HeatMapMetrics.h
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
// Project Lab - NHTV Igad
|
||||
|
||||
#pragma once
|
||||
|
||||
#if PLATFORM_SPECIFIC_WIN == 0
|
||||
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
class UNREALPROJECT_API HeatMapMetrics
|
||||
{
|
||||
public:
|
||||
static void AddTime(struct FVector2D position, float time, size_t team);
|
||||
static void ExportToFile();
|
||||
static void ResetMap();
|
||||
protected:
|
||||
static void m_RetrieveCurrentTM(std::tm& a_TM);
|
||||
static std::string m_GetCurrentTime();
|
||||
static std::string m_GetCurrentDateTime();
|
||||
private:
|
||||
static float s_timeMap[3][512][512];
|
||||
};
|
||||
|
||||
#endif
|
||||
46
Source/UnrealProject/External/InputDeviceBases.hpp
vendored
Normal file
46
Source/UnrealProject/External/InputDeviceBases.hpp
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef _HEADER_INPUT_DEVICE_BASES
|
||||
#define _HEADER_INPUT_DEVICE_BASES
|
||||
|
||||
#include "InputEnums.hpp"
|
||||
#include "TeaVector2.hpp"
|
||||
#include "TeaVector3.hpp"
|
||||
|
||||
namespace Input
|
||||
{
|
||||
enum InputDeviceType
|
||||
{
|
||||
IDT_NONE,
|
||||
IDT_NOTDEFINED,
|
||||
IDT_XBOX,
|
||||
IDT_DS4
|
||||
};
|
||||
|
||||
class InputDevice
|
||||
{
|
||||
public:
|
||||
virtual void Update() = 0;
|
||||
};
|
||||
|
||||
class Keyboard : public InputDevice
|
||||
{
|
||||
public:
|
||||
virtual bool GetKey(const InputKey a_Key) = 0;
|
||||
virtual bool GetKeyDown(const InputKey a_Key) = 0;
|
||||
};
|
||||
class Joystick : public InputDevice
|
||||
{
|
||||
public:
|
||||
virtual ~Joystick() {};
|
||||
virtual bool GetButton(const InputJoystickButton a_JoystickButton) = 0;
|
||||
virtual bool GetButton(const InputJoystickPhysical a_JoystickButton) = 0;
|
||||
virtual bool GetButtonDown(const InputJoystickButton a_JoystickButton) = 0;
|
||||
virtual bool GetButtonDown(const InputJoystickPhysical a_JoystickButton) = 0;
|
||||
virtual bool GetButtonUp(const InputJoystickButton a_JoystickButton) = 0;
|
||||
virtual bool GetButtonUp(const InputJoystickPhysical a_JoystickButton) = 0;
|
||||
virtual bool IsValid() = 0;
|
||||
virtual TeaLib::Math::Vector2f GetDelta(const InputJoystickAxis a_InputStick) = 0;
|
||||
virtual InputDeviceType GetDeviceType() = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
285
Source/UnrealProject/External/InputEnums.hpp
vendored
Normal file
285
Source/UnrealProject/External/InputEnums.hpp
vendored
Normal file
@@ -0,0 +1,285 @@
|
||||
#ifndef _HEADER_INPUT_ENUMS
|
||||
#define _HEADER_INPUT_ENUMS
|
||||
|
||||
namespace Input
|
||||
{
|
||||
|
||||
// Keyboard input keys
|
||||
enum InputKey : unsigned char
|
||||
{
|
||||
IK_ESCAPE = 0x01,
|
||||
IK_1 = 0x02,
|
||||
IK_2 = 0x03,
|
||||
IK_3 = 0x04,
|
||||
IK_4 = 0x05,
|
||||
IK_5 = 0x06,
|
||||
IK_6 = 0x07,
|
||||
IK_7 = 0x08,
|
||||
IK_8 = 0x09,
|
||||
IK_9 = 0x0A,
|
||||
IK_0 = 0x0B,
|
||||
IK_MINUS = 0x0C,
|
||||
IK_EQUALS = 0x0D,
|
||||
IK_BACK = 0x0E,
|
||||
IK_TAB = 0x0F,
|
||||
IK_Q = 0x10,
|
||||
IK_W = 0x11,
|
||||
IK_E = 0x12,
|
||||
IK_R = 0x13,
|
||||
IK_T = 0x14,
|
||||
IK_Y = 0x15,
|
||||
IK_U = 0x16,
|
||||
IK_I = 0x17,
|
||||
IK_O = 0x18,
|
||||
IK_P = 0x19,
|
||||
IK_LBRACKET = 0x1A,
|
||||
IK_RBRACKET = 0x1B,
|
||||
IK_RETURN = 0x1C,
|
||||
IK_LCONTROL = 0x1D,
|
||||
IK_A = 0x1E,
|
||||
IK_S = 0x1F,
|
||||
IK_D = 0x20,
|
||||
IK_F = 0x21,
|
||||
IK_G = 0x22,
|
||||
IK_H = 0x23,
|
||||
IK_J = 0x24,
|
||||
IK_K = 0x25,
|
||||
IK_L = 0x26,
|
||||
IK_SEMICOLON = 0x27,
|
||||
IK_APOSTROPHE = 0x28,
|
||||
IK_GRAVE = 0x29,
|
||||
IK_LSHIFT = 0x2A,
|
||||
IK_BACKSLASH = 0x2B,
|
||||
IK_Z = 0x2C,
|
||||
IK_X = 0x2D,
|
||||
IK_C = 0x2E,
|
||||
IK_V = 0x2F,
|
||||
IK_B = 0x30,
|
||||
IK_N = 0x31,
|
||||
IK_M = 0x32,
|
||||
IK_COMMA = 0x33,
|
||||
IK_PERIOD = 0x34,
|
||||
IK_SLASH = 0x35,
|
||||
IK_RSHIFT = 0x36,
|
||||
IK_MULTIPLY = 0x37,
|
||||
IK_LMENU = 0x38,
|
||||
IK_SPACE = 0x39,
|
||||
IK_CAPITAL = 0x3A,
|
||||
IK_F1 = 0x3B,
|
||||
IK_F2 = 0x3C,
|
||||
IK_F3 = 0x3D,
|
||||
IK_F4 = 0x3E,
|
||||
IK_F5 = 0x3F,
|
||||
IK_F6 = 0x40,
|
||||
IK_F7 = 0x41,
|
||||
IK_F8 = 0x42,
|
||||
IK_F9 = 0x43,
|
||||
IK_F10 = 0x44,
|
||||
IK_NUMLOCK = 0x45,
|
||||
IK_SCROLL = 0x46,
|
||||
IK_NUMPAD7 = 0x47,
|
||||
IK_NUMPAD8 = 0x48,
|
||||
IK_NUMPAD9 = 0x49,
|
||||
IK_SUBTRACT = 0x4A,
|
||||
IK_NUMPAD4 = 0x4B,
|
||||
IK_NUMPAD5 = 0x4C,
|
||||
IK_NUMPAD6 = 0x4D,
|
||||
IK_ADD = 0x4E,
|
||||
IK_NUMPAD1 = 0x4F,
|
||||
IK_NUMPAD2 = 0x50,
|
||||
IK_NUMPAD3 = 0x51,
|
||||
IK_NUMPAD0 = 0x52,
|
||||
IK_DECIMAL = 0x53,
|
||||
IK_OEM_102 = 0x56,
|
||||
IK_F11 = 0x57,
|
||||
IK_F12 = 0x58,
|
||||
IK_F13 = 0x64,
|
||||
IK_F14 = 0x65,
|
||||
IK_F15 = 0x66,
|
||||
IK_KANA = 0x70,
|
||||
IK_ABNT_C1 = 0x73,
|
||||
IK_CONVERT = 0x79,
|
||||
IK_NOCONVERT = 0x7B,
|
||||
IK_YEN = 0x7D,
|
||||
IK_ABNT_C2 = 0x7E,
|
||||
IK_NUMPADEQUALS = 0x8D,
|
||||
IK_PREVTRACK = 0x90,
|
||||
IK_AT = 0x91,
|
||||
IK_COLON = 0x92,
|
||||
IK_UNDERLINE = 0x93,
|
||||
IK_KANJI = 0x94,
|
||||
IK_STOP = 0x95,
|
||||
IK_AX = 0x96,
|
||||
IK_UNLABELED = 0x97,
|
||||
IK_NEXTTRACK = 0x99,
|
||||
IK_NUMPADENTER = 0x9C,
|
||||
IK_RCONTROL = 0x9D,
|
||||
IK_MUTE = 0xA0,
|
||||
IK_CALCULATOR = 0xA1,
|
||||
IK_PLAYPAUSE = 0xA2,
|
||||
IK_MEDIASTOP = 0xA4,
|
||||
IK_VOLUMEDOWN = 0xAE,
|
||||
IK_VOLUMEUP = 0xB0,
|
||||
IK_WEBHOME = 0xB2,
|
||||
IK_NUMPADCOMMA = 0xB3,
|
||||
IK_DIVIDE = 0xB5,
|
||||
IK_SYSRQ = 0xB7,
|
||||
IK_RMENU = 0xB8,
|
||||
IK_PAUSE = 0xC5,
|
||||
IK_HOME = 0xC7,
|
||||
IK_UP = 0xC8,
|
||||
IK_PRIOR = 0xC9,
|
||||
IK_LEFT = 0xCB,
|
||||
IK_RIGHT = 0xCD,
|
||||
IK_END = 0xCF,
|
||||
IK_DOWN = 0xD0,
|
||||
IK_NEXT = 0xD1,
|
||||
IK_INSERT = 0xD2,
|
||||
IK_DELETE = 0xD3,
|
||||
IK_LWIN = 0xDB,
|
||||
IK_RWIN = 0xDC,
|
||||
IK_APPS = 0xDD,
|
||||
IK_POWER = 0xDE,
|
||||
IK_SLEEP = 0xDF,
|
||||
IK_WAKE = 0xE3,
|
||||
IK_WEBSEARCH = 0xE5,
|
||||
IK_WEBFAVORITES = 0xE6,
|
||||
IK_WEBREFRESH = 0xE7,
|
||||
IK_WEBSTOP = 0xE8,
|
||||
IK_WEBFORWARD = 0xE9,
|
||||
IK_WEBBACK = 0xEA,
|
||||
IK_MYCOMPUTER = 0xEB,
|
||||
IK_MAIL = 0xEC,
|
||||
IK_MEDIASELECT = 0xED,
|
||||
IK_BACKSPACE = IK_BACK,
|
||||
IK_NUMPADSTAR = IK_MULTIPLY,
|
||||
IK_LALT = IK_LMENU,
|
||||
IK_CAPSLOCK = IK_CAPITAL,
|
||||
IK_NUMPADMINUS = IK_SUBTRACT,
|
||||
IK_NUMPADPLUS = IK_ADD,
|
||||
IK_NUMPADPERIOD = IK_DECIMAL,
|
||||
IK_NUMPADSLASH = IK_DIVIDE,
|
||||
IK_RALT = IK_RMENU,
|
||||
IK_UPARROW = IK_UP,
|
||||
IK_PGUP = IK_PRIOR,
|
||||
IK_LEFTARROW = IK_LEFT,
|
||||
IK_RIGHTARROW = IK_RIGHT,
|
||||
IK_DOWNARROW = IK_DOWN,
|
||||
IK_PGDN = IK_NEXT,
|
||||
};
|
||||
|
||||
// Joystick axis
|
||||
enum InputJoystickAxis
|
||||
{
|
||||
IJA_LSTICK,
|
||||
IJA_RSTICK,
|
||||
IJA_LRTRIGGER,
|
||||
IJA_DPAD,
|
||||
};
|
||||
|
||||
// Joystick buttons
|
||||
enum InputJoystickButton : unsigned char
|
||||
{
|
||||
IJB_BUTTON0,
|
||||
IJB_BUTTON1,
|
||||
IJB_BUTTON2,
|
||||
IJB_BUTTON3,
|
||||
IJB_BUTTON4,
|
||||
IJB_BUTTON5,
|
||||
IJB_BUTTON6,
|
||||
IJB_BUTTON7,
|
||||
IJB_BUTTON8,
|
||||
IJB_BUTTON9,
|
||||
IJB_BUTTON10,
|
||||
IJB_BUTTON11,
|
||||
IJB_BUTTON12,
|
||||
IJB_BUTTON13,
|
||||
IJB_BUTTON14,
|
||||
IJB_BUTTON15,
|
||||
IJB_BUTTON16,
|
||||
IJB_BUTTON17,
|
||||
IJB_BUTTON18,
|
||||
IJB_BUTTON19,
|
||||
IJB_BUTTON20,
|
||||
IJB_BUTTON21,
|
||||
IJB_BUTTON22,
|
||||
IJB_BUTTON23,
|
||||
IJB_BUTTON24,
|
||||
IJB_BUTTON25,
|
||||
IJB_BUTTON26,
|
||||
IJB_BUTTON27,
|
||||
IJB_BUTTON28,
|
||||
IJB_BUTTON29,
|
||||
IJB_BUTTON30,
|
||||
IJB_BUTTON31,
|
||||
IJB_DPADUP = 200,
|
||||
IJB_DPADRIGHT = 201,
|
||||
IJB_DPADLEFT = 202,
|
||||
IJB_DPADDOWN = 203,
|
||||
// Xbox 360 buttons
|
||||
IJB_XBOXA = IJB_BUTTON0,
|
||||
IJB_XBOXB = IJB_BUTTON1,
|
||||
IJB_XBOXX = IJB_BUTTON2,
|
||||
IJB_XBOXY = IJB_BUTTON3,
|
||||
IJB_XBOXLB = IJB_BUTTON4,
|
||||
IJB_XBOXRB = IJB_BUTTON5,
|
||||
IJB_XBOXBACK = IJB_BUTTON6,
|
||||
IJB_XBOXSTART = IJB_BUTTON7,
|
||||
IJB_XBOXLEFTSTICK = IJB_BUTTON8,
|
||||
IJB_XBOXRIGHTSTICK = IJB_BUTTON9,
|
||||
IJB_XBOXDPADUP = IJB_DPADUP,
|
||||
IJB_XBOXDPADRIGHT = IJB_DPADRIGHT,
|
||||
IJB_XBOXDPADLEFT = IJB_DPADLEFT,
|
||||
IJB_XBOXDPADDOWN = IJB_DPADDOWN,
|
||||
IJB_XBOXLT = 204,
|
||||
IJB_XBOXRT = 205,
|
||||
// Dualshock 4 buttons
|
||||
IJB_DS4SQUARE = IJB_BUTTON0,
|
||||
IJB_DS4CROSS = IJB_BUTTON1,
|
||||
IJB_DS4CIRCLE = IJB_BUTTON2,
|
||||
IJB_DS4TRIANGLE = IJB_BUTTON3,
|
||||
IJB_DS4L1 = IJB_BUTTON4,
|
||||
IJB_DS4R1 = IJB_BUTTON5,
|
||||
IJB_DS4L2 = IJB_BUTTON6,
|
||||
IJB_DS4R2 = IJB_BUTTON7,
|
||||
IJB_DS4SHARE = IJB_BUTTON8,
|
||||
IJB_DS4OPTIONS = IJB_BUTTON9,
|
||||
IJB_DS4LEFTSTICK = IJB_BUTTON10,
|
||||
IJB_DS4RIGHTSTICK = IJB_BUTTON11,
|
||||
IJB_DS4PLAYSTATION = IJB_BUTTON12,
|
||||
IJB_DS4TOUCH = IJB_BUTTON13,
|
||||
IJB_DS4DPADUP = IJB_DPADUP,
|
||||
IJB_DS4DPADRIGHT = IJB_DPADRIGHT,
|
||||
IJB_DS4DPADLEFT = IJB_DPADLEFT,
|
||||
IJB_DS4DPADDOWN = IJB_DPADDOWN,
|
||||
};
|
||||
|
||||
enum InputJoystickPhysical : unsigned char
|
||||
{
|
||||
IJP_FACEDOWN = 0,
|
||||
IJP_FACERIGHT = 1,
|
||||
IJP_FACELEFT = 2,
|
||||
IJP_FACEUP = 3,
|
||||
IJP_DPADDOWN = 4,
|
||||
IJP_DPADRIGHT = 5,
|
||||
IJP_DPADLEFT = 6,
|
||||
IJP_DPADUP = 7,
|
||||
IJP_SHOULDERRIGHT = 8,
|
||||
IJP_SHOULDERLEFT = 9,
|
||||
IJP_TRIGGERRIGHT = 10,
|
||||
IJP_TRIGGERLEFT = 11,
|
||||
IJP_START = 12,
|
||||
IJP_SELECT = 13,
|
||||
IJP_STICKLEFT = 14,
|
||||
IJP_STICKRIGHT = 15,
|
||||
};
|
||||
|
||||
enum InputManagerEvent : unsigned char
|
||||
{
|
||||
IME_PRESSED = 0,
|
||||
IME_RELEASED = 1,
|
||||
IME_REPEAT = 2,
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
688
Source/UnrealProject/External/InputManager.cpp
vendored
Normal file
688
Source/UnrealProject/External/InputManager.cpp
vendored
Normal file
@@ -0,0 +1,688 @@
|
||||
#include "UnrealProject.h"
|
||||
#if PLATFORM_SPECIFIC_WIN == 0
|
||||
|
||||
#define _SOURCE_INPUT_MANAGER
|
||||
#include "InputManager.hpp"
|
||||
|
||||
#include "AllowWindowsPlatformTypes.h"
|
||||
|
||||
#pragma comment(lib, "dinput8.lib")
|
||||
#pragma comment (lib, "dxguid.lib")
|
||||
|
||||
#define DIRECTINPUT_VERSION 0x0800
|
||||
#include <Windows.h>
|
||||
|
||||
#include <dinput.h>
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define DUALSHOCK4PRODUCTDATA (0x05C4054CUL)
|
||||
#define DUALSHOCK4DEVTYPE (0x00010318UL)
|
||||
#define WIREDXBOXDEVTYPE (0x00010215UL)
|
||||
#define PI 3.14159265359f
|
||||
|
||||
namespace Input
|
||||
{
|
||||
struct GUID_Impl
|
||||
{
|
||||
GUID instance;
|
||||
DWORD devType;
|
||||
unsigned long productData1;
|
||||
};
|
||||
|
||||
|
||||
LPDIRECTINPUT8 g_DirectInput;
|
||||
HWND g_HWND;
|
||||
InputManager* InputManager::s_instance;
|
||||
bool InputManager::s_isInitialized = false;
|
||||
vector<GUID_Impl> g_GUIDs;
|
||||
|
||||
bool InputManager::IsInitialized()
|
||||
{
|
||||
return s_isInitialized;
|
||||
}
|
||||
bool InputManager::Initialize()
|
||||
{
|
||||
if (!IsInitialized())
|
||||
{
|
||||
g_HWND = GetActiveWindow();
|
||||
HRESULT hr;
|
||||
HINSTANCE hInstance = GetModuleHandle(nullptr);
|
||||
|
||||
hr = DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&g_DirectInput, NULL);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
s_instance = new InputManager();
|
||||
|
||||
|
||||
s_isInitialized = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void InputManager::Cleanup()
|
||||
{
|
||||
if (IsInitialized())
|
||||
{
|
||||
delete s_instance;
|
||||
s_instance = nullptr;
|
||||
g_DirectInput->Release();
|
||||
s_isInitialized = false;
|
||||
}
|
||||
}
|
||||
InputManager* InputManager::GetInstance()
|
||||
{
|
||||
if (!s_isInitialized)
|
||||
Initialize();
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
|
||||
// Implementation of Input Devices
|
||||
class Keyboard_Impl : public Keyboard
|
||||
{
|
||||
public:
|
||||
Keyboard_Impl()
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
hr = g_DirectInput->CreateDevice(GUID_SysKeyboard, &m_Device, NULL);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
}
|
||||
hr = m_Device->SetDataFormat(&c_dfDIKeyboard);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
}
|
||||
hr = m_Device->SetCooperativeLevel(g_HWND, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
}
|
||||
}
|
||||
~Keyboard_Impl()
|
||||
{
|
||||
m_Device->Unacquire();
|
||||
}
|
||||
virtual void Update() override final
|
||||
{
|
||||
HRESULT hr;
|
||||
hr = m_Device->Acquire();
|
||||
memcpy(m_PreviousState, m_CurrentState, sizeof(BYTE) * 256);
|
||||
m_Device->GetDeviceState(sizeof(m_CurrentState), (LPVOID)&m_CurrentState);
|
||||
}
|
||||
virtual bool GetKey(const InputKey a_Key) override final
|
||||
{
|
||||
return (m_CurrentState[a_Key] & 0x80) != 0;
|
||||
}
|
||||
virtual bool GetKeyDown(const InputKey a_Key) override final
|
||||
{
|
||||
return m_CurrentState[a_Key] & 0x80 && !(m_PreviousState[a_Key] & 0x80);
|
||||
}
|
||||
|
||||
private:
|
||||
IDirectInputDevice8* m_Device;
|
||||
BYTE m_CurrentState[256];
|
||||
BYTE m_PreviousState[256];
|
||||
};
|
||||
class Joystick_Impl : public Joystick
|
||||
{
|
||||
public:
|
||||
Joystick_Impl(IDirectInputDevice8* a_Device)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
m_Device = a_Device;
|
||||
|
||||
hr = m_Device->SetDataFormat(&c_dfDIJoystick);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
}
|
||||
hr = m_Device->SetCooperativeLevel(g_HWND, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
}
|
||||
}
|
||||
virtual ~Joystick_Impl()
|
||||
{
|
||||
m_Device->Unacquire();
|
||||
m_Device->Release();
|
||||
}
|
||||
virtual void Update() override final
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
m_PreviousState = m_CurrentState;
|
||||
hr = m_Device->Acquire();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
m_IsValid = false;
|
||||
return;
|
||||
}
|
||||
hr = m_Device->GetDeviceState(sizeof(DIJOYSTATE), (LPVOID)&m_CurrentState);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
m_IsValid = false;
|
||||
return;
|
||||
}
|
||||
m_IsValid = true;
|
||||
}
|
||||
virtual bool IsValid() override final
|
||||
{
|
||||
return m_IsValid;
|
||||
}
|
||||
virtual bool GetButton(const InputJoystickButton a_JoystickButton)
|
||||
{
|
||||
return (m_CurrentState.rgbButtons[a_JoystickButton] & 0x80) != 0;
|
||||
}
|
||||
virtual bool GetButton(const InputJoystickPhysical a_JoystickButton)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool GetButtonDown(const InputJoystickButton a_JoystickButton)
|
||||
{
|
||||
return m_CurrentState.rgbButtons[a_JoystickButton] & 0x80 && !(m_PreviousState.rgbButtons[a_JoystickButton] & 0x80);
|
||||
}
|
||||
virtual bool GetButtonDown(const InputJoystickPhysical a_JoystickButton)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool GetButtonUp(const InputJoystickButton a_JoystickButton)
|
||||
{
|
||||
return m_PreviousState.rgbButtons[a_JoystickButton] & 0x80 && !(m_CurrentState.rgbButtons[a_JoystickButton] & 0x80);
|
||||
}
|
||||
virtual bool GetButtonUp(const InputJoystickPhysical a_JoystickButton)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual TeaLib::Math::Vector2f GetDelta(const InputJoystickAxis a_InputStick)
|
||||
{
|
||||
if (IsValid())
|
||||
{
|
||||
switch (a_InputStick)
|
||||
{
|
||||
case Input::IJA_LSTICK:
|
||||
return TeaLib::Math::Vector2f((float)m_CurrentState.lX, (float)m_CurrentState.lY) / 32767.0f;
|
||||
case Input::IJA_RSTICK:
|
||||
return TeaLib::Math::Vector2f((float)m_CurrentState.lRx, (float)m_CurrentState.lRy) / 32767.0f;
|
||||
case Input::IJA_LRTRIGGER:
|
||||
return TeaLib::Math::Vector2f((float)m_CurrentState.lZ, (float)m_CurrentState.lRz) / 32767.0f;
|
||||
default:
|
||||
return TeaLib::Math::Vector2f();
|
||||
}
|
||||
}
|
||||
return TeaLib::Math::Vector2f();
|
||||
}
|
||||
virtual InputDeviceType GetDeviceType()
|
||||
{
|
||||
return IDT_NOTDEFINED;
|
||||
}
|
||||
protected:
|
||||
bool m_IsValid = false;
|
||||
IDirectInputDevice8* m_Device;
|
||||
DIJOYSTATE m_CurrentState, m_PreviousState;
|
||||
};
|
||||
class JoystickDS4_Impl : public Joystick_Impl
|
||||
{
|
||||
public:
|
||||
JoystickDS4_Impl(IDirectInputDevice8* a_Device) : Joystick_Impl(a_Device)
|
||||
{
|
||||
m_PhysicalBindings[IJP_FACEDOWN] = IJB_DS4CROSS;
|
||||
m_PhysicalBindings[IJP_FACERIGHT] = IJB_DS4CIRCLE;
|
||||
m_PhysicalBindings[IJP_FACELEFT] = IJB_BUTTON0;
|
||||
m_PhysicalBindings[IJP_FACEUP] = IJB_BUTTON3;
|
||||
m_PhysicalBindings[IJP_DPADDOWN] = IJB_DS4DPADDOWN;
|
||||
m_PhysicalBindings[IJP_DPADRIGHT] = IJB_DS4DPADRIGHT;
|
||||
m_PhysicalBindings[IJP_DPADLEFT] = IJB_DS4DPADLEFT;
|
||||
m_PhysicalBindings[IJP_DPADUP] = IJB_DS4DPADUP;
|
||||
m_PhysicalBindings[IJP_SHOULDERRIGHT] = IJB_DS4R1;
|
||||
m_PhysicalBindings[IJP_SHOULDERLEFT] = IJB_DS4L1;
|
||||
m_PhysicalBindings[IJP_TRIGGERRIGHT] = IJB_DS4R2;
|
||||
m_PhysicalBindings[IJP_TRIGGERLEFT] = IJB_DS4L2;
|
||||
m_PhysicalBindings[IJP_START] = IJB_DS4OPTIONS;
|
||||
m_PhysicalBindings[IJP_SELECT] = IJB_DS4SHARE;
|
||||
m_PhysicalBindings[IJP_STICKLEFT] = IJB_DS4LEFTSTICK;
|
||||
m_PhysicalBindings[IJP_STICKRIGHT] = IJB_DS4RIGHTSTICK;
|
||||
}
|
||||
virtual bool GetButton(const InputJoystickButton a_JoystickButton) override final
|
||||
{
|
||||
if (a_JoystickButton < 200)
|
||||
return (m_CurrentState.rgbButtons[a_JoystickButton] & 0x80) != 0;
|
||||
else
|
||||
{
|
||||
switch (a_JoystickButton)
|
||||
{
|
||||
case Input::IJB_DS4DPADUP:
|
||||
if (m_CurrentState.rgdwPOV[0] < 36000 && m_CurrentState.rgdwPOV[0] > 27000 || m_CurrentState.rgdwPOV[0] < 9000)
|
||||
return true;
|
||||
break;
|
||||
case Input::IJB_DS4DPADRIGHT:
|
||||
if (m_CurrentState.rgdwPOV[0] > 0 && m_CurrentState.rgdwPOV[0] < 18000)
|
||||
return true;
|
||||
break;
|
||||
case Input::IJB_DS4DPADDOWN:
|
||||
if (m_CurrentState.rgdwPOV[0] > 9000 && m_CurrentState.rgdwPOV[0] < 27000)
|
||||
return true;
|
||||
break;
|
||||
case Input::IJB_DS4DPADLEFT:
|
||||
if (m_CurrentState.rgdwPOV[0] > 18000 && m_CurrentState.rgdwPOV[0] < 36000)
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
virtual bool GetButton(const InputJoystickPhysical a_JoystickButton) override final
|
||||
{
|
||||
return GetButton(m_PhysicalBindings[a_JoystickButton]);
|
||||
}
|
||||
virtual bool GetButtonDown(const InputJoystickButton a_JoystickButton) override final
|
||||
{
|
||||
if (a_JoystickButton < 200)
|
||||
return m_CurrentState.rgbButtons[a_JoystickButton] & 0x80 && !(m_PreviousState.rgbButtons[a_JoystickButton] & 0x80);
|
||||
else
|
||||
{
|
||||
switch (a_JoystickButton)
|
||||
{
|
||||
case Input::IJB_DS4DPADUP:
|
||||
if (m_CurrentState.rgdwPOV[0] == 0 && m_PreviousState.rgdwPOV[0] != 0)
|
||||
return true;
|
||||
break;
|
||||
case Input::IJB_DS4DPADRIGHT:
|
||||
if (m_CurrentState.rgdwPOV[0] == 9000 && m_PreviousState.rgdwPOV[0] != 9000)
|
||||
return true;
|
||||
break;
|
||||
case Input::IJB_DS4DPADDOWN:
|
||||
if (m_CurrentState.rgdwPOV[0] == 18000 && m_PreviousState.rgdwPOV[0] != 18000)
|
||||
return true;
|
||||
break;
|
||||
case Input::IJB_DS4DPADLEFT:
|
||||
if (m_CurrentState.rgdwPOV[0] == 27000 && m_PreviousState.rgdwPOV[0] != 27000)
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
virtual bool GetButtonDown(const InputJoystickPhysical a_JoystickButton) override final
|
||||
{
|
||||
return GetButtonDown(m_PhysicalBindings[a_JoystickButton]);
|
||||
}
|
||||
virtual bool GetButtonUp(const InputJoystickButton a_JoystickButton) override final
|
||||
{
|
||||
if (a_JoystickButton < 200)
|
||||
return m_PreviousState.rgbButtons[a_JoystickButton] & 0x80 && !(m_CurrentState.rgbButtons[a_JoystickButton] & 0x80);
|
||||
else
|
||||
{
|
||||
switch (a_JoystickButton)
|
||||
{
|
||||
case Input::IJB_DS4DPADUP:
|
||||
if (m_PreviousState.rgdwPOV[0] == 0 && m_CurrentState.rgdwPOV[0] != 0)
|
||||
return true;
|
||||
break;
|
||||
case Input::IJB_DS4DPADRIGHT:
|
||||
if (m_PreviousState.rgdwPOV[0] == 9000 && m_CurrentState.rgdwPOV[0] != 9000)
|
||||
return true;
|
||||
break;
|
||||
case Input::IJB_DS4DPADDOWN:
|
||||
if (m_PreviousState.rgdwPOV[0] == 18000 && m_CurrentState.rgdwPOV[0] != 18000)
|
||||
return true;
|
||||
break;
|
||||
case Input::IJB_DS4DPADLEFT:
|
||||
if (m_PreviousState.rgdwPOV[0] == 27000 && m_CurrentState.rgdwPOV[0] != 27000)
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
virtual bool GetButtonUp(const InputJoystickPhysical a_JoystickButton) override final
|
||||
{
|
||||
return GetButtonUp(m_PhysicalBindings[a_JoystickButton]);
|
||||
}
|
||||
virtual TeaLib::Math::Vector2f GetDelta(const InputJoystickAxis a_InputStick) override final
|
||||
{
|
||||
if (IsValid())
|
||||
{
|
||||
float angle;
|
||||
switch (a_InputStick)
|
||||
{
|
||||
case Input::IJA_LSTICK:
|
||||
return TeaLib::Math::Vector2f((float)m_CurrentState.lX - 32767.0f, (float)m_CurrentState.lY - 32767.0f) / 32767.0f;
|
||||
case Input::IJA_RSTICK:
|
||||
return TeaLib::Math::Vector2f((float)m_CurrentState.lZ - 32767.0f, (float)m_CurrentState.lRz - 32767.0f) / 32767.0f;
|
||||
case Input::IJA_LRTRIGGER:
|
||||
return TeaLib::Math::Vector2f((float)m_CurrentState.lRx, (float)m_CurrentState.lRy) / 65534.0f;
|
||||
case Input::IJA_DPAD:
|
||||
if (m_PreviousState.rgdwPOV[0] < 90000)
|
||||
{
|
||||
angle = (((float)m_PreviousState.rgdwPOV[0] / 100.0f) * PI / 180.0f);
|
||||
return TeaLib::Math::Vector2f(sinf(angle), -cosf(angle));
|
||||
}
|
||||
return TeaLib::Math::Vector2f();
|
||||
default:
|
||||
return TeaLib::Math::Vector2f();
|
||||
}
|
||||
}
|
||||
return TeaLib::Math::Vector2f();
|
||||
}
|
||||
virtual InputDeviceType GetDeviceType() override final
|
||||
{
|
||||
return IDT_DS4;
|
||||
}
|
||||
private:
|
||||
map<InputJoystickPhysical, InputJoystickButton> m_PhysicalBindings;
|
||||
};
|
||||
class JoystickXbox360_Impl : public Joystick_Impl
|
||||
{
|
||||
public:
|
||||
JoystickXbox360_Impl(IDirectInputDevice8* a_Device) : Joystick_Impl(a_Device)
|
||||
{
|
||||
m_PhysicalBindings[IJP_FACEDOWN] = IJB_XBOXA;
|
||||
m_PhysicalBindings[IJP_FACERIGHT] = IJB_XBOXB;
|
||||
m_PhysicalBindings[IJP_FACELEFT] = IJB_XBOXX;
|
||||
m_PhysicalBindings[IJP_FACEUP] = IJB_XBOXY;
|
||||
m_PhysicalBindings[IJP_DPADDOWN] = IJB_XBOXDPADDOWN;
|
||||
m_PhysicalBindings[IJP_DPADRIGHT] = IJB_XBOXDPADRIGHT;
|
||||
m_PhysicalBindings[IJP_DPADLEFT] = IJB_XBOXDPADLEFT;
|
||||
m_PhysicalBindings[IJP_DPADUP] = IJB_XBOXDPADUP;
|
||||
m_PhysicalBindings[IJP_SHOULDERRIGHT] = IJB_XBOXRB;
|
||||
m_PhysicalBindings[IJP_SHOULDERLEFT] = IJB_XBOXLB;
|
||||
m_PhysicalBindings[IJP_TRIGGERRIGHT] = IJB_XBOXRT;
|
||||
m_PhysicalBindings[IJP_TRIGGERLEFT] = IJB_XBOXLT;
|
||||
m_PhysicalBindings[IJP_START] = IJB_XBOXSTART;
|
||||
m_PhysicalBindings[IJP_SELECT] = IJB_XBOXBACK;
|
||||
m_PhysicalBindings[IJP_STICKLEFT] = IJB_XBOXLEFTSTICK;
|
||||
m_PhysicalBindings[IJP_STICKRIGHT] = IJB_XBOXRIGHTSTICK;
|
||||
}
|
||||
virtual TeaLib::Math::Vector2f GetDelta(const InputJoystickAxis a_InputStick) override final
|
||||
{
|
||||
if (IsValid())
|
||||
{
|
||||
float result;
|
||||
float angle;
|
||||
switch (a_InputStick)
|
||||
{
|
||||
case Input::IJA_LSTICK:
|
||||
return TeaLib::Math::Vector2f((float)m_CurrentState.lX - 32767.0f, (float)m_CurrentState.lY - 32767.0f) / 32767.0f;
|
||||
case Input::IJA_RSTICK:
|
||||
return TeaLib::Math::Vector2f((float)m_CurrentState.lRx - 32767.0f, (float)m_CurrentState.lRy - 32767.0f) / 32767.0f;
|
||||
case Input::IJA_LRTRIGGER:
|
||||
result = ((float)m_CurrentState.lZ - 32767.0f) / 32767.0f;
|
||||
return TeaLib::Math::Vector2f(result, result);
|
||||
case Input::IJA_DPAD:
|
||||
if (m_PreviousState.rgdwPOV[0] < 90000)
|
||||
{
|
||||
angle = (((float)m_PreviousState.rgdwPOV[0] / 100.0f) * PI / 180.0f);
|
||||
return TeaLib::Math::Vector2f(sinf(angle), -cosf(angle));
|
||||
}
|
||||
return TeaLib::Math::Vector2f();
|
||||
default:
|
||||
return TeaLib::Math::Vector2f();
|
||||
}
|
||||
}
|
||||
return TeaLib::Math::Vector2f();
|
||||
}
|
||||
virtual bool GetButton(const InputJoystickButton a_JoystickButton) override final
|
||||
{
|
||||
if (a_JoystickButton < 200)
|
||||
return (m_CurrentState.rgbButtons[a_JoystickButton] & 0x80) != 0;
|
||||
else
|
||||
{
|
||||
float val;
|
||||
switch (a_JoystickButton)
|
||||
{
|
||||
case Input::IJB_XBOXDPADUP:
|
||||
if (m_CurrentState.rgdwPOV[0] < 36000 && m_CurrentState.rgdwPOV[0] > 27000 || m_CurrentState.rgdwPOV[0] < 9000)
|
||||
return true;
|
||||
break;
|
||||
case Input::IJB_XBOXDPADRIGHT:
|
||||
if (m_CurrentState.rgdwPOV[0] > 0 && m_CurrentState.rgdwPOV[0] < 18000)
|
||||
return true;
|
||||
break;
|
||||
case Input::IJB_XBOXDPADDOWN:
|
||||
if (m_CurrentState.rgdwPOV[0] > 9000 && m_CurrentState.rgdwPOV[0] < 27000)
|
||||
return true;
|
||||
break;
|
||||
case Input::IJB_XBOXDPADLEFT:
|
||||
if (m_CurrentState.rgdwPOV[0] > 18000 && m_CurrentState.rgdwPOV[0] < 36000)
|
||||
return true;
|
||||
break;
|
||||
case Input::IJB_XBOXLT:
|
||||
val = ((float)m_CurrentState.lZ - 32767.0f) / 32767.0f;;
|
||||
return val > 0.1f;
|
||||
case Input::IJB_XBOXRT:
|
||||
val = ((float)m_CurrentState.lZ - 32767.0f) / 32767.0f;;
|
||||
return val < -0.1f;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
virtual bool GetButton(const InputJoystickPhysical a_JoystickButton) override final
|
||||
{
|
||||
return GetButton(m_PhysicalBindings[a_JoystickButton]);
|
||||
}
|
||||
virtual bool GetButtonDown(const InputJoystickButton a_JoystickButton) override final
|
||||
{
|
||||
if (a_JoystickButton < 200)
|
||||
return m_CurrentState.rgbButtons[a_JoystickButton] & 0x80 && !(m_PreviousState.rgbButtons[a_JoystickButton] & 0x80);
|
||||
else
|
||||
{
|
||||
float curr, prev;
|
||||
switch (a_JoystickButton)
|
||||
{
|
||||
case Input::IJB_XBOXDPADUP:
|
||||
if (m_CurrentState.rgdwPOV[0] == 0 && m_PreviousState.rgdwPOV[0] != 0)
|
||||
return true;
|
||||
break;
|
||||
case Input::IJB_XBOXDPADRIGHT:
|
||||
if (m_CurrentState.rgdwPOV[0] == 9000 && m_PreviousState.rgdwPOV[0] != 9000)
|
||||
return true;
|
||||
break;
|
||||
case Input::IJB_XBOXDPADDOWN:
|
||||
if (m_CurrentState.rgdwPOV[0] == 18000 && m_PreviousState.rgdwPOV[0] != 18000)
|
||||
return true;
|
||||
break;
|
||||
case Input::IJB_XBOXDPADLEFT:
|
||||
if (m_CurrentState.rgdwPOV[0] == 27000 && m_PreviousState.rgdwPOV[0] != 27000)
|
||||
return true;
|
||||
break;
|
||||
case Input::IJB_XBOXLT:
|
||||
curr = ((float)m_CurrentState.lZ - 32767.0f) / 32767.0f;
|
||||
prev = ((float)m_PreviousState.lZ - 32767.0f) / 32767.0f;
|
||||
return curr > 0.1f && prev <= 0.1f;
|
||||
case Input::IJB_XBOXRT:
|
||||
curr = ((float)m_CurrentState.lZ - 32767.0f) / 32767.0f;
|
||||
prev = ((float)m_PreviousState.lZ - 32767.0f) / 32767.0f;
|
||||
return curr < -0.1f && prev >= -0.1f;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
virtual bool GetButtonDown(const InputJoystickPhysical a_JoystickButton) override final
|
||||
{
|
||||
if (m_PhysicalBindings.find(a_JoystickButton) != m_PhysicalBindings.end())
|
||||
return GetButtonDown(m_PhysicalBindings[a_JoystickButton]);
|
||||
return false;
|
||||
}
|
||||
virtual bool GetButtonUp(const InputJoystickButton a_JoystickButton) override final
|
||||
{
|
||||
if (a_JoystickButton < 200)
|
||||
return m_PreviousState.rgbButtons[a_JoystickButton] & 0x80 && !(m_CurrentState.rgbButtons[a_JoystickButton] & 0x80);
|
||||
else
|
||||
{
|
||||
float curr, prev;
|
||||
switch (a_JoystickButton)
|
||||
{
|
||||
case Input::IJB_XBOXDPADUP:
|
||||
if (m_PreviousState.rgdwPOV[0] == 0 && m_CurrentState.rgdwPOV[0] != 0)
|
||||
return true;
|
||||
break;
|
||||
case Input::IJB_XBOXDPADRIGHT:
|
||||
if (m_PreviousState.rgdwPOV[0] == 9000 && m_CurrentState.rgdwPOV[0] != 9000)
|
||||
return true;
|
||||
break;
|
||||
case Input::IJB_XBOXDPADDOWN:
|
||||
if (m_PreviousState.rgdwPOV[0] == 18000 && m_CurrentState.rgdwPOV[0] != 18000)
|
||||
return true;
|
||||
break;
|
||||
case Input::IJB_XBOXDPADLEFT:
|
||||
if (m_PreviousState.rgdwPOV[0] == 27000 && m_CurrentState.rgdwPOV[0] != 27000)
|
||||
return true;
|
||||
break;
|
||||
case Input::IJB_XBOXLT:
|
||||
curr = ((float)m_CurrentState.lZ - 32767.0f) / 32767.0f;
|
||||
prev = ((float)m_PreviousState.lZ - 32767.0f) / 32767.0f;
|
||||
return curr <= 0.1f && prev > 0.1f;
|
||||
case Input::IJB_XBOXRT:
|
||||
curr = ((float)m_CurrentState.lZ - 32767.0f) / 32767.0f;
|
||||
prev = ((float)m_PreviousState.lZ - 32767.0f) / 32767.0f;
|
||||
return curr >= -0.1f && prev < -0.1f;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
virtual bool GetButtonUp(const InputJoystickPhysical a_JoystickButton) override final
|
||||
{
|
||||
if (m_PhysicalBindings.find(a_JoystickButton) != m_PhysicalBindings.end())
|
||||
return GetButtonUp(m_PhysicalBindings[a_JoystickButton]);
|
||||
return false;
|
||||
}
|
||||
virtual InputDeviceType GetDeviceType() override final
|
||||
{
|
||||
return IDT_XBOX;
|
||||
}
|
||||
private:
|
||||
map<InputJoystickPhysical, InputJoystickButton> m_PhysicalBindings;
|
||||
};
|
||||
|
||||
InputManager::InputManager() : joystick(nullptr)
|
||||
{
|
||||
keyboard = new Keyboard_Impl();
|
||||
}
|
||||
|
||||
void InputManager::Update()
|
||||
{
|
||||
keyboard->Update();
|
||||
if (joystick)
|
||||
{
|
||||
joystick->Update();
|
||||
|
||||
if (joystick->IsValid())
|
||||
{
|
||||
for (auto it : m_joystickCallbacks)
|
||||
{
|
||||
switch (it.first.second)
|
||||
{
|
||||
case IME_PRESSED:
|
||||
if (joystick->GetButtonDown(it.first.first))
|
||||
{
|
||||
it.second->Call();
|
||||
}
|
||||
break;
|
||||
case IME_RELEASED:
|
||||
if (joystick->GetButtonUp(it.first.first))
|
||||
{
|
||||
it.second->Call();
|
||||
}
|
||||
break;
|
||||
case IME_REPEAT:
|
||||
if (joystick->GetButton(it.first.first))
|
||||
{
|
||||
it.second->Call();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BOOL __stdcall JoystickEnumCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
|
||||
{
|
||||
InputManager* inputInstance = InputManager::GetInstance();
|
||||
|
||||
inputInstance->AddJoystickName(lpddi->tszProductName);
|
||||
|
||||
GUID_Impl newGUID;
|
||||
newGUID.devType = lpddi->dwDevType;
|
||||
newGUID.instance = lpddi->guidInstance;
|
||||
newGUID.productData1 = lpddi->guidProduct.Data1;
|
||||
|
||||
g_GUIDs.push_back(newGUID);
|
||||
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
void InputManager::AddJoystickName(std::wstring a_name)
|
||||
{
|
||||
m_joystickNames.push_back(a_name);
|
||||
}
|
||||
|
||||
void InputManager::SearchForJoystick()
|
||||
{
|
||||
m_joystickNames.clear();
|
||||
g_GUIDs.clear();
|
||||
g_DirectInput->EnumDevices(DI8DEVCLASS_GAMECTRL, &JoystickEnumCallback, NULL, DIEDFL_ATTACHEDONLY);
|
||||
}
|
||||
|
||||
vector<wstring>& InputManager::GetJoystickNames()
|
||||
{
|
||||
return m_joystickNames;
|
||||
}
|
||||
|
||||
void InputManager::ConnectJoystickByIndex(size_t a_index)
|
||||
{
|
||||
if (joystick)
|
||||
delete joystick;
|
||||
|
||||
if (a_index >= g_GUIDs.size())
|
||||
return;
|
||||
|
||||
HRESULT hr;
|
||||
IDirectInputDevice8* device;
|
||||
hr = g_DirectInput->CreateDevice(g_GUIDs[a_index].instance, &device, NULL);
|
||||
if (!FAILED(hr))
|
||||
{
|
||||
if (g_GUIDs[a_index].devType == DUALSHOCK4DEVTYPE || g_GUIDs[a_index].productData1 == DUALSHOCK4PRODUCTDATA)
|
||||
joystick = new JoystickDS4_Impl(device);
|
||||
else if (g_GUIDs[a_index].devType == WIREDXBOXDEVTYPE)
|
||||
joystick = new JoystickXbox360_Impl(device);
|
||||
else
|
||||
joystick = new Joystick_Impl(device);
|
||||
}
|
||||
}
|
||||
|
||||
InputManager::~InputManager()
|
||||
{
|
||||
delete keyboard;
|
||||
delete joystick;
|
||||
ClearCallbacks();
|
||||
}
|
||||
|
||||
void InputManager::ClearCallbacks()
|
||||
{
|
||||
for (auto it : m_joystickCallbacks)
|
||||
{
|
||||
delete it.second;
|
||||
}
|
||||
m_joystickCallbacks.clear();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
95
Source/UnrealProject/External/InputManager.hpp
vendored
Normal file
95
Source/UnrealProject/External/InputManager.hpp
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
#ifndef _HEADER_INPUT_MANAGER
|
||||
#define _HEADER_INPUT_MANAGER
|
||||
|
||||
#include "InputDeviceBases.hpp"
|
||||
#include "TeaCallback.hpp"
|
||||
#include <map>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
|
||||
namespace Input
|
||||
{
|
||||
class InputManager
|
||||
{
|
||||
public:
|
||||
static bool IsInitialized();
|
||||
static bool Initialize();
|
||||
static void Cleanup();
|
||||
static InputManager* GetInstance();
|
||||
|
||||
private:
|
||||
static bool s_isInitialized;
|
||||
static InputManager* s_instance;
|
||||
|
||||
public:
|
||||
InputManager();
|
||||
~InputManager();
|
||||
|
||||
InputDeviceType GetConnectedType()
|
||||
{
|
||||
if (joystick)
|
||||
return joystick->GetDeviceType();
|
||||
return IDT_NONE;
|
||||
}
|
||||
bool IsJoystickConnected(const unsigned int a_Channel);
|
||||
|
||||
void SearchForJoystick();
|
||||
|
||||
std::vector<std::wstring>& GetJoystickNames();
|
||||
void AddJoystickName(std::wstring a_name);
|
||||
|
||||
void ConnectJoystickByIndex(size_t m_index);
|
||||
|
||||
void Update();
|
||||
|
||||
void RegisterCallback(InputJoystickPhysical a_Button, InputManagerEvent a_Event, void(*a_CallbackFunction)())
|
||||
{
|
||||
std::pair<InputJoystickPhysical, InputManagerEvent> newEvent(a_Button, a_Event);
|
||||
if (m_joystickCallbacks.find(newEvent) == m_joystickCallbacks.end())
|
||||
{
|
||||
m_joystickCallbacks[newEvent] = new TeaLib::Utility::Callback<>();
|
||||
}
|
||||
m_joystickCallbacks[newEvent]->Register(a_CallbackFunction);
|
||||
}
|
||||
template<typename ClassType> void RegisterCallback(InputJoystickPhysical a_Button, InputManagerEvent a_Event, ClassType* a_ClassInstance, void(ClassType::*a_CallbackFunction)())
|
||||
{
|
||||
std::pair<InputJoystickPhysical, InputManagerEvent> newEvent(a_Button, a_Event);
|
||||
if (m_joystickCallbacks.find(newEvent) == m_joystickCallbacks.end())
|
||||
{
|
||||
m_joystickCallbacks[newEvent] = new TeaLib::Utility::Callback<>();
|
||||
}
|
||||
m_joystickCallbacks[newEvent]->Register(a_ClassInstance, a_CallbackFunction);
|
||||
}
|
||||
void DeregisterCallback(InputJoystickPhysical a_Button, InputManagerEvent a_Event, void(*a_CallbackFunction)())
|
||||
{
|
||||
if (!this)
|
||||
return;
|
||||
std::pair<InputJoystickPhysical, InputManagerEvent> newEvent(a_Button, a_Event);
|
||||
if (m_joystickCallbacks.find(newEvent) != m_joystickCallbacks.end())
|
||||
{
|
||||
m_joystickCallbacks[newEvent]->Deregister(a_CallbackFunction);
|
||||
};
|
||||
}
|
||||
template<typename ClassType> void DeregisterCallback(InputJoystickPhysical a_Button, InputManagerEvent a_Event, ClassType* a_ClassInstance, void(ClassType::*a_CallbackFunction)())
|
||||
{
|
||||
if (!this)
|
||||
return;
|
||||
std::pair<InputJoystickPhysical, InputManagerEvent> newEvent(a_Button, a_Event);
|
||||
if (m_joystickCallbacks.find(newEvent) != m_joystickCallbacks.end())
|
||||
{
|
||||
m_joystickCallbacks[newEvent]->Deregister(a_ClassInstance, a_CallbackFunction);
|
||||
}
|
||||
}
|
||||
|
||||
void ClearCallbacks();
|
||||
|
||||
Keyboard* keyboard;
|
||||
Joystick* joystick;
|
||||
|
||||
private:
|
||||
std::vector<std::wstring> m_joystickNames;
|
||||
std::map<std::pair<InputJoystickPhysical, InputManagerEvent>, TeaLib::Utility::Callback<>*> m_joystickCallbacks;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
362
Source/UnrealProject/External/Metrics.cpp
vendored
Normal file
362
Source/UnrealProject/External/Metrics.cpp
vendored
Normal file
@@ -0,0 +1,362 @@
|
||||
#include "UnrealProject.h"
|
||||
|
||||
#if WITH_EDITOR
|
||||
|
||||
#include "Metrics.hpp"
|
||||
//#include <append>
|
||||
#include <timer>
|
||||
|
||||
#include <fstream>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <chrono>
|
||||
#include <algorithm>
|
||||
|
||||
#if PLATFORM_SPECIFIC_WIN == 0
|
||||
#include "AllowWindowsPlatformTypes.h"
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
using namespace jlib;
|
||||
using namespace std;
|
||||
using namespace std::chrono;
|
||||
|
||||
#include "Events.hpp"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace Metrics
|
||||
{
|
||||
ofstream writeStream;
|
||||
timer writeTime;
|
||||
uint32_t lastWriteTime;
|
||||
|
||||
unordered_map<uint8_t, PlayerHandle*> players;
|
||||
|
||||
uint32_t CurrentTime()
|
||||
{
|
||||
return uint32_t(writeTime.milliseconds());
|
||||
}
|
||||
uint32_t TimeOffset()
|
||||
{
|
||||
const uint32_t currentTime = uint32_t(writeTime.milliseconds());
|
||||
const uint32_t offset = currentTime - lastWriteTime;
|
||||
lastWriteTime = currentTime;
|
||||
return offset;
|
||||
}
|
||||
wstring FormatNumber(uint16_t number, size_t desiredLength)
|
||||
{
|
||||
wstring result = wstring() + number;
|
||||
while (result.size() < desiredLength)
|
||||
result = wstring(L"0") + result;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Event> void WriteEvent(const Event& event)
|
||||
{
|
||||
writeStream.write((const char*)&event, streamsize(sizeof(Event)));
|
||||
}
|
||||
void WriteBinary(void* addr, size_t size)
|
||||
{
|
||||
writeStream.write((const char*)addr, size);
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
for (auto iter = players.begin(); iter != players.end(); iter++)
|
||||
delete iter->second;
|
||||
players.clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool Metrics::StartSession(const wstring& filePath)
|
||||
{
|
||||
EndSession();
|
||||
|
||||
time_t timePoint = system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
const char* timeData = ctime(&timePoint);
|
||||
wstring dateTime = convert_cstring_type<wchar_t, char>(timeData);
|
||||
|
||||
wstring dateTimeFiltered;
|
||||
for (size_t i = 0; i < dateTime.size(); i++)
|
||||
{
|
||||
if (dateTime[i] == L'\n' || dateTime[i] == L'\r')
|
||||
continue;
|
||||
dateTimeFiltered += dateTime[i];
|
||||
}
|
||||
dateTime = dateTimeFiltered;
|
||||
|
||||
wstring sessionName = L"MetricsSession";
|
||||
#if PLATFORM_SPECIFIC_WIN == 0
|
||||
sessionName.clear();
|
||||
sessionName.resize(256);
|
||||
DWORD length = 256;
|
||||
GetComputerName(&sessionName[0], &length);
|
||||
sessionName.resize(length);
|
||||
wstring sessionNameFiltered;
|
||||
for (size_t i = 0; i < sessionName.size(); i++)
|
||||
{
|
||||
wchar_t character = sessionName[i];
|
||||
if ((character >= L'0' && character <= L'9') || (character >= L'a' && character <= L'z') || (character >= L'A' && character <= L'Z') || character == L'-' || character == L'_')
|
||||
sessionNameFiltered += character;
|
||||
}
|
||||
sessionName = sessionNameFiltered;
|
||||
#endif
|
||||
|
||||
wstring fileName = sessionName + L" - " + dateTime + L".hms";
|
||||
replace(fileName.begin(), fileName.end(), L':', L'-');
|
||||
writeStream.open(convert_string_type<char, wchar_t>(filePath + fileName), ios::out | ios::binary | ios::trunc);
|
||||
writeTime.restart();
|
||||
lastWriteTime = 0;
|
||||
|
||||
// Write the header
|
||||
writeStream.write("HMS", 3);
|
||||
|
||||
return writeStream.is_open();
|
||||
}
|
||||
bool Metrics::EndSession()
|
||||
{
|
||||
if (writeStream.is_open())
|
||||
{
|
||||
WriteEvent(SessionEnd(TimeOffset()));
|
||||
|
||||
Clear();
|
||||
writeStream.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
Clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
struct Metrics::PlayerHandleSet
|
||||
{
|
||||
static void Enable(PlayerHandle& handle, uint8_t id, uint8_t team)
|
||||
{
|
||||
handle.m_id = id;
|
||||
handle.m_isValid = true;
|
||||
handle.m_team = team;
|
||||
}
|
||||
};
|
||||
|
||||
void Metrics::SetMapData(float minX, float maxX, float minY, float maxY)
|
||||
{
|
||||
if (!writeStream.is_open())
|
||||
return;
|
||||
|
||||
WriteEvent(MapData(minX, maxX, minY, maxY));
|
||||
}
|
||||
void Metrics::SetMapImage(uint8_t* ptr, uint32_t width, uint32_t height)
|
||||
{
|
||||
if (!writeStream.is_open())
|
||||
return;
|
||||
|
||||
WriteEvent(MapImage(width, height));
|
||||
WriteBinary(ptr, width * height * 4);
|
||||
}
|
||||
|
||||
Metrics::PlayerHandle::PlayerHandle() : m_isValid(false), m_id(-1), m_team(-1), m_updateTime(0), m_alive(false), m_health(INT_MAX), m_mana(INT_MAX), m_maxHealth(INT_MAX), m_maxMana(INT_MAX), m_level(255), m_playerX(FLT_MAX), m_playerY(FLT_MAX)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Metrics::PlayerHandle::OnPlayerSpawn(float playerX, float playerY)
|
||||
{
|
||||
if (!writeStream.is_open() || !m_isValid)
|
||||
return;
|
||||
|
||||
if (m_alive)
|
||||
return;
|
||||
m_alive = true;
|
||||
|
||||
m_playerX = playerX;
|
||||
m_playerY = playerY;
|
||||
|
||||
WriteEvent(PlayerSpawn(TimeOffset(), m_id, playerX, playerY));
|
||||
}
|
||||
void Metrics::PlayerHandle::OnPlayerUpdate(float playerX, float playerY)
|
||||
{
|
||||
if (!writeStream.is_open() || !m_isValid)
|
||||
return;
|
||||
|
||||
if (!m_alive)
|
||||
return;
|
||||
|
||||
// No need to write an event if the player hasnt moved
|
||||
if (fabsf(playerX - m_playerX) < 0.01f && fabsf(playerY - m_playerY) < 0.01f)
|
||||
return;
|
||||
|
||||
// Only update position 30 times per second
|
||||
const uint32_t currentTime = CurrentTime();
|
||||
if (currentTime - m_updateTime < 33)
|
||||
return;
|
||||
m_updateTime = currentTime;
|
||||
|
||||
m_playerX = playerX;
|
||||
m_playerY = playerY;
|
||||
|
||||
WriteEvent(PlayerUpdate(TimeOffset(), m_id, playerX, playerY));
|
||||
}
|
||||
void Metrics::PlayerHandle::OnPlayerDie(uint8_t source)
|
||||
{
|
||||
if (!writeStream.is_open() || !m_isValid)
|
||||
return;
|
||||
|
||||
if (!m_alive)
|
||||
return;
|
||||
m_alive = false;
|
||||
|
||||
WriteEvent(PlayerDie(TimeOffset(), m_id, source));
|
||||
}
|
||||
void Metrics::PlayerHandle::OnPlayerCast(uint32_t ability)
|
||||
{
|
||||
if (!writeStream.is_open() || !m_isValid)
|
||||
return;
|
||||
|
||||
if (!m_alive)
|
||||
return;
|
||||
|
||||
WriteEvent(PlayerCast(TimeOffset(), m_id, ability));
|
||||
}
|
||||
void Metrics::PlayerHandle::OnPlayerHealth(int32_t health)
|
||||
{
|
||||
if (!writeStream.is_open() || !m_isValid)
|
||||
return;
|
||||
|
||||
if (!m_alive)
|
||||
return;
|
||||
|
||||
// No need to write an event if the player hasnt lost/gained health
|
||||
if (m_health == health)
|
||||
return;
|
||||
|
||||
m_health = health;
|
||||
|
||||
WriteEvent(PlayerHealth(TimeOffset(), m_id, health));
|
||||
}
|
||||
void Metrics::PlayerHandle::OnPlayerMana(int32_t mana)
|
||||
{
|
||||
if (!writeStream.is_open() || !m_isValid)
|
||||
return;
|
||||
|
||||
if (!m_alive)
|
||||
return;
|
||||
|
||||
// No need to write an event if the player hasnt lost/gained mana
|
||||
if (m_mana == mana)
|
||||
return;
|
||||
|
||||
m_mana = mana;
|
||||
|
||||
WriteEvent(PlayerMana(TimeOffset(), m_id, mana));
|
||||
}
|
||||
void Metrics::PlayerHandle::OnPlayerMaxHealth(int32_t maxHealth)
|
||||
{
|
||||
if (!writeStream.is_open() || !m_isValid)
|
||||
return;
|
||||
|
||||
if (!m_alive)
|
||||
return;
|
||||
|
||||
// No need to write an event if the player hasnt changed max health
|
||||
if (m_maxHealth == maxHealth)
|
||||
return;
|
||||
|
||||
m_maxHealth = maxHealth;
|
||||
|
||||
WriteEvent(PlayerMaxHealth(TimeOffset(), m_id, maxHealth));
|
||||
}
|
||||
void Metrics::PlayerHandle::OnPlayerMaxMana(int32_t maxMana)
|
||||
{
|
||||
if (!writeStream.is_open() || !m_isValid)
|
||||
return;
|
||||
|
||||
if (!m_alive)
|
||||
return;
|
||||
|
||||
// No need to write an event if the player hasnt changed max mana
|
||||
if (m_maxMana == maxMana)
|
||||
return;
|
||||
|
||||
m_maxMana = maxMana;
|
||||
|
||||
WriteEvent(PlayerMaxMana(TimeOffset(), m_id, maxMana));
|
||||
}
|
||||
void Metrics::PlayerHandle::OnPlayerDealDamage(uint32_t ability, int32_t damage)
|
||||
{
|
||||
if (!writeStream.is_open() || !m_isValid)
|
||||
return;
|
||||
|
||||
if (!m_alive)
|
||||
return;
|
||||
|
||||
WriteEvent(PlayerDealDamage(TimeOffset(), m_id, ability, damage));
|
||||
}
|
||||
void Metrics::PlayerHandle::OnPlayerLevel(uint8_t level)
|
||||
{
|
||||
if (!writeStream.is_open() || !m_isValid)
|
||||
return;
|
||||
|
||||
if (m_level == level)
|
||||
return;
|
||||
|
||||
m_level = level;
|
||||
|
||||
WriteEvent(PlayerLevel(TimeOffset(), m_id, level));
|
||||
}
|
||||
|
||||
bool Metrics::PlayerHandle::IsValid() const
|
||||
{
|
||||
return m_isValid;
|
||||
}
|
||||
uint8_t Metrics::PlayerHandle::Id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
uint8_t Metrics::PlayerHandle::Team() const
|
||||
{
|
||||
return m_team;
|
||||
}
|
||||
|
||||
Metrics::PlayerHandle& Metrics::RegisterPlayer(const wstring& name, uint8_t team)
|
||||
{
|
||||
static PlayerHandle errorHandle;
|
||||
if (!writeStream.is_open())
|
||||
return errorHandle;
|
||||
|
||||
const uint8_t id = uint8_t(players.size() + 1);
|
||||
|
||||
PlayerHandle* newHandle = new PlayerHandle();
|
||||
PlayerHandleSet::Enable(*newHandle, id, team);
|
||||
|
||||
players.emplace(id, newHandle);
|
||||
|
||||
wstring copy = name;
|
||||
if (copy.size() > 128)
|
||||
copy.resize(128);
|
||||
else if (copy.empty())
|
||||
copy = L"UNKNOWN PLAYER";
|
||||
|
||||
WriteEvent(PlayerName(id, (uint16_t)copy.size()));
|
||||
WriteBinary((void*)copy.data(), copy.size() * sizeof(wstring::value_type));
|
||||
|
||||
WriteEvent(PlayerTeam(id, team));
|
||||
|
||||
return *newHandle;
|
||||
}
|
||||
void Metrics::RegisterAbility(uint32_t ability, const std::wstring& name)
|
||||
{
|
||||
if (!writeStream.is_open())
|
||||
return;
|
||||
|
||||
wstring copy = name;
|
||||
if (copy.size() > 128)
|
||||
copy.resize(128);
|
||||
else if (copy.empty())
|
||||
copy = L"UNKNOWN ABILITY";
|
||||
|
||||
WriteEvent(AbilityName(ability, (uint16_t)copy.size()));
|
||||
WriteBinary((void*)copy.data(), copy.size() * sizeof(wstring::value_type));
|
||||
}
|
||||
|
||||
#endif
|
||||
71
Source/UnrealProject/External/Metrics.hpp
vendored
Normal file
71
Source/UnrealProject/External/Metrics.hpp
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#if WITH_EDITOR
|
||||
|
||||
#define UE_INCLUDE_METRICS 1
|
||||
|
||||
#define METRICS_EXPR(expr) expr
|
||||
|
||||
namespace Metrics
|
||||
{
|
||||
bool StartSession(const std::wstring& filePath);
|
||||
bool EndSession();
|
||||
|
||||
void SetMapData(float minX, float maxX, float minY, float maxY);
|
||||
void SetMapImage(uint8_t* ptr, uint32_t width, uint32_t height);
|
||||
|
||||
struct PlayerHandleSet;
|
||||
struct PlayerHandle
|
||||
{
|
||||
public:
|
||||
PlayerHandle();
|
||||
|
||||
void OnPlayerSpawn(float playerX, float playerY);
|
||||
void OnPlayerUpdate(float playerX, float playerY);
|
||||
void OnPlayerDie(uint8_t source);
|
||||
void OnPlayerCast(uint32_t ability);
|
||||
void OnPlayerHealth(int32_t health);
|
||||
void OnPlayerMana(int32_t mana);
|
||||
void OnPlayerMaxHealth(int32_t maxHealth);
|
||||
void OnPlayerMaxMana(int32_t maxMana);
|
||||
void OnPlayerDealDamage(uint32_t ability, int32_t damage);
|
||||
void OnPlayerLevel(uint8_t level);
|
||||
|
||||
bool IsValid() const;
|
||||
uint8_t Id() const;
|
||||
uint8_t Team() const;
|
||||
|
||||
private:
|
||||
PlayerHandle(const PlayerHandle& other) = delete;
|
||||
PlayerHandle& operator=(const PlayerHandle& other) = delete;
|
||||
|
||||
friend struct PlayerHandleSet;
|
||||
|
||||
bool m_isValid;
|
||||
uint8_t m_id;
|
||||
uint8_t m_team;
|
||||
uint32_t m_updateTime;
|
||||
|
||||
bool m_alive;
|
||||
int32_t m_health;
|
||||
int32_t m_mana;
|
||||
int32_t m_maxHealth;
|
||||
int32_t m_maxMana;
|
||||
uint8_t m_level;
|
||||
float m_playerX;
|
||||
float m_playerY;
|
||||
};
|
||||
|
||||
PlayerHandle& RegisterPlayer(const std::wstring& name, uint8_t team);
|
||||
void RegisterAbility(uint32_t ability, const std::wstring& name);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define UE_INCLUDE_METRICS 0
|
||||
|
||||
#define METRICS_EXPR(expr)
|
||||
|
||||
#endif
|
||||
137
Source/UnrealProject/External/TeaCallback.hpp
vendored
Normal file
137
Source/UnrealProject/External/TeaCallback.hpp
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
#ifndef _HEADER_TEA_CALLBACK
|
||||
#define _HEADER_TEA_CALLBACK
|
||||
|
||||
#include <vector>
|
||||
#include <type_traits>
|
||||
|
||||
namespace TeaLib
|
||||
{
|
||||
namespace Utility
|
||||
{
|
||||
#define NOVOIDFUNC(FuncRetVal) template<typename Test = ReturnValue> typename std::enable_if<!std::is_void<Test>::value, FuncRetVal>::type
|
||||
template<typename ReturnValue, typename... Arguments>
|
||||
class ReturnCallback
|
||||
{
|
||||
private:
|
||||
// Typedef for comparing function pointers.
|
||||
typedef ReturnValue(ReturnCallback::*CompareHandle)(Arguments...);
|
||||
struct CallbackStructBase
|
||||
{
|
||||
public:
|
||||
virtual ~CallbackStructBase() {};
|
||||
virtual ReturnValue Call(Arguments...) = 0;
|
||||
virtual bool Compare(ReturnValue(*a_CallbackFunction)(Arguments...))
|
||||
{
|
||||
return false;
|
||||
};
|
||||
virtual bool Compare(void* a_ClassInstance, CompareHandle a_CallbackFunction)
|
||||
{
|
||||
return false;
|
||||
};
|
||||
};
|
||||
struct CallbackStruct : public CallbackStructBase
|
||||
{
|
||||
public:
|
||||
virtual ReturnValue Call(Arguments... a_Arg)
|
||||
{
|
||||
return m_CallbackFunction(a_Arg...);
|
||||
}
|
||||
virtual bool Compare(ReturnValue(*a_CallbackFunction)(Arguments...))
|
||||
{
|
||||
return (a_CallbackFunction == m_CallbackFunction);
|
||||
};
|
||||
ReturnValue(*m_CallbackFunction)(Arguments...);
|
||||
};
|
||||
template<typename ClassType> struct ClassCallbackStruct : public CallbackStructBase
|
||||
{
|
||||
public:
|
||||
virtual ReturnValue Call(Arguments... a_Arg)
|
||||
{
|
||||
return (m_ClassInstance->*m_CallbackFunction)(a_Arg...);
|
||||
}
|
||||
virtual bool Compare(void* a_ClassInstance, CompareHandle a_CallbackFunction)
|
||||
{
|
||||
CompareHandle compareHandle;
|
||||
memcpy(&compareHandle, &m_CallbackFunction, sizeof(CompareHandle));
|
||||
|
||||
return ((a_ClassInstance == m_ClassInstance) && (a_CallbackFunction == compareHandle));
|
||||
};
|
||||
ClassType* m_ClassInstance;
|
||||
ReturnValue(ClassType::*m_CallbackFunction)(Arguments...);
|
||||
};
|
||||
public:
|
||||
virtual ~ReturnCallback()
|
||||
{
|
||||
for (int i = (int)m_CallbackFunctions.size() - 1; i >= 0; i--)
|
||||
{
|
||||
delete m_CallbackFunctions[i];
|
||||
}
|
||||
m_CallbackFunctions.clear();
|
||||
}
|
||||
void Call(Arguments... a_Arg)
|
||||
{
|
||||
for (auto it : m_CallbackFunctions)
|
||||
{
|
||||
it->Call(a_Arg...);
|
||||
}
|
||||
}
|
||||
NOVOIDFUNC(void) Call(std::vector<ReturnValue>* a_ReturnValues, Arguments... a_Arg)
|
||||
{
|
||||
for (auto it : m_CallbackFunctions)
|
||||
{
|
||||
a_ReturnValues->push_back(it->Call(a_Arg...));
|
||||
}
|
||||
}
|
||||
void Register(ReturnValue(*a_CallbackFunction)(Arguments...))
|
||||
{
|
||||
CallbackStruct* newCallback = new CallbackStruct();
|
||||
newCallback->m_CallbackFunction = a_CallbackFunction;
|
||||
m_CallbackFunctions.push_back(newCallback);
|
||||
}
|
||||
template<typename ClassType> void Register(ClassType* a_ClassInstance, ReturnValue(ClassType::*a_CallbackFunction)(Arguments...))
|
||||
{
|
||||
ClassCallbackStruct<ClassType>* newCallback = new ClassCallbackStruct<ClassType>();
|
||||
newCallback->m_ClassInstance = a_ClassInstance;
|
||||
newCallback->m_CallbackFunction = a_CallbackFunction;
|
||||
m_CallbackFunctions.push_back(newCallback);
|
||||
}
|
||||
// Removes the first registered callback that matches the function.
|
||||
void Deregister(ReturnValue(*a_CallbackFunction)(Arguments...))
|
||||
{
|
||||
for (unsigned int i = 0; i < m_CallbackFunctions.size(); i++)
|
||||
{
|
||||
if (m_CallbackFunctions[i]->Compare(a_CallbackFunction))
|
||||
{
|
||||
delete m_CallbackFunctions[i];
|
||||
m_CallbackFunctions.erase(m_CallbackFunctions.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Removes the first registered callback that matches the class instance and the function.
|
||||
template<typename ClassType> void Deregister(ClassType* a_ClassInstance, ReturnValue(ClassType::*a_CallbackFunction)(Arguments...))
|
||||
{
|
||||
CompareHandle compareHandle;
|
||||
memcpy(&compareHandle, &a_CallbackFunction, sizeof(CompareHandle));
|
||||
for (unsigned int i = 0; i < m_CallbackFunctions.size(); i++)
|
||||
{
|
||||
if (m_CallbackFunctions[i]->Compare(a_ClassInstance, compareHandle))
|
||||
{
|
||||
delete m_CallbackFunctions[i];
|
||||
m_CallbackFunctions.erase(m_CallbackFunctions.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
std::vector<CallbackStructBase*> m_CallbackFunctions;
|
||||
};
|
||||
// Alias template for callbacks that return void.
|
||||
template<typename... Arguments>
|
||||
using Callback = ReturnCallback<void, Arguments...>;
|
||||
#undef NOVOIDFUNC
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
91
Source/UnrealProject/External/TeaVector2.hpp
vendored
Normal file
91
Source/UnrealProject/External/TeaVector2.hpp
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
#ifndef _HEADER_TEA_MATH_VECTOR2
|
||||
#define _HEADER_TEA_MATH_VECTOR2
|
||||
|
||||
namespace TeaLib
|
||||
{
|
||||
namespace Math
|
||||
{
|
||||
template<typename T>
|
||||
class Vector2
|
||||
{
|
||||
public:
|
||||
Vector2() : x(0), y(0){};
|
||||
Vector2(const T a_X, const T a_Y) : x(a_X), y(a_Y){};
|
||||
|
||||
Vector2& operator+=(const Vector2& rhs)
|
||||
{
|
||||
this->x += rhs.x;
|
||||
this->y += rhs.y;
|
||||
return *this;
|
||||
}
|
||||
Vector2& operator-=(const Vector2& rhs)
|
||||
{
|
||||
this->x -= rhs.x;
|
||||
this->y -= rhs.y;
|
||||
return *this;
|
||||
}
|
||||
Vector2& operator*=(const float& rhs)
|
||||
{
|
||||
this->x *= rhs;
|
||||
this->y *= rhs;
|
||||
return *this;
|
||||
}
|
||||
Vector2& operator/=(const float& rhs)
|
||||
{
|
||||
this->x /= rhs;
|
||||
this->y /= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector2 operator+(const Vector2& rhs)
|
||||
{
|
||||
Vector2 retVal;
|
||||
retVal.x = this->x + rhs.x;
|
||||
retVal.y = this->y + rhs.y;
|
||||
return retVal;
|
||||
}
|
||||
Vector2 operator-(const Vector2& rhs)
|
||||
{
|
||||
Vector2 retVal;
|
||||
retVal.x = this->x - rhs.x;
|
||||
retVal.y = this->y - rhs.y;
|
||||
return retVal;
|
||||
}
|
||||
Vector2 operator*(const float& rhs)
|
||||
{
|
||||
Vector2 retVal;
|
||||
retVal.x = this->x * rhs;
|
||||
retVal.y = this->y * rhs;
|
||||
return retVal;
|
||||
}
|
||||
Vector2 operator/(const float& rhs)
|
||||
{
|
||||
Vector2 retVal;
|
||||
retVal.x = this->x / rhs;
|
||||
retVal.y = this->y / rhs;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool operator==(const Vector2& rhs)
|
||||
{
|
||||
return ((this->x == rhs.x) && (this->y == rhs.y));
|
||||
}
|
||||
|
||||
float LengthSquared()
|
||||
{
|
||||
return ((x*x) + (y*y));
|
||||
}
|
||||
|
||||
float Length()
|
||||
{
|
||||
return sqrtf(LengthSquared());
|
||||
}
|
||||
|
||||
T x, y;
|
||||
};
|
||||
typedef Vector2<float> Vector2f;
|
||||
typedef Vector2<int> Vector2i;
|
||||
typedef Vector2<unsigned int> Vector2u;
|
||||
};
|
||||
};
|
||||
#endif
|
||||
149
Source/UnrealProject/External/TeaVector3.hpp
vendored
Normal file
149
Source/UnrealProject/External/TeaVector3.hpp
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
#ifndef _HEADER_TEA_MATH_VECTOR3
|
||||
#define _HEADER_TEA_MATH_VECTOR3
|
||||
|
||||
namespace TeaLib
|
||||
{
|
||||
namespace Math
|
||||
{
|
||||
template<typename T>
|
||||
class Vector3
|
||||
{
|
||||
public:
|
||||
Vector3() : x(0), y(0), z(0){};
|
||||
Vector3(const T a_X, const T a_Y, const T a_Z) : x(a_X), y(a_Y), z(a_Z){};
|
||||
|
||||
Vector3& operator+=(const Vector3& rhs)
|
||||
{
|
||||
this->x += rhs.x;
|
||||
this->y += rhs.y;
|
||||
this->z += rhs.z;
|
||||
return *this;
|
||||
}
|
||||
Vector3& operator-=(const Vector3& rhs)
|
||||
{
|
||||
this->x -= rhs.x;
|
||||
this->y -= rhs.y;
|
||||
this->z -= rhs.z;
|
||||
return *this;
|
||||
}
|
||||
Vector3& operator*=(const float& rhs)
|
||||
{
|
||||
this->x *= rhs;
|
||||
this->y *= rhs;
|
||||
this->z *= rhs;
|
||||
return *this;
|
||||
}
|
||||
Vector3& operator/=(const float& rhs)
|
||||
{
|
||||
this->x /= rhs;
|
||||
this->y /= rhs;
|
||||
this->z /= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector3 operator+(const Vector3& rhs)
|
||||
{
|
||||
Vector3 retVal;
|
||||
retVal.x = this->x + rhs.x;
|
||||
retVal.y = this->y + rhs.y;
|
||||
retVal.z = this->z + rhs.z;
|
||||
return retVal;
|
||||
}
|
||||
Vector3 operator-(const Vector3& rhs)
|
||||
{
|
||||
Vector3 retVal;
|
||||
retVal.x = this->x - rhs.x;
|
||||
retVal.y = this->y - rhs.y;
|
||||
retVal.z = this->z - rhs.z;
|
||||
return retVal;
|
||||
}
|
||||
Vector3 operator*(const float& rhs)
|
||||
{
|
||||
Vector3 retVal;
|
||||
retVal.x = this->x * rhs;
|
||||
retVal.y = this->y * rhs;
|
||||
retVal.z = this->z * rhs;
|
||||
return retVal;
|
||||
}
|
||||
friend Vector3 operator*(const float& lhs, const Vector3& rhs)
|
||||
{
|
||||
Vector3 retVal;
|
||||
retVal.x = rhs.x * lhs;
|
||||
retVal.y = rhs.y * lhs;
|
||||
retVal.z = rhs.z * lhs;
|
||||
return retVal;
|
||||
}
|
||||
Vector3 operator/(const float& rhs)
|
||||
{
|
||||
Vector3 retVal;
|
||||
retVal.x = this->x / rhs;
|
||||
retVal.y = this->y / rhs;
|
||||
retVal.z = this->z / rhs;
|
||||
return retVal;
|
||||
}
|
||||
Vector3 operator-()
|
||||
{
|
||||
Vector3 retVal;
|
||||
retVal.x = -this->x;
|
||||
retVal.y = -this->y;
|
||||
retVal.z = -this->z;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool operator==(const Vector3& rhs)
|
||||
{
|
||||
return ((this->x == rhs.x) && (this->y == rhs.y) && (this->z == rhs.z));
|
||||
}
|
||||
|
||||
|
||||
float LengthSquared()
|
||||
{
|
||||
return ((x*x) + (y*y) + (z*z));
|
||||
}
|
||||
float Length()
|
||||
{
|
||||
return sqrtf(LengthSquared());
|
||||
}
|
||||
|
||||
Vector3 Normalized()
|
||||
{
|
||||
return ((*this) / Length());
|
||||
}
|
||||
|
||||
T x, y, z;
|
||||
|
||||
public:
|
||||
static Vector3 Cross(Vector3& lhs, Vector3& rhs)
|
||||
{
|
||||
Vector3 retVal;
|
||||
|
||||
retVal.x = lhs.y * rhs.z - lhs.z * rhs.y;
|
||||
retVal.y = lhs.z * rhs.x - lhs.x * rhs.z;
|
||||
retVal.z = lhs.x * rhs.y - lhs.y * rhs.x;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
static float Dot(Vector3& lhs, Vector3& rhs)
|
||||
{
|
||||
float retVal;
|
||||
|
||||
retVal = lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
static Vector3 Lerp(Vector3& a_Source, Vector3& a_Destination, float a_Scale)
|
||||
{
|
||||
Vector3 between = a_Destination - a_Source;
|
||||
|
||||
return a_Source + between * a_Scale;
|
||||
}
|
||||
};
|
||||
|
||||
typedef Vector3<float> Vector3f;
|
||||
typedef Vector3<int> Vector3i;
|
||||
typedef Vector3<unsigned int> Vector3u;
|
||||
typedef Vector3<long> Vector3l;
|
||||
|
||||
};
|
||||
};
|
||||
#endif
|
||||
146
Source/UnrealProject/External/append
vendored
Normal file
146
Source/UnrealProject/External/append
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Copyright (c) 2012-2015, Jan de Graaf (jan@jlib.nl) //
|
||||
// //
|
||||
// Permission to use, copy, modify, and/or distribute this software for any purpose with or //
|
||||
// without fee is hereby granted, provided that the above copyright notice and this permission //
|
||||
// notice appear in all copies. //
|
||||
// //
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS //
|
||||
// SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL //
|
||||
// THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES //
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE //
|
||||
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _JLIB_HEADER_APPEND
|
||||
#define _JLIB_HEADER_APPEND
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <type_traits>
|
||||
|
||||
namespace std
|
||||
{
|
||||
// Stream operator
|
||||
template<typename char_type_t, typename input_type_t> inline basic_string<char_type_t>& operator<<(basic_string<char_type_t>& lhs, const input_type_t& rhs)
|
||||
{
|
||||
basic_ostringstream<char_type_t> stream;
|
||||
return lhs.append(static_cast<basic_ostringstream<char_type_t>*>(&(stream << rhs))->str());
|
||||
}
|
||||
|
||||
// Parsing numbers
|
||||
template<typename char_type_t, typename input_type_t> inline bool operator>>(const basic_string<char_type_t>& lhs, input_type_t& rhs)
|
||||
{
|
||||
return (bool)(basic_istringstream<char_type_t>(lhs) >> rhs);
|
||||
}
|
||||
|
||||
// Addition operators
|
||||
// Utilizes enable_if to prevent colliding with string's existing operators
|
||||
template<typename char_type_t, typename value_type> struct is_string_operand
|
||||
{
|
||||
static const bool value = std::is_same<typename std::decay<value_type>::type, char_type_t>::value || std::is_same<typename std::decay<value_type>::type, char_type_t*>::value || std::is_same<typename std::decay<value_type>::type, std::basic_string<char_type_t>>::value;
|
||||
};
|
||||
template<typename char_type_t, typename input_type_t> inline typename std::enable_if<!is_string_operand<char_type_t, input_type_t>::value, basic_string<char_type_t>&>::type operator+=(basic_string<char_type_t>& lhs, const input_type_t& rhs)
|
||||
{
|
||||
basic_ostringstream<char_type_t> stream;
|
||||
return lhs.append(static_cast<basic_ostringstream<char_type_t>*>(&(stream << rhs))->str());
|
||||
}
|
||||
template<typename char_type_t, typename input_type_t> inline typename std::enable_if<!is_string_operand<char_type_t, input_type_t>::value, basic_string<char_type_t>>::type operator+(const basic_string<char_type_t>& lhs, const input_type_t& rhs)
|
||||
{
|
||||
basic_ostringstream<char_type_t> stream;
|
||||
return basic_string<char_type_t>(lhs).append(static_cast<basic_ostringstream<char_type_t>*>(&(stream << rhs))->str());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename to_type_t, typename from_type_t> inline std::basic_string<to_type_t> convert_cstring_type(const from_type_t* cstr)
|
||||
{
|
||||
static_assert(std::is_same<to_type_t, from_type_t>::value, "Invalid char overload");
|
||||
return std::basic_string<to_type_t>(cstr);
|
||||
}
|
||||
template<> inline std::basic_string<char> convert_cstring_type(const wchar_t* wcstr)
|
||||
{
|
||||
std::string str;
|
||||
size_t i = 0;
|
||||
while (wcstr[i] != L'\0')
|
||||
{
|
||||
const uint32_t c = uint32_t(wcstr[i]);
|
||||
str.resize(i + 1);
|
||||
str[i++] = (c < 32 || c >= 126) ? '?' : char(c);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
template<> inline std::basic_string<wchar_t> convert_cstring_type(const char* cstr)
|
||||
{
|
||||
std::wstring wstr;
|
||||
size_t i = 0;
|
||||
while (cstr[i] != L'\0')
|
||||
{
|
||||
const wchar_t c = wchar_t(cstr[i]);
|
||||
wstr.resize(i + 1);
|
||||
wstr[i++] = c;
|
||||
}
|
||||
return wstr;
|
||||
}
|
||||
template<typename to_type_t, typename from_type_t> inline std::basic_string<to_type_t> convert_string_type(const std::basic_string<from_type_t>& from_string)
|
||||
{
|
||||
static_assert(std::is_same<to_type_t, from_type_t>::value, "Invalid char overload");
|
||||
return from_string;
|
||||
}
|
||||
template<> inline std::basic_string<char> convert_string_type(const std::basic_string<wchar_t>& wstr)
|
||||
{
|
||||
return convert_cstring_type<char, wchar_t>(wstr.data());
|
||||
}
|
||||
template<> inline std::basic_string<wchar_t> convert_string_type(const std::basic_string<char>& str)
|
||||
{
|
||||
return convert_cstring_type<wchar_t, char>(str.data());
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
#ifndef _NOUNREAL
|
||||
template<typename char_type_t> inline basic_string<char_type_t> operator+(const basic_string<char_type_t>& lhs, const class FString& rhs)
|
||||
{
|
||||
if (rhs.GetCharArray().GetData())
|
||||
return basic_string<char_type_t>(lhs).append((convert_cstring_type<char_type_t, wchar_t>(rhs.GetCharArray().GetData())));
|
||||
return basic_string<char_type_t>(lhs);
|
||||
}
|
||||
template<typename char_type_t> inline basic_string<char_type_t> operator+(const basic_string<char_type_t>& lhs, const class FName& rhs)
|
||||
{
|
||||
return basic_string<char_type_t>(lhs) + rhs.ToString();
|
||||
}
|
||||
template<typename char_type_t> inline basic_string<char_type_t> operator+(const basic_string<char_type_t>& lhs, const class FText& rhs)
|
||||
{
|
||||
return basic_string<char_type_t>(lhs) + rhs.ToString();
|
||||
}
|
||||
|
||||
template<typename char_type_t> inline basic_string<char_type_t> operator+(const basic_string<char_type_t>& lhs, const struct FVector& rhs)
|
||||
{
|
||||
static const char __LogSpace = ' ';
|
||||
static const char __FVectorOpen = '{';
|
||||
static const char __FVectorEnd = '}';
|
||||
static const char __LogSep = ',';
|
||||
return lhs + (char_type_t)__FVectorOpen + rhs.X + (char_type_t)__LogSep + (char_type_t)__LogSpace + rhs.Y + (char_type_t)__LogSep + (char_type_t)__LogSpace + rhs.Z + (char_type_t)__FVectorEnd;
|
||||
}
|
||||
template<typename char_type_t> inline basic_string<char_type_t> operator+(const basic_string<char_type_t>& lhs, const struct FVector2D& rhs)
|
||||
{
|
||||
static const char __LogSpace = ' ';
|
||||
static const char __FVectorOpen = '{';
|
||||
static const char __FVectorEnd = '}';
|
||||
static const char __LogSep = ',';
|
||||
return lhs + (char_type_t)__FVectorOpen + rhs.X + (char_type_t)__LogSep + (char_type_t)__LogSpace + rhs.Y + (char_type_t)__FVectorEnd;
|
||||
}
|
||||
template<typename char_type_t> inline basic_string<char_type_t> operator+(const basic_string<char_type_t>& lhs, const struct FRotator& rhs)
|
||||
{
|
||||
static const char __LogSpace = ' ';
|
||||
static const char __FVectorOpen = '{';
|
||||
static const char __FVectorEnd = '}';
|
||||
static const char __LogSep = ',';
|
||||
return lhs + (char_type_t)__FVectorOpen + rhs.Pitch + (char_type_t)__LogSep + (char_type_t)__LogSpace + rhs.Yaw + (char_type_t)__LogSep + (char_type_t)__LogSpace + rhs.Roll + (char_type_t)__FVectorEnd;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
106
Source/UnrealProject/External/timer
vendored
Normal file
106
Source/UnrealProject/External/timer
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Copyright (c) 2012-2015, Jan de Graaf (jan@jlib.nl) //
|
||||
// //
|
||||
// Permission to use, copy, modify, and/or distribute this software for any purpose with or //
|
||||
// without fee is hereby granted, provided that the above copyright notice and this permission //
|
||||
// notice appear in all copies. //
|
||||
// //
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS //
|
||||
// SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL //
|
||||
// THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES //
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE //
|
||||
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _JLIB_HEADER_TIMER
|
||||
#define _JLIB_HEADER_TIMER
|
||||
|
||||
/*
|
||||
|
||||
Template chrono timer class
|
||||
|
||||
Wraps std chrono basic time functions in a timer object.
|
||||
|
||||
*/
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace jlib
|
||||
{
|
||||
class timer
|
||||
{
|
||||
public:
|
||||
// Constructors
|
||||
timer() : m_start(std::chrono::high_resolution_clock::now()) {}
|
||||
template<typename rep, typename period> timer(std::chrono::duration<rep, period> duration) : m_start(std::chrono::high_resolution_clock::now())
|
||||
{
|
||||
m_start -= duration;
|
||||
}
|
||||
template<typename rep, typename period> timer& operator=(std::chrono::duration<rep, period> duration)
|
||||
{
|
||||
restart();
|
||||
m_start -= duration;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void restart()
|
||||
{
|
||||
m_start = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
|
||||
template<typename dur> inline dur duration() const
|
||||
{
|
||||
return std::chrono::duration_cast<dur>(std::chrono::high_resolution_clock::now() - m_start);
|
||||
}
|
||||
|
||||
// Simplified get functions
|
||||
inline std::chrono::nanoseconds::rep nanoseconds() const
|
||||
{
|
||||
return duration<std::chrono::nanoseconds>().count();
|
||||
}
|
||||
inline std::chrono::microseconds::rep microseconds() const
|
||||
{
|
||||
return duration<std::chrono::microseconds>().count();
|
||||
}
|
||||
inline std::chrono::milliseconds::rep milliseconds() const
|
||||
{
|
||||
return duration<std::chrono::milliseconds>().count();
|
||||
}
|
||||
inline std::chrono::seconds::rep seconds() const
|
||||
{
|
||||
return duration<std::chrono::seconds>().count();
|
||||
}
|
||||
inline std::chrono::minutes::rep minutes() const
|
||||
{
|
||||
return duration<std::chrono::minutes>().count();
|
||||
}
|
||||
inline std::chrono::hours::rep hours() const
|
||||
{
|
||||
return duration<std::chrono::hours>().count();
|
||||
}
|
||||
inline float seconds_float() const
|
||||
{
|
||||
return duration<std::chrono::duration<float>>().count();
|
||||
}
|
||||
|
||||
// Addition or substraction
|
||||
// Allows to add or substract time periods from the timer
|
||||
template<typename rep, typename period> inline timer& operator+=(std::chrono::duration<rep, period> duration)
|
||||
{
|
||||
m_start -= duration;
|
||||
return *this;
|
||||
}
|
||||
template<typename rep, typename period> inline timer& operator-=(std::chrono::duration<rep, period> duration)
|
||||
{
|
||||
m_start += duration;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
std::chrono::high_resolution_clock::time_point m_start;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user