Added drawScaledSpriteOutline function that (basically) draws an outline of the given sprite from the passed spritesheet. Although this function could later be used for drawing items/players behind tall objects, it is only used to outline the selected item while in the inventory screen at the moment. The function produces many warnings during compile, but they will be fixed later. Most of the draw*Sprite* functions should be combined - that is to say, drawScaledSprite and drawSprite should likely be the same function that chooses which spritesheet to use via a passed flag.

master
kts 2013-11-17 16:02:49 -08:00
parent 81b566f9c8
commit 7e7a4bd2fe
2 changed files with 49 additions and 0 deletions

View File

@ -371,6 +371,7 @@ void cameraDraw() {
break;
case PLAYER:
drawScaledSprite(&shadow_sprites, 0, camera_surface, (step_x*shadow_sprites.s_width)-camera_offset_x, (step_y*shadow_sprites.s_height/2)-camera_offset_y);
//drawScaledSpriteOutline(&player_sprites, current_tile->id, camera_surface, (step_x*player_sprites.s_width)-camera_offset_x, (step_y*player_sprites.s_height/2)-camera_offset_y);
drawScaledSprite(&player_sprites, current_tile->id, camera_surface, (step_x*player_sprites.s_width)-camera_offset_x, (step_y*player_sprites.s_height/2)-camera_offset_y);
break;
case ITEM:
@ -515,6 +516,7 @@ void interfaceDrawInventory() {
while (current_item) {
if (i == ((struct PlayerTile*)player->data)->inventory.selected) {
drawScaledSprite(&item_sprites, current_item->id, new_surface, i*item_sprites.s_width, 0);
drawScaledSpriteOutline(&item_sprites, current_item->id, new_surface, i*item_sprites.s_width, 0);
interfaceDrawStringF(&font_mini, new_surface, ((struct ItemTile*)current_item->data)->name, inventory_width/2-(strlen(((struct ItemTile*)current_item->data)->name)*font_mini.width*font_mini.scale_x/2), inventory_height - (font_mini.height*font_mini.scale_y));
} else {
drawScaledTransparentSprite(&item_sprites, current_item->id, 0.50f, new_surface, i*item_sprites.s_width, 0);
@ -960,6 +962,51 @@ void drawScaledTransparentSprite(struct Spritesheet *spritesheet, int id, double
//SDL_BlitSurface(spritesheet->s_spritesheet, &sprite_offset, target_surface, &render_position);
}
void drawScaledSpriteOutline(struct Spritesheet *spritesheet, int id, SDL_Surface *target_surface, int start_x, int start_y) {
int y_offset = id / spritesheet->columns;
int x_offset = id - (y_offset * spritesheet->columns);
SDL_Rect sprite_offset = { x_offset*spritesheet->s_width, y_offset*spritesheet->s_height, spritesheet->s_width, spritesheet->s_height};
SDL_Rect render_position = {start_x, start_y, spritesheet->s_width, spritesheet->s_height};
SDL_Surface *temp_sprite = SDL_CreateRGBSurface(spritesheet->spritesheet->flags, spritesheet->s_width, spritesheet->s_height, spritesheet->spritesheet->format->BitsPerPixel, spritesheet->s_spritesheet->format->Rmask, spritesheet->s_spritesheet->format->Gmask, spritesheet->s_spritesheet->format->Bmask, spritesheet->s_spritesheet->format->Amask);
int x = 0;
int y = 0;
SDL_LockSurface(temp_sprite);
SDL_LockSurface(spritesheet->s_spritesheet);
int bpp = spritesheet->s_spritesheet->format->BytesPerPixel;
for (y = 0;y < spritesheet->s_height;y++) {
for (x = 0;x < spritesheet->s_width;x++) {
// TODO: optimize!
Uint32 *p_l = getpixel(spritesheet->s_spritesheet, sprite_offset.x+x-1, sprite_offset.y+y);
Uint32 *p_u = getpixel(spritesheet->s_spritesheet, sprite_offset.x+x, sprite_offset.y+y-1);
Uint32 *p_r = getpixel(spritesheet->s_spritesheet, sprite_offset.x+x+1, sprite_offset.y+y);
Uint32 *p_d = getpixel(spritesheet->s_spritesheet, sprite_offset.x+x, sprite_offset.y+y+1);
// It's endian-ambiguous!
Uint32 p_o = 0xFFFFFFFF;
Uint8 *val = 128; // pixels under 128 opacity are considered empty
if ((Uint8 *)&p_l[3] < val && (Uint8 *)&p_u[3] < val && (Uint8*)&p_d[3] < val && (Uint8*)&p_r[3] > val) {
putpixel(temp_sprite, x, y, p_o);
}
if ((Uint8 *)&p_l[3] > val && (Uint8 *)&p_u[3] < val && (Uint8*)&p_d[3] < val && (Uint8*)&p_r[3] < val) {
putpixel(temp_sprite, x, y, p_o);
}
if ((Uint8 *)&p_l[3] < val && (Uint8 *)&p_u[3] > val && (Uint8*)&p_d[3] < val && (Uint8*)&p_r[3] < val) {
putpixel(temp_sprite, x, y, p_o);
}
if ((Uint8 *)&p_l[3] < val && (Uint8 *)&p_u[3] < val && (Uint8*)&p_d[3] > val && (Uint8*)&p_r[3] < val) {
putpixel(temp_sprite, x, y, p_o);
}
}
}
SDL_UnlockSurface(spritesheet->s_spritesheet);
SDL_UnlockSurface(temp_sprite);
SDL_BlitSurface(temp_sprite, NULL, target_surface, &render_position);
}
void interfaceQuit() {
SDL_Event event;
event.type = SDL_QUIT;

View File

@ -71,9 +71,11 @@ void interfaceSetScale(float scale_x, float scale_y);
void loadSpritesheetFromMemory(struct Spritesheet *spritesheet, unsigned char *memory, unsigned int length, int width, int height, int columns);
void freeSpritesheet(struct Spritesheet *spritesheet);
void setSpritesheetScale(struct Spritesheet *spritesheet, float scale_x, float scale_y);
// TODO: drawSprite/drawScaledSprite should probably be the same function that uses a flag to use either the scaled or non-scaled surface
void drawSprite(struct Spritesheet *spritesheet, int id, SDL_Surface *target_surface, int start_x, int start_y);
void drawScaledSprite(struct Spritesheet *spritesheet, int id, SDL_Surface *target_surface, int start_x, int start_y);
void drawScaledTransparentSprite(struct Spritesheet *spritesheet, int id, double opacity, SDL_Surface *target_surface, int start_x, int start_y);
void drawScaledSpriteOutline(struct Spritesheet *spritesheet, int id, SDL_Surface *target_surface, int start_x, int start_y);
/* --- core drawing stuff --- */
void interfaceDrawString(SDL_Surface *to_surface, const char *string, int start_x, int start_y);