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/wall/label.cpp raw
#include "entities/camera.hpp"
#include "rendering/gl_renderer.hpp"
#include "utils/config.hpp"
#include "wall/label.hpp"
#include "wall/wall.hpp"
namespace
Nimbin
{
// ── Label appearance ──────────────────────────────────────────────────────────
namespace {
static const char* label_Name(Wall::Role r)
{
switch (r) {
case Wall::Role::Program: return "Program";
case Wall::Role::Editor: return "Editor";
case Wall::Role::Info: return "Info";
case Wall::Role::Compiler: return "Compiler";
}
return "";
}
// Per-role tint — echoes the wall surface colors from wall_surfaces.cpp.
static SDL_FColor label_Color(Wall::Role r)
{
switch (r) {
case Wall::Role::Program: return Config::Color::program_label;
case Wall::Role::Editor: return Config::Color::editor_label;
case Wall::Role::Info: return Config::Color::info_label;
case Wall::Role::Compiler: return Config::Color::compiler_label;
}
return Config::Color::white;
}
} // namespace
// ── generate_All ─────────────────────────────────────────────────────────────
DynArray<Wall::Label>
Wall::Label::generate_All(float world_scale)
{
DynArray<Wall::Label> labels;
labels.reserve(4);
const float label_y = -world_scale * 0.48f;
// Pull slightly further from the wall so it floats in front of wall text.
const double extra_offset = 2.5f;
// Large scale so the name is readable from across the room.
// depth is Text::Token::depth_wall * 4 for chunky, visible letters.
const float label_scale = 0.012f;
const float label_depth = Text::Token::depth_wall * 4.0f;
for (uint8_t ri = 0; ri < 4; ++ri) {
Wall::Role role = static_cast<Wall::Role> (ri);
Wall::Position pos = Wall::position_Of (role);
Wall::Transform tf = Wall::get_Transform (role, world_scale);
Vec3 anch = tf.position;
anch.y = static_cast<double>(label_y);
switch (pos) {
case Wall::Position::PosX: anch.x -= extra_offset; break;
case Wall::Position::NegX: anch.x += extra_offset; break;
case Wall::Position::PosZ: anch.z -= extra_offset; break;
case Wall::Position::NegZ: anch.z += extra_offset; break;
}
Wall::Label wl;
wl.role = role;
wl.anchor = anch;
wl.face_yaw = tf.yaw;
wl.label.set_Style (label_Color(role), label_depth, label_scale);
wl.label.set_FaceCamera (false);
wl.label.set_FaceYaw (tf.yaw);
wl.label.set_Collidable (true);
wl.label.set_Centre (anch);
wl.label.set_Text (label_Name(role));
labels.push_back (std::move(wl));
}
return labels;
}
// ── on_Hit ───────────────────────────────────────────────────────────────────
void
Wall::Label::on_Hit(size_t word_index, const Vec3& projectile_vel)
{
const Vec3 normal = Wall::inward_Normal(Wall::position_Of(role));
label.kick(word_index, projectile_vel, normal);
}
// ── update ───────────────────────────────────────────────────────────────────
void
Wall::Label::update(double dt, const Camera& camera)
{
// Positions + jiggle spring first. In non-facecam mode Text::Handler::update
// forces every word's pitch to 0, so we must apply our eye-tilt AFTER it,
// not before — otherwise the tilt gets clobbered. Pitch doesn't affect the
// positions update() computes, so ordering it last is safe.
label.update(dt, camera);
// Tilt up/down toward the player's eye, clamped — identical to the
// editor wall text tilt in wall.hpp::tilt_TwardEye. Shared anchor pitch
// keeps the whole word reading as one rigid plane.
const float pitch = Wall::tilt_TwardEye(anchor, camera.pos);
for (const Text::TokenPtr& w : label.get_Words())
if (w) w->pitch = pitch;
}
// ── draw ─────────────────────────────────────────────────────────────────────
void
Wall::Label::draw(GlRenderer& gl, const Camera& camera, const Light& light) const
{
label.draw(gl, camera, light);
}
} // namespace Nimbin