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:
shweetandClaude Opus 5.5 committed 2026-11-08 01:46:07 -05:00
1 parent 2007fb7edc
commit 465f75f6d7
38 files changed
+2225 -1965

No files matched your search

+23 -23
View File
@@ -1,12 +1,16 @@
#pragma once
#include "anm2.h"
#include "input.h"
#include "renderer.h"
#include "trinket.h"
#include "world.h"
constexpr float CRAWL_STRIDE = 5;
constexpr float ROLL_RADIUS = 10;
constexpr float STEP_SPEED = 40;
constexpr float WALK_STRIDE = 7;
struct Attack;
struct Sim;
constexpr int ECHO_MAX = 64;
constexpr int MAX_FIGHTERS = SPAWN_COUNT;
@@ -53,6 +57,8 @@ constexpr float ABSORB_KNOCK_SHARE = 2 / 3.0f;
// ground until it slows.
class Fighter
{
friend class Scene;
public:
Body body;
Controls controls;
@@ -90,19 +96,18 @@ public:
bool isPvp = false;
bool isSliding = false;
void init(Game& game, int number);
void state_reset(Game& game, float maxHealth);
void position_reset(Game& game);
void position_set(Game& game, Vec2 feet);
void init(Sim& sim, int number);
void state_reset(Sim& sim, float maxHealth);
void position_reset(Sim& sim);
void position_set(Sim& sim, Vec2 feet);
void slots_set(int weapons, int trinkets);
void damage_take(Game& game, Damage damage);
void update(Game& game);
void draw(Game& game);
void damage_take(Sim& sim, Damage damage);
void update(Sim& sim);
void blend(float alpha);
void impulse_add(Vec2 impulse, bool isDamped = true);
void teleport_to(Vec2 centre);
void burst_add(Vec2 impulse);
void charge_cancel(Game& game);
void charge_cancel(Sim& sim);
int weapon_get();
int weapon_key(int weaponSlot);
int off_slot_get();
@@ -119,9 +124,6 @@ public:
float trinket_cooldown_get(int trinket);
float knock_absorb_get();
float pound_area_get();
const char* animation_get();
void animator_update(Animator& animator);
Pose pose_get(Game& game);
Vec2 center_get();
Vec2 hand_get();
Vec2 offhand_get();
@@ -130,9 +132,8 @@ public:
bool is_pressed(Control control);
bool is_released(Control control);
bool is_trinket_equipped(int trinket);
int wall_get(Game& game);
int wall_get(Sim& sim);
bool is_crawling();
bool is_flashing();
bool is_left();
private:
@@ -151,7 +152,6 @@ private:
float rollSpin = 0;
float tumble = 0;
float wallSpeed = 0;
int chargeVoice = -1;
int slideWall = 0;
Uint16 buttonsPrevious = 0;
bool isCharging = false;
@@ -159,15 +159,15 @@ private:
bool isFacingLeft = false;
bool isJumping = false;
void slot_update(Game& game);
void safe_update(Game& game);
void slot_update(Sim& sim);
void safe_update(Sim& sim);
void size_update();
void dash_update(Game& game, bool isJumpPressed);
void climb_update(Game& game);
void dash_update(Sim& sim, bool isJumpPressed);
void climb_update(Sim& sim);
Vec2 wall_point_get(int wall);
void wall_push(Game& game, int wall, Vec2 base);
void bounce_resolve(Game& game, Vec2 before);
void wall_push(Sim& sim, int wall, Vec2 base);
void bounce_resolve(Sim& sim, Vec2 before);
void run_update(Attack* hook);
void rope_update(Attack& hook);
void charge_update(Game& game);
void charge_update(Sim& sim);
};