mirror of https://github.com/OpenTTD/OpenTTD
(svn r27628) -Codechange: Prepare for drawing cursors consisting of multiple sprites.
parent
4d1843a95e
commit
3cb7d9703b
|
@ -512,8 +512,9 @@ struct DepotWindow : Window {
|
||||||
this->sel = v->index;
|
this->sel = v->index;
|
||||||
this->SetDirty();
|
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;
|
_cursor.vehchain = _ctrl_pressed;
|
||||||
|
UpdateCursorSize();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
107
src/gfx.cpp
107
src/gfx.cpp
|
@ -1223,10 +1223,6 @@ void DrawMouseCursor()
|
||||||
if (_screen.dst_ptr == NULL) return;
|
if (_screen.dst_ptr == NULL) return;
|
||||||
|
|
||||||
Blitter *blitter = BlitterFactory::GetCurrentBlitter();
|
Blitter *blitter = BlitterFactory::GetCurrentBlitter();
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
int w;
|
|
||||||
int h;
|
|
||||||
|
|
||||||
/* Redraw mouse cursor but only when it's inside the window */
|
/* Redraw mouse cursor but only when it's inside the window */
|
||||||
if (!_cursor.in_window) return;
|
if (!_cursor.in_window) return;
|
||||||
|
@ -1237,36 +1233,44 @@ void DrawMouseCursor()
|
||||||
UndrawMouseCursor();
|
UndrawMouseCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
w = _cursor.size.x;
|
/* Determine visible area */
|
||||||
x = _cursor.pos.x + _cursor.offs.x + _cursor.short_vehicle_offset;
|
int left = _cursor.pos.x + _cursor.total_offs.x;
|
||||||
if (x < 0) {
|
int width = _cursor.total_size.x;
|
||||||
w += x;
|
if (left < 0) {
|
||||||
x = 0;
|
width += left;
|
||||||
|
left = 0;
|
||||||
}
|
}
|
||||||
if (w > _screen.width - x) w = _screen.width - x;
|
if (left + width > _screen.width) {
|
||||||
if (w <= 0) return;
|
width = _screen.width - left;
|
||||||
_cursor.draw_pos.x = x;
|
|
||||||
_cursor.draw_size.x = w;
|
|
||||||
|
|
||||||
h = _cursor.size.y;
|
|
||||||
y = _cursor.pos.y + _cursor.offs.y;
|
|
||||||
if (y < 0) {
|
|
||||||
h += y;
|
|
||||||
y = 0;
|
|
||||||
}
|
}
|
||||||
if (h > _screen.height - y) h = _screen.height - y;
|
if (width <= 0) return;
|
||||||
if (h <= 0) return;
|
|
||||||
_cursor.draw_pos.y = y;
|
|
||||||
_cursor.draw_size.y = h;
|
|
||||||
|
|
||||||
uint8 *buffer = _cursor_backup.Allocate(blitter->BufferSize(w, h));
|
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 (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(_cursor.draw_size.x, _cursor.draw_size.y));
|
||||||
|
|
||||||
/* Make backup of stuff below cursor */
|
/* 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);
|
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 */
|
/* Draw cursor on screen */
|
||||||
_cur_dpi = &_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);
|
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()
|
void UpdateCursorSize()
|
||||||
{
|
{
|
||||||
CursorVars *cv = &_cursor;
|
/* Ignore setting any cursor before the sprites are loaded. */
|
||||||
const Sprite *p = GetSprite(GB(cv->sprite, 0, SPRITE_WIDTH), ST_NORMAL);
|
if (GetMaxSpriteID() == 0) return;
|
||||||
|
|
||||||
cv->size.y = UnScaleGUI(p->height);
|
assert_compile(lengthof(_cursor.sprite_seq) == lengthof(_cursor.sprite_pos));
|
||||||
cv->size.x = UnScaleGUI(p->width);
|
assert(_cursor.sprite_count <= lengthof(_cursor.sprite_seq));
|
||||||
cv->offs.x = UnScaleGUI(p->x_offs);
|
for (uint i = 0; i < _cursor.sprite_count; ++i) {
|
||||||
cv->offs.y = UnScaleGUI(p->y_offs);
|
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);
|
||||||
|
|
||||||
cv->dirty = true;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_cursor.dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1543,14 +1565,15 @@ void UpdateCursorSize()
|
||||||
*/
|
*/
|
||||||
static void SetCursorSprite(CursorID cursor, PaletteID pal)
|
static void SetCursorSprite(CursorID cursor, PaletteID pal)
|
||||||
{
|
{
|
||||||
CursorVars *cv = &_cursor;
|
if (_cursor.sprite_count == 1 && _cursor.sprite_seq[0].sprite == cursor && _cursor.sprite_seq[0].pal == pal) return;
|
||||||
if (cv->sprite == cursor) 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;
|
||||||
|
|
||||||
cv->sprite = cursor;
|
|
||||||
cv->pal = pal;
|
|
||||||
UpdateCursorSize();
|
UpdateCursorSize();
|
||||||
|
|
||||||
cv->short_vehicle_offset = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SwitchAnimatedCursor()
|
static void SwitchAnimatedCursor()
|
||||||
|
@ -1559,7 +1582,7 @@ static void SwitchAnimatedCursor()
|
||||||
|
|
||||||
if (cur == NULL || cur->sprite == AnimCursor::LAST) cur = _cursor.animate_list;
|
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_timeout = cur->display_time;
|
||||||
_cursor.animate_cur = cur + 1;
|
_cursor.animate_cur = cur + 1;
|
||||||
|
@ -1579,9 +1602,9 @@ void CursorTick()
|
||||||
void SetMouseCursorBusy(bool busy)
|
void SetMouseCursorBusy(bool busy)
|
||||||
{
|
{
|
||||||
if (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 {
|
} 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_list = table;
|
||||||
_cursor.animate_cur = NULL;
|
_cursor.animate_cur = NULL;
|
||||||
_cursor.pal = PAL_NONE;
|
_cursor.sprite_seq[0].pal = PAL_NONE;
|
||||||
SwitchAnimatedCursor();
|
SwitchAnimatedCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,9 +127,11 @@ struct CursorVars {
|
||||||
int h_wheel;
|
int h_wheel;
|
||||||
|
|
||||||
/* Mouse appearance */
|
/* Mouse appearance */
|
||||||
CursorID sprite; ///< current image of cursor
|
PalSpriteID sprite_seq[16]; ///< current image of cursor
|
||||||
PaletteID pal;
|
Point sprite_pos[16]; ///< relative position of individual sprites
|
||||||
Point size, offs; ///< sprite properties
|
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
|
Point draw_pos, draw_size; ///< position and size bounding-box for drawing
|
||||||
|
|
||||||
const AnimCursor *animate_list; ///< in case of animated cursor, list of frames
|
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
|
bool in_window; ///< mouse inside this window, determines drawing logic
|
||||||
|
|
||||||
/* Drag data */
|
/* Drag data */
|
||||||
int short_vehicle_offset; ///< offset of the X for short vehicles
|
|
||||||
bool vehchain; ///< vehicle chain is dragged
|
bool vehchain; ///< vehicle chain is dragged
|
||||||
|
|
||||||
bool UpdateCursorPosition(int x, int y, bool queued_warp);
|
bool UpdateCursorPosition(int x, int y, bool queued_warp);
|
||||||
|
|
|
@ -672,8 +672,8 @@ struct TooltipsWindow : public Window
|
||||||
/* Correctly position the tooltip position, watch out for window and cursor size
|
/* Correctly position the tooltip position, watch out for window and cursor size
|
||||||
* Clamp value to below main toolbar and above statusbar. If tooltip would
|
* Clamp value to below main toolbar and above statusbar. If tooltip would
|
||||||
* go below window, flip it so it is shown above the cursor */
|
* 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);
|
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.offs.y - 5, scr_bot) - sm_height;
|
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);
|
pt.x = sm_width >= _screen.width ? 0 : Clamp(_cursor.pos.x - (sm_width >> 1), 0, _screen.width - sm_width);
|
||||||
|
|
||||||
return pt;
|
return pt;
|
||||||
|
|
|
@ -2825,7 +2825,6 @@ static void MouseLoop(MouseClick click, int mousewheel)
|
||||||
switch (click) {
|
switch (click) {
|
||||||
case MC_DOUBLE_LEFT:
|
case MC_DOUBLE_LEFT:
|
||||||
case MC_LEFT:
|
case MC_LEFT:
|
||||||
DEBUG(misc, 2, "Cursor: 0x%X (%d)", _cursor.sprite, _cursor.sprite);
|
|
||||||
if (!HandleViewportClicked(vp, x, y) &&
|
if (!HandleViewportClicked(vp, x, y) &&
|
||||||
!(w->flags & WF_DISABLE_VP_SCROLL) &&
|
!(w->flags & WF_DISABLE_VP_SCROLL) &&
|
||||||
_settings_client.gui.left_mouse_btn_scrolling) {
|
_settings_client.gui.left_mouse_btn_scrolling) {
|
||||||
|
|
Loading…
Reference in New Issue