Split play into body, items, interactions, autofeed and camera, with events, commands and literal strings
This commit is contained in:
1 parent
167f1a5ddd
commit
3e9a0cbd34
21 files changed
+2504
-2431
No files matched your search
+2
-174
@@ -1,96 +1,13 @@
|
||||
#include "save.h"
|
||||
#include <SDL3/SDL.h>
|
||||
#include <cstdio>
|
||||
#include <type_traits>
|
||||
|
||||
#ifdef SDL_PLATFORM_EMSCRIPTEN
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
constexpr const char* KEY_DISCOVERED = "discovered";
|
||||
constexpr const char* KEY_ITEM = "item";
|
||||
constexpr const char* SETTINGS_FILE = "settings.txt";
|
||||
|
||||
static void value_read(const char* text, float& value)
|
||||
{
|
||||
value = (float)SDL_atof(text);
|
||||
}
|
||||
|
||||
static void value_read(const char* text, int& value)
|
||||
{
|
||||
value = SDL_atoi(text);
|
||||
}
|
||||
|
||||
static void value_read(const char* text, bool& value)
|
||||
{
|
||||
value = SDL_atoi(text);
|
||||
}
|
||||
|
||||
static void value_read(const char* text, Measurement& value)
|
||||
{
|
||||
value = (Measurement)SDL_atoi(text);
|
||||
}
|
||||
|
||||
static void value_read(const char* text, std::string& value)
|
||||
{
|
||||
value = text;
|
||||
}
|
||||
|
||||
static void value_read(const char* text, Vec2& value)
|
||||
{
|
||||
SDL_sscanf(text, "%f %f", &value.x, &value.y);
|
||||
}
|
||||
|
||||
static void value_read(const char* text, Color& value)
|
||||
{
|
||||
SDL_sscanf(text, "%f %f %f", &value.r, &value.g, &value.b);
|
||||
}
|
||||
|
||||
static std::string value_write(float value)
|
||||
{
|
||||
return std::to_string(value);
|
||||
}
|
||||
|
||||
static std::string value_write(int value)
|
||||
{
|
||||
return std::to_string(value);
|
||||
}
|
||||
|
||||
static std::string value_write(const std::string& value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
static std::string value_write(Vec2 value)
|
||||
{
|
||||
return value_write(value.x) + " " + value_write(value.y);
|
||||
}
|
||||
|
||||
static std::string value_write(Color value)
|
||||
{
|
||||
return value_write(value.r) + " " + value_write(value.g) + " " + value_write(value.b);
|
||||
}
|
||||
|
||||
// Calls line with each key and value of a key=value text file. Returns whether it was there.
|
||||
template <class Line> static bool lines_read(const std::string& path, Line&& line)
|
||||
{
|
||||
char* text = (char*)SDL_LoadFile(path.c_str(), nullptr);
|
||||
if (!text)
|
||||
return false;
|
||||
char* rest = nullptr;
|
||||
for (char* entry = SDL_strtok_r(text, "\r\n", &rest); entry; entry = SDL_strtok_r(nullptr, "\r\n", &rest))
|
||||
{
|
||||
char* value = SDL_strchr(entry, '=');
|
||||
if (!value)
|
||||
continue;
|
||||
*value++ = '\0';
|
||||
line(std::string(entry), value);
|
||||
}
|
||||
SDL_free(text);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void file_write(const std::string& path, const std::string& text)
|
||||
void file_write(const std::string& path, const std::string& text)
|
||||
{
|
||||
SDL_CreateDirectory(path.substr(0, path.find_last_of('/')).c_str());
|
||||
if (!SDL_SaveFile(path.c_str(), text.data(), text.size()))
|
||||
@@ -100,48 +17,9 @@ static void file_write(const std::string& path, const std::string& text)
|
||||
#endif
|
||||
}
|
||||
|
||||
// Reads every field a visitable struct names from a key=value file, and writes them back.
|
||||
template <class Fields> static bool fields_read(const std::string& path, Fields& fields)
|
||||
{
|
||||
return lines_read(path, [&](const std::string& key, const char* value) {
|
||||
fields.visit([&](const char* name, auto& field) {
|
||||
if (key == name)
|
||||
value_read(value, field);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
template <class Fields> static std::string fields_write(Fields& fields)
|
||||
{
|
||||
std::string text;
|
||||
fields.visit([&](const char* name, auto& field) {
|
||||
using Type = std::decay_t<decltype(field)>;
|
||||
if constexpr (std::is_same_v<Type, bool> || std::is_enum_v<Type>)
|
||||
text += std::string(name) + "=" + value_write((int)field) + "\n";
|
||||
else
|
||||
text += std::string(name) + "=" + value_write(field) + "\n";
|
||||
});
|
||||
return text;
|
||||
}
|
||||
|
||||
template <class Visitor> void Settings::visit(Visitor&& visitor)
|
||||
{
|
||||
visitor("character_color", isCharacterColor);
|
||||
visitor("color", color);
|
||||
visitor("console", isConsole);
|
||||
visitor("height", height);
|
||||
visitor("last_character", lastCharacter);
|
||||
visitor("measurement", measurement);
|
||||
visitor("mute", isMuted);
|
||||
visitor("volume", volume);
|
||||
visitor("width", width);
|
||||
visitor("x", x);
|
||||
visitor("y", y);
|
||||
}
|
||||
|
||||
void Settings::load()
|
||||
{
|
||||
fields_read(pref_path_get(SETTINGS_FILE), *this);
|
||||
is_fields_read(pref_path_get(SETTINGS_FILE), *this);
|
||||
}
|
||||
|
||||
void Settings::save()
|
||||
@@ -159,53 +37,3 @@ void Settings::reset()
|
||||
isCharacterColor = defaults.isCharacterColor;
|
||||
isMuted = defaults.isMuted;
|
||||
}
|
||||
|
||||
template <class Visitor> void Progress::visit(Visitor&& visitor)
|
||||
{
|
||||
visitor("alternate", isAlternate);
|
||||
visitor("calories", calories);
|
||||
visitor("capacity", capacity);
|
||||
visitor("digesting", isDigesting);
|
||||
visitor("digestion_progress", digestionProgress);
|
||||
visitor("digestion_rate", digestionRate);
|
||||
visitor("digestion_timer", digestionTimer);
|
||||
visitor("pan", pan);
|
||||
visitor("playtime", playtime);
|
||||
visitor("postgame", isPostgame);
|
||||
visitor("spawn_delay", spawnDelay);
|
||||
visitor("total_calories", totalCalories);
|
||||
visitor("total_consumed", totalConsumed);
|
||||
visitor("total_spawned", totalSpawned);
|
||||
visitor("weight", weight);
|
||||
visitor("zoom", zoom);
|
||||
}
|
||||
|
||||
// Items are kept one per line as their position, velocity, rotation and then name.
|
||||
void Progress::load(const std::string& path)
|
||||
{
|
||||
*this = {};
|
||||
isValid = fields_read(path, *this);
|
||||
lines_read(path, [&](const std::string& key, const char* value) {
|
||||
if (key == KEY_DISCOVERED)
|
||||
discovered.emplace_back(value);
|
||||
SavedItem item;
|
||||
int length = 0;
|
||||
if (key == KEY_ITEM && std::sscanf(value, "%f %f %f %f %f %n", &item.position.x, &item.position.y,
|
||||
&item.velocity.x, &item.velocity.y, &item.rotation, &length) == 5)
|
||||
{
|
||||
item.name = value + length;
|
||||
items.push_back(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Progress::save(const std::string& path)
|
||||
{
|
||||
std::string text = fields_write(*this);
|
||||
for (const std::string& name : discovered)
|
||||
text += std::string(KEY_DISCOVERED) + "=" + name + "\n";
|
||||
for (const SavedItem& item : items)
|
||||
text += std::string(KEY_ITEM) + "=" + value_write(item.position) + " " + value_write(item.velocity) + " " +
|
||||
value_write(item.rotation) + " " + item.name + "\n";
|
||||
file_write(path, text);
|
||||
}
|
||||
Reference in new issue
Block a user