[openjk] 08/130: Add initial saved game archive class
Simon McVittie
smcv at debian.org
Fri Oct 28 11:09:11 UTC 2016
This is an automated email from the git hooks/post-receive script.
smcv pushed a commit to branch debian/master
in repository openjk.
commit ea9c36eb6bf8eac66bcf827ad1e181d65a0fe356
Author: bibendovsky <bibendovsky at NOSTROMO>
Date: Sun Jul 3 20:29:06 2016 +0300
Add initial saved game archive class
---
code/CMakeLists.txt | 7 +
code/cgame/cg_main.cpp | 1 +
code/game/CMakeLists.txt | 7 +
code/game/G_Timer.cpp | 1 +
code/game/Q3_Interface.cpp | 1 +
code/game/g_main.cpp | 1 +
code/game/g_objectives.cpp | 1 +
code/game/g_roff.cpp | 1 +
code/game/g_savegame.cpp | 1 +
code/icarus/IcarusImplementation.cpp | 1 +
code/qcommon/cm_load.cpp | 1 +
code/qcommon/q_shared.h | 1 +
code/rd-vanilla/CMakeLists.txt | 9 +-
code/rd-vanilla/G2_misc.cpp | 1 +
code/server/sv_savegame.cpp | 1 +
codeJK2/cgame/cg_main.cpp | 1 +
codeJK2/game/CMakeLists.txt | 7 +
codeJK2/game/G_Timer.cpp | 1 +
codeJK2/game/Q3_Registers.cpp | 1 +
codeJK2/game/g_main.cpp | 1 +
codeJK2/game/g_objectives.cpp | 1 +
codeJK2/game/g_roff.cpp | 1 +
codeJK2/game/g_savegame.cpp | 1 +
codeJK2/icarus/Instance.cpp | 1 +
codeJK2/icarus/Sequence.cpp | 1 +
codeJK2/icarus/Sequencer.cpp | 1 +
codeJK2/icarus/TaskManager.cpp | 1 +
shared/qcommon/ojk_exception.cpp | 29 ++
shared/qcommon/ojk_exception.h | 35 ++
shared/qcommon/ojk_sg_archive.cpp | 80 ++++
shared/qcommon/ojk_sg_archive.h | 587 ++++++++++++++++++++++++++++
shared/qcommon/ojk_sg_archive_exception.cpp | 31 ++
shared/qcommon/ojk_sg_archive_exception.h | 36 ++
shared/qcommon/ojk_sg_archive_fwd.h | 257 ++++++++++++
34 files changed, 1107 insertions(+), 1 deletion(-)
diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt
index c3f94c1..fcf9b47 100644
--- a/code/CMakeLists.txt
+++ b/code/CMakeLists.txt
@@ -177,6 +177,13 @@ if(BuildSPEngine OR BuildJK2SPEngine)
"${SharedDir}/qcommon/ojk_sg_wrappers.h"
"${SharedDir}/qcommon/ojk_sg_wrappers_fwd.h"
"${SharedDir}/qcommon/ojk_sg_wrappers_shared.h"
+ "${SharedDir}/qcommon/ojk_exception.h"
+ "${SharedDir}/qcommon/ojk_exception.cpp"
+ "${SharedDir}/qcommon/ojk_sg_archive.h"
+ "${SharedDir}/qcommon/ojk_sg_archive_fwd.h"
+ "${SharedDir}/qcommon/ojk_sg_archive.cpp"
+ "${SharedDir}/qcommon/ojk_sg_archive_exception.h"
+ "${SharedDir}/qcommon/ojk_sg_archive_exception.cpp"
${SharedCommonFiles}
)
diff --git a/code/cgame/cg_main.cpp b/code/cgame/cg_main.cpp
index 649ddf4..6360ce5 100644
--- a/code/cgame/cg_main.cpp
+++ b/code/cgame/cg_main.cpp
@@ -29,6 +29,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#include "../qcommon/sstring.h"
#include "qcommon/ojk_sg_wrappers.h"
+#include "qcommon/ojk_sg_archive.h"
//NOTENOTE: Be sure to change the mirrored code in g_shared.h
typedef std::map< sstring_t, unsigned char > namePrecache_m;
diff --git a/code/game/CMakeLists.txt b/code/game/CMakeLists.txt
index 6190bc9..d19b9f8 100644
--- a/code/game/CMakeLists.txt
+++ b/code/game/CMakeLists.txt
@@ -263,6 +263,13 @@ set(SPGameCommonFiles
"${SharedDir}/qcommon/ojk_sg_wrappers.h"
"${SharedDir}/qcommon/ojk_sg_wrappers_fwd.h"
"${SharedDir}/qcommon/ojk_sg_wrappers_shared.h"
+ "${SharedDir}/qcommon/ojk_exception.h"
+ "${SharedDir}/qcommon/ojk_exception.cpp"
+ "${SharedDir}/qcommon/ojk_sg_archive.h"
+ "${SharedDir}/qcommon/ojk_sg_archive_fwd.h"
+ "${SharedDir}/qcommon/ojk_sg_archive.cpp"
+ "${SharedDir}/qcommon/ojk_sg_archive_exception.h"
+ "${SharedDir}/qcommon/ojk_sg_archive_exception.cpp"
${SharedCommonFiles}
)
diff --git a/code/game/G_Timer.cpp b/code/game/G_Timer.cpp
index c469fc1..4521e8b 100644
--- a/code/game/G_Timer.cpp
+++ b/code/game/G_Timer.cpp
@@ -23,6 +23,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#include "g_local.h"
#include "../Rufl/hstring.h"
#include "qcommon/ojk_sg_wrappers.h"
+#include "qcommon/ojk_sg_archive.h"
#define MAX_GTIMERS 16384
diff --git a/code/game/Q3_Interface.cpp b/code/game/Q3_Interface.cpp
index ea4d7fc..b9eb56a 100644
--- a/code/game/Q3_Interface.cpp
+++ b/code/game/Q3_Interface.cpp
@@ -41,6 +41,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#include "g_vehicles.h"
#include "g_navigator.h"
#include "qcommon/ojk_sg_wrappers.h"
+#include "qcommon/ojk_sg_archive.h"
extern cvar_t *com_buildScript;
diff --git a/code/game/g_main.cpp b/code/game/g_main.cpp
index 4b94b70..60c05bf 100644
--- a/code/game/g_main.cpp
+++ b/code/game/g_main.cpp
@@ -37,6 +37,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
//rww - RAGDOLL_END
#include "qcommon/ojk_sg_wrappers.h"
+#include "qcommon/ojk_sg_archive.h"
extern void WP_SaberLoadParms( void );
extern qboolean G_PlayerSpawned( void );
diff --git a/code/game/g_objectives.cpp b/code/game/g_objectives.cpp
index 6843a32..a55f3b6 100644
--- a/code/game/g_objectives.cpp
+++ b/code/game/g_objectives.cpp
@@ -30,6 +30,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#include "objectives.h"
#include "qcommon/ojk_sg_wrappers.h"
+#include "qcommon/ojk_sg_archive.h"
qboolean missionInfo_Updated;
diff --git a/code/game/g_roff.cpp b/code/game/g_roff.cpp
index 321b3df..47d4205 100644
--- a/code/game/g_roff.cpp
+++ b/code/game/g_roff.cpp
@@ -26,6 +26,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#include "../cgame/cg_local.h"
#include "g_functions.h"
#include "qcommon/ojk_sg_wrappers.h"
+#include "qcommon/ojk_sg_archive.h"
// The list of precached ROFFs
roff_list_t roffs[MAX_ROFFS];
diff --git a/code/game/g_savegame.cpp b/code/game/g_savegame.cpp
index 29515bb..c8e3dcf 100644
--- a/code/game/g_savegame.cpp
+++ b/code/game/g_savegame.cpp
@@ -31,6 +31,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#include "../cgame/cg_camera.h"
#include "../qcommon/sstring.h"
#include "qcommon/ojk_sg_wrappers.h"
+#include "qcommon/ojk_sg_archive.h"
extern void OBJ_LoadTacticalInfo(void);
diff --git a/code/icarus/IcarusImplementation.cpp b/code/icarus/IcarusImplementation.cpp
index 6308115..076bd30 100644
--- a/code/icarus/IcarusImplementation.cpp
+++ b/code/icarus/IcarusImplementation.cpp
@@ -34,6 +34,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#include "../qcommon/q_shared.h"
#include "../qcommon/qcommon.h"
#include "qcommon/ojk_sg_wrappers.h"
+#include "qcommon/ojk_sg_archive.h"
#define STL_ITERATE( a, b ) for ( a = b.begin(); a != b.end(); ++a )
#define STL_INSERT( a, b ) a.insert( a.end(), b );
diff --git a/code/qcommon/cm_load.cpp b/code/qcommon/cm_load.cpp
index d3f4c81..4566854 100644
--- a/code/qcommon/cm_load.cpp
+++ b/code/qcommon/cm_load.cpp
@@ -25,6 +25,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#include "cm_local.h"
#include "qcommon/ojk_sg_wrappers.h"
+#include "qcommon/ojk_sg_archive.h"
#ifdef BSPC
void SetPlaneSignbits (cplane_t *out) {
diff --git a/code/qcommon/q_shared.h b/code/qcommon/q_shared.h
index 5790a63..c026a9b 100644
--- a/code/qcommon/q_shared.h
+++ b/code/qcommon/q_shared.h
@@ -161,6 +161,7 @@ float FloatSwap( const float *f );
#include "qcommon/q_platform.h"
#include "qcommon/ojk_sg_wrappers_fwd.h"
+#include "qcommon/ojk_sg_archive_fwd.h"
// ================================================================
diff --git a/code/rd-vanilla/CMakeLists.txt b/code/rd-vanilla/CMakeLists.txt
index 449e2e4..824050e 100644
--- a/code/rd-vanilla/CMakeLists.txt
+++ b/code/rd-vanilla/CMakeLists.txt
@@ -81,7 +81,14 @@ if(BuildSPRdVanilla OR BuildJK2SPRdVanilla)
"${SharedDir}/qcommon/ojk_sg_wrappers.h"
"${SharedDir}/qcommon/ojk_sg_wrappers_fwd.h"
"${SharedDir}/qcommon/ojk_sg_wrappers_shared.h"
-
+ "${SharedDir}/qcommon/ojk_exception.h"
+ "${SharedDir}/qcommon/ojk_exception.cpp"
+ "${SharedDir}/qcommon/ojk_sg_archive.h"
+ "${SharedDir}/qcommon/ojk_sg_archive_fwd.h"
+ "${SharedDir}/qcommon/ojk_sg_archive.cpp"
+ "${SharedDir}/qcommon/ojk_sg_archive_exception.h"
+ "${SharedDir}/qcommon/ojk_sg_archive_exception.cpp"
+
${SharedCommonFiles}
)
source_group("common" FILES ${SPRDVanillaCommonFiles})
diff --git a/code/rd-vanilla/G2_misc.cpp b/code/rd-vanilla/G2_misc.cpp
index d0a1a95..7e319d0 100644
--- a/code/rd-vanilla/G2_misc.cpp
+++ b/code/rd-vanilla/G2_misc.cpp
@@ -51,6 +51,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#ifdef _G2_GORE
#include "../ghoul2/ghoul2_gore.h"
#include "qcommon/ojk_sg_wrappers.h"
+#include "qcommon/ojk_sg_archive.h"
#define GORE_TAG_UPPER (256)
#define GORE_TAG_MASK (~255)
diff --git a/code/server/sv_savegame.cpp b/code/server/sv_savegame.cpp
index 2c01d39..e4069d6 100644
--- a/code/server/sv_savegame.cpp
+++ b/code/server/sv_savegame.cpp
@@ -38,6 +38,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#include <map>
#include "qcommon/ojk_sg_wrappers.h"
+#include "qcommon/ojk_sg_archive.h"
static char saveGameComment[iSG_COMMENT_SIZE];
diff --git a/codeJK2/cgame/cg_main.cpp b/codeJK2/cgame/cg_main.cpp
index f8f1ff1..f6279e7 100644
--- a/codeJK2/cgame/cg_main.cpp
+++ b/codeJK2/cgame/cg_main.cpp
@@ -29,6 +29,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#include "../../code/qcommon/sstring.h"
#include "qcommon/ojk_sg_wrappers.h"
+#include "qcommon/ojk_sg_archive.h"
//NOTENOTE: Be sure to change the mirrored code in g_shared.h
typedef std::map< sstring_t, unsigned char, std::less<sstring_t>, std::allocator< unsigned char > > namePrecache_m;
diff --git a/codeJK2/game/CMakeLists.txt b/codeJK2/game/CMakeLists.txt
index 6abe3ee..e38f6b9 100644
--- a/codeJK2/game/CMakeLists.txt
+++ b/codeJK2/game/CMakeLists.txt
@@ -235,6 +235,13 @@ set(JK2SPGameCommonFiles
"${SharedDir}/qcommon/ojk_sg_wrappers.h"
"${SharedDir}/qcommon/ojk_sg_wrappers_fwd.h"
"${SharedDir}/qcommon/ojk_sg_wrappers_shared.h"
+ "${SharedDir}/qcommon/ojk_exception.h"
+ "${SharedDir}/qcommon/ojk_exception.cpp"
+ "${SharedDir}/qcommon/ojk_sg_archive.h"
+ "${SharedDir}/qcommon/ojk_sg_archive_fwd.h"
+ "${SharedDir}/qcommon/ojk_sg_archive.cpp"
+ "${SharedDir}/qcommon/ojk_sg_archive_exception.h"
+ "${SharedDir}/qcommon/ojk_sg_archive_exception.cpp"
${SharedCommonFiles}
)
diff --git a/codeJK2/game/G_Timer.cpp b/codeJK2/game/G_Timer.cpp
index 737861e..6b5de3a 100644
--- a/codeJK2/game/G_Timer.cpp
+++ b/codeJK2/game/G_Timer.cpp
@@ -24,6 +24,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#include "g_local.h"
#include "../../code/Rufl/hstring.h"
#include "qcommon/ojk_sg_wrappers.h"
+#include "qcommon/ojk_sg_archive.h"
#define MAX_GTIMERS 16384
diff --git a/codeJK2/game/Q3_Registers.cpp b/codeJK2/game/Q3_Registers.cpp
index 74a19b2..3ed0835 100644
--- a/codeJK2/game/Q3_Registers.cpp
+++ b/codeJK2/game/Q3_Registers.cpp
@@ -25,6 +25,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#include "g_local.h"
#include "Q3_Registers.h"
#include "qcommon/ojk_sg_wrappers.h"
+#include "qcommon/ojk_sg_archive.h"
extern void Q3_DebugPrint( int level, const char *format, ... );
diff --git a/codeJK2/game/g_main.cpp b/codeJK2/game/g_main.cpp
index 4fb5a70..9bb1260 100644
--- a/codeJK2/game/g_main.cpp
+++ b/codeJK2/game/g_main.cpp
@@ -36,6 +36,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#include "../cgame/cg_local.h" // yeah I know this is naughty, but we're shipping soon...
#include "time.h"
#include "qcommon/ojk_sg_wrappers.h"
+#include "qcommon/ojk_sg_archive.h"
extern CNavigator navigator;
diff --git a/codeJK2/game/g_objectives.cpp b/codeJK2/game/g_objectives.cpp
index a0488ae..c5e2ae8 100644
--- a/codeJK2/game/g_objectives.cpp
+++ b/codeJK2/game/g_objectives.cpp
@@ -32,6 +32,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#include "objectives.h"
#include "qcommon/ojk_sg_wrappers.h"
+#include "qcommon/ojk_sg_archive.h"
qboolean missionInfo_Updated;
diff --git a/codeJK2/game/g_roff.cpp b/codeJK2/game/g_roff.cpp
index 409785b..60ceed6 100644
--- a/codeJK2/game/g_roff.cpp
+++ b/codeJK2/game/g_roff.cpp
@@ -26,6 +26,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#include "g_roff.h"
#include "g_icarus.h"
#include "qcommon/ojk_sg_wrappers.h"
+#include "qcommon/ojk_sg_archive.h"
// The list of precached ROFFs
roff_list_t roffs[MAX_ROFFS];
diff --git a/codeJK2/game/g_savegame.cpp b/codeJK2/game/g_savegame.cpp
index c342535..d3108fa 100644
--- a/codeJK2/game/g_savegame.cpp
+++ b/codeJK2/game/g_savegame.cpp
@@ -34,6 +34,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#include "g_icarus.h"
#include "../../code/qcommon/sstring.h"
#include "qcommon/ojk_sg_wrappers.h"
+#include "qcommon/ojk_sg_archive.h"
extern void OBJ_LoadTacticalInfo(void);
diff --git a/codeJK2/icarus/Instance.cpp b/codeJK2/icarus/Instance.cpp
index d675291..7888ee7 100644
--- a/codeJK2/icarus/Instance.cpp
+++ b/codeJK2/icarus/Instance.cpp
@@ -30,6 +30,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#include <assert.h>
#include "qcommon/ojk_sg_wrappers.h"
+#include "qcommon/ojk_sg_archive.h"
// Instance
diff --git a/codeJK2/icarus/Sequence.cpp b/codeJK2/icarus/Sequence.cpp
index a619397..2b9a56f 100644
--- a/codeJK2/icarus/Sequence.cpp
+++ b/codeJK2/icarus/Sequence.cpp
@@ -29,6 +29,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#include <assert.h>
#include "qcommon/ojk_sg_wrappers.h"
+#include "qcommon/ojk_sg_archive.h"
CSequence::CSequence( void )
{
diff --git a/codeJK2/icarus/Sequencer.cpp b/codeJK2/icarus/Sequencer.cpp
index b100329..8096d3f 100644
--- a/codeJK2/icarus/Sequencer.cpp
+++ b/codeJK2/icarus/Sequencer.cpp
@@ -31,6 +31,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#include "assert.h"
#include "qcommon/ojk_sg_wrappers.h"
+#include "qcommon/ojk_sg_archive.h"
// Sequencer
diff --git a/codeJK2/icarus/TaskManager.cpp b/codeJK2/icarus/TaskManager.cpp
index 2cf235a..9fb06d0 100644
--- a/codeJK2/icarus/TaskManager.cpp
+++ b/codeJK2/icarus/TaskManager.cpp
@@ -32,6 +32,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#include <assert.h>
#include "qcommon/ojk_sg_wrappers.h"
+#include "qcommon/ojk_sg_archive.h"
#define ICARUS_VALIDATE(a) if ( a == false ) return TASK_FAILED;
diff --git a/shared/qcommon/ojk_exception.cpp b/shared/qcommon/ojk_exception.cpp
new file mode 100644
index 0000000..82e4bc1
--- /dev/null
+++ b/shared/qcommon/ojk_exception.cpp
@@ -0,0 +1,29 @@
+//
+// Base exception.
+//
+
+
+#include "ojk_exception.h"
+
+
+namespace ojk {
+
+
+Exception::Exception(
+ const char* message) :
+ std::runtime_error(message)
+{
+}
+
+Exception::Exception(
+ const std::string& message) :
+ std::runtime_error(message)
+{
+}
+
+Exception::~Exception()
+{
+}
+
+
+} // ojk
diff --git a/shared/qcommon/ojk_exception.h b/shared/qcommon/ojk_exception.h
new file mode 100644
index 0000000..8e4704e
--- /dev/null
+++ b/shared/qcommon/ojk_exception.h
@@ -0,0 +1,35 @@
+//
+// Base exception.
+//
+
+
+#ifndef OJK_EXCEPTION_INCLUDED
+#define OJK_EXCEPTION_INCLUDED
+
+
+#include <stdexcept>
+#include <string>
+
+
+namespace ojk {
+
+
+class Exception :
+ public std::runtime_error
+{
+public:
+ explicit Exception(
+ const char* message);
+
+ explicit Exception(
+ const std::string& message);
+
+ virtual ~Exception();
+}; // Exception
+
+
+} // ojk
+
+
+#endif // OJK_EXCEPTION_INCLUDED
+
diff --git a/shared/qcommon/ojk_sg_archive.cpp b/shared/qcommon/ojk_sg_archive.cpp
new file mode 100644
index 0000000..d669e83
--- /dev/null
+++ b/shared/qcommon/ojk_sg_archive.cpp
@@ -0,0 +1,80 @@
+#include "ojk_sg_archive.h"
+#include <cstdio>
+#include <unordered_map>
+#include "ojk_sg_archive_exception.h"
+
+
+namespace ojk {
+namespace sg {
+
+
+Archive::Archive() :
+ file_handle_(),
+ io_buffer_(),
+ io_buffer_offset_()
+{
+}
+
+Archive::~Archive()
+{
+ close();
+}
+
+bool Archive::open(
+ const std::string& file_path)
+{
+ throw ArchiveException(
+ "Not implemented.");
+}
+
+bool Archive::create(
+ const std::string& file_path)
+{
+ throw ArchiveException(
+ "Not implemented.");
+}
+
+void Archive::close()
+{
+ throw ArchiveException(
+ "Not implemented.");
+}
+
+void Archive::read_chunk(
+ const Archive::ChunkId chunk_id)
+{
+ throw ArchiveException(
+ "Not implemented.");
+}
+
+void Archive::write_chunk(
+ const Archive::ChunkId chunk_id)
+{
+ throw ArchiveException(
+ "Not implemented.");
+}
+
+void Archive::rename(
+ const std::string& old_file_path,
+ const std::string& new_file_path)
+{
+ throw ArchiveException(
+ "Not implemented.");
+}
+
+void Archive::remove(
+ const std::string& file_path)
+{
+ throw ArchiveException(
+ "Not implemented.");
+}
+
+Archive& Archive::get_instance()
+{
+ static Archive result;
+ return result;
+}
+
+
+} // sg
+} // ojk
diff --git a/shared/qcommon/ojk_sg_archive.h b/shared/qcommon/ojk_sg_archive.h
new file mode 100644
index 0000000..64ec1fb
--- /dev/null
+++ b/shared/qcommon/ojk_sg_archive.h
@@ -0,0 +1,587 @@
+//
+// Saved game archive.
+// (forward declaration)
+//
+
+
+#ifndef OJK_SG_ARCHIVE_INCLUDED
+#define OJK_SG_ARCHIVE_INCLUDED
+
+
+#include <cstdint>
+#include <algorithm>
+#include <type_traits>
+#include "ojk_sg_archive_fwd.h"
+
+
+namespace ojk {
+namespace sg {
+
+
+// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+// I/O buffer manipulation.
+
+template<typename T>
+void Archive::check_io_buffer(
+ int count)
+{
+ if (count <= 0) {
+ throw ArchiveException(
+ "Zero or negative count.");
+ }
+
+ const auto data_size = sizeof(T) * count;
+
+ if ((io_buffer_offset_ + data_size) > io_buffer_.size()) {
+ throw ArchiveException(
+ "Not enough data.");
+ }
+}
+
+template<typename T>
+void Archive::accomodate_io_buffer(
+ int count)
+{
+ if (count <= 0) {
+ throw ArchiveException(
+ "Zero or negative count.");
+ }
+
+ const auto data_size = sizeof(T) * count;
+
+ const auto new_buffer_size = io_buffer_offset_ + data_size;
+
+ io_buffer_.resize(
+ new_buffer_size);
+}
+
+template<typename T>
+T Archive::cast_io_buffer()
+{
+ return reinterpret_cast<T>(&io_buffer_[io_buffer_offset_]);
+}
+
+template<typename T>
+void Archive::advance_io_buffer(
+ int count)
+{
+ if (count <= 0) {
+ throw ArchiveException(
+ "Zero or negative count.");
+ }
+
+ const auto data_size = sizeof(T) * count;
+ io_buffer_offset_ += data_size;
+}
+
+// I/O buffer manipulation.
+// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+
+// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+// read_chunk
+
+template<typename TSrc, typename TDst>
+void Archive::read_chunk(
+ const ChunkId chunk_id,
+ TDst& dst_value)
+{
+ read_chunk(
+ chunk_id);
+
+ read<TSrc>(
+ dst_value);
+}
+
+template<typename TSrc, typename TDst>
+void Archive::read_chunk(
+ const ChunkId chunk_id,
+ TDst* dst_values,
+ int dst_count)
+{
+ read_chunk(
+ chunk_id);
+
+ read<TSrc>(
+ dst_values,
+ dst_count);
+}
+
+// read_chunk
+// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+
+// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+// write_chunk
+
+template<typename TDst, typename TSrc>
+void Archive::write_chunk(
+ const ChunkId chunk_id,
+ const TSrc& src_value)
+{
+ io_buffer_offset_ = 0;
+
+ write<TDst>(
+ src_value);
+
+ write_chunk(
+ chunk_id);
+}
+
+template<typename TDst, typename TSrc>
+void Archive::write_chunk(
+ const ChunkId chunk_id,
+ const TSrc* src_values,
+ int src_count)
+{
+ io_buffer_offset_ = 0;
+
+ write<TDst>(
+ src_values,
+ src_count);
+
+ write_chunk(
+ chunk_id);
+}
+
+// write_chunk
+// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+
+// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+// read
+
+template<typename TSrc, typename TDst>
+void Archive::read(
+ TDst& dst_value)
+{
+ using Tag = typename std::conditional<
+ std::is_same<TDst, bool>::value,
+ BooleanTag,
+ typename std::conditional<
+ std::is_arithmetic<TDst>::value || std::is_enum<TDst>::value,
+ NumericTag,
+ typename std::conditional<
+ std::is_pointer<TDst>::value,
+ PointerTag,
+ typename std::conditional<
+ std::is_class<TDst>::value,
+ ClassTag,
+ typename std::conditional<
+ std::rank<TDst>::value == 1,
+ Array1dTag,
+ void
+ >::type
+ >::type
+ >::type
+ >::type
+ >::type;
+
+ static_assert(
+ !std::is_same<Tag, void>::value,
+ "Unsupported type.");
+
+ read<TSrc>(
+ dst_value,
+ Tag());
+}
+
+template<typename TSrc, typename TDst>
+void Archive::read(
+ TDst& dst_value,
+ BooleanTag)
+{
+ constexpr auto src_size = sizeof(TSrc);
+
+ check_io_buffer<TSrc>();
+
+ dst_value = (cast_io_buffer<const TSrc&>() != 0);
+
+ // FIXME Byte order
+ //
+
+ advance_io_buffer<TSrc>();
+}
+
+template<typename TSrc, typename TDst>
+void Archive::read(
+ TDst& dst_value,
+ NumericTag)
+{
+ check_io_buffer<TSrc>();
+
+ dst_value = static_cast<TDst>(cast_io_buffer<const TSrc&>());
+
+ // FIXME Byte order
+ //
+
+ advance_io_buffer<TSrc>();
+}
+
+template<typename TSrc, typename TDst>
+void Archive::read(
+ TDst*& dst_value,
+ PointerTag)
+{
+ static_assert(
+ std::is_arithmetic<TSrc>::value &&
+ !std::is_same<TSrc, bool>::value,
+ "Unsupported types.");
+
+ using DstNumeric = typename std::conditional<
+ std::is_signed<TSrc>::value,
+ std::intptr_t,
+ std::uintptr_t
+ >::type;
+
+ auto dst_number = DstNumeric();
+
+ read<TSrc>(
+ dst_number,
+ NumericTag());
+
+ dst_value = reinterpret_cast<TDst*>(dst_number);
+}
+
+template<typename TSrc, typename TDst>
+void Archive::read(
+ TDst& dst_value,
+ ClassTag)
+{
+ throw ArchiveException(
+ "Not implemented.");
+}
+
+template<typename TSrc, typename TDst, int TCount>
+void Archive::read(
+ TDst (&dst_values)[TCount],
+ Array1dTag)
+{
+ read<TSrc>(
+ &dst_values[0],
+ TCount);
+}
+
+// read
+// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+
+// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+// read (C-array)
+
+template<typename TSrc, typename TDst>
+void Archive::read(
+ TDst* dst_values,
+ int dst_count)
+{
+ static_assert(
+ (std::is_arithmetic<TDst>::value &&
+ !std::is_same<TDst, bool>::value &&
+ !std::is_enum<TDst>::value) ||
+ std::is_class<TDst>::value,
+ "Unsupported types.");
+
+ if (!dst_values) {
+ throw ArchiveException(
+ "Null pointer.");
+ }
+
+ if (dst_count < 0) {
+ throw ArchiveException(
+ "Negative count.");
+ }
+
+ if (dst_count == 0) {
+ return;
+ }
+
+ using Src = typename std::conditional<
+ std::is_same<TSrc, void>::value,
+ TDst,
+ TSrc>::type;
+
+ constexpr auto is_src_pure_numeric =
+ std::is_arithmetic<Src>::value &&
+ (!std::is_same<Src, bool>::value) &&
+ (!std::is_enum<Src>::value);
+
+ constexpr auto is_dst_pure_numeric =
+ std::is_arithmetic<TDst>::value &&
+ (!std::is_same<TDst, bool>::value) &&
+ (!std::is_enum<TDst>::value);
+
+ constexpr auto has_same_size =
+ (sizeof(Src) == sizeof(TDst));
+
+ constexpr auto use_inplace =
+ is_src_pure_numeric &&
+ is_dst_pure_numeric &&
+ has_same_size;
+
+ using Tag = typename std::conditional<
+ use_inplace,
+ InplaceTag,
+ CastTag
+ >::type;
+
+ read<TSrc>(
+ dst_values,
+ dst_count,
+ Tag());
+}
+
+template<typename TSrc, typename TDst>
+void Archive::read(
+ TDst* dst_values,
+ int dst_count,
+ InplaceTag)
+{
+ check_io_buffer<TDst>(
+ dst_count);
+
+ std::uninitialized_copy_n(
+ cast_io_buffer<const TDst*>(),
+ dst_count,
+ dst_values);
+
+ // FIXME Byte order
+ //
+
+ advance_io_buffer<TDst>(
+ dst_count);
+}
+
+template<typename TSrc, typename TDst>
+void Archive::read(
+ TDst* dst_values,
+ int dst_count,
+ CastTag)
+{
+ using Tag = typename std::conditional<
+ std::is_arithmetic<TDst>::value,
+ NumericTag,
+ typename std::conditional<
+ std::is_class<TDst>::value,
+ ClassTag,
+ void
+ >::type
+ >::type;
+
+ for (int i = 0; i < dst_count; ++i) {
+ read<TSrc>(
+ dst_values[i],
+ Tag());
+ }
+}
+
+// read (C-array)
+// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+
+// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+// write
+
+template<typename TDst, typename TSrc>
+void Archive::write(
+ const TSrc& src_value)
+{
+ using Tag = typename std::conditional<
+ std::is_arithmetic<TSrc>::value || std::is_enum<TSrc>::value,
+ NumericTag,
+ typename std::conditional<
+ std::is_pointer<TSrc>::value,
+ PointerTag,
+ typename std::conditional<
+ std::is_class<TSrc>::value,
+ ClassTag,
+ typename std::conditional<
+ std::rank<TSrc>::value == 1,
+ Array1dTag,
+ void
+ >::type
+ >::type
+ >::type
+ >::type;
+
+ static_assert(
+ !std::is_same<Tag, void>::value,
+ "Unsupported type.");
+
+ write<TDst>(
+ src_value,
+ Tag());
+}
+
+template<typename TDst, typename TSrc>
+void Archive::write(
+ const TSrc& src_value,
+ NumericTag)
+{
+ accomodate_io_buffer<TSrc>();
+
+ cast_io_buffer<TDst&>() = static_cast<TDst>(src_value);
+
+ // FIXME Byte order
+ //
+
+ advance_io_buffer<TSrc>();
+}
+
+template<typename TDst, typename TSrc>
+void Archive::write(
+ const TSrc*& src_value,
+ PointerTag)
+{
+ using DstNumeric = typename std::conditional<
+ std::is_signed<TSrc>::value,
+ std::intptr_t,
+ std::uintptr_t
+ >::type;
+
+ auto dst_number = reinterpret_cast<DstNumeric>(src_value);
+
+ write<TDst>(
+ dst_number,
+ NumericTag());
+}
+
+template<typename TDst, typename TSrc>
+void Archive::write(
+ const TSrc& src_value,
+ ClassTag)
+{
+ throw ArchiveException(
+ "Not implemented.");
+}
+
+template<typename TDst, typename TSrc, int TCount>
+void Archive::write(
+ const TSrc (&src_values)[TCount],
+ Array1dTag)
+{
+ write<TDst>(
+ &src_values[0],
+ TCount);
+}
+
+// write
+// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+
+// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+// write (C-array)
+
+template<typename TDst, typename TSrc>
+void Archive::write(
+ const TSrc* src_values,
+ int src_count)
+{
+ static_assert(
+ (std::is_arithmetic<TSrc>::value &&
+ !std::is_same<TSrc, bool>::value &&
+ !std::is_enum<TSrc>::value) ||
+ std::is_class<TSrc>::value,
+ "Unsupported types.");
+
+ if (!src_values) {
+ throw ArchiveException(
+ "Null pointer.");
+ }
+
+ if (src_count < 0) {
+ throw ArchiveException(
+ "Negative count.");
+ }
+
+ if (src_count == 0) {
+ return;
+ }
+
+ using Dst = typename std::conditional<
+ std::is_same<TDst, void>::value,
+ TSrc,
+ TDst>::type;
+
+ constexpr auto is_src_pure_numeric =
+ std::is_arithmetic<TSrc>::value &&
+ (!std::is_same<TSrc, bool>::value) &&
+ (!std::is_enum<TSrc>::value);
+
+ constexpr auto is_dst_pure_numeric =
+ std::is_arithmetic<Dst>::value &&
+ (!std::is_same<Dst, bool>::value) &&
+ (!std::is_enum<Dst>::value);
+
+ constexpr auto has_same_size =
+ (sizeof(TSrc) == sizeof(Dst));
+
+ constexpr auto use_inplace =
+ is_src_pure_numeric &&
+ is_dst_pure_numeric &&
+ has_same_size;
+
+ using Tag = typename std::conditional<
+ use_inplace,
+ InplaceTag,
+ CastTag
+ >::type;
+
+ write<TDst>(
+ src_values,
+ src_count,
+ Tag());
+}
+
+template<typename TDst, typename TSrc>
+void Archive::write(
+ const TSrc* src_values,
+ int src_count,
+ InplaceTag)
+{
+ accomodate_io_buffer<TSrc>(
+ src_count);
+
+ std::uninitialized_copy_n(
+ src_values,
+ src_count,
+ cast_io_buffer<TSrc*>());
+
+ // FIXME Byte order
+ //
+
+ advance_io_buffer<TSrc>(
+ src_count);
+}
+
+template<typename TDst, typename TSrc>
+void Archive::write(
+ const TSrc* src_values,
+ int src_count,
+ CastTag)
+{
+ using Tag = typename std::conditional<
+ std::is_arithmetic<TSrc>::value,
+ NumericTag,
+ typename std::conditional<
+ std::is_class<TSrc>::value,
+ ClassTag,
+ void
+ >::type
+ >::type;
+
+ for (int i = 0; i < src_count; ++i) {
+ write<TDst>(
+ src_values[i],
+ Tag());
+ }
+}
+
+// write (C-array)
+// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+
+} // sg
+} // ojk
+
+
+#endif // OJK_SG_ARCHIVE_INCLUDED
diff --git a/shared/qcommon/ojk_sg_archive_exception.cpp b/shared/qcommon/ojk_sg_archive_exception.cpp
new file mode 100644
index 0000000..a582836
--- /dev/null
+++ b/shared/qcommon/ojk_sg_archive_exception.cpp
@@ -0,0 +1,31 @@
+//
+// Saved game archive exception.
+//
+
+
+#include "ojk_sg_archive_exception.h"
+
+
+namespace ojk {
+namespace sg {
+
+
+ArchiveException::ArchiveException(
+ const char* message) :
+ Exception(message)
+{
+}
+
+ArchiveException::ArchiveException(
+ const std::string& message) :
+ Exception(message)
+{
+}
+
+ArchiveException::~ArchiveException()
+{
+}
+
+
+} // sg
+} // ojk
diff --git a/shared/qcommon/ojk_sg_archive_exception.h b/shared/qcommon/ojk_sg_archive_exception.h
new file mode 100644
index 0000000..a709724
--- /dev/null
+++ b/shared/qcommon/ojk_sg_archive_exception.h
@@ -0,0 +1,36 @@
+//
+// Saved game archive exception.
+//
+
+
+#ifndef OJK_SG_ARCHIVE_EXCEPTION_INCLUDED
+#define OJK_SG_ARCHIVE_EXCEPTION_INCLUDED
+
+
+#include "ojk_exception.h"
+
+
+namespace ojk {
+namespace sg {
+
+
+class ArchiveException :
+ public Exception
+{
+public:
+ explicit ArchiveException(
+ const char* message);
+
+ explicit ArchiveException(
+ const std::string& message);
+
+ virtual ~ArchiveException();
+}; // ArchiveException
+
+
+} // sg
+} // ojk
+
+
+#endif // OJK_SG_ARCHIVE_EXCEPTION_INCLUDED
+
diff --git a/shared/qcommon/ojk_sg_archive_fwd.h b/shared/qcommon/ojk_sg_archive_fwd.h
new file mode 100644
index 0000000..31eca73
--- /dev/null
+++ b/shared/qcommon/ojk_sg_archive_fwd.h
@@ -0,0 +1,257 @@
+//
+// Saved game archive.
+// (forward declaration)
+//
+
+
+#ifndef OJK_SG_ARCHIVE_FWD_INCLUDED
+#define OJK_SG_ARCHIVE_FWD_INCLUDED
+
+
+#include <cstdint>
+#include <string>
+#include <vector>
+#include "ojk_sg_archive_exception.h"
+
+
+using fileHandle_t = int32_t;
+
+
+namespace ojk {
+namespace sg {
+
+
+enum class ArchiveMode {
+ jedi_outcast,
+ jedi_academy,
+}; // ArchiveMode
+
+
+class Archive
+{
+public:
+ using ChunkId = uint32_t;
+
+
+ Archive();
+
+ Archive(
+ const Archive& that) = delete;
+
+ Archive& operator=(
+ const Archive& that) = delete;
+
+ ~Archive();
+
+
+ // Creates a new saved game file for writing.
+ bool create(
+ const std::string& file_path);
+
+ // Opens an existing saved game file for reading.
+ bool open(
+ const std::string& file_path);
+
+ // Closes the current saved game file.
+ void close();
+
+
+ // Reads a chunk from the file into the internal buffer.
+ void read_chunk(
+ const ChunkId chunk_id);
+
+ // Reads a value or an array of values from the file via
+ // the internal buffer.
+ template<typename TSrc = void, typename TDst = void>
+ void read_chunk(
+ const ChunkId chunk_id,
+ TDst& dst_value);
+
+ // Reads an array of values with specified count from
+ // the file via the internal buffer.
+ template<typename TSrc = void, typename TDst = void>
+ void read_chunk(
+ const ChunkId chunk_id,
+ TDst* dst_values,
+ int dst_count);
+
+
+ // Writes a chunk into the file from the internal buffer.
+ void write_chunk(
+ const ChunkId chunk_id);
+
+ // Writes a value or an array of values into the file via
+ // the internal buffer.
+ template<typename TDst = void, typename TSrc = void>
+ void write_chunk(
+ const ChunkId chunk_id,
+ const TSrc& src_value);
+
+ // Writes an array of values with specified count into
+ // the file via the internal buffer.
+ template<typename TDst = void, typename TSrc = void>
+ void write_chunk(
+ const ChunkId chunk_id,
+ const TSrc* src_values,
+ int src_count);
+
+
+ // Reads a value or array of values from the internal buffer.
+ template<typename TSrc = void, typename TDst = void>
+ void read(
+ TDst& dst_value);
+
+ // Reads an array of values with specificed count from the internal buffer.
+ template<typename TSrc = void, typename TDst = void>
+ void read(
+ TDst* dst_values,
+ int dst_count);
+
+
+ // Writes a value or array of values into the internal buffer.
+ template<typename TDst = void, typename TSrc = void>
+ void write(
+ const TSrc& src_value);
+
+ // Writes an array of values with specificed count into the internal buffer.
+ template<typename TDst = void, typename TSrc = void>
+ void write(
+ const TSrc* src_values,
+ int src_count);
+
+
+ // Renames a saved game file.
+ static void rename(
+ const std::string& old_file_path,
+ const std::string& new_file_path);
+
+ // Remove a saved game file.
+ static void remove(
+ const std::string& file_path);
+
+ // Returns a default instance of the class.
+ static Archive& get_instance();
+
+
+private:
+ using Buffer = std::vector<uint8_t>;
+ using BufferOffset = Buffer::size_type;
+
+ // Tags for dispatching.
+ class BooleanTag { public: };
+ class NumericTag { public: };
+ class PointerTag { public: };
+ class ClassTag { public: };
+ class Array1dTag { public: };
+ class InplaceTag { public: };
+ class CastTag { public: };
+
+ // A handle to a file.
+ fileHandle_t file_handle_;
+
+ // I/O buffer.
+ Buffer io_buffer_;
+
+ // A current offset inside the I/O buffer.
+ BufferOffset io_buffer_offset_;
+
+
+ // Checks if there is enough data for reading in the I/O buffer.
+ template<typename T>
+ void check_io_buffer(
+ int count = 1);
+
+ // Resizes the I/O buffer according to desire size of data to write.
+ template<typename T>
+ void accomodate_io_buffer(
+ int count = 1);
+
+ // Casts I/O buffer data at the current offset.
+ template<typename T>
+ T cast_io_buffer();
+
+ // Advances the current I/O buffer offset.
+ template<typename T>
+ void advance_io_buffer(
+ int count = 1);
+
+
+ template<typename TSrc, typename TDst>
+ void read(
+ TDst& dst_value,
+ BooleanTag);
+
+ template<typename TSrc, typename TDst>
+ void read(
+ TDst& dst_value,
+ NumericTag);
+
+ template<typename TSrc, typename TDst>
+ void read(
+ TDst*& dst_value,
+ PointerTag);
+
+ template<typename TSrc, typename TDst>
+ void read(
+ TDst& dst_value,
+ ClassTag);
+
+ template<typename TSrc, typename TDst, int TCount>
+ void read(
+ TDst (&dst_values)[TCount],
+ Array1dTag);
+
+
+ template<typename TSrc, typename TDst>
+ void read(
+ TDst* dst_values,
+ int dst_count,
+ InplaceTag);
+
+ template<typename TSrc, typename TDst>
+ void read(
+ TDst* dst_values,
+ int dst_count,
+ CastTag);
+
+
+ template<typename TDst, typename TSrc>
+ void write(
+ const TSrc& src_value,
+ NumericTag);
+
+ template<typename TDst, typename TSrc>
+ void write(
+ const TSrc*& src_value,
+ PointerTag);
+
+ template<typename TDst, typename TSrc>
+ void write(
+ const TSrc& src_value,
+ ClassTag);
+
+ template<typename TDst, typename TSrc, int TCount>
+ void write(
+ const TSrc (&src_values)[TCount],
+ Array1dTag);
+
+
+ template<typename TDst, typename TSrc>
+ void write(
+ const TSrc* src_values,
+ int src_count,
+ InplaceTag);
+
+ template<typename TDst, typename TSrc>
+ void write(
+ const TSrc* src_values,
+ int src_count,
+ CastTag);
+}; // Archive
+
+
+} // sg
+} // ojk
+
+
+#endif // OJK_SG_ARCHIVE_FWD_INCLUDED
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/openjk.git
More information about the Pkg-games-commits
mailing list