diff --git a/code/wincursor.cpp b/code/wincursor.cpp index d8121cb..88b2edc 100644 --- a/code/wincursor.cpp +++ b/code/wincursor.cpp @@ -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); @@ -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; } } @@ -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; diff --git a/code/wwmouse.cpp b/code/wwmouse.cpp index a533581..a8c4462 100644 --- a/code/wwmouse.cpp +++ b/code/wwmouse.cpp @@ -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(); } } diff --git a/manual/changes/cursor-dialog-visibility.md b/manual/changes/cursor-dialog-visibility.md new file mode 100644 index 0000000..5cad8ef --- /dev/null +++ b/manual/changes/cursor-dialog-visibility.md @@ -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. diff --git a/manual/changes/cursor-size-cap.md b/manual/changes/cursor-size-cap.md new file mode 100644 index 0000000..2d823a6 --- /dev/null +++ b/manual/changes/cursor-size-cap.md @@ -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. diff --git a/manual/content/keys/cursorscale.md b/manual/content/keys/cursorscale.md index c67d2ab..6b33461 100644 --- a/manual/content/keys/cursorscale.md +++ b/manual/content/keys/cursorscale.md @@ -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.