145 lines
3.1 KiB
C
145 lines
3.1 KiB
C
#include <gfx.h>
|
|
#include <gfx/port.h>
|
|
#include <header.h>
|
|
#include <sdl-1.2/gfx_private.h>
|
|
#include <SDL.h>
|
|
#include <SDL_rotozoom.h>
|
|
#include <errno.h>
|
|
#include <stddef.h>
|
|
#include <stdlib.h>
|
|
|
|
void sprite_free(struct sprite *const s)
|
|
{
|
|
if (s && s->s)
|
|
SDL_FreeSurface(s->s);
|
|
}
|
|
|
|
int sprite_clone(const struct sprite *const src, struct sprite *const dst)
|
|
{
|
|
*dst = *src;
|
|
return 0;
|
|
}
|
|
|
|
static int set_transparent(SDL_Surface *const s)
|
|
{
|
|
/* Magenta as transparent. */
|
|
const Uint32 map = SDL_MapRGB(s->format, 255, 0, 255);
|
|
const int ret = SDL_SetColorKey(s, SDL_SRCCOLORKEY | SDL_RLEACCEL, map);
|
|
|
|
if (ret)
|
|
fprintf(stderr, "SDL_SetColorKey: %s\n", SDL_GetError());
|
|
|
|
return ret;
|
|
}
|
|
|
|
int sprite_screen_resize_ev(struct sprite *const s)
|
|
{
|
|
int ret = -1;
|
|
SDL_Surface *const old = s->s, *const old_x = s->s_x;
|
|
|
|
/* Magenta as transparent. */
|
|
if (s->transparent && (set_transparent(old) || set_transparent(old_x)))
|
|
goto end;
|
|
else if (!(s->s = SDL_DisplayFormat(old)))
|
|
{
|
|
fprintf(stderr, "SDL_DisplayFormat: %s\n", SDL_GetError());
|
|
goto end;
|
|
}
|
|
else if (!(s->s_x = SDL_DisplayFormat(old_x)))
|
|
{
|
|
fprintf(stderr, "SDL_DisplayFormat: %s\n", SDL_GetError());
|
|
goto end;
|
|
}
|
|
|
|
ret = 0;
|
|
|
|
end:
|
|
SDL_FreeSurface(old);
|
|
SDL_FreeSurface(old_x);
|
|
return ret;
|
|
}
|
|
|
|
static int load_header(struct sprite *const s, FILE *const f)
|
|
{
|
|
if (header_load_bool(f, "transparent", &s->transparent))
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int load_bitmap(struct sprite *const s, FILE *const f)
|
|
{
|
|
int ret = -1;
|
|
SDL_RWops *ops = NULL;
|
|
SDL_Surface *ts = NULL, *zs = NULL;
|
|
|
|
if (!(ops = SDL_RWFromFP(f, 0)))
|
|
{
|
|
fprintf(stderr, "SDL_RWFromFP: %s\n", SDL_GetError());
|
|
goto end;
|
|
}
|
|
else if (!(ts = SDL_LoadBMP_RW(ops, 0)))
|
|
{
|
|
fprintf(stderr, "SDL_LoadBMP_RW: %s\n", SDL_GetError());
|
|
goto end;
|
|
}
|
|
else if (!(zs = zoomSurface(ts, -1, 1, 0)))
|
|
{
|
|
fprintf(stderr, "zoomSurface: %s\n", SDL_GetError());
|
|
goto end;
|
|
}
|
|
else if (s->transparent && (set_transparent(ts) || set_transparent(zs)))
|
|
goto end;
|
|
else if (!(s->s = SDL_DisplayFormat(ts)))
|
|
{
|
|
fprintf(stderr, "SDL_DisplayFormat: %s\n", SDL_GetError());
|
|
goto end;
|
|
}
|
|
else if (!(s->s_x = SDL_DisplayFormat(zs)))
|
|
{
|
|
fprintf(stderr, "SDL_DisplayFormat: %s\n", SDL_GetError());
|
|
goto end;
|
|
}
|
|
|
|
gfx_register_sprite(s);
|
|
s->w = ts->w;
|
|
s->h = ts->h;
|
|
ret = 0;
|
|
|
|
end:
|
|
SDL_FreeRW(ops);
|
|
SDL_FreeSurface(ts);
|
|
SDL_FreeSurface(zs);
|
|
return ret;
|
|
}
|
|
|
|
int sprite_from_fp(struct sprite *const s, FILE *const f)
|
|
{
|
|
*s = (const struct sprite){0};
|
|
|
|
if (load_header(s, f) || load_bitmap(s, f))
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void sprite_sort(struct sprite *const s)
|
|
{
|
|
SDL_Rect r =
|
|
{
|
|
.x = s->x,
|
|
.y = s->y
|
|
};
|
|
|
|
SDL_Rect clip =
|
|
{
|
|
.x = s->u,
|
|
.y = s->v,
|
|
.w = s->w,
|
|
.h = s->h
|
|
};
|
|
|
|
if (SDL_BlitSurface(s->s, &clip, gfx_screen(), &r))
|
|
fprintf(stderr, "SDL_BlitSurface: %s\n", SDL_GetError());
|
|
}
|