Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 66 additions & 1 deletion engine/source/autosplitter/autosplitter.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <cstdio>

#include "autosplitter.h"
#include "console/console.h"
#include "platform/platform.h"


Expand Down Expand Up @@ -33,13 +34,26 @@ Autosplitter *Autosplitter::get()

Autosplitter::Autosplitter()
{
// Initialize AutosplitterData memory chunk
dMemset(&data, 0, sizeof(data));
sprintf(data.signature, "OMBU_ASR_");
// We add the "abcdef" procedurally to guarantee that the sigscan only finds this buffer, rather than potentially
// finding a full "OMBU_ASR_abcdef" string somewhere else in memory
for (int i = 0; i < 6; i++)
{
data.signature[i + 9] = 'a' + i;
}
data.currentLevel = -1;
// The rest is all zeros thanks to the memset, which is what we want.

// Initialize autosplitter file
mActive = false;
mFilename = Platform::getPrefsPath(AUTOSPLITTER_FILE_NAME);
mFile.open(mFilename, std::ios_base::app);
if (!mFile.is_open())
{
Con::errorf("Failed to open autosplitter file %s.", mFilename.c_str());
Con::errorf("Autosplitter is disabled.");
Con::errorf("Autosplitter file is disabled. Autosplitter memory will still work.");
return;
}
Con::printf("Autosplitter Initialized to file %s", mFilename.c_str());
Expand Down Expand Up @@ -70,3 +84,54 @@ ConsoleFunction(sendAutosplitterData, void, 2, 2, "")

autosplitter->sendData(argv[1]);
}

ConsoleFunction(autosplitterSetLevel, void, 2, 2, "autosplitterSetLevel(level)")
{
Autosplitter *autosplitter = Autosplitter::get();
autosplitter->data.currentLevel = atoi(argv[1]);
}

ConsoleFunction(autosplitterSetIsLoading, void, 2, 2, "autosplitterSetIsLoading(isLoading)")
{
Autosplitter *autosplitter = Autosplitter::get();
if (dStrcmp(argv[1], "false") == 0 || dStrcmp(argv[1], "0") == 0)
autosplitter->data.flags &= ~FLAG_IS_LOADING;
else
autosplitter->data.flags |= FLAG_IS_LOADING;
}

ConsoleFunction(autosplitterSetLevelStarted, void, 2, 2, "autosplitterSetLevelStarted(levelStarted)")
{
Autosplitter *autosplitter = Autosplitter::get();
if (dStrcmp(argv[1], "false") == 0 || dStrcmp(argv[1], "0") == 0)
autosplitter->data.flags &= ~FLAG_LEVEL_STARTED;
else
autosplitter->data.flags |= FLAG_LEVEL_STARTED;
}

ConsoleFunction(autosplitterSetLevelFinished, void, 2, 2, "autosplitterSetLevelFinished(levelFinished)")
{
Autosplitter *autosplitter = Autosplitter::get();
if (dStrcmp(argv[1], "false") == 0 || dStrcmp(argv[1], "0") == 0)
autosplitter->data.flags &= ~FLAG_LEVEL_FINISHED;
else
autosplitter->data.flags |= FLAG_LEVEL_FINISHED;
}

ConsoleFunction(autosplitterSetEggFound, void, 2, 2, "autosplitterSetEggFound(eggFound)")
{
Autosplitter *autosplitter = Autosplitter::get();
if (dStrcmp(argv[1], "false") == 0 || dStrcmp(argv[1], "0") == 0)
autosplitter->data.flags &= ~FLAG_EGG_FOUND;
else
autosplitter->data.flags |= FLAG_EGG_FOUND;
}

ConsoleFunction(autosplitterSetQuitToMenu, void, 2, 2, "autosplitterSetQuitToMenu(quitToMenu)")
{
Autosplitter *autosplitter = Autosplitter::get();
if (dStrcmp(argv[1], "false") == 0 || dStrcmp(argv[1], "0") == 0)
autosplitter->data.flags &= ~FLAG_QUIT_TO_MENU;
else
autosplitter->data.flags |= FLAG_QUIT_TO_MENU;
}
19 changes: 17 additions & 2 deletions engine/source/autosplitter/autosplitter.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
#ifndef _AUTOSPLITTER_H_
#define _AUTOSPLITTER_H_

#include <iostream>
#include <fstream>

#include "console/console.h"
#include "platform/types.h"

constexpr const char *AUTOSPLITTER_FILE_NAME = "autosplitter.txt";
constexpr U32 AUTOSPLITTER_BUF_SIZE = 512;

// This data can be scanned for in memory and used to drive autosplitters more precisely than via a log file
struct AutosplitterData {
char signature[16]; // Header set to "OMBU_ASR_abcdef", entry point for memory scan
S32 currentLevel; // The level index of the current loading/loaded level
U32 flags; // Boolean flags. 32 is probably overkill but is good for future proofing
};

enum {
FLAG_IS_LOADING = (1 << 0),
FLAG_LEVEL_STARTED = (1 << 1),
FLAG_LEVEL_FINISHED = (1 << 2),
FLAG_EGG_FOUND = (1 << 3),
FLAG_QUIT_TO_MENU = (1 << 4),
};

class Autosplitter
{
public:
Expand All @@ -17,6 +31,7 @@ class Autosplitter
static Autosplitter *get();
bool isActive() { return mActive; }
void sendData(const char *data);
AutosplitterData data;
private:
Autosplitter();
~Autosplitter();
Expand Down
2 changes: 2 additions & 0 deletions game/marble/client/scripts/default.bind.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ function pauseToggle(%defaultItem)
{
$Client::willfullDisconnect = true;

autosplitterSetQuitToMenu(true);

%killMission = MissionLoadingGui.isAwake();
// if we are hosting a multiplayer server, we just re-enter preview mode
// without disconnecting
Expand Down
3 changes: 3 additions & 0 deletions game/marble/client/scripts/game.cs
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,7 @@ function clientCmdSetGameState(%state, %data)

// Tell autosplitter we finished the level
XBLivePresenceStopTimer();
autosplitterSetLevelFinished(true);
sendAutosplitterData("finish" SPC GameMissionInfo.getCurrentMission().level);
}
else
Expand Down Expand Up @@ -860,6 +861,8 @@ function clientCmdSetGameState(%state, %data)
// read the pair of leaderboards
XBLiveReadStats($Leaderboard::SPOverall, %mission.level, "", true, true);
}
autosplitterSetLevelFinished(false);
autosplitterSetEggFound(false);
}

// Check here to see if we need to pop the upsell
Expand Down
2 changes: 2 additions & 0 deletions game/marble/client/scripts/playGui.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@
UpsellGui.displayPDLCUpsell = %isFreeLevel ? false : !%hasLevel;
}

autosplitterSetIsLoading(false);
autosplitterSetLevelStarted(false);
sendAutosplitterData("loading finished");
}

Expand Down
4 changes: 4 additions & 0 deletions game/marble/client/ui/LevelPreviewGui.gui
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ function levelPreviewGui::onA()
loadMission(GameMissionInfo.getCurrentMission().file, true);

// Tell autosplitter to start
autosplitterSetIsLoading(true);
autosplitterSetLevel(GameMissionInfo.getCurrentMission().level);
autosplitterSetLevelStarted(true);
autosplitterSetQuitToMenu(false);
sendAutosplitterData("start" SPC GameMissionInfo.getCurrentMission().level);
sendAutosplitterData("loading started");
}
Expand Down
1 change: 1 addition & 0 deletions game/marble/server/scripts/easter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ function clientCmdOnEasterEggPickup( %index )
return;
}

autosplitterSetEggFound(true);
sendAutosplitterData("egg" SPC %index);

if( hasFoundEgg( %index ) )
Expand Down
Loading