parent
72e1eec3b8
commit
49ac2695e1
@ -0,0 +1,183 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include "olcPixelGameEngine.h" |
||||||
|
|
||||||
|
namespace olc |
||||||
|
{ |
||||||
|
enum class InputType{ |
||||||
|
KEY, |
||||||
|
MOUSE, |
||||||
|
MOUSE_MOVE, |
||||||
|
MOUSE_WHEEL |
||||||
|
}; |
||||||
|
class Input{ |
||||||
|
friend class Replay; |
||||||
|
InputType type; |
||||||
|
int32_t key; |
||||||
|
bool press; |
||||||
|
float delay; |
||||||
|
vi2d mousePos; |
||||||
|
|
||||||
|
public: |
||||||
|
Input(int32_t key,bool press,InputType type,float delay); |
||||||
|
Input(int32_t key,bool press,InputType type,float delay,vi2d mousePos); //MOUSE_MOVE
|
||||||
|
friend std::ostream&operator<<(std::ostream&os,const Input&rhs){os<<"Input(Key="<<rhs.key<<",Press="<<rhs.press<<",Type="<<int(rhs.type)<<",Delay="<<rhs.delay<<",MousePos="<<rhs.mousePos;return os;}; |
||||||
|
}; |
||||||
|
|
||||||
|
class Recording{ |
||||||
|
friend class Replay; |
||||||
|
std::string filename; |
||||||
|
std::vector<Input>inputs; |
||||||
|
float lastKeyTime; |
||||||
|
vi2d prevMousePos; |
||||||
|
}; |
||||||
|
|
||||||
|
class ReplayFile{ |
||||||
|
friend class Replay; |
||||||
|
std::string filename; |
||||||
|
std::vector<Input>inputs; |
||||||
|
float accTime; |
||||||
|
float nextKeyTime; |
||||||
|
}; |
||||||
|
|
||||||
|
class Replay : public olc::PGEX |
||||||
|
{ |
||||||
|
bool isRecording=false; |
||||||
|
bool isReplaying=false; |
||||||
|
Recording currentRecording; |
||||||
|
ReplayFile currentReplay; |
||||||
|
|
||||||
|
public: |
||||||
|
Replay(); |
||||||
|
|
||||||
|
void StartRecording(const std::string filename); |
||||||
|
void StopRecording(); |
||||||
|
void StartReplay(const std::string filename); |
||||||
|
void StopReplay(); |
||||||
|
|
||||||
|
protected: |
||||||
|
virtual void OnAfterUserCreate() override; |
||||||
|
virtual bool OnBeforeUserUpdate(float& fElapsedTime) override; |
||||||
|
virtual void OnAfterUserUpdate(float fElapsedTime) override; |
||||||
|
|
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
#ifdef OLC_PGEX_REPLAY |
||||||
|
#undef OLC_PGEX_REPLAY |
||||||
|
namespace olc{ |
||||||
|
Replay::Replay() : olc::PGEX(true) |
||||||
|
{
|
||||||
|
std::cout<<"Replay system initialized."<<std::endl; |
||||||
|
} |
||||||
|
|
||||||
|
void Replay::OnAfterUserCreate(){ |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
bool Replay::OnBeforeUserUpdate(float& fElapsedTime){ |
||||||
|
if (isRecording){ |
||||||
|
bool keyChanged=false; |
||||||
|
for (int i=0;i<256;i++){ |
||||||
|
if (pge->GetKey(Key(i)).bPressed){ |
||||||
|
currentRecording.inputs.push_back({i,true,InputType::KEY,currentRecording.lastKeyTime}); |
||||||
|
keyChanged=true; |
||||||
|
} |
||||||
|
if (pge->GetKey(Key(i)).bReleased){ |
||||||
|
currentRecording.inputs.push_back({i,false,InputType::KEY,currentRecording.lastKeyTime}); |
||||||
|
keyChanged=true; |
||||||
|
} |
||||||
|
} |
||||||
|
for (int i=0;i<5;i++){ |
||||||
|
if (pge->GetMouse(i).bPressed){ |
||||||
|
currentRecording.inputs.push_back({i,true,InputType::MOUSE,currentRecording.lastKeyTime}); |
||||||
|
keyChanged=true; |
||||||
|
} |
||||||
|
if (pge->GetMouse(i).bReleased){ |
||||||
|
currentRecording.inputs.push_back({i,false,InputType::MOUSE,currentRecording.lastKeyTime}); |
||||||
|
keyChanged=true; |
||||||
|
} |
||||||
|
} |
||||||
|
if (pge->GetMousePos()!=currentRecording.prevMousePos){ |
||||||
|
currentRecording.prevMousePos=pge->GetMousePos(); |
||||||
|
currentRecording.inputs.push_back({0,false,InputType::MOUSE_MOVE,currentRecording.lastKeyTime,pge->GetMousePos()}); |
||||||
|
keyChanged=true; |
||||||
|
} |
||||||
|
if (pge->GetMouseWheel()!=0){ |
||||||
|
currentRecording.inputs.push_back({pge->GetMouseWheel(),false,InputType::MOUSE_WHEEL,currentRecording.lastKeyTime}); |
||||||
|
keyChanged=true; |
||||||
|
} |
||||||
|
if (!keyChanged){ |
||||||
|
currentRecording.lastKeyTime+=fElapsedTime; |
||||||
|
} else { |
||||||
|
currentRecording.lastKeyTime=fElapsedTime; |
||||||
|
} |
||||||
|
} else { |
||||||
|
|
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
void Replay::OnAfterUserUpdate(float fElapsedTime){ |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
void Replay::StartRecording(const std::string filename){ |
||||||
|
std::cout<<"Recording inputs has begun..."<<std::endl; |
||||||
|
currentRecording.inputs.clear(); |
||||||
|
currentRecording.filename=filename; |
||||||
|
currentRecording.lastKeyTime=0; |
||||||
|
currentRecording.prevMousePos=pge->GetMousePos(); |
||||||
|
isRecording=true; |
||||||
|
} |
||||||
|
|
||||||
|
void Replay::StopRecording(){ |
||||||
|
std::ofstream file(currentRecording.filename); |
||||||
|
for (Input&i:currentRecording.inputs){ |
||||||
|
if (i.type==InputType::MOUSE_MOVE){ |
||||||
|
file<<i.key<<" "<<i.delay<<" "<<int(i.type)<<" "<<i.press<<" "<<i.mousePos.x<<" "<<i.mousePos.y<<" "; |
||||||
|
} else { |
||||||
|
file<<i.key<<" "<<i.delay<<" "<<int(i.type)<<" "<<i.press<<" "; |
||||||
|
} |
||||||
|
} |
||||||
|
file.close(); |
||||||
|
isRecording=false; |
||||||
|
std::cout<<"Recording has stopped. Recording saved to "<<currentRecording.filename<<"."<<std::endl; |
||||||
|
} |
||||||
|
|
||||||
|
void Replay::StartReplay(const std::string filename){ |
||||||
|
std::ifstream file(filename); |
||||||
|
currentReplay.filename=filename; |
||||||
|
currentReplay.inputs.clear(); |
||||||
|
currentReplay.accTime=0; |
||||||
|
currentReplay.nextKeyTime=0; |
||||||
|
while (file.good()){ |
||||||
|
Input newInput(0,false,InputType::KEY,0); |
||||||
|
int type; |
||||||
|
file >> newInput.key; |
||||||
|
file >> newInput.delay; |
||||||
|
file >> type; |
||||||
|
newInput.type = InputType(type); |
||||||
|
file >> newInput.press; |
||||||
|
if (newInput.type==InputType::MOUSE_MOVE){ |
||||||
|
file >> newInput.mousePos.x; |
||||||
|
file >> newInput.mousePos.y; |
||||||
|
} |
||||||
|
if (file.eof()){ |
||||||
|
break; |
||||||
|
} |
||||||
|
currentReplay.inputs.push_back(newInput); |
||||||
|
} |
||||||
|
std::cout<<"Read "<<currentReplay.inputs.size()<<" inputs from "<<filename<<"."<<std::endl; |
||||||
|
isReplaying=true; |
||||||
|
} |
||||||
|
|
||||||
|
void Replay::StopReplay(){ |
||||||
|
isReplaying=false; |
||||||
|
std::cout<<"Replay has halted."<<std::endl; |
||||||
|
} |
||||||
|
|
||||||
|
Input::Input(int32_t key,bool press,InputType type,float delay):key(key),type(type),delay(delay),press(press){}; |
||||||
|
Input::Input(int32_t key,bool press,InputType type,float delay,vi2d mousePos):key(key),type(type),delay(delay),press(press),mousePos(mousePos){}; |
||||||
|
} |
||||||
|
#endif |
@ -0,0 +1,139 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||||
|
<ItemGroup Label="ProjectConfigurations"> |
||||||
|
<ProjectConfiguration Include="Debug|Win32"> |
||||||
|
<Configuration>Debug</Configuration> |
||||||
|
<Platform>Win32</Platform> |
||||||
|
</ProjectConfiguration> |
||||||
|
<ProjectConfiguration Include="Release|Win32"> |
||||||
|
<Configuration>Release</Configuration> |
||||||
|
<Platform>Win32</Platform> |
||||||
|
</ProjectConfiguration> |
||||||
|
<ProjectConfiguration Include="Debug|x64"> |
||||||
|
<Configuration>Debug</Configuration> |
||||||
|
<Platform>x64</Platform> |
||||||
|
</ProjectConfiguration> |
||||||
|
<ProjectConfiguration Include="Release|x64"> |
||||||
|
<Configuration>Release</Configuration> |
||||||
|
<Platform>x64</Platform> |
||||||
|
</ProjectConfiguration> |
||||||
|
</ItemGroup> |
||||||
|
<PropertyGroup Label="Globals"> |
||||||
|
<VCProjectVersion>16.0</VCProjectVersion> |
||||||
|
<Keyword>Win32Proj</Keyword> |
||||||
|
<ProjectGuid>{91688684-a622-44ce-a73d-8827f431b148}</ProjectGuid> |
||||||
|
<RootNamespace>olcPGEXReplay</RootNamespace> |
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> |
||||||
|
</PropertyGroup> |
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> |
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> |
||||||
|
<ConfigurationType>Application</ConfigurationType> |
||||||
|
<UseDebugLibraries>true</UseDebugLibraries> |
||||||
|
<PlatformToolset>v143</PlatformToolset> |
||||||
|
<CharacterSet>Unicode</CharacterSet> |
||||||
|
</PropertyGroup> |
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> |
||||||
|
<ConfigurationType>Application</ConfigurationType> |
||||||
|
<UseDebugLibraries>false</UseDebugLibraries> |
||||||
|
<PlatformToolset>v143</PlatformToolset> |
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization> |
||||||
|
<CharacterSet>Unicode</CharacterSet> |
||||||
|
</PropertyGroup> |
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> |
||||||
|
<ConfigurationType>Application</ConfigurationType> |
||||||
|
<UseDebugLibraries>true</UseDebugLibraries> |
||||||
|
<PlatformToolset>v143</PlatformToolset> |
||||||
|
<CharacterSet>Unicode</CharacterSet> |
||||||
|
</PropertyGroup> |
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> |
||||||
|
<ConfigurationType>Application</ConfigurationType> |
||||||
|
<UseDebugLibraries>false</UseDebugLibraries> |
||||||
|
<PlatformToolset>v143</PlatformToolset> |
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization> |
||||||
|
<CharacterSet>Unicode</CharacterSet> |
||||||
|
</PropertyGroup> |
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> |
||||||
|
<ImportGroup Label="ExtensionSettings"> |
||||||
|
</ImportGroup> |
||||||
|
<ImportGroup Label="Shared"> |
||||||
|
</ImportGroup> |
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> |
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> |
||||||
|
</ImportGroup> |
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> |
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> |
||||||
|
</ImportGroup> |
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> |
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> |
||||||
|
</ImportGroup> |
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> |
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> |
||||||
|
</ImportGroup> |
||||||
|
<PropertyGroup Label="UserMacros" /> |
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> |
||||||
|
<ClCompile> |
||||||
|
<WarningLevel>Level3</WarningLevel> |
||||||
|
<SDLCheck>true</SDLCheck> |
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||||
|
<ConformanceMode>true</ConformanceMode> |
||||||
|
</ClCompile> |
||||||
|
<Link> |
||||||
|
<SubSystem>Console</SubSystem> |
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation> |
||||||
|
</Link> |
||||||
|
</ItemDefinitionGroup> |
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> |
||||||
|
<ClCompile> |
||||||
|
<WarningLevel>Level3</WarningLevel> |
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking> |
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions> |
||||||
|
<SDLCheck>true</SDLCheck> |
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||||
|
<ConformanceMode>true</ConformanceMode> |
||||||
|
</ClCompile> |
||||||
|
<Link> |
||||||
|
<SubSystem>Console</SubSystem> |
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding> |
||||||
|
<OptimizeReferences>true</OptimizeReferences> |
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation> |
||||||
|
</Link> |
||||||
|
</ItemDefinitionGroup> |
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> |
||||||
|
<ClCompile> |
||||||
|
<WarningLevel>Level3</WarningLevel> |
||||||
|
<SDLCheck>true</SDLCheck> |
||||||
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||||
|
<ConformanceMode>true</ConformanceMode> |
||||||
|
</ClCompile> |
||||||
|
<Link> |
||||||
|
<SubSystem>Console</SubSystem> |
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation> |
||||||
|
</Link> |
||||||
|
</ItemDefinitionGroup> |
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> |
||||||
|
<ClCompile> |
||||||
|
<WarningLevel>Level3</WarningLevel> |
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking> |
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions> |
||||||
|
<SDLCheck>true</SDLCheck> |
||||||
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||||
|
<ConformanceMode>true</ConformanceMode> |
||||||
|
</ClCompile> |
||||||
|
<Link> |
||||||
|
<SubSystem>Console</SubSystem> |
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding> |
||||||
|
<OptimizeReferences>true</OptimizeReferences> |
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation> |
||||||
|
</Link> |
||||||
|
</ItemDefinitionGroup> |
||||||
|
<ItemGroup> |
||||||
|
<ClInclude Include="olcPGEX_Replay.h" /> |
||||||
|
<ClInclude Include="olcPixelGameEngine.h" /> |
||||||
|
</ItemGroup> |
||||||
|
<ItemGroup> |
||||||
|
<ClCompile Include="replay_test.cpp" /> |
||||||
|
</ItemGroup> |
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> |
||||||
|
<ImportGroup Label="ExtensionTargets"> |
||||||
|
</ImportGroup> |
||||||
|
</Project> |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,54 @@ |
|||||||
|
#define OLC_PGE_APPLICATION |
||||||
|
#include "olcPixelGameEngine.h" |
||||||
|
#define OLC_PGEX_REPLAY |
||||||
|
#include "olcPGEX_Replay.h" |
||||||
|
|
||||||
|
class Example : public olc::PixelGameEngine |
||||||
|
{ |
||||||
|
public: |
||||||
|
Example() |
||||||
|
{ |
||||||
|
sAppName = "Example"; |
||||||
|
} |
||||||
|
|
||||||
|
public: |
||||||
|
|
||||||
|
olc::Replay replaySystem; |
||||||
|
|
||||||
|
bool OnUserCreate() override |
||||||
|
{ |
||||||
|
// Called once at the start, so create things here
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
bool OnUserUpdate(float fElapsedTime) override |
||||||
|
{ |
||||||
|
if (GetKey(olc::F1).bPressed){ |
||||||
|
replaySystem.StartRecording("test.replay"); |
||||||
|
} |
||||||
|
if (GetKey(olc::F2).bPressed){ |
||||||
|
replaySystem.StopRecording(); |
||||||
|
} |
||||||
|
if (GetKey(olc::F3).bPressed){ |
||||||
|
replaySystem.StartReplay("test.replay"); |
||||||
|
} |
||||||
|
if (GetKey(olc::F4).bPressed){ |
||||||
|
replaySystem.StopReplay(); |
||||||
|
} |
||||||
|
// called once per frame
|
||||||
|
for (int x = 0; x < ScreenWidth(); x++) |
||||||
|
for (int y = 0; y < ScreenHeight(); y++) |
||||||
|
Draw(x, y, olc::Pixel(rand() % 255, rand() % 255, rand()% 255));
|
||||||
|
return true; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
int main() |
||||||
|
{ |
||||||
|
Example demo; |
||||||
|
if (demo.Construct(256, 240, 4, 4)) |
||||||
|
demo.Start(); |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue