Verified Commit 14b840b5 authored by RobLoach's avatar RobLoach
Browse files

Add zlib to compress the state string

parent 386bf806
......@@ -25,3 +25,6 @@
[submodule "vendor/RobLoachChaiScript_Extras"]
path = vendor/RobLoachChaiScript_Extras
url = https://github.com/RobLoach/ChaiScript_Extras.git
[submodule "vendor/zlib"]
path = vendor/zlib
url = https://github.com/madler/zlib.git
# ChaiLove
SOURCES_CXX += $(wildcard \
src/*.cpp \
......@@ -17,6 +16,20 @@ FLAGS += -Ivendor/filesystem
# libretro-common
FLAGS += -Ivendor/libretro-common/include
# zlib
SOURCES_C += \
vendor/zlib/crc32.c \
vendor/zlib/deflate.c \
vendor/zlib/trees.c \
vendor/zlib/inftrees.c \
vendor/zlib/adler32.c \
vendor/zlib/zutil.c \
vendor/zlib/inflate.c \
vendor/zlib/infback.c \
vendor/zlib/inffast.c
FLAGS += -Ivendor/zlib
FLAGS += -DWANT_ZLIB
# PhysFS
FLAGS += -Ivendor/physfs/src
FLAGS += -Ivendor/physfs/extras
......
#include "math.h"
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <string>
#include <sstream>
#include <iostream>
#include "zlib.h"
namespace Modules {
......@@ -43,4 +48,82 @@ namespace Modules {
int math::getRandomSeed() {
return m_seed;
}
std::string math::compress(const std::string& str) {
int compressionlevel = Z_BEST_COMPRESSION;
z_stream zs;
memset(&zs, 0, sizeof(zs));
if (deflateInit(&zs, compressionlevel) != Z_OK) {
std::cout << "[ChaiLove] [math] deflateInit failed while compressing." << std::endl;
return str;
}
zs.next_in = (Bytef*)str.data();
zs.avail_in = str.size();
int ret;
char outbuffer[32768];
std::string outstring;
do {
zs.next_out = reinterpret_cast<Bytef*>(outbuffer);
zs.avail_out = sizeof(outbuffer);
ret = deflate(&zs, Z_FINISH);
if (outstring.size() < zs.total_out) {
outstring.append(outbuffer,
zs.total_out - outstring.size());
}
} while (ret == Z_OK);
deflateEnd(&zs);
if (ret != Z_STREAM_END) {
std::cout << "[ChaiLove] [math] Exception during zlib compression: (" << ret << ") " << zs.msg << std::endl;
return str;
}
return outstring;
}
std::string math::decompress(const std::string& str) {
z_stream zs;
memset(&zs, 0, sizeof(zs));
if (inflateInit(&zs) != Z_OK)
throw(std::runtime_error("inflateInit failed while decompressing."));
zs.next_in = (Bytef*)str.data();
zs.avail_in = str.size();
int ret;
char outbuffer[32768];
std::string outstring;
do {
zs.next_out = reinterpret_cast<Bytef*>(outbuffer);
zs.avail_out = sizeof(outbuffer);
ret = inflate(&zs, 0);
if (outstring.size() < zs.total_out) {
outstring.append(outbuffer,
zs.total_out - outstring.size());
}
} while (ret == Z_OK);
inflateEnd(&zs);
if (ret != Z_STREAM_END) { // an error occurred that was not EOF
std::ostringstream oss;
oss << "Exception during zlib decompression: (" << ret << ") "
<< zs.msg;
throw(std::runtime_error(oss.str()));
}
return outstring;
}
}
#ifndef CHAILOVE_MATH_H
#define CHAILOVE_MATH_H
#include <string>
namespace Modules {
/**
* @brief Provides system-independent mathematical functions.
......@@ -33,6 +35,24 @@ namespace Modules {
*/
int getRandomSeed();
/**
* @brief Compress the given string.
*
* @param str The string to compress.
*
* @return Compressed data in the form of a string.
*/
std::string compress(const std::string& str);
/**
* @brief Decompress the given string.
*
* @param str The string to decompress.
*
* @return The decompressed string.
*/
std::string decompress(const std::string& str);
/**
* @brief Pi
*/
......
......@@ -251,6 +251,8 @@ namespace Modules {
chai.add(fun<void, math, int>(&math::setRandomSeed), "setRandomSeed");
chai.add(fun<void, math, int, int>(&math::setRandomSeed), "setRandomSeed");
chai.add(fun(&math::getRandomSeed), "getRandomSeed");
chai.add(fun(&math::compress), "compress");
chai.add(fun(&math::decompress), "decompress");
chai.add_global(var(std::ref(app->math)), "math");
// Load main.chai if it's a ChaiLove file.
......
......@@ -242,6 +242,9 @@ bool retro_serialize(void *data, size_t size) {
return false;
}
// Compress the JSON state data.
state = app->math.compress(state);
// Save the information to the state data.
std::copy(state.begin(), state.end(), reinterpret_cast<char*>(data));
return true;
......@@ -261,6 +264,11 @@ bool retro_unserialize(const void *data, size_t size) {
// Pass the string to the script.
ChaiLove* app = ChaiLove::getInstance();
// Decompress the state data.
loadData = app->math.decompress(loadData);
// Finally, load the string.
return app->loadstate(loadData);
}
......
Subproject commit cacf7f1d4e3d44d871b605da3b647f07d718623f
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment