mirror of https://github.com/OpenTTD/OpenTTD
(svn r11212) -Codechange: add support for drawing parts of sprites. Patch by frosch.
parent
bf35f3a21a
commit
6e7402a1c5
|
@ -132,7 +132,6 @@ bool ScrollWindowTo(int x, int y, Window *w, bool instant = false);
|
|||
|
||||
bool ScrollMainWindowToTile(TileIndex tile, bool instant = false);
|
||||
bool ScrollMainWindowTo(int x, int y, bool instant = false);
|
||||
void DrawSprite(SpriteID img, SpriteID pal, int x, int y);
|
||||
bool EnsureNoVehicle(TileIndex tile);
|
||||
bool EnsureNoVehicleOnGround(TileIndex tile);
|
||||
|
||||
|
|
33
src/gfx.cpp
33
src/gfx.cpp
|
@ -43,7 +43,7 @@ int _pal_count_dirty;
|
|||
Colour _cur_palette[256];
|
||||
byte _stringwidth_table[FS_END][224];
|
||||
|
||||
static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode);
|
||||
static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub = NULL);
|
||||
|
||||
FontSize _cur_fontsize;
|
||||
static FontSize _last_fontsize;
|
||||
|
@ -652,24 +652,33 @@ int DoDrawStringTruncated(const char *str, int x, int y, uint16 color, uint maxw
|
|||
return DoDrawString(buffer, x, y, color);
|
||||
}
|
||||
|
||||
void DrawSprite(SpriteID img, SpriteID pal, int x, int y)
|
||||
void DrawSprite(SpriteID img, SpriteID pal, int x, int y, const SubSprite *sub)
|
||||
{
|
||||
if (HASBIT(img, PALETTE_MODIFIER_TRANSPARENT)) {
|
||||
_color_remap_ptr = GetNonSprite(GB(pal, 0, PALETTE_WIDTH)) + 1;
|
||||
GfxMainBlitter(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y, BM_TRANSPARENT);
|
||||
GfxMainBlitter(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y, BM_TRANSPARENT, sub);
|
||||
} else if (pal != PAL_NONE) {
|
||||
_color_remap_ptr = GetNonSprite(GB(pal, 0, PALETTE_WIDTH)) + 1;
|
||||
GfxMainBlitter(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y, BM_COLOUR_REMAP);
|
||||
GfxMainBlitter(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y, BM_COLOUR_REMAP, sub);
|
||||
} else {
|
||||
GfxMainBlitter(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y, BM_NORMAL);
|
||||
GfxMainBlitter(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y, BM_NORMAL, sub);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode)
|
||||
static inline void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub)
|
||||
{
|
||||
const DrawPixelInfo *dpi = _cur_dpi;
|
||||
Blitter::BlitterParams bp;
|
||||
|
||||
/* Amount of pixels to clip from the source sprite */
|
||||
int clip_left = (sub != NULL ? max(0, -sprite->x_offs + sub->left ) : 0);
|
||||
int clip_top = (sub != NULL ? max(0, -sprite->y_offs + sub->top ) : 0);
|
||||
int clip_right = (sub != NULL ? max(0, sprite->width - (-sprite->x_offs + sub->right + 1)) : 0);
|
||||
int clip_bottom = (sub != NULL ? max(0, sprite->height - (-sprite->y_offs + sub->bottom + 1)) : 0);
|
||||
|
||||
if (clip_left + clip_right >= sprite->width) return;
|
||||
if (clip_top + clip_bottom >= sprite->height) return;
|
||||
|
||||
/* Move to the correct offset */
|
||||
x += sprite->x_offs;
|
||||
y += sprite->y_offs;
|
||||
|
@ -678,12 +687,16 @@ static inline void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMod
|
|||
bp.sprite = sprite->data;
|
||||
bp.sprite_width = sprite->width;
|
||||
bp.sprite_height = sprite->height;
|
||||
bp.width = UnScaleByZoom(sprite->width, dpi->zoom);
|
||||
bp.height = UnScaleByZoom(sprite->height, dpi->zoom);
|
||||
bp.width = UnScaleByZoom(sprite->width - clip_left - clip_right, dpi->zoom);
|
||||
bp.height = UnScaleByZoom(sprite->height - clip_top - clip_bottom, dpi->zoom);
|
||||
bp.top = 0;
|
||||
bp.left = 0;
|
||||
bp.skip_left = 0;
|
||||
bp.skip_top = 0;
|
||||
bp.skip_left = UnScaleByZoom(clip_left, dpi->zoom);
|
||||
bp.skip_top = UnScaleByZoom(clip_top, dpi->zoom);
|
||||
|
||||
x += ScaleByZoom(bp.skip_left, dpi->zoom);
|
||||
y += ScaleByZoom(bp.skip_top, dpi->zoom);
|
||||
|
||||
bp.dst = dpi->dst_ptr;
|
||||
bp.pitch = dpi->pitch;
|
||||
bp.remap = _color_remap_ptr;
|
||||
|
|
10
src/gfx.h
10
src/gfx.h
|
@ -242,6 +242,16 @@ DECLARE_POSTFIX_INCREMENT(FontSize);
|
|||
void RedrawScreenRect(int left, int top, int right, int bottom);
|
||||
void GfxScroll(int left, int top, int width, int height, int xo, int yo);
|
||||
|
||||
/**
|
||||
* Used to only draw a part of the sprite.
|
||||
* Draw the subsprite in the rect (sprite_x_offset + left, sprite_y_offset + top) to (sprite_x_offset + right, sprite_y_offset + bottom).
|
||||
* Both corners are included in the drawing area.
|
||||
*/
|
||||
struct SubSprite {
|
||||
int left, top, right, bottom;
|
||||
};
|
||||
|
||||
void DrawSprite(SpriteID img, SpriteID pal, int x, int y, const SubSprite *sub = NULL);
|
||||
|
||||
/* XXX doesn't really belong here, but the only
|
||||
* consumers always use it in conjunction with DoDrawString() */
|
||||
|
|
|
@ -66,6 +66,7 @@ struct StringSpriteToDraw {
|
|||
struct TileSpriteToDraw {
|
||||
SpriteID image;
|
||||
SpriteID pal;
|
||||
const SubSprite *sub; ///< only draw a rectangular part of the sprite
|
||||
TileSpriteToDraw *next;
|
||||
int32 x;
|
||||
int32 y;
|
||||
|
@ -75,6 +76,7 @@ struct TileSpriteToDraw {
|
|||
struct ChildScreenSpriteToDraw {
|
||||
SpriteID image;
|
||||
SpriteID pal;
|
||||
const SubSprite *sub; ///< only draw a rectangular part of the sprite
|
||||
int32 x;
|
||||
int32 y;
|
||||
ChildScreenSpriteToDraw *next;
|
||||
|
@ -83,6 +85,7 @@ struct ChildScreenSpriteToDraw {
|
|||
struct ParentSpriteToDraw {
|
||||
SpriteID image; ///< sprite to draw
|
||||
SpriteID pal; ///< palette to use
|
||||
const SubSprite *sub; ///< only draw a rectangular part of the sprite
|
||||
|
||||
int32 x; ///< screen X coordinate of sprite
|
||||
int32 y; ///< screen Y coordinate of sprite
|
||||
|
@ -428,7 +431,18 @@ void HandleZoomMessage(Window *w, const ViewPort *vp, byte widget_zoom_in, byte
|
|||
InvalidateWidget(w, widget_zoom_out);
|
||||
}
|
||||
|
||||
void DrawGroundSpriteAt(SpriteID image, SpriteID pal, int32 x, int32 y, byte z)
|
||||
/**
|
||||
* Draws a ground sprite at a specific world-coordinate.
|
||||
*
|
||||
* @param image the image to draw.
|
||||
* @param pal the provided palette.
|
||||
* @param x position x of the sprite.
|
||||
* @param y position y of the sprite.
|
||||
* @param z position z of the sprite.
|
||||
* @param sub Only draw a part of the sprite.
|
||||
*
|
||||
*/
|
||||
void DrawGroundSpriteAt(SpriteID image, SpriteID pal, int32 x, int32 y, byte z, const SubSprite *sub)
|
||||
{
|
||||
ViewportDrawer *vd = _cur_vd;
|
||||
TileSpriteToDraw *ts;
|
||||
|
@ -445,6 +459,7 @@ void DrawGroundSpriteAt(SpriteID image, SpriteID pal, int32 x, int32 y, byte z)
|
|||
|
||||
ts->image = image;
|
||||
ts->pal = pal;
|
||||
ts->sub = sub;
|
||||
ts->next = NULL;
|
||||
ts->x = x;
|
||||
ts->y = y;
|
||||
|
@ -453,14 +468,22 @@ void DrawGroundSpriteAt(SpriteID image, SpriteID pal, int32 x, int32 y, byte z)
|
|||
vd->last_tile = &ts->next;
|
||||
}
|
||||
|
||||
void DrawGroundSprite(SpriteID image, SpriteID pal)
|
||||
/**
|
||||
* Draws a ground sprite for the current tile.
|
||||
* If the current tile is drawn on top of a foundation the sprite is added as child sprite to the "foundation"-ParentSprite.
|
||||
*
|
||||
* @param image the image to draw.
|
||||
* @param pal the provided palette.
|
||||
* @param sub Only draw a part of the sprite.
|
||||
*/
|
||||
void DrawGroundSprite(SpriteID image, SpriteID pal, const SubSprite *sub)
|
||||
{
|
||||
if (_offset_ground_sprites) {
|
||||
/* offset ground sprite because of foundation? */
|
||||
AddChildSpriteScreen(image, pal, _cur_vd->offs_x, _cur_vd->offs_y);
|
||||
AddChildSpriteScreen(image, pal, _cur_vd->offs_x, _cur_vd->offs_y, false, sub);
|
||||
} else {
|
||||
_added_tile_sprite = true;
|
||||
DrawGroundSpriteAt(image, pal, _cur_ti->x, _cur_ti->y, _cur_ti->z);
|
||||
DrawGroundSpriteAt(image, pal, _cur_ti->x, _cur_ti->y, _cur_ti->z, sub);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -472,7 +495,18 @@ void OffsetGroundSprite(int x, int y)
|
|||
_offset_ground_sprites = true;
|
||||
}
|
||||
|
||||
static void AddCombinedSprite(SpriteID image, SpriteID pal, int x, int y, byte z)
|
||||
/**
|
||||
* Adds a child sprite to a parent sprite.
|
||||
* In contrast to "AddChildSpriteScreen()" the sprite position is in world coordinates
|
||||
*
|
||||
* @param image the image to draw.
|
||||
* @param pal the provided palette.
|
||||
* @param x position x of the sprite.
|
||||
* @param y position y of the sprite.
|
||||
* @param z position z of the sprite.
|
||||
* @param sub Only draw a part of the sprite.
|
||||
*/
|
||||
static void AddCombinedSprite(SpriteID image, SpriteID pal, int x, int y, byte z, const SubSprite *sub)
|
||||
{
|
||||
const ViewportDrawer *vd = _cur_vd;
|
||||
Point pt = RemapCoords(x, y, z);
|
||||
|
@ -484,7 +518,7 @@ static void AddCombinedSprite(SpriteID image, SpriteID pal, int x, int y, byte z
|
|||
pt.y + spr->y_offs + spr->height <= vd->dpi.top)
|
||||
return;
|
||||
|
||||
AddChildSpriteScreen(image, pal, pt.x - vd->parent_list[-1]->left, pt.y - vd->parent_list[-1]->top);
|
||||
AddChildSpriteScreen(image, pal, pt.x - vd->parent_list[-1]->left, pt.y - vd->parent_list[-1]->top, false, sub);
|
||||
}
|
||||
|
||||
/** Draw a (transparent) sprite at given coordinates with a given bounding box.
|
||||
|
@ -509,8 +543,9 @@ static void AddCombinedSprite(SpriteID image, SpriteID pal, int x, int y, byte z
|
|||
* @param bb_offset_x bounding box extent towards negative X (world),
|
||||
* @param bb_offset_y bounding box extent towards negative Y (world),
|
||||
* @param bb_offset_z bounding box extent towards negative Z (world)
|
||||
* @param sub Only draw a part of the sprite.
|
||||
*/
|
||||
void AddSortableSpriteToDraw(SpriteID image, SpriteID pal, int x, int y, int w, int h, int dz, int z, bool transparent, int bb_offset_x, int bb_offset_y, int bb_offset_z)
|
||||
void AddSortableSpriteToDraw(SpriteID image, SpriteID pal, int x, int y, int w, int h, int dz, int z, bool transparent, int bb_offset_x, int bb_offset_y, int bb_offset_z, const SubSprite *sub)
|
||||
{
|
||||
ViewportDrawer *vd = _cur_vd;
|
||||
ParentSpriteToDraw *ps;
|
||||
|
@ -526,7 +561,7 @@ void AddSortableSpriteToDraw(SpriteID image, SpriteID pal, int x, int y, int w,
|
|||
}
|
||||
|
||||
if (vd->combine_sprites == 2) {
|
||||
AddCombinedSprite(image, pal, x, y, z);
|
||||
AddCombinedSprite(image, pal, x, y, z, sub);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -585,6 +620,7 @@ void AddSortableSpriteToDraw(SpriteID image, SpriteID pal, int x, int y, int w,
|
|||
|
||||
ps->image = image;
|
||||
ps->pal = pal;
|
||||
ps->sub = sub;
|
||||
ps->xmin = x + bb_offset_x;
|
||||
ps->xmax = x + max(bb_offset_x, w) - 1;
|
||||
|
||||
|
@ -613,7 +649,17 @@ void EndSpriteCombine()
|
|||
_cur_vd->combine_sprites = 0;
|
||||
}
|
||||
|
||||
void AddChildSpriteScreen(SpriteID image, SpriteID pal, int x, int y, bool transparent)
|
||||
/**
|
||||
* Add a child sprite to a parent sprite.
|
||||
*
|
||||
* @param image the image to draw.
|
||||
* @param pal the provided palette.
|
||||
* @param x sprite x-offset (screen coordinates) relative to parent sprite.
|
||||
* @param y sprite y-offset (screen coordinates) relative to parent sprite.
|
||||
* @param transparent if true, switch the palette between the provided palette and the transparent palette,
|
||||
* @param sub Only draw a part of the sprite.
|
||||
*/
|
||||
void AddChildSpriteScreen(SpriteID image, SpriteID pal, int x, int y, bool transparent, const SubSprite *sub)
|
||||
{
|
||||
ViewportDrawer *vd = _cur_vd;
|
||||
ChildScreenSpriteToDraw *cs;
|
||||
|
@ -642,6 +688,7 @@ void AddChildSpriteScreen(SpriteID image, SpriteID pal, int x, int y, bool trans
|
|||
|
||||
cs->image = image;
|
||||
cs->pal = pal;
|
||||
cs->sub = sub;
|
||||
cs->x = x;
|
||||
cs->y = y;
|
||||
cs->next = NULL;
|
||||
|
@ -1179,7 +1226,7 @@ static void ViewportDrawTileSprites(TileSpriteToDraw *ts)
|
|||
{
|
||||
do {
|
||||
Point pt = RemapCoords(ts->x, ts->y, ts->z);
|
||||
DrawSprite(ts->image, ts->pal, pt.x, pt.y);
|
||||
DrawSprite(ts->image, ts->pal, pt.x, pt.y, ts->sub);
|
||||
ts = ts->next;
|
||||
} while (ts != NULL);
|
||||
}
|
||||
|
@ -1250,10 +1297,10 @@ static void ViewportDrawParentSprites(ParentSpriteToDraw *psd[])
|
|||
const ParentSpriteToDraw* ps = *psd;
|
||||
const ChildScreenSpriteToDraw* cs;
|
||||
|
||||
if (ps->image != SPR_EMPTY_BOUNDING_BOX) DrawSprite(ps->image, ps->pal, ps->x, ps->y);
|
||||
if (ps->image != SPR_EMPTY_BOUNDING_BOX) DrawSprite(ps->image, ps->pal, ps->x, ps->y, ps->sub);
|
||||
|
||||
for (cs = ps->child; cs != NULL; cs = cs->next) {
|
||||
DrawSprite(cs->image, cs->pal, ps->left + cs->x, ps->top + cs->y);
|
||||
DrawSprite(cs->image, cs->pal, ps->left + cs->x, ps->top + cs->y, cs->sub);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,11 +57,11 @@ enum {
|
|||
|
||||
void OffsetGroundSprite(int x, int y);
|
||||
|
||||
void DrawGroundSprite(SpriteID image, SpriteID pal);
|
||||
void DrawGroundSpriteAt(SpriteID image, SpriteID pal, int32 x, int32 y, byte z);
|
||||
void AddSortableSpriteToDraw(SpriteID image, SpriteID pal, int x, int y, int w, int h, int dz, int z, bool transparent = false, int bb_offset_x = 0, int bb_offset_y = 0, int bb_offset_z = 0);
|
||||
void DrawGroundSprite(SpriteID image, SpriteID pal, const SubSprite *sub = NULL);
|
||||
void DrawGroundSpriteAt(SpriteID image, SpriteID pal, int32 x, int32 y, byte z, const SubSprite *sub = NULL);
|
||||
void AddSortableSpriteToDraw(SpriteID image, SpriteID pal, int x, int y, int w, int h, int dz, int z, bool transparent = false, int bb_offset_x = 0, int bb_offset_y = 0, int bb_offset_z = 0, const SubSprite *sub = NULL);
|
||||
void *AddStringToDraw(int x, int y, StringID string, uint64 params_1, uint64 params_2);
|
||||
void AddChildSpriteScreen(SpriteID image, SpriteID pal, int x, int y, bool transparent = false);
|
||||
void AddChildSpriteScreen(SpriteID image, SpriteID pal, int x, int y, bool transparent = false, const SubSprite *sub = NULL);
|
||||
|
||||
|
||||
void StartSpriteCombine();
|
||||
|
|
Loading…
Reference in New Issue