95 lines
2.0 KiB
C
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;
|
|
}
|