diff --git a/PlayLayer.cpp b/PlayLayer.cpp index bc70bf3..7d10eab 100644 --- a/PlayLayer.cpp +++ b/PlayLayer.cpp @@ -197,6 +197,10 @@ uintptr_t PlayLayer::getSelf() { return follow(follow(base + 0x3222D0) + 0x164); } +double PlayLayer::getTime() { + return *reinterpret_cast(getSelf() + 0x450); +} + void* __fastcall PlayLayer::markCheckpointHook(CCLayer* self, void*, void* idk2) { auto isDead = reinterpret_cast(reinterpret_cast(PlayLayer::self) + 0x39C); if (!*isDead) { diff --git a/PlayLayer.h b/PlayLayer.h index 708a742..58cabd5 100644 --- a/PlayLayer.h +++ b/PlayLayer.h @@ -53,5 +53,6 @@ namespace PlayLayer { uintptr_t getPlayer(); uintptr_t getPlayer2(); uintptr_t getSelf(); + double getTime(); }; diff --git a/ReplaySystem.cpp b/ReplaySystem.cpp index abf0a84..c58faed 100644 --- a/ReplaySystem.cpp +++ b/ReplaySystem.cpp @@ -27,6 +27,7 @@ void ReplaySystem::togglePlaying() { PlayLayer::updateStatusLabel(playing ? "Playing" : ""); if (playing) { curActionIndex = 0; + timeActions.clear(); } } } @@ -52,12 +53,14 @@ void ReplaySystem::onReset() { PlayLayer::releaseButton(PlayLayer::self, 0, true); PlayLayer::releaseButton(PlayLayer::self, 0, false); curActionIndex = 0; + timeActions.clear(); } } void ReplaySystem::playAction(Action action) { auto layer = PlayLayer::self; // if (!PlayLayer::is2Player() && action.player2) return; + timeActions.push_back({ PlayLayer::getTime(), action.hold }); auto flip = PlayLayer::is2Player() && GameManager::is2PFlipped(); if (action.hold) PlayLayer::pushButton(layer, 0, !action.player2 ^ flip); else PlayLayer::releaseButton(layer, 0, !action.player2 ^ flip); diff --git a/ReplaySystem.h b/ReplaySystem.h index 96e838e..8d709a2 100644 --- a/ReplaySystem.h +++ b/ReplaySystem.h @@ -5,6 +5,12 @@ using namespace cocos2d; +struct TimeAction { + double time; + bool hold; + // no player 2 L +}; + class ReplaySystem { static ReplaySystem* instance; @@ -16,6 +22,7 @@ class ReplaySystem { size_t curActionIndex = 0; public: + std::vector timeActions; static ReplaySystem* getInstance() { if (!instance) instance = new ReplaySystem(); return instance; diff --git a/dllmain.cpp b/dllmain.cpp index 462a1d3..7bb286d 100644 --- a/dllmain.cpp +++ b/dllmain.cpp @@ -4,6 +4,7 @@ #include "PlayLayer.h" #include "PlayerObject.h" #include "GameManager.h" +#include void readInput(HMODULE hModule) { for (std::string line; std::getline(std::cin, line);) { @@ -32,6 +33,28 @@ void readInput(HMODULE hModule) { std::cout << "speedhack " << speed << std::endl; CCDirector::sharedDirector()->getScheduler()->setTimeScale(speed); } + else if (line == "save-frame") { + // TODO: put this in a helper function + OPENFILENAMEA info; + ZeroMemory(&info, sizeof info); + CHAR fileName[MAX_PATH] = ""; + info.lStructSize = sizeof info; + info.hwndOwner = NULL; + info.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; + info.lpstrFile = fileName; + info.nMaxFile = MAX_PATH; + info.lpstrDefExt = "dat"; + if (GetSaveFileNameA(&info)) { + std::cout << "Saving file: " << info.lpstrFile << std::endl; + std::ofstream outfile; + outfile.open(info.lpstrFile, std::ios::binary | std::ios::out); + for (auto& action : ReplaySystem::getInstance()->timeActions) { + outfile.write(reinterpret_cast(&action.time), sizeof(double)); + outfile.write(reinterpret_cast(&action.hold), sizeof(bool)); + } + outfile.close(); + } + } } }