1#ifndef ASTEROIDS3D_TYPES_HPP
2#define ASTEROIDS3D_TYPES_HPP
20#include <glm/ext/matrix_transform.hpp>
25 constexpr float PI = 3.14159265358979323846f;
64 inline std::default_random_engine &
rng() {
65 static thread_local std::default_random_engine engine{std::random_device{}()};
69 inline float random_float(
float min_value,
float max_value) {
70 std::uniform_real_distribution<float> dist(min_value, max_value);
74 inline int random_int(
int min_value,
int max_value) {
75 std::uniform_int_distribution<int> dist(min_value, max_value);
79 inline SDL_Surface *
load_color_keyed_png(
const std::string &path, std::uint8_t threshold = 12, std::uint8_t softness = 48) {
81 if (loaded_surface ==
nullptr) {
82 throw mxvk::Exception(
"Failed to load PNG: " + path);
85 SDL_Surface *surface = SDL_ConvertSurface(loaded_surface, SDL_PIXELFORMAT_RGBA32);
86 SDL_DestroySurface(loaded_surface);
87 if (surface ==
nullptr) {
88 throw mxvk::Exception(
"Failed to convert PNG to RGBA: " + path);
91 const SDL_PixelFormatDetails *format_details = SDL_GetPixelFormatDetails(surface->format);
92 if (format_details ==
nullptr) {
93 SDL_DestroySurface(surface);
94 throw mxvk::Exception(
"Failed to query pixel format details for: " + path);
97 if (!SDL_LockSurface(surface)) {
98 SDL_DestroySurface(surface);
99 throw mxvk::Exception(
"Failed to lock PNG surface: " + path);
102 auto *pixels =
static_cast<std::uint32_t *
>(surface->pixels);
103 const int pixel_count = surface->w * surface->h;
112 std::vector<KeyedPixel> keyed(
static_cast<std::size_t
>(pixel_count));
113 for (
int i = 0; i < pixel_count; ++i) {
118 SDL_GetRGBA(pixels[i], format_details,
nullptr, &r, &g, &b, &a);
119 const int brightness = std::max({
static_cast<int>(r),
static_cast<int>(g),
static_cast<int>(b)});
120 if (brightness <= threshold) {
121 keyed[
static_cast<std::size_t
>(i)] = {r, g, b, 0};
124 const int soft_end =
static_cast<int>(threshold) +
static_cast<int>(softness);
125 if (brightness < soft_end) {
126 const float t =
static_cast<float>(brightness - threshold) /
static_cast<float>(std::max<int>(1, softness));
127 a =
static_cast<std::uint8_t
>(std::clamp(
static_cast<int>(std::lround(
static_cast<float>(a) * t)), 0, 255));
129 keyed[
static_cast<std::size_t
>(i)] = {r, g, b, a};
132 constexpr int COLOR_BLEED_PASSES = 5;
133 for (
int pass = 0; pass < COLOR_BLEED_PASSES; ++pass) {
134 std::vector<KeyedPixel> next = keyed;
135 for (
int y = 0; y < surface->h; ++y) {
136 for (
int x = 0; x < surface->w; ++x) {
137 const int index = y * surface->w + x;
138 if (keyed[
static_cast<std::size_t
>(index)].a != 0) {
146 for (
int oy = -1; oy <= 1; ++oy) {
147 for (
int ox = -1; ox <= 1; ++ox) {
148 if (ox == 0 && oy == 0) {
151 const int nx = x + ox;
152 const int ny = y + oy;
153 if (nx < 0 || ny < 0 || nx >= surface->w || ny >= surface->h) {
156 const KeyedPixel &neighbor = keyed[
static_cast<std::size_t
>(ny * surface->w + nx)];
157 if (neighbor.a == 0) {
167 KeyedPixel &out = next[
static_cast<std::size_t
>(index)];
168 out.r =
static_cast<std::uint8_t
>(red / count);
169 out.g =
static_cast<std::uint8_t
>(green / count);
170 out.b =
static_cast<std::uint8_t
>(blue / count);
174 keyed = std::move(next);
177 for (
int i = 0; i < pixel_count; ++i) {
178 const KeyedPixel &px = keyed[
static_cast<std::size_t
>(i)];
179 pixels[i] = SDL_MapRGBA(format_details,
nullptr, px.r, px.g, px.b, px.a);
182 SDL_UnlockSurface(surface);
187 const float len = glm::length(value);
189 return glm::vec3(0.0f, 0.0f, -1.0f);
195 const glm::vec3 &rotation_degrees,
197 const glm::vec3 ¢er_offset) {
198 glm::mat4 model(1.0f);
199 model = glm::translate(model, position);
200 model = glm::rotate(model, glm::radians(rotation_degrees.y), glm::vec3(0.0f, 1.0f, 0.0f));
201 model = glm::rotate(model, glm::radians(rotation_degrees.x), glm::vec3(1.0f, 0.0f, 0.0f));
202 model = glm::rotate(model, glm::radians(rotation_degrees.z), glm::vec3(0.0f, 0.0f, 1.0f));
203 model = glm::scale(model, glm::vec3(scale));
204 model = glm::translate(model, center_offset);
212 glm::vec4
color{1.0f, 0.58f, 0.12f, 1.0f};
236 glm::vec4
color{1.0f};
258 glm::vec4
color{1.0f};
PNG image loading and saving utilities via SDL3.
SDL_Surface * LoadPNG(const char *file)
Load a PNG file into an SDL_Surface.
GameMode
High-level state of the Asteroids application.
@ Loading
Asset-loading screen.
@ Intro
Introductory screen.
@ GameComplete
Completed game.
@ GameOver
Player has no remaining lives.
@ Playing
Active gameplay.
glm::vec3 normalize_or_zero(const glm::vec3 &value)
Normalizes a direction with a stable fallback.
constexpr float ROUND_TIME_LIMIT_SECONDS
Multiplayer round limit in seconds.
glm::mat4 build_model_matrix(const glm::vec3 &position, const glm::vec3 &rotation_degrees, float scale, const glm::vec3 ¢er_offset)
Builds a translated, rotated, scaled model matrix.
int random_int(int min_value, int max_value)
Generates a uniformly distributed integer.
std::default_random_engine & rng()
Returns the thread-local random number engine used by simulation helpers.
constexpr int SMALL_ASTEROID_POINTS
Score awarded for a small asteroid.
constexpr int FIRE_COOLDOWN
Frames between firing bursts.
constexpr float BOUNDARY_X_MAX
Maximum simulation x-coordinate.
constexpr int MAX_GENERATIONS
Maximum asteroid split generation.
constexpr int CHILDREN_PER_SPAWN
Child asteroids created by a split.
SDL_Surface * load_color_keyed_png(const std::string &path, std::uint8_t threshold=12, std::uint8_t softness=48)
Loads a PNG and fades dark color-key pixels to transparency.
constexpr float ASTEROID_PROJECTILE_COLLISION_SCALE
Projectile collision-radius adjustment.
constexpr int MAX_PROJECTILES
Maximum locally simulated projectiles.
constexpr float BOUNDARY_Y_MAX
Maximum simulation y-coordinate.
constexpr int MAX_ASTEROIDS
Maximum locally simulated asteroids.
constexpr int MAX_PARTICLES
Maximum particles in the shared particle pool.
constexpr float BOUNDARY_Y_MIN
Minimum simulation y-coordinate.
constexpr float ASTEROID_SHIP_COLLISION_SCALE
Ship collision-radius adjustment.
constexpr glm::vec4 PROJECTILE_COLOR
Default projectile color.
constexpr int SHOTS_PER_BURST
Projectiles fired in one burst.
constexpr int EXPLOSION_DURATION_FRAMES
Ship explosion duration in frames.
constexpr int FIRE_DELAY
Frames between shots within a burst.
constexpr float BOUNDARY_X_MIN
Minimum simulation x-coordinate.
constexpr int LARGE_ASTEROID_POINTS
Score awarded for a large asteroid.
constexpr float BOUNDARY_BOUNCE_FACTOR
Boundary collision response multiplier.
constexpr float PROJECTILE_SPEED
Projectile travel speed in world units per second.
constexpr float BOUNDARY_Z_MIN
Minimum simulation z-coordinate.
constexpr int MEDIUM_ASTEROID_POINTS
Score awarded for a medium asteroid.
constexpr float PI
Single-precision value of pi.
constexpr float SHIP_MODEL_SCALE
Uniform ship model scale.
constexpr float PROJECTILE_LIFETIME
Projectile lifetime in seconds.
constexpr Sint16 CONTROLLER_DEAD_ZONE
Controller axis dead-zone magnitude.
constexpr float CONTROLLER_AXIS_MAX
Maximum signed controller axis magnitude.
float random_float(float min_value, float max_value)
Generates a uniformly distributed floating-point value.
constexpr int GAME_STARS
Number of stars in the background field.
constexpr float BOUNDARY_Z_MAX
Maximum simulation z-coordinate.
Runtime state for an asteroid.
bool active
Whether this slot is active.
glm::vec3 rotation_speed
Angular velocity in degrees per second.
int model_index
Asteroid model variant.
glm::vec3 rotation
Euler rotation in degrees.
glm::vec3 velocity
World-space velocity.
float radius
Collision radius.
int generation
Split generation used to determine size and scoring.
glm::vec3 position
Current world-space position.
Push-constant payload for the engine-flame shaders.
glm::vec4 params
Shader-specific animation parameters.
glm::mat4 mvp
Model-view-projection matrix.
Vertex consumed by the procedural engine-flame pipeline.
glm::vec4 color
Vertex color.
glm::vec3 pos
Vertex position.
Runtime state for an explosion or engine particle.
float max_lifetime
Initial lifetime in seconds.
bool color_flash
Whether the particle flashes as it ages.
bool active
Whether this slot is active.
glm::vec3 position
Current world-space position.
float lifetime
Remaining lifetime in seconds.
float size
Rendered point size.
glm::vec3 velocity
World-space velocity.
glm::vec4 color
Render color.
Runtime state for a ship projectile.
bool active
Whether this slot is active.
glm::vec3 position
Current world-space position.
glm::vec3 velocity
World-space velocity.
float lifetime
Remaining lifetime in seconds.
glm::vec3 prev_position
Position from the previous simulation step.
glm::vec4 color
Render color.
One spherical sample used by the compound ship collision shape.
float radius
Sample sphere radius.
glm::vec3 local_position
Sample center in ship-local space.
Runtime state for one animated background star.
glm::vec3 position
World-space position.
glm::vec4 base_color
Color before brightness modulation.
float brightness
Base brightness multiplier.
float twinkle_phase
Twinkle animation phase.
glm::vec3 velocity
World-space velocity.
float size
Rendered point size.
int layer
Parallax layer index.
glm::vec4 color
Current rendered color.
float twinkle_speed
Twinkle animation rate.