1#ifndef ASTEROIDS3D_TYPES_HPP
2#define ASTEROIDS3D_TYPES_HPP
25#include <glm/ext/matrix_transform.hpp>
33 constexpr float PI = 3.14159265358979323846f;
77 inline std::default_random_engine &
rng() {
78 static thread_local std::default_random_engine engine{std::random_device{}()};
89 std::uniform_real_distribution<float> dist(min_value, max_value);
100 std::uniform_int_distribution<int> dist(min_value, max_value);
112 inline SDL_Surface *
load_color_keyed_png(
const std::string &path, std::uint8_t threshold = 12, std::uint8_t softness = 48) {
114 if (loaded_surface ==
nullptr) {
118 SDL_Surface *
surface = SDL_ConvertSurface(loaded_surface, SDL_PIXELFORMAT_RGBA32);
119 SDL_DestroySurface(loaded_surface);
124 const SDL_PixelFormatDetails *format_details = SDL_GetPixelFormatDetails(
surface->format);
125 if (format_details ==
nullptr) {
127 throw mxvk::Exception(
"Failed to query pixel format details for: " + path);
130 if (!SDL_LockSurface(
surface)) {
135 auto *pixels =
static_cast<std::uint32_t *
>(
surface->pixels);
145 std::vector<KeyedPixel> keyed(
static_cast<std::size_t
>(pixel_count));
146 for (
int i = 0; i < pixel_count; ++i) {
151 SDL_GetRGBA(pixels[i], format_details,
nullptr, &r, &g, &b, &a);
152 const int brightness = std::max({
static_cast<int>(r),
static_cast<int>(g),
static_cast<int>(b)});
153 if (brightness <= threshold) {
154 keyed[
static_cast<std::size_t
>(i)] = {r, g, b, 0};
157 const int soft_end =
static_cast<int>(threshold) +
static_cast<int>(softness);
158 if (brightness < soft_end) {
159 const float t =
static_cast<float>(brightness - threshold) /
static_cast<float>(std::max<int>(1, softness));
160 a =
static_cast<std::uint8_t
>(std::clamp(
static_cast<int>(std::lround(
static_cast<float>(a) * t)), 0, 255));
162 keyed[
static_cast<std::size_t
>(i)] = {r, g, b, a};
165 constexpr int COLOR_BLEED_PASSES = 5;
166 for (
int pass = 0; pass < COLOR_BLEED_PASSES; ++pass) {
167 std::vector<KeyedPixel> next = keyed;
168 for (
int y = 0; y <
surface->h; ++y) {
169 for (
int x = 0; x <
surface->w; ++x) {
170 const int index = y *
surface->w + x;
171 if (keyed[
static_cast<std::size_t
>(index)].a != 0) {
179 for (
int oy = -1; oy <= 1; ++oy) {
180 for (
int ox = -1; ox <= 1; ++ox) {
181 if (ox == 0 && oy == 0) {
184 const int nx = x + ox;
185 const int ny = y + oy;
189 const KeyedPixel &neighbor = keyed[
static_cast<std::size_t
>(ny *
surface->w + nx)];
190 if (neighbor.a == 0) {
200 KeyedPixel &out = next[
static_cast<std::size_t
>(index)];
201 out.r =
static_cast<std::uint8_t
>(red / count);
202 out.g =
static_cast<std::uint8_t
>(green / count);
203 out.b =
static_cast<std::uint8_t
>(blue / count);
207 keyed = std::move(next);
210 for (
int i = 0; i < pixel_count; ++i) {
211 const KeyedPixel &px = keyed[
static_cast<std::size_t
>(i)];
212 pixels[i] = SDL_MapRGBA(format_details,
nullptr, px.r, px.g, px.b, px.a);
225 const float len = glm::length(value);
227 return glm::vec3(0.0f, 0.0f, -1.0f);
241 const glm::vec3 &rotation_degrees,
243 const glm::vec3 ¢er_offset) {
244 glm::mat4 model(1.0f);
245 model = glm::translate(model, position);
246 model = glm::rotate(model, glm::radians(rotation_degrees.y), glm::vec3(0.0f, 1.0f, 0.0f));
247 model = glm::rotate(model, glm::radians(rotation_degrees.x), glm::vec3(1.0f, 0.0f, 0.0f));
248 model = glm::rotate(model, glm::radians(rotation_degrees.z), glm::vec3(0.0f, 0.0f, 1.0f));
249 model = glm::scale(model, glm::vec3(scale));
250 model = glm::translate(model, center_offset);
259 glm::vec4
color{1.0f, 0.58f, 0.12f, 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.
@ Lobby
Multiplayer lobby.
@ Loading
Asset-loading screen.
@ Intro
Introductory screen.
@ GameComplete
Completed game.
@ GameOver
Player has no remaining lives.
@ MatchOver
Completed multiplayer round.
@ 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.