Split the simulation from presentation into an SDL-free library
Sim holds one whole game (tick, snapshots, checksum) and talks to the screen only through Cues, which the client's Scene plays and the server ignores. All drawing moved to scene.cpp. Match takes this screen's wishes as request flags instead of reading the menu, input and settings. The sim library builds without SDL and the server links it, ready to run games itself. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2007fb7edc
commit
465f75f6d7
38 files changed
+2225
-1965
No files matched your search
+10
-10
@@ -259,7 +259,7 @@ void Settings::load(Game& game)
|
||||
std::fill(std::begin(sandbox.trinketLoadout), std::end(sandbox.trinketLoadout), -1);
|
||||
std::fill(std::begin(sandbox.weaponSlotLevels), std::end(sandbox.weaponSlotLevels), -1);
|
||||
std::fill(std::begin(sandbox.trinketSlotLevels), std::end(sandbox.trinketSlotLevels), -1);
|
||||
savedRules = game.match.rules;
|
||||
savedRules = game.sim.match.rules;
|
||||
char* text = (char*)SDL_LoadFile(file_path_get().c_str(), nullptr);
|
||||
if (!text)
|
||||
return;
|
||||
@@ -304,7 +304,7 @@ void Settings::load(Game& game)
|
||||
weaponSlots = std::clamp(number, 1, SLOT_MAX);
|
||||
if (SDL_strcmp(line, KEY_TRINKET_SLOTS) == 0)
|
||||
trinketSlots = std::clamp(number, 1, SLOT_MAX);
|
||||
rules_read(game.match.rules, line, value);
|
||||
rules_read(game.sim.match.rules, line, value);
|
||||
sandbox_read(sandbox, line, value);
|
||||
for (int i = 0; i < CONTROL_COUNT; i++)
|
||||
{
|
||||
@@ -316,7 +316,7 @@ void Settings::load(Game& game)
|
||||
}
|
||||
}
|
||||
SDL_free(text);
|
||||
savedRules = game.match.rules;
|
||||
savedRules = game.sim.match.rules;
|
||||
}
|
||||
|
||||
void Settings::save(Game& game)
|
||||
@@ -336,7 +336,7 @@ void Settings::save(Game& game)
|
||||
length += SDL_snprintf(text + length, sizeof(text) - length, "%s%s=%d,%d\n", KEY_BIND, CONTROL_KEYS[i],
|
||||
binding.key, binding.pad);
|
||||
}
|
||||
Match& match = game.match;
|
||||
Match& match = game.sim.match;
|
||||
length += rules_write(match.rules, text + length, sizeof(text) - length);
|
||||
length += sandbox_write(match.state == MATCH_PRACTICE ? game.local_get() : match.sandbox, text + length,
|
||||
sizeof(text) - length);
|
||||
@@ -354,7 +354,7 @@ void Settings::apply(Game& game)
|
||||
fullscreen_apply(game);
|
||||
game.renderer.vsync_set(isVsync);
|
||||
game.audio.gain_set(isMuted ? 0 : volume);
|
||||
if (game.match.state == MATCH_PRACTICE)
|
||||
if (game.sim.match.state == MATCH_PRACTICE)
|
||||
{
|
||||
Fighter& fighter = game.local_get();
|
||||
fighter.slots_set(weaponSlots, trinketSlots);
|
||||
@@ -402,7 +402,7 @@ void Settings::draw(Game& game, Rect area, Page& page)
|
||||
|
||||
// The sandbox's slots only show in the sandbox.
|
||||
bool isSandbox = false;
|
||||
if (game.match.state == MATCH_PRACTICE)
|
||||
if (game.sim.match.state == MATCH_PRACTICE)
|
||||
{
|
||||
if (ui.row_get(page, ROW_HEIGHT, y))
|
||||
ui.separator_draw(game, {row.x, y, row.w, row.h}, "Sandbox");
|
||||
@@ -586,7 +586,7 @@ void Settings::defaults_restore(Game& game)
|
||||
fullscreen_apply(game);
|
||||
game.renderer.vsync_set(isVsync);
|
||||
game.audio.gain_set(isMuted ? 0 : volume);
|
||||
if (game.match.state == MATCH_PRACTICE)
|
||||
if (game.sim.match.state == MATCH_PRACTICE)
|
||||
game.input.edit_send(game.devices[game.local],
|
||||
edit_encode({.type = EDIT_SLOTS, .index = weaponSlots, .value = trinketSlots}));
|
||||
isDirty = true;
|
||||
@@ -664,7 +664,7 @@ void Settings::restore(Game& game)
|
||||
Vec2 centre = {sandbox.feet.x, sandbox.feet.y - box.h / 2 - 1};
|
||||
for (float y = -box.h / 2; y <= box.h / 2; y += CLEAR_PROBE)
|
||||
for (float x = -box.w / 2; x <= box.w / 2; x += CLEAR_PROBE)
|
||||
if (game.world.is_blocking_at({centre.x + x, centre.y + y}))
|
||||
if (game.sim.world.is_blocking_at({centre.x + x, centre.y + y}))
|
||||
return;
|
||||
fighter.teleport_to(centre);
|
||||
}
|
||||
@@ -673,8 +673,8 @@ void Settings::restore(Game& game)
|
||||
// match starts from it.
|
||||
void Settings::update(Game& game)
|
||||
{
|
||||
bool isPractice = game.match.state == MATCH_PRACTICE;
|
||||
isDirty |= !(game.match.rules == savedRules) || (wasPractice && !isPractice);
|
||||
bool isPractice = game.sim.match.state == MATCH_PRACTICE;
|
||||
isDirty |= !(game.sim.match.rules == savedRules) || (wasPractice && !isPractice);
|
||||
#ifdef __EMSCRIPTEN__
|
||||
// A browser tab can close at any moment without a quit, so the sandbox is saved every so often there.
|
||||
Uint64 now = SDL_GetTicks();
|
||||
|
||||
Reference in new issue
Block a user