mirror of https://github.com/OpenTTD/OpenTTD.git
Codechange: Store cursor sprites in vector. (#12564)
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
5e689ce25e
40
src/gfx.cpp
40
src/gfx.cpp
|
@ -1363,8 +1363,8 @@ void DrawMouseCursor()
|
||||||
|
|
||||||
/* Draw cursor on screen */
|
/* Draw cursor on screen */
|
||||||
_cur_dpi = &_screen;
|
_cur_dpi = &_screen;
|
||||||
for (uint i = 0; i < _cursor.sprite_count; ++i) {
|
for (const auto &cs : _cursor.sprites) {
|
||||||
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);
|
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);
|
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. */
|
/* Ignore setting any cursor before the sprites are loaded. */
|
||||||
if (GetMaxSpriteID() == 0) return;
|
if (GetMaxSpriteID() == 0) return;
|
||||||
|
|
||||||
static_assert(lengthof(_cursor.sprite_seq) == lengthof(_cursor.sprite_pos));
|
bool first = true;
|
||||||
assert(_cursor.sprite_count <= lengthof(_cursor.sprite_seq));
|
for (const auto &cs : _cursor.sprites) {
|
||||||
for (uint i = 0; i < _cursor.sprite_count; ++i) {
|
const Sprite *p = GetSprite(GB(cs.image.sprite, 0, SPRITE_WIDTH), SpriteType::Normal);
|
||||||
const Sprite *p = GetSprite(GB(_cursor.sprite_seq[i].sprite, 0, SPRITE_WIDTH), SpriteType::Normal);
|
|
||||||
Point offs, size;
|
Point offs, size;
|
||||||
offs.x = UnScaleGUI(p->x_offs) + _cursor.sprite_pos[i].x;
|
offs.x = UnScaleGUI(p->x_offs) + cs.pos.x;
|
||||||
offs.y = UnScaleGUI(p->y_offs) + _cursor.sprite_pos[i].y;
|
offs.y = UnScaleGUI(p->y_offs) + cs.pos.y;
|
||||||
size.x = UnScaleGUI(p->width);
|
size.x = UnScaleGUI(p->width);
|
||||||
size.y = UnScaleGUI(p->height);
|
size.y = UnScaleGUI(p->height);
|
||||||
|
|
||||||
if (i == 0) {
|
if (first) {
|
||||||
|
/* First sprite sets the total. */
|
||||||
_cursor.total_offs = offs;
|
_cursor.total_offs = offs;
|
||||||
_cursor.total_size = size;
|
_cursor.total_size = size;
|
||||||
|
first = false;
|
||||||
} else {
|
} else {
|
||||||
|
/* Additional sprites expand the total. */
|
||||||
int right = std::max(_cursor.total_offs.x + _cursor.total_size.x, offs.x + size.x);
|
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);
|
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;
|
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)
|
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.sprites.clear();
|
||||||
_cursor.sprite_seq[0].sprite = cursor;
|
_cursor.sprites.emplace_back(cursor, pal, 0, 0);
|
||||||
_cursor.sprite_seq[0].pal = pal;
|
|
||||||
_cursor.sprite_pos[0].x = 0;
|
|
||||||
_cursor.sprite_pos[0].y = 0;
|
|
||||||
|
|
||||||
UpdateCursorSize();
|
UpdateCursorSize();
|
||||||
}
|
}
|
||||||
|
@ -1665,7 +1664,8 @@ static void SwitchAnimatedCursor()
|
||||||
|
|
||||||
if (cur == nullptr || cur->sprite == AnimCursor::LAST) cur = _cursor.animate_list;
|
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_timeout = cur->display_time;
|
||||||
_cursor.animate_cur = cur + 1;
|
_cursor.animate_cur = cur + 1;
|
||||||
|
@ -1684,10 +1684,11 @@ void CursorTick()
|
||||||
*/
|
*/
|
||||||
void SetMouseCursorBusy(bool busy)
|
void SetMouseCursorBusy(bool busy)
|
||||||
{
|
{
|
||||||
|
assert(!_cursor.sprites.empty());
|
||||||
if (busy) {
|
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 {
|
} 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)
|
void SetAnimatedMouseCursor(const AnimCursor *table)
|
||||||
{
|
{
|
||||||
|
assert(!_cursor.sprites.empty());
|
||||||
_cursor.animate_list = table;
|
_cursor.animate_list = table;
|
||||||
_cursor.animate_cur = nullptr;
|
_cursor.animate_cur = nullptr;
|
||||||
_cursor.sprite_seq[0].pal = PAL_NONE;
|
_cursor.sprites[0].image.pal = PAL_NONE;
|
||||||
SwitchAnimatedCursor();
|
SwitchAnimatedCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,13 @@ struct AnimCursor {
|
||||||
uint8_t display_time; ///< Amount of ticks this sprite will be shown
|
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 */
|
/** Collection of variables for cursor-display and -animation */
|
||||||
struct CursorVars {
|
struct CursorVars {
|
||||||
/* Logical mouse position */
|
/* Logical mouse position */
|
||||||
|
@ -126,9 +133,7 @@ struct CursorVars {
|
||||||
int h_wheel;
|
int h_wheel;
|
||||||
|
|
||||||
/* Mouse appearance */
|
/* Mouse appearance */
|
||||||
PalSpriteID sprite_seq[16]; ///< current image of cursor
|
std::vector<CursorSprite> sprites; ///< Sprites comprising cursor.
|
||||||
Point sprite_pos[16]; ///< relative position of individual sprites
|
|
||||||
uint sprite_count; ///< number of sprites to draw
|
|
||||||
Point total_offs, total_size; ///< union of sprite properties
|
Point total_offs, total_size; ///< union of sprite properties
|
||||||
|
|
||||||
Point draw_pos, draw_size; ///< position and size bounding-box for drawing
|
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;
|
bool rtl = _current_text_dir == TD_RTL;
|
||||||
|
|
||||||
_cursor.sprite_count = 0;
|
_cursor.sprites.clear();
|
||||||
int total_width = 0;
|
int total_width = 0;
|
||||||
int y_offset = 0;
|
int y_offset = 0;
|
||||||
bool rotor_seq = false; // Whether to draw the rotor of the vehicle in this step.
|
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);
|
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;
|
int x_offs = 0;
|
||||||
if (v->type == VEH_TRAIN) x_offs = Train::From(v)->GetCursorImageOffset();
|
if (v->type == VEH_TRAIN) x_offs = Train::From(v)->GetCursorImageOffset();
|
||||||
|
|
||||||
for (uint i = 0; i < seq.count; ++i) {
|
for (uint i = 0; i < seq.count; ++i) {
|
||||||
PaletteID pal2 = (v->vehstatus & VS_CRASHED) || !seq.seq[i].pal ? pal : seq.seq[i].pal;
|
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.sprites.emplace_back(seq.seq[i].sprite, pal2, rtl ? (-total_width + x_offs) : (total_width + x_offs), y_offset);
|
||||||
_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++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v->type == VEH_AIRCRAFT && v->subtype == AIR_HELICOPTER && !rotor_seq) {
|
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 */
|
/* Center trains and road vehicles on the front vehicle */
|
||||||
int offs = (ScaleSpriteTrad(VEHICLEINFO_FULL_VEHICLE_WIDTH) - total_width) / 2;
|
int offs = (ScaleSpriteTrad(VEHICLEINFO_FULL_VEHICLE_WIDTH) - total_width) / 2;
|
||||||
if (rtl) offs = -offs;
|
if (rtl) offs = -offs;
|
||||||
for (uint i = 0; i < _cursor.sprite_count; ++i) {
|
for (auto &cs : _cursor.sprites) {
|
||||||
_cursor.sprite_pos[i].x += offs;
|
cs.pos.x += offs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1074,16 +1074,14 @@ void OpenGLBackend::DrawMouseCursor()
|
||||||
|
|
||||||
/* Draw cursor on screen */
|
/* Draw cursor on screen */
|
||||||
_cur_dpi = &_screen;
|
_cur_dpi = &_screen;
|
||||||
for (uint i = 0; i < this->cursor_sprite_count; ++i) {
|
for (const auto &cs : this->cursor_sprites) {
|
||||||
SpriteID sprite = this->cursor_sprite_seq[i].sprite;
|
|
||||||
|
|
||||||
/* Sprites are cached by PopulateCursorCache(). */
|
/* Sprites are cached by PopulateCursorCache(). */
|
||||||
if (this->cursor_cache.Contains(sprite)) {
|
if (this->cursor_cache.Contains(cs.image.sprite)) {
|
||||||
Sprite *spr = this->cursor_cache.Get(sprite);
|
Sprite *spr = this->cursor_cache.Get(cs.image.sprite);
|
||||||
|
|
||||||
this->RenderOglSprite((OpenGLSprite *)spr->data, this->cursor_sprite_seq[i].pal,
|
this->RenderOglSprite((OpenGLSprite *)spr->data, cs.image.pal,
|
||||||
this->cursor_pos.x + this->cursor_sprite_pos[i].x + UnScaleByZoom(spr->x_offs, ZOOM_LVL_GUI),
|
this->cursor_pos.x + cs.pos.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->cursor_pos.y + cs.pos.y + UnScaleByZoom(spr->y_offs, ZOOM_LVL_GUI),
|
||||||
ZOOM_LVL_GUI);
|
ZOOM_LVL_GUI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1091,9 +1089,6 @@ void OpenGLBackend::DrawMouseCursor()
|
||||||
|
|
||||||
void OpenGLBackend::PopulateCursorCache()
|
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) {
|
if (this->clear_cursor_cache) {
|
||||||
/* We have a pending cursor cache clear to do first. */
|
/* We have a pending cursor cache clear to do first. */
|
||||||
this->clear_cursor_cache = false;
|
this->clear_cursor_cache = false;
|
||||||
|
@ -1103,16 +1098,14 @@ void OpenGLBackend::PopulateCursorCache()
|
||||||
}
|
}
|
||||||
|
|
||||||
this->cursor_pos = _cursor.pos;
|
this->cursor_pos = _cursor.pos;
|
||||||
this->cursor_sprite_count = _cursor.sprite_count;
|
|
||||||
this->cursor_in_window = _cursor.in_window;
|
this->cursor_in_window = _cursor.in_window;
|
||||||
|
|
||||||
for (uint i = 0; i < _cursor.sprite_count; ++i) {
|
this->cursor_sprites.clear();
|
||||||
this->cursor_sprite_seq[i] = _cursor.sprite_seq[i];
|
for (const auto &sc : _cursor.sprites) {
|
||||||
this->cursor_sprite_pos[i] = _cursor.sprite_pos[i];
|
this->cursor_sprites.emplace_back(sc);
|
||||||
SpriteID sprite = _cursor.sprite_seq[i].sprite;
|
|
||||||
|
|
||||||
if (!this->cursor_cache.Contains(sprite)) {
|
if (!this->cursor_cache.Contains(sc.image.sprite)) {
|
||||||
Sprite *old = this->cursor_cache.Insert(sprite, (Sprite *)GetRawSprite(sprite, SpriteType::Normal, &SimpleSpriteAlloc, this));
|
Sprite *old = this->cursor_cache.Insert(sc.image.sprite, (Sprite *)GetRawSprite(sc.image.sprite, SpriteType::Normal, &SimpleSpriteAlloc, this));
|
||||||
if (old != nullptr) {
|
if (old != nullptr) {
|
||||||
OpenGLSprite *gl_sprite = (OpenGLSprite *)old->data;
|
OpenGLSprite *gl_sprite = (OpenGLSprite *)old->data;
|
||||||
gl_sprite->~OpenGLSprite();
|
gl_sprite->~OpenGLSprite();
|
||||||
|
|
|
@ -65,9 +65,7 @@ private:
|
||||||
|
|
||||||
Point cursor_pos; ///< Cursor position
|
Point cursor_pos; ///< Cursor position
|
||||||
bool cursor_in_window; ///< Cursor inside this window
|
bool cursor_in_window; ///< Cursor inside this window
|
||||||
PalSpriteID cursor_sprite_seq[16]; ///< Current image of cursor
|
std::vector<CursorSprite> cursor_sprites; ///< Sprites comprising cursor
|
||||||
Point cursor_sprite_pos[16]; ///< Relative position of individual cursor sprites
|
|
||||||
uint cursor_sprite_count; ///< Number of cursor sprites to draw
|
|
||||||
|
|
||||||
OpenGLBackend();
|
OpenGLBackend();
|
||||||
~OpenGLBackend();
|
~OpenGLBackend();
|
||||||
|
|
Loading…
Reference in New Issue