Skip to content

Instantly share code, notes, and snippets.

@Theldus
Last active October 9, 2024 16:23
Show Gist options
  • Save Theldus/10614722638269fdd0491230ca416f3f to your computer and use it in GitHub Desktop.
Save Theldus/10614722638269fdd0491230ca416f3f to your computer and use it in GitHub Desktop.
Star trails in C+SDL2 (inspired by @rlaneth's code in https://startrail.rlaneth.com/)
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <inttypes.h>
#include <SDL.h>
/*
* Tuto nice:
* https://lazyfoo.net/tutorials/SDL/index.php
*/
/*
* Build instructions:
*
* gcc sdl.c -o star -O3 `pkg-config --cflags --libs sdl2`
*/
typedef uint8_t u8;
#define WIDTH 1920
#define HEIGHT 1080
#define PI 3.141592653589793
static int centerX, centerY;
static u8 *buff;
#define MAX_STARS 100
static SDL_Window* window;
static SDL_Renderer* renderer;
static int screen_width = WIDTH;
static int screen_height = HEIGHT;
static int IsWindowResized = 1;
int min_w_h;
struct star {
double x;
double y;
double size;
double speed;
double angle;
} stars[MAX_STARS];
static void resize(int width, int height) {
if (width > 599) {
centerY = height - 250;
centerX = width - 250;
} else {
centerY = height;
centerX = width / 2;
}
if (width <= height)
min_w_h = width;
else
min_w_h = height;
}
static void create_stars(void) {
for (int i = 0; i < MAX_STARS; i++) {
double radius = drand48() * (double)min_w_h;
double angle = drand48() * PI * 2.0;
stars[i].x = (double)centerX + SDL_cos(angle) * radius;
stars[i].y = (double)centerY + SDL_sin(angle) * radius;
stars[i].size = 2;
stars[i].speed = (drand48() * 0.0002) + 0.0002;
stars[i].angle = angle;
}
}
void drawcircle(int centerX, int centerY, int radius)
{
int x = radius - 1;
int y = 0;
int dx = 1;
int dy = 1;
int err = dx - (radius * 2);
while (x >= y) {
SDL_RenderDrawPoint(renderer, centerX + x, centerY + y);
SDL_RenderDrawPoint(renderer, centerX + y, centerY + x);
SDL_RenderDrawPoint(renderer, centerX - y, centerY + x);
SDL_RenderDrawPoint(renderer, centerX - x, centerY + y);
SDL_RenderDrawPoint(renderer, centerX - x, centerY - y);
SDL_RenderDrawPoint(renderer, centerX - y, centerY - x);
SDL_RenderDrawPoint(renderer, centerX + y, centerY - x);
SDL_RenderDrawPoint(renderer, centerX + x, centerY - y);
if (err <= 0) {
y++;
err += dy;
dy += 2;
}
if (err > 0) {
x--;
dx += 2;
err += dx - (radius * 2);
}
}
}
static void draw_stars(void) {
SDL_SetRenderDrawColor(renderer, 0,4,20, 12);
SDL_RenderFillRect(renderer,
&(SDL_Rect){
.x = 0, .y = 0,
.w = screen_width, .h = screen_height
}
);
SDL_SetRenderDrawColor(renderer, 255,255,255, 255);
for (int i = 0; i < MAX_STARS; i++)
drawcircle(stars[i].x, stars[i].y, 2);
}
static void update_stars(void) {
double radius;
for (int i = 0; i < MAX_STARS; i++) {
radius =
SDL_sqrt(
SDL_pow(stars[i].x - centerX, 2)
+
SDL_pow(stars[i].y - centerY, 2)
);
stars[i].angle += stars[i].speed;
stars[i].x = centerX + SDL_cos(stars[i].angle) * radius;
stars[i].y = centerY + SDL_sin(stars[i].angle) * radius;
}
}
static void animate(void) {
/* Check if resize. */
if (IsWindowResized) {
IsWindowResized = 0;
resize(screen_width, screen_height);
create_stars();
}
update_stars();
draw_stars();
/* Render everything. */
SDL_RenderPresent(renderer);
}
/**
* Main game loop.
*/
int main(void)
{
SDL_Event event;
srand48(time(NULL));
/* Initialize. */
if (SDL_Init(SDL_INIT_VIDEO) < 0)
errx(1, "SDL could not initialize!: %s\n", SDL_GetError());
window = SDL_CreateWindow("startrail",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
screen_width, screen_height,
SDL_WINDOW_SHOWN|SDL_WINDOW_RESIZABLE);
if (!window)
errx(1, "Unable to create Window, %s\n", SDL_GetError());
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC);
if (!renderer)
errx(1, "Unable to create Renderer, %s\n", SDL_GetError());
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
while (1)
{
while (SDL_PollEvent(&event) != 0)
{
if (event.type == SDL_QUIT)
goto quit;
else if (event.type == SDL_WINDOWEVENT &&
event.window.event == SDL_WINDOWEVENT_RESIZED)
{
IsWindowResized = 1;
screen_width = event.window.data1;
screen_height = event.window.data2;
}
}
animate();
}
quit:
if (renderer)
SDL_DestroyRenderer(renderer);
if (window)
SDL_DestroyWindow(window);
SDL_Quit();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment