Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions code/wincursor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,19 @@ static HCURSOR Build_Cursor(ShapeSet const * shape, int frame, int hotx, int hot
return(NULL);
}

int width = shape->Get_Width() * scale;
int height = shape->Get_Height() * scale;
int eff = scale;
int maxw = GetSystemMetrics(SM_CXCURSOR);
int maxh = GetSystemMetrics(SM_CYCURSOR);
if (shape->Get_Width() > 0 && shape->Get_Height() > 0 && maxw > 0 && maxh > 0) {
int capw = maxw / shape->Get_Width();
int caph = maxh / shape->Get_Height();
if (eff > capw) eff = capw;
if (eff > caph) eff = caph;
if (eff < 1) eff = 1;
}

int width = shape->Get_Width() * eff;
int height = shape->Get_Height() * eff;

if (width <= 0 || height <= 0) {
return(NULL);
Expand Down Expand Up @@ -134,9 +145,9 @@ static HCURSOR Build_Cursor(ShapeSet const * shape, int frame, int hotx, int hot
unsigned long blue = (pixel & 0x1F) << 3;
unsigned long argb = 0xFF000000UL | (red << 16) | (green << 8) | blue;

for (int suby = 0; suby < scale; suby++) {
unsigned long * row = (unsigned long *)bits + ((rect.Y + y) * scale + suby) * width + (rect.X + x) * scale;
for (int subx = 0; subx < scale; subx++) {
for (int suby = 0; suby < eff; suby++) {
unsigned long * row = (unsigned long *)bits + ((rect.Y + y) * eff + suby) * width + (rect.X + x) * eff;
for (int subx = 0; subx < eff; subx++) {
row[subx] = argb;
}
}
Expand All @@ -151,8 +162,8 @@ static HCURSOR Build_Cursor(ShapeSet const * shape, int frame, int hotx, int hot
HBITMAP mask = CreateBitmap(width, height, 1, 1, mask_bits);
delete [] mask_bits;

int cursor_hotx = hotx * scale;
int cursor_hoty = hoty * scale;
int cursor_hotx = hotx * eff;
int cursor_hoty = hoty * eff;
if (cursor_hotx < 0) cursor_hotx = 0;
if (cursor_hoty < 0) cursor_hoty = 0;
if (cursor_hotx >= width) cursor_hotx = width - 1;
Expand Down
3 changes: 3 additions & 0 deletions code/wwmouse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,9 @@ void WWMouseClass::Release_Mouse(void)
ClipCursor(NULL);
if (GetCapture() == Window) ReleaseCapture();
while (ShowCursor(TRUE) < 0) {}

SetCursor(LoadCursor(NULL, IDC_ARROW));

Show_Mouse();
}
}
Expand Down
17 changes: 17 additions & 0 deletions manual/changes/cursor-dialog-visibility.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
title: Show the pointer when a dialog takes the mouse
category: fix
release: 0.2.0
targets:
- type: key
id: CursorScale
effect: changed
credit: [JusticarProgramming]
---

When the game gave the mouse back to the operating system so a dialog could use it, the
pointer was hidden and stayed hidden until it next moved. The release path cleared the cursor
but nothing put it back, so a dialog that opened under the pointer came up over a blank cursor.

The release path now restores the arrow as it gives up the mouse, so the pointer is visible
the moment a dialog appears.
19 changes: 19 additions & 0 deletions manual/changes/cursor-size-cap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
title: Keep the pointer within the system cursor size
category: fix
release: 0.2.0
targets:
- type: key
id: CursorScale
effect: changed
credit: [JusticarProgramming]
---

The pointer is drawn at the size its setting asks for times the size of its artwork. On a
display where the picture is enlarged a lot, that could come to a bitmap larger than the
cursor the operating system actually renders, and Windows then clips the cursor to its own
size. The clipped corner holds no artwork, so the pointer disappeared.

The pointer is now reduced to the largest whole size the system cursor can hold, so it always
shows. `CursorScale` still accepts its usual values; a size the display cannot render is
drawn as large as it can be.
2 changes: 2 additions & 0 deletions manual/content/keys/cursorscale.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ The pointer is a real system cursor built from the game's own artwork, so it sta
Left at `0` it follows the picture: the enlargement is rounded to the nearest whole number and used as the pointer's size, so a picture displayed at roughly double size gets a double-size pointer. A value above zero sets the size directly, and eight is the largest accepted. A value below zero draws the pointer at the size the artwork was drawn at, however large the picture is displayed.

The pointer is rebuilt whenever the size it should be drawn at changes, so resizing the window resizes the pointer with it.

However large the size asks to be, the pointer is held to the size the operating system can draw a cursor at. A display that cannot show the requested size draws the pointer as large as it can rather than clipping it to an invisible corner.