ACSUtils Wiki

An ACS library for ZDoom-based ports

User Tools

Site Tools


new:mouse

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 640×480).

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 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 GetPlayerInput with BT_ATTACK (left mouse button) and BT_ALTATTACK (right mouse button). Better yet, use ACSUtils 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 HudMessage (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 640×480 (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 1×1 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 640×480).

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 640×480).

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.

new/mouse.txt · Last modified: 2018/02/19 13:04 by korshun