Add save/load stream for ACS

Saves the majority of the VM state, but not the SRB2-specific vars ... that can come after food
This commit is contained in:
Sally Coolatta 2022-12-26 22:17:36 -05:00
parent 7a5b276ece
commit 8034fd326f
6 changed files with 221 additions and 0 deletions

View file

@ -5,6 +5,8 @@ target_sources(SRB2SDL2 PRIVATE
thread.hpp
call-funcs.cpp
call-funcs.hpp
stream.cpp
stream.hpp
interface.cpp
interface.h
)

View file

@ -21,6 +21,7 @@ extern "C" {
#include "../r_defs.h"
#include "../g_game.h"
#include "../i_system.h"
#include "../p_saveg.h"
}
#include <cmath>
@ -39,6 +40,7 @@ extern "C" {
#include "environment.hpp"
#include "thread.hpp"
#include "stream.hpp"
#include "../cxxutil.hpp"
@ -230,3 +232,56 @@ void ACS_Tick(void)
env->exec();
}
}
/*--------------------------------------------------
void ACS_Archive(savebuffer_t *save)
See header file for description.
--------------------------------------------------*/
void ACS_Archive(savebuffer_t *save)
{
Environment *env = &ACSEnv;
SaveBuffer buffer{save};
std::ostream stream{&buffer};
ACSVM::Serial serial{stream};
// Enable debug signatures.
serial.signs = true;
try
{
serial.saveHead();
env->saveState(serial);
serial.saveTail();
}
catch (ACSVM::SerialError const &e)
{
I_Error("ACS_Archive: %s\n", e.what());
}
}
/*--------------------------------------------------
void ACS_UnArchive(savebuffer_t *save)
See header file for description.
--------------------------------------------------*/
void ACS_UnArchive(savebuffer_t *save)
{
Environment *env = &ACSEnv;
SaveBuffer buffer{save};
std::istream stream{&buffer};
ACSVM::Serial serial{stream};
try
{
serial.loadHead();
env->loadState(serial);
serial.loadTail();
}
catch (ACSVM::SerialError const &e)
{
I_Error("ACS_UnArchive: %s\n", e.what());
}
}

View file

@ -113,4 +113,34 @@ void ACS_RunLapScript(mobj_t *mo, line_t *line);
void ACS_Tick(void);
/*--------------------------------------------------
void ACS_Archive(savebuffer_t *save);
Saves the ACS VM state into a save buffer.
Input Arguments:-
save: Pointer to the save buffer from P_SaveNetGame.
Return:-
None
--------------------------------------------------*/
void ACS_Archive(savebuffer_t *save);
/*--------------------------------------------------
void ACS_UnArchive(savebuffer_t *save);
Loads the ACS VM state from a save buffer.
Input Arguments:-
save: Pointer to the save buffer from P_LoadNetGame.
Return:-
None
--------------------------------------------------*/
void ACS_UnArchive(savebuffer_t *save);
#endif // __SRB2_ACS_INTERFACE_H__

71
src/acs/stream.cpp Normal file
View file

@ -0,0 +1,71 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2016 by James Haley, David Hill, et al. (Team Eternity)
// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2022 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file stream.cpp
/// \brief Action Code Script: Dummy stream buffer to
/// interact with P_Save/LoadNetGame
// TODO? Maybe untie this file from ACS?
extern "C" {
#include "../doomtype.h"
#include "../doomdef.h"
#include "../doomstat.h"
#include "../p_saveg.h"
}
#include "stream.hpp"
#include "../cxxutil.hpp"
#include <istream>
#include <ostream>
#include <streambuf>
using namespace srb2::acs;
SaveBuffer::SaveBuffer(savebuffer_t *save_) :
save{save_}
{
}
SaveBuffer::int_type SaveBuffer::overflow(SaveBuffer::int_type ch)
{
if (save->p == save->end)
{
return traits_type::eof();
}
*save->p = static_cast<UINT8>(ch);
save->p++;
return ch;
}
SaveBuffer::int_type SaveBuffer::underflow()
{
if (save->p == save->end)
{
return traits_type::eof();
}
UINT8 ret = *save->p;
save->p++;
// Allow the streambuf internal funcs to work
buf[0] = ret;
setg(
reinterpret_cast<SaveBuffer::char_type *>(buf),
reinterpret_cast<SaveBuffer::char_type *>(buf),
reinterpret_cast<SaveBuffer::char_type *>(buf + 1)
);
return static_cast<SaveBuffer::int_type>(ret);
}

59
src/acs/stream.hpp Normal file
View file

@ -0,0 +1,59 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2016 by James Haley, David Hill, et al. (Team Eternity)
// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2022 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file stream.hpp
/// \brief Action Code Script: Dummy stream buffer to
/// interact with P_Save/LoadNetGame
// TODO? Maybe untie this file from ACS?
#ifndef __SRB2_ACS_STREAM_HPP__
#define __SRB2_ACS_STREAM_HPP__
extern "C" {
#include "../doomtype.h"
#include "../doomdef.h"
#include "../doomstat.h"
#include "../p_saveg.h"
}
#include <ACSVM/Code.hpp>
#include <ACSVM/CodeData.hpp>
#include <ACSVM/Environment.hpp>
#include <ACSVM/Error.hpp>
#include <ACSVM/Module.hpp>
#include <ACSVM/Scope.hpp>
#include <ACSVM/Script.hpp>
#include <ACSVM/Serial.hpp>
#include <ACSVM/Thread.hpp>
#include <Util/Floats.hpp>
#include <istream>
#include <ostream>
#include <streambuf>
namespace srb2::acs {
class SaveBuffer : public std::streambuf
{
public:
savebuffer_t *save;
UINT8 buf[1];
explicit SaveBuffer(savebuffer_t *save_);
private:
virtual int_type overflow(int_type ch);
virtual int_type underflow();
};
}
#endif // __SRB2_ACS_STREAM_HPP__

View file

@ -41,6 +41,7 @@
#include "k_battle.h"
#include "k_pwrlv.h"
#include "k_terrain.h"
#include "acs/interface.h"
savedata_t savedata;
@ -5176,6 +5177,8 @@ void P_SaveNetGame(savebuffer_t *save, boolean resending)
P_NetArchiveTubeWaypoints(save);
P_NetArchiveWaypoints(save);
}
ACS_Archive(save);
LUA_Archive(save, true);
P_NetArchiveRNG(save);
@ -5226,6 +5229,7 @@ boolean P_LoadNetGame(savebuffer_t *save, boolean reloading)
P_FinishMobjs();
}
ACS_UnArchive(save);
LUA_UnArchive(save, true);
P_NetUnArchiveRNG(save);