Files
librefront/src/common/world.c
T
2025-09-24 19:17:48 +02:00

95 lines
2.0 KiB
C

#include <common/world.h>
static inline Uint32
_surf_pixel (SDL_Surface *surface, int x, int y)
{
int bpp = SDL_BYTESPERPIXEL (surface->format);
Uint8 *p = (Uint8 *) surface->pixels + y * surface->pitch + x * bpp;
switch (bpp)
{
case 1:
return *p;
case 2:
return *(Uint16 *) p;
case 3:
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
{
return p[0] << 16 | p[1] << 8 | p[2];
}
else
{
return p[0] | p[1] << 8 | p[2] << 16;
}
case 4:
return *(Uint32 *) p;
default:
return 0; // shouldn't happen
}
}
World *
World_load_from_file (const char *path)
{
World *self = g_new0 (World, 1);
self->buildings = g_array_new (FALSE, FALSE, sizeof (Building *));
SDL_Surface *surf = IMG_Load (path);
if (!surf)
{
g_warning ("Failed to load map from path %s (returning NULL): %s", path,
SDL_GetError ());
return NULL;
}
self->width = surf->w;
self->height = surf->h;
self->tiles =
g_array_sized_new (FALSE, FALSE, sizeof (MapTile *), surf->w * surf->h);
SDL_LockSurface (surf);
const SDL_PixelFormatDetails *details =
SDL_GetPixelFormatDetails (surf->format);
for (int y = 0; y < surf->h; ++y)
{
for (int x = 0; x < surf->w; ++x)
{
MapTile *mt = g_new0 (MapTile, 1);
mt->x = x;
mt->y = y;
Uint32 pixel = _surf_pixel (surf, x, y);
Uint8 r, g, b, a;
/* NULL is a palette, only used in indexed images. */
SDL_GetRGBA (pixel, details, NULL, &r, &g, &b, &a);
/* Improved color ranges (handles light blue water better) */
if (b > 120 && (b > g || b > r))
{
/* Water: medium-to-light blues */
mt->terrain_type = TERRAIN_WATER;
}
else if (g > 140 && g >= r && g >= b)
{
/* Green-dominant = flat/grassland */
mt->terrain_type = TERRAIN_FLAT;
}
else
{
/* Otherwise: hills/mountains */
mt->terrain_type = TERRAIN_HILL;
}
/* Thanks, ChatGPT! */
g_array_append_val (self->tiles, mt);
}
}
SDL_UnlockSurface (surf);
SDL_DestroySurface (surf);
return self;
}