mirror of https://github.com/OpenTTD/OpenTTD.git
Codechange: Store cursor sprites in vector.
Combine two separate fixed length arrays to allow simpler iteration. No need to check that arrays are all the same length. No need to separately store the number of sprites to draw. Removes the upper limit of the number of sprites that can be drawn. Removes lengthof and array indices.
This commit is contained in:
parent
9121770582
commit
1a2679cb3c
40
src/gfx.cpp
40
src/gfx.cpp
|
@ -1363,8 +1363,8 @@ void DrawMouseCursor()
|
|||
|
||||
/* Draw cursor on screen */
|
||||
_cur_dpi = &_screen;
|
||||
for (uint i = 0; i < _cursor.sprite_count; ++i) {
|
||||
DrawSprite(_cursor.sprite_seq[i].sprite, _cursor.sprite_seq[i].pal, _cursor.pos.x + _cursor.sprite_pos[i].x, _cursor.pos.y + _cursor.sprite_pos[i].y);
|
||||
for (const auto &cs : _cursor.sprites) {
|
||||
DrawSprite(cs.image.sprite, cs.image.pal, _cursor.pos.x + cs.pos.x, _cursor.pos.y + cs.pos.y);
|
||||
}
|
||||
|
||||
VideoDriver::GetInstance()->MakeDirty(_cursor.draw_pos.x, _cursor.draw_pos.y, _cursor.draw_size.x, _cursor.draw_size.y);
|
||||
|
@ -1615,20 +1615,22 @@ void UpdateCursorSize()
|
|||
/* Ignore setting any cursor before the sprites are loaded. */
|
||||
if (GetMaxSpriteID() == 0) return;
|
||||
|
||||
static_assert(lengthof(_cursor.sprite_seq) == lengthof(_cursor.sprite_pos));
|
||||
assert(_cursor.sprite_count <= lengthof(_cursor.sprite_seq));
|
||||
for (uint i = 0; i < _cursor.sprite_count; ++i) {
|
||||
const Sprite *p = GetSprite(GB(_cursor.sprite_seq[i].sprite, 0, SPRITE_WIDTH), SpriteType::Normal);
|
||||
bool first = true;
|
||||
for (const auto &cs : _cursor.sprites) {
|
||||
const Sprite *p = GetSprite(GB(cs.image.sprite, 0, SPRITE_WIDTH), SpriteType::Normal);
|
||||
Point offs, size;
|
||||
offs.x = UnScaleGUI(p->x_offs) + _cursor.sprite_pos[i].x;
|
||||
offs.y = UnScaleGUI(p->y_offs) + _cursor.sprite_pos[i].y;
|
||||
offs.x = UnScaleGUI(p->x_offs) + cs.pos.x;
|
||||
offs.y = UnScaleGUI(p->y_offs) + cs.pos.y;
|
||||
size.x = UnScaleGUI(p->width);
|
||||
size.y = UnScaleGUI(p->height);
|
||||
|
||||
if (i == 0) {
|
||||
if (first) {
|
||||
/* First sprite sets the total. */
|
||||
_cursor.total_offs = offs;
|
||||
_cursor.total_size = size;
|
||||
first = false;
|
||||
} else {
|
||||
/* Additional sprites expand the total. */
|
||||
int right = std::max(_cursor.total_offs.x + _cursor.total_size.x, offs.x + size.x);
|
||||
int bottom = std::max(_cursor.total_offs.y + _cursor.total_size.y, offs.y + size.y);
|
||||
if (offs.x < _cursor.total_offs.x) _cursor.total_offs.x = offs.x;
|
||||
|
@ -1648,13 +1650,10 @@ void UpdateCursorSize()
|
|||
*/
|
||||
static void SetCursorSprite(CursorID cursor, PaletteID pal)
|
||||
{
|
||||
if (_cursor.sprite_count == 1 && _cursor.sprite_seq[0].sprite == cursor && _cursor.sprite_seq[0].pal == pal) return;
|
||||
if (_cursor.sprites.size() == 1 && _cursor.sprites[0].image.sprite == cursor && _cursor.sprites[0].image.pal == pal) return;
|
||||
|
||||
_cursor.sprite_count = 1;
|
||||
_cursor.sprite_seq[0].sprite = cursor;
|
||||
_cursor.sprite_seq[0].pal = pal;
|
||||
_cursor.sprite_pos[0].x = 0;
|
||||
_cursor.sprite_pos[0].y = 0;
|
||||
_cursor.sprites.clear();
|
||||
_cursor.sprites.emplace_back(cursor, pal, 0, 0);
|
||||
|
||||
UpdateCursorSize();
|
||||
}
|
||||
|
@ -1665,7 +1664,8 @@ static void SwitchAnimatedCursor()
|
|||
|
||||
if (cur == nullptr || cur->sprite == AnimCursor::LAST) cur = _cursor.animate_list;
|
||||
|
||||
SetCursorSprite(cur->sprite, _cursor.sprite_seq[0].pal);
|
||||
assert(!_cursor.sprites.empty());
|
||||
SetCursorSprite(cur->sprite, _cursor.sprites[0].image.pal);
|
||||
|
||||
_cursor.animate_timeout = cur->display_time;
|
||||
_cursor.animate_cur = cur + 1;
|
||||
|
@ -1684,10 +1684,11 @@ void CursorTick()
|
|||
*/
|
||||
void SetMouseCursorBusy(bool busy)
|
||||
{
|
||||
assert(!_cursor.sprites.empty());
|
||||
if (busy) {
|
||||
if (_cursor.sprite_seq[0].sprite == SPR_CURSOR_MOUSE) SetMouseCursor(SPR_CURSOR_ZZZ, PAL_NONE);
|
||||
if (_cursor.sprites[0].image.sprite == SPR_CURSOR_MOUSE) SetMouseCursor(SPR_CURSOR_ZZZ, PAL_NONE);
|
||||
} else {
|
||||
if (_cursor.sprite_seq[0].sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE, PAL_NONE);
|
||||
if (_cursor.sprites[0].image.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE, PAL_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1712,9 +1713,10 @@ void SetMouseCursor(CursorID sprite, PaletteID pal)
|
|||
*/
|
||||
void SetAnimatedMouseCursor(const AnimCursor *table)
|
||||
{
|
||||
assert(!_cursor.sprites.empty());
|
||||
_cursor.animate_list = table;
|
||||
_cursor.animate_cur = nullptr;
|
||||
_cursor.sprite_seq[0].pal = PAL_NONE;
|
||||
_cursor.sprites[0].image.pal = PAL_NONE;
|
||||
SwitchAnimatedCursor();
|
||||
}
|
||||
|
||||
|
|
|
@ -112,6 +112,13 @@ struct AnimCursor {
|
|||
uint8_t display_time; ///< Amount of ticks this sprite will be shown
|
||||
};
|
||||
|
||||
struct CursorSprite {
|
||||
PalSpriteID image; ///< Image.
|
||||
Point pos; ///< Relative position.
|
||||
|
||||
constexpr CursorSprite(SpriteID spr, PaletteID pal, int x, int y) : image({spr, pal}), pos({x, y}) {}
|
||||
};
|
||||
|
||||
/** Collection of variables for cursor-display and -animation */
|
||||
struct CursorVars {
|
||||
/* Logical mouse position */
|
||||
|
@ -126,9 +133,7 @@ struct CursorVars {
|
|||
int h_wheel;
|
||||
|
||||
/* Mouse appearance */
|
||||
PalSpriteID sprite_seq[16]; ///< current image of cursor
|
||||
Point sprite_pos[16]; ///< relative position of individual sprites
|
||||
uint sprite_count; ///< number of sprites to draw
|
||||
std::vector<CursorSprite> sprites; ///< Sprites comprising cursor.
|
||||
Point total_offs, total_size; ///< union of sprite properties
|
||||
|
||||
Point draw_pos, draw_size; ///< position and size bounding-box for drawing
|
||||
|
|
|
@ -3537,7 +3537,7 @@ void SetMouseCursorVehicle(const Vehicle *v, EngineImageType image_type)
|
|||
{
|
||||
bool rtl = _current_text_dir == TD_RTL;
|
||||
|
||||
_cursor.sprite_count = 0;
|
||||
_cursor.sprites.clear();
|
||||
int total_width = 0;
|
||||
int y_offset = 0;
|
||||
bool rotor_seq = false; // Whether to draw the rotor of the vehicle in this step.
|
||||
|
@ -3557,18 +3557,12 @@ void SetMouseCursorVehicle(const Vehicle *v, EngineImageType image_type)
|
|||
v->GetImage(rtl ? DIR_E : DIR_W, image_type, &seq);
|
||||
}
|
||||
|
||||
if (_cursor.sprite_count + seq.count > lengthof(_cursor.sprite_seq)) break;
|
||||
|
||||
int x_offs = 0;
|
||||
if (v->type == VEH_TRAIN) x_offs = Train::From(v)->GetCursorImageOffset();
|
||||
|
||||
for (uint i = 0; i < seq.count; ++i) {
|
||||
PaletteID pal2 = (v->vehstatus & VS_CRASHED) || !seq.seq[i].pal ? pal : seq.seq[i].pal;
|
||||
_cursor.sprite_seq[_cursor.sprite_count].sprite = seq.seq[i].sprite;
|
||||
_cursor.sprite_seq[_cursor.sprite_count].pal = pal2;
|
||||
_cursor.sprite_pos[_cursor.sprite_count].x = rtl ? (-total_width + x_offs) : (total_width + x_offs);
|
||||
_cursor.sprite_pos[_cursor.sprite_count].y = y_offset;
|
||||
_cursor.sprite_count++;
|
||||
_cursor.sprites.emplace_back(seq.seq[i].sprite, pal2, rtl ? (-total_width + x_offs) : (total_width + x_offs), y_offset);
|
||||
}
|
||||
|
||||
if (v->type == VEH_AIRCRAFT && v->subtype == AIR_HELICOPTER && !rotor_seq) {
|
||||
|
@ -3584,8 +3578,8 @@ void SetMouseCursorVehicle(const Vehicle *v, EngineImageType image_type)
|
|||
/* Center trains and road vehicles on the front vehicle */
|
||||
int offs = (ScaleSpriteTrad(VEHICLEINFO_FULL_VEHICLE_WIDTH) - total_width) / 2;
|
||||
if (rtl) offs = -offs;
|
||||
for (uint i = 0; i < _cursor.sprite_count; ++i) {
|
||||
_cursor.sprite_pos[i].x += offs;
|
||||
for (auto &cs : _cursor.sprites) {
|
||||
cs.pos.x += offs;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1074,16 +1074,14 @@ void OpenGLBackend::DrawMouseCursor()
|
|||
|
||||
/* Draw cursor on screen */
|
||||
_cur_dpi = &_screen;
|
||||
for (uint i = 0; i < this->cursor_sprite_count; ++i) {
|
||||
SpriteID sprite = this->cursor_sprite_seq[i].sprite;
|
||||
|
||||
for (const auto &cs : this->cursor_sprites) {
|
||||
/* Sprites are cached by PopulateCursorCache(). */
|
||||
if (this->cursor_cache.Contains(sprite)) {
|
||||
Sprite *spr = this->cursor_cache.Get(sprite);
|
||||
if (this->cursor_cache.Contains(cs.image.sprite)) {
|
||||
Sprite *spr = this->cursor_cache.Get(cs.image.sprite);
|
||||
|
||||
this->RenderOglSprite((OpenGLSprite *)spr->data, this->cursor_sprite_seq[i].pal,
|
||||
this->cursor_pos.x + this->cursor_sprite_pos[i].x + UnScaleByZoom(spr->x_offs, ZOOM_LVL_GUI),
|
||||
this->cursor_pos.y + this->cursor_sprite_pos[i].y + UnScaleByZoom(spr->y_offs, ZOOM_LVL_GUI),
|
||||
this->RenderOglSprite((OpenGLSprite *)spr->data, cs.image.pal,
|
||||
this->cursor_pos.x + cs.pos.x + UnScaleByZoom(spr->x_offs, ZOOM_LVL_GUI),
|
||||
this->cursor_pos.y + cs.pos.y + UnScaleByZoom(spr->y_offs, ZOOM_LVL_GUI),
|
||||
ZOOM_LVL_GUI);
|
||||
}
|
||||
}
|
||||
|
@ -1091,9 +1089,6 @@ void OpenGLBackend::DrawMouseCursor()
|
|||
|
||||
void OpenGLBackend::PopulateCursorCache()
|
||||
{
|
||||
static_assert(lengthof(_cursor.sprite_seq) == lengthof(this->cursor_sprite_seq));
|
||||
static_assert(lengthof(_cursor.sprite_pos) == lengthof(this->cursor_sprite_pos));
|
||||
|
||||
if (this->clear_cursor_cache) {
|
||||
/* We have a pending cursor cache clear to do first. */
|
||||
this->clear_cursor_cache = false;
|
||||
|
@ -1103,16 +1098,14 @@ void OpenGLBackend::PopulateCursorCache()
|
|||
}
|
||||
|
||||
this->cursor_pos = _cursor.pos;
|
||||
this->cursor_sprite_count = _cursor.sprite_count;
|
||||
this->cursor_in_window = _cursor.in_window;
|
||||
|
||||
for (uint i = 0; i < _cursor.sprite_count; ++i) {
|
||||
this->cursor_sprite_seq[i] = _cursor.sprite_seq[i];
|
||||
this->cursor_sprite_pos[i] = _cursor.sprite_pos[i];
|
||||
SpriteID sprite = _cursor.sprite_seq[i].sprite;
|
||||
this->cursor_sprites.clear();
|
||||
for (const auto &sc : _cursor.sprites) {
|
||||
this->cursor_sprites.emplace_back(sc);
|
||||
|
||||
if (!this->cursor_cache.Contains(sprite)) {
|
||||
Sprite *old = this->cursor_cache.Insert(sprite, (Sprite *)GetRawSprite(sprite, SpriteType::Normal, &SimpleSpriteAlloc, this));
|
||||
if (!this->cursor_cache.Contains(sc.image.sprite)) {
|
||||
Sprite *old = this->cursor_cache.Insert(sc.image.sprite, (Sprite *)GetRawSprite(sc.image.sprite, SpriteType::Normal, &SimpleSpriteAlloc, this));
|
||||
if (old != nullptr) {
|
||||
OpenGLSprite *gl_sprite = (OpenGLSprite *)old->data;
|
||||
gl_sprite->~OpenGLSprite();
|
||||
|
|
|
@ -65,9 +65,7 @@ private:
|
|||
|
||||
Point cursor_pos; ///< Cursor position
|
||||
bool cursor_in_window; ///< Cursor inside this window
|
||||
PalSpriteID cursor_sprite_seq[16]; ///< Current image of cursor
|
||||
Point cursor_sprite_pos[16]; ///< Relative position of individual cursor sprites
|
||||
uint cursor_sprite_count; ///< Number of cursor sprites to draw
|
||||
std::vector<CursorSprite> cursor_sprites; ///< Sprites comprising cursor
|
||||
|
||||
OpenGLBackend();
|
||||
~OpenGLBackend();
|
||||
|
|
Loading…
Reference in New Issue