diff options
author | frosch <frosch@openttd.org> | 2016-08-15 18:33:08 +0000 |
---|---|---|
committer | frosch <frosch@openttd.org> | 2016-08-15 18:33:08 +0000 |
commit | 3cb7d9703b376b8798e5726591add2d4e2a17223 (patch) | |
tree | 745e4ef13842d3ac7044ac6b62a15e1761232e84 | |
parent | 4d1843a95e26a64ff3ff0b967d721794dbf0fe46 (diff) | |
download | openttd-3cb7d9703b376b8798e5726591add2d4e2a17223.tar.xz |
(svn r27628) -Codechange: Prepare for drawing cursors consisting of multiple sprites.
-rw-r--r-- | src/depot_gui.cpp | 3 | ||||
-rw-r--r-- | src/gfx.cpp | 107 | ||||
-rw-r--r-- | src/gfx_type.h | 9 | ||||
-rw-r--r-- | src/misc_gui.cpp | 4 | ||||
-rw-r--r-- | src/window.cpp | 1 |
5 files changed, 74 insertions, 50 deletions
diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 24a14b833..76bb8df50 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -512,8 +512,9 @@ struct DepotWindow : Window { this->sel = v->index; this->SetDirty(); - _cursor.short_vehicle_offset = v->IsGroundVehicle() ? (16 - v->GetGroundVehicleCache()->cached_veh_length * 2) * (rtl ? -1 : 1) : 0; + _cursor.sprite_pos[0].x = v->IsGroundVehicle() ? (16 - v->GetGroundVehicleCache()->cached_veh_length * 2) * (rtl ? -1 : 1) : 0; _cursor.vehchain = _ctrl_pressed; + UpdateCursorSize(); } break; } diff --git a/src/gfx.cpp b/src/gfx.cpp index 909f6729e..719505157 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -1223,10 +1223,6 @@ void DrawMouseCursor() if (_screen.dst_ptr == NULL) return; Blitter *blitter = BlitterFactory::GetCurrentBlitter(); - int x; - int y; - int w; - int h; /* Redraw mouse cursor but only when it's inside the window */ if (!_cursor.in_window) return; @@ -1237,36 +1233,44 @@ void DrawMouseCursor() UndrawMouseCursor(); } - w = _cursor.size.x; - x = _cursor.pos.x + _cursor.offs.x + _cursor.short_vehicle_offset; - if (x < 0) { - w += x; - x = 0; + /* Determine visible area */ + int left = _cursor.pos.x + _cursor.total_offs.x; + int width = _cursor.total_size.x; + if (left < 0) { + width += left; + left = 0; + } + if (left + width > _screen.width) { + width = _screen.width - left; } - if (w > _screen.width - x) w = _screen.width - x; - if (w <= 0) return; - _cursor.draw_pos.x = x; - _cursor.draw_size.x = w; + if (width <= 0) return; - h = _cursor.size.y; - y = _cursor.pos.y + _cursor.offs.y; - if (y < 0) { - h += y; - y = 0; + int top = _cursor.pos.y + _cursor.total_offs.y; + int height = _cursor.total_size.y; + if (top < 0) { + height += top; + top = 0; + } + if (top + height > _screen.height) { + height = _screen.height - top; } - if (h > _screen.height - y) h = _screen.height - y; - if (h <= 0) return; - _cursor.draw_pos.y = y; - _cursor.draw_size.y = h; + if (height <= 0) return; + + _cursor.draw_pos.x = left; + _cursor.draw_pos.y = top; + _cursor.draw_size.x = width; + _cursor.draw_size.y = height; - uint8 *buffer = _cursor_backup.Allocate(blitter->BufferSize(w, h)); + uint8 *buffer = _cursor_backup.Allocate(blitter->BufferSize(_cursor.draw_size.x, _cursor.draw_size.y)); /* Make backup of stuff below cursor */ blitter->CopyToBuffer(blitter->MoveTo(_screen.dst_ptr, _cursor.draw_pos.x, _cursor.draw_pos.y), buffer, _cursor.draw_size.x, _cursor.draw_size.y); /* Draw cursor on screen */ _cur_dpi = &_screen; - DrawSprite(_cursor.sprite, _cursor.pal, _cursor.pos.x + _cursor.short_vehicle_offset, _cursor.pos.y); + 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); + } VideoDriver::GetInstance()->MakeDirty(_cursor.draw_pos.x, _cursor.draw_pos.y, _cursor.draw_size.x, _cursor.draw_size.y); @@ -1525,15 +1529,33 @@ bool FillDrawPixelInfo(DrawPixelInfo *n, int left, int top, int width, int heigh */ void UpdateCursorSize() { - CursorVars *cv = &_cursor; - const Sprite *p = GetSprite(GB(cv->sprite, 0, SPRITE_WIDTH), ST_NORMAL); - - cv->size.y = UnScaleGUI(p->height); - cv->size.x = UnScaleGUI(p->width); - cv->offs.x = UnScaleGUI(p->x_offs); - cv->offs.y = UnScaleGUI(p->y_offs); + /* Ignore setting any cursor before the sprites are loaded. */ + if (GetMaxSpriteID() == 0) return; + + assert_compile(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), ST_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; + size.x = UnScaleGUI(p->width); + size.y = UnScaleGUI(p->height); + + if (i == 0) { + _cursor.total_offs = offs; + _cursor.total_size = size; + } else { + int right = max(_cursor.total_offs.x + _cursor.total_size.x, offs.x + size.x); + int bottom = 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.y < _cursor.total_offs.y) _cursor.total_offs.y = offs.y; + _cursor.total_size.x = right - _cursor.total_offs.x; + _cursor.total_size.y = bottom - _cursor.total_offs.y; + } + } - cv->dirty = true; + _cursor.dirty = true; } /** @@ -1543,14 +1565,15 @@ void UpdateCursorSize() */ static void SetCursorSprite(CursorID cursor, PaletteID pal) { - CursorVars *cv = &_cursor; - if (cv->sprite == cursor) return; + if (_cursor.sprite_count == 1 && _cursor.sprite_seq[0].sprite == cursor && _cursor.sprite_seq[0].pal == pal) return; - cv->sprite = cursor; - cv->pal = pal; - UpdateCursorSize(); + _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; - cv->short_vehicle_offset = 0; + UpdateCursorSize(); } static void SwitchAnimatedCursor() @@ -1559,7 +1582,7 @@ static void SwitchAnimatedCursor() if (cur == NULL || cur->sprite == AnimCursor::LAST) cur = _cursor.animate_list; - SetCursorSprite(cur->sprite, _cursor.pal); + SetCursorSprite(cur->sprite, _cursor.sprite_seq[0].pal); _cursor.animate_timeout = cur->display_time; _cursor.animate_cur = cur + 1; @@ -1579,9 +1602,9 @@ void CursorTick() void SetMouseCursorBusy(bool busy) { if (busy) { - if (_cursor.sprite == SPR_CURSOR_MOUSE) SetMouseCursor(SPR_CURSOR_ZZZ, PAL_NONE); + if (_cursor.sprite_seq[0].sprite == SPR_CURSOR_MOUSE) SetMouseCursor(SPR_CURSOR_ZZZ, PAL_NONE); } else { - if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE, PAL_NONE); + if (_cursor.sprite_seq[0].sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE, PAL_NONE); } } @@ -1608,7 +1631,7 @@ void SetAnimatedMouseCursor(const AnimCursor *table) { _cursor.animate_list = table; _cursor.animate_cur = NULL; - _cursor.pal = PAL_NONE; + _cursor.sprite_seq[0].pal = PAL_NONE; SwitchAnimatedCursor(); } diff --git a/src/gfx_type.h b/src/gfx_type.h index 707887619..ca9bf9fce 100644 --- a/src/gfx_type.h +++ b/src/gfx_type.h @@ -127,9 +127,11 @@ struct CursorVars { int h_wheel; /* Mouse appearance */ - CursorID sprite; ///< current image of cursor - PaletteID pal; - Point size, offs; ///< sprite properties + 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 + Point total_offs, total_size; ///< union of sprite properties + Point draw_pos, draw_size; ///< position and size bounding-box for drawing const AnimCursor *animate_list; ///< in case of animated cursor, list of frames @@ -141,7 +143,6 @@ struct CursorVars { bool in_window; ///< mouse inside this window, determines drawing logic /* Drag data */ - int short_vehicle_offset; ///< offset of the X for short vehicles bool vehchain; ///< vehicle chain is dragged bool UpdateCursorPosition(int x, int y, bool queued_warp); diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 9c6e3f334..b751407e2 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -672,8 +672,8 @@ struct TooltipsWindow : public Window /* Correctly position the tooltip position, watch out for window and cursor size * Clamp value to below main toolbar and above statusbar. If tooltip would * go below window, flip it so it is shown above the cursor */ - pt.y = Clamp(_cursor.pos.y + _cursor.size.y + _cursor.offs.y + 5, scr_top, scr_bot); - if (pt.y + sm_height > scr_bot) pt.y = min(_cursor.pos.y + _cursor.offs.y - 5, scr_bot) - sm_height; + pt.y = Clamp(_cursor.pos.y + _cursor.total_size.y + _cursor.total_offs.y + 5, scr_top, scr_bot); + if (pt.y + sm_height > scr_bot) pt.y = min(_cursor.pos.y + _cursor.total_offs.y - 5, scr_bot) - sm_height; pt.x = sm_width >= _screen.width ? 0 : Clamp(_cursor.pos.x - (sm_width >> 1), 0, _screen.width - sm_width); return pt; diff --git a/src/window.cpp b/src/window.cpp index bc92416b6..24683d0a6 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -2825,7 +2825,6 @@ static void MouseLoop(MouseClick click, int mousewheel) switch (click) { case MC_DOUBLE_LEFT: case MC_LEFT: - DEBUG(misc, 2, "Cursor: 0x%X (%d)", _cursor.sprite, _cursor.sprite); if (!HandleViewportClicked(vp, x, y) && !(w->flags & WF_DISABLE_VP_SCROLL) && _settings_client.gui.left_mouse_btn_scrolling) { |