====== Mouse cursor library ======
ACSUtils provides a mouse cursor library, which lets you easily add mouse support to any interface in your mod. It is very easy to use:
while (true)
{
UpdateCursor();
DRAW_CURSOR_AT(CursorX(), CursorY());
Delay(1);
}
''UpdateCursor()'' reads player input and uses it to move the cursor, while taking many mouse setting cvars into account to make sure the cursor is not affected by first person mouse settings. ''CursorX()'' and ''CursorY()'' return the coordinates in the cursor in the [[HUD_coordinate_system]] (default size is 640x480).
**The cursor library does not draw the cursor.** This is to give you freedom to draw it any way you want, using the coordinates provided by ''CursorX()'' and ''CursorY()''.
The cursor library fully supports widescreen thanks to ACSUtils [[Widescreeen|widescreen support functions]].
The cursor library doesn't handle mouse clicks, as ZDoom doesn't provide access to mouse buttons. To read mouse clicks, use [[zdoom>GetPlayerInput]] with ''BT_ATTACK'' (left mouse button) and ''BT_ALTATTACK'' (right mouse button). Better yet, use ACSUtils [[input|GetPlayerInput wrappers]] for simpler input handling that will not register multiple clicks if the player holds a mouse button.
To check if a button is clicked on screen, check that the cursor is inside the button's rectangle and was clicked.
The cursor library **cannot be used serverside**.
Serverside cursors are very laggy and the server can't read the client's mouse settings, so use of the cursor library serverside is unsupported and untested.
===== A complete example =====
An example using [[zdoom>HudMessage]] (''[[rounding|floor()]]'' is used to clear alignment flags):
// OPTIONAL: Sets cursor coordinate system
// 640x480 is already the default.
SetCursorArea(640.0, 480.0);
// Main loop
while (true)
{
UpdateCursor();
SetHudSize(640, 480, false); // Must match SetCursorArea
SetFont("CURSOR");
HudMessage(s:"A"; HUDMSG_PLAIN, 1, CR_NONE, floor(CursorX()), floor(CursorY()), 0);
}
This example uses the [[HUD library]] to make the code simpler:
while (true)
{
UpdateCursor();
HudResetState(); // Sets 640x480 coordinate system by default
HudSetPoint(CursorX(), CursorY());
HudDrawImage(1, "CURSOR");
}
===== Moving the cursor =====
* ''void SetCursorPosition(fixed x, fixed y)'' -- Teleports the cursor to the new position.
* ''void CenterCursor()'' -- Teleports the cursor to the center of the screen.
===== Cursor settings =====
You may want to customize the mouse cursor before using it. For example:
SetCursorArea(800.0, 600.0); // Use 800x600 coordinate system instead of 640x480
SetCursorSpeed(2.0); // Cursor is twice more sensitive
EnableCursorWrap(true); // Teleport the cursor to the opposite end of the screen if it reaches one end
while (true)
{
UpdateCursor();
DRAW_CURSOR(CursorX(), CursorY());
Delay(1);
}
These settings can be changed at anytime, but they are usually set before the cursor is used.
==== SetCursorArea ====
''void SetCursorArea(fixed width, fixed height)''
Sets the size of the [[HUD coordinate system]] the cursor is in. Default is 640x480 (''SetCursorArea(640.0, 480.0)'').
To draw the cursor, you need to use the same HUD coordinate system when drawing stuff. For [[HudMessage]], use ''SetHudSize(640, 480, false)'', for [[HUD Library]], use ''HudSetVirtualSize(640.0, 480.0)''.
When this function is called, it changes cursor coordinates so that the cursor stays in the same place on the screen.
If you want, you can set a 1x1 HUD coordinate system by calling ''SetCursorArea(1.0, 1.0)''. The cursor will continue to work properly.
==== SetCursorSpeed ====
''void SetCursorSpeed(fixed speed)''
Sets the speed (sensitivity) of the cursor. Default is ''1.0''.
Speed can be set separetly for each axis:
* ''void SetCursorSpeedX(fixed speed)''
* ''void SetCursorSpeedY(fixed speed)''
==== EnableCursorWrap ====
''void EnableCursorWrap(bool enable)''
Enables or disables cursor wrapping. Cursor wrapping makes the cursor teleport to the opposite end of the screeen when it hits a screen boundary, instead of being stopped.
X and Y cursor wrapping can be enabled or disabled separately:
* ''void EnableCursorWrapX(bool enable)''
* ''void EnableCursorWrapY(bool enable)''
===== Reading current cursor state =====
There is more to current cursor state than just its position. All functions here return values in the current [[HUD coordinate system]] set by ''SetCursorArea()'' (default is 640x480).
==== Cursor position ====
* ''fixed CursorX()''
* ''fixed CursorY()''
These functions return the cursor's current X and Y position respectively, in the [[HUD coordinate system]] specified by ''SetCursorArea()'' (default is 640x480).
==== Cursor position delta ====
* ''fixed CursorDeltaX()''
* ''fixed CursorDeltaY()''
Return the X and Y difference between the cursor's current position and the cursor's previous position.
If the cursor is blocked by a screen boundary, its X or Y delta (or both!) is 0.
If cursor wrapping is enabled, the delta values don't suddenly jump when crossing a screen boundary. They behave just like if there were no teleporting at all, and the cursor just continued moving forward.
==== Cursor motion vector ====
* ''fixed CursorMotionX()''
* ''fixed CursorMotionY()''
Return the cursor motion vector's X and Y respectively.
Cursor motion vector is similar to cursor delta vector, except it ignores screen boundaries. If the cursor is stuck at a screen boundary, but the user is moving it toward the screen boundary, its motion vector is how much the cursor would move if nothing was blocking it.
Otherwise it's the same as cursor delta.