sdl_runtime_compiler git · main
SDL3 game for running and compiling code at runtime
C++ 72.3% C 26.2%git clone https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler.gitwget https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler/archive/sdl_runtime_compiler.tar.gzsrc/systems/pult_system.cpp raw
#include "entities/camera.hpp"
#include "entities/player.hpp"
#include "pult_system.hpp"
#include "rendering/gl_renderer.hpp"
#include "systems/physics_system.hpp"
#include "wall/label.hpp"
#include "wall/wall.hpp"
namespace
Nimbin
{
void
PultSystem::init(DynArray<GameObjectPtr>& scenery,
DynArray<PultButton*>& buttons_out,
float world_scale)
{
const float floor_y = -world_scale;
const float pult_y = floor_y + Pult::H;
const double inset = 3.0;
const float btn_dy = Pult::H + 0.10f + 0.04f;
const float lane_1 = -5.5f;
const float lane_2 = 8.5f;
const float lane_3 = 5.5f;
auto make_pult_pos = [&](Wall::Role role, float along) -> Vec3
{
const Wall::Transform wall = Wall::get_Transform(role, world_scale);
switch (wall.wall_position) {
case Wall::Position::PosX: return { wall.position.x - inset, pult_y, along };
case Wall::Position::NegX: return { wall.position.x + inset, pult_y, along };
case Wall::Position::PosZ: return { along, pult_y, wall.position.z - inset };
case Wall::Position::NegZ:
default: return { along, pult_y, wall.position.z + inset };
}
};
auto spawn_pult = [&](const std::string& name,
Wall::Role role, float along) -> Pult*
{
auto owned = cpputils::make_unique<Pult>(name, make_pult_pos(role, along));
Pult* raw = owned.get();
_pults.push_back(raw);
scenery.push_back(std::move(owned));
return raw;
};
auto add_btn = [&](Pult* pult, const std::string& lbl,
PultAction act, float dx, float dz)
{
Vec3 bpos {
pult->pos.x + static_cast<double>(dx),
pult->pos.y + static_cast<double>(btn_dy),
pult->pos.z + static_cast<double>(dz)
};
auto owned = cpputils::make_unique<PultButton>(lbl, act, bpos);
PultButton* raw = owned.get();
buttons_out.push_back(raw);
pult->buttons.push_back(raw);
scenery.push_back(std::move(owned));
};
Pult* scroll = spawn_pult("Scroll", Wall::Role::Editor, lane_1);
add_btn(scroll, "UP", PultAction::ScrollEditorUp, 0.0f, -0.42f);
add_btn(scroll, "DOWN", PultAction::ScrollEditorDown, 0.0f, 0.42f);
Pult* clr = spawn_pult("Clear", Wall::Role::Editor, lane_2);
add_btn(clr, "CLEAR", PultAction::ClearEditor, 0.0f, 0.0f);
Pult* compile = spawn_pult("Compile", Wall::Role::Compiler, lane_3);
add_btn(compile, "BUILD", PultAction::Compile, 0.0f, 0.0f);
Pult* run = spawn_pult("Run", Wall::Role::Program, lane_2);
add_btn(run, "RUN", PultAction::RunProgram, 0.0f, 0.0f);
Pult* connp = spawn_pult("Connect", Wall::Role::Program, lane_3);
add_btn(connp, "CONN", PultAction::ConnectProgram, 0.0f, 0.0f);
_connect_program = connp;
Pult* conne = spawn_pult("Edit", Wall::Role::Editor, lane_3);
add_btn(conne, "EDIT", PultAction::ConnectEditor, 0.0f, 0.0f);
_connect_editor = conne;
}
std::optional<PultAction>
PultSystem::try_Activate(GameObject* obj, const DynArray<PultButton*>& buttons)
{
if (!obj) return std::nullopt;
for (PultButton* btn : buttons) {
if (btn == obj) {
btn->press();
return btn->action;
}
}
return std::nullopt;
}
std::optional<PultAction>
PultSystem::handle_ProjectileContact(const ProjectileContactEvent& ev,
const DynArray<PultButton*>& buttons)
{
if (!ev.other) return std::nullopt;
for (PultButton* btn : buttons) {
if (!btn->pressed && btn == ev.other) {
btn->press();
return btn->action;
}
}
return std::nullopt;
}
static bool
player_OnButton(const Player& p, const PultButton& b)
{
constexpr double TOL = 0.10;
const double hx = b.shape.half_extents.x;
const double hy = b.shape.half_extents.y;
const double hz = b.shape.half_extents.z;
if (std::fabs(p.pos.x - b.pos.x) > hx + TOL) return false;
if (std::fabs(p.pos.z - b.pos.z) > hz + TOL) return false;
const double dy = p.pos.y - (b.pos.y + hy);
return dy >= -0.10 && dy <= 1.8;
}
std::optional<PultAction>
PultSystem::handle_PlayerContact(const Player& player, const DynArray<PultButton*>& buttons)
{
std::optional<PultAction> fired;
for (PultButton* btn : buttons) {
const bool over = player_OnButton(player, *btn);
if (over && !btn->player_on) {
btn->press();
if (!fired) fired = btn->action;
}
btn->player_on = over;
}
return fired;
}
void
PultSystem::update(double dt, const Camera& camera)
{
for (Pult* p : _pults) {
p->tick(dt);
p->label.update(dt, camera);
}
}
void
PultSystem::draw_Labels(GlRenderer& gl, const Camera& camera, const Light& light) const
{
for (const Pult* p : _pults)
p->label.draw(gl, camera, light);
}
DynArray<Text::Handler*>
PultSystem::get_Labels() const
{
DynArray<Text::Handler*> out;
out.reserve(_pults.size());
for (Pult* p : _pults) out.push_back(&p->label);
return out;
}
Vec3
PultSystem::get_ConnectProgramPos() const
{
return _connect_program ? _connect_program->pos : Vec3{};
}
Vec3
PultSystem::get_ConnectEditorPos() const
{
return _connect_editor ? _connect_editor->pos : Vec3{};
}
} // namespace Nimbin