This commit is contained in:
r2dliu 2020-11-26 21:26:23 -05:00
commit 64ea1c47d2
3 changed files with 42 additions and 3 deletions

View file

@ -270,6 +270,15 @@ namespace Slippi {
}
}
void handleFrameEnd(Game* game, uint32_t maxSize) {
int idx = 0;
int32_t frameCount = readWord(data, idx, maxSize, 0);
int32_t lastFinalizedFrame = readWord(data, idx, maxSize, frameCount);
game->lastFinalizedFrame = lastFinalizedFrame;
}
void handleGameEnd(Game* game, uint32_t maxSize) {
int idx = 0;
@ -459,6 +468,9 @@ namespace Slippi {
case EVENT_POST_FRAME_UPDATE:
handlePostFrameUpdate(game.get(), payloadSize);
break;
case EVENT_FRAME_END:
handleFrameEnd(game.get(), payloadSize);
break;
case EVENT_GAME_END:
handleGameEnd(game.get(), payloadSize);
isProcessingComplete = true;
@ -530,6 +542,14 @@ namespace Slippi {
return game->version;
}
std::string SlippiGame::GetVersionString()
{
char version[30];
sprintf(version, "%d.%d.%d", game->version[0], game->version[1], game->version[2]);
return std::string(version);
}
FrameData* SlippiGame::GetFrame(int32_t frame) {
// Get the frame we want
return game->framesByIndex.at(frame);
@ -544,6 +564,11 @@ namespace Slippi {
return game->frames[pos].get();
}
int32_t SlippiGame::GetLastFinalizedFrame() {
processData();
return game->lastFinalizedFrame;
}
int32_t SlippiGame::GetLatestIndex() {
processData();
return game->frameCount;

View file

@ -16,6 +16,7 @@ namespace Slippi {
const uint8_t EVENT_POST_FRAME_UPDATE = 0x38;
const uint8_t EVENT_GAME_END = 0x39;
const uint8_t EVENT_FRAME_START = 0x3A;
const uint8_t EVENT_FRAME_END = 0x3C;
const uint8_t EVENT_GECKO_LIST = 0x3D;
const uint8_t GAME_INFO_HEADER_SIZE = 78;
@ -100,6 +101,7 @@ namespace Slippi {
bool areSettingsLoaded = false;
int32_t frameCount; // Current/last frame count
int32_t lastFinalizedFrame = -124;
//From OnGameEnd event
uint8_t winCondition;
@ -122,8 +124,10 @@ namespace Slippi {
bool AreSettingsLoaded();
bool DoesFrameExist(int32_t frame);
std::array<uint8_t, 4> GetVersion();
std::string GetVersionString();
FrameData* GetFrame(int32_t frame);
FrameData* GetFrameAt(uint32_t pos);
int32_t GetLastFinalizedFrame();
int32_t GetLatestIndex();
GameSettings* GetSettings();
bool DoesPlayerExist(int8_t port);

View file

@ -1132,9 +1132,20 @@ bool CEXISlippi::checkFrameFullyFetched(s32 frameIndex)
Slippi::FrameData* frame = m_current_game->GetFrame(frameIndex);
version::Semver200_version lastFinalizedVersion("3.7.0");
version::Semver200_version currentVersion(m_current_game->GetVersionString());
bool frameIsFinalized = true;
if (currentVersion >= lastFinalizedVersion)
{
// If latest finalized frame should exist, check it as well. This will prevent us
// from loading a non-committed frame when mirroring a rollback game
frameIsFinalized = m_current_game->GetLastFinalizedFrame() >= frameIndex;
}
// This flag is set to true after a post frame update has been received. At that point
// we know we have received all of the input data for the frame
return frame->inputsFullyFetched;
return frame->inputsFullyFetched && frameIsFinalized;
}
void CEXISlippi::prepareFrameData(u8* payload)
@ -1175,9 +1186,8 @@ void CEXISlippi::prepareFrameData(u8* payload)
// (this is the last frame, in that case)
auto isFrameFound = m_current_game->DoesFrameExist(frameIndex);
g_playbackStatus->lastFrame = m_current_game->GetLatestIndex();
auto isNextFrameFound = g_playbackStatus->lastFrame > frameIndex;
auto isFrameComplete = checkFrameFullyFetched(frameIndex);
auto isFrameReady = isFrameFound && (isProcessingComplete || isNextFrameFound || isFrameComplete);
auto isFrameReady = isFrameFound && (isProcessingComplete || isFrameComplete);
// If there is a startFrame configured, manage the fast-forward flag
if (watchSettings.startFrame > Slippi::GAME_FIRST_FRAME)