Game Development Community

Canvas.setCursor not working?

by CdnGater · in Torque Game Engine Advanced · 04/28/2008 (11:50 am) · 18 replies

I dont think the Canvas.setCursor in TGEA is working anymore. I can't set a custom cursor.

As an experiment I used a clean SDK, changed the DefaultCursor.png to something different, and the cursor did not change when I ran the demos. I tried in window mode and fullscreen mode, and keep getting the arrow pointer.

Am I missing something in using Canvas.setCursor in TGEA? or is it truly a bug?

btw, it works still in TGE.

thanks

#1
04/28/2008 (6:22 pm)
Yep, confirmed. Will take a look.

Note that changing DefaultCursor.png can't possibly work because in the current script files, the relevant datablocks are only loaded after the initializeCanvas call in game/common/gameScripts/common.cs, i.e. the profile is never used.
#2
04/28/2008 (6:48 pm)
Just a quick look, but the results are as follows: unlike TGE, TGEA now uses the platform's cursors (i.e. those that Windows uses) and always uses them except the platform cursor isn't visible (which currently seems to be the case whenever the mouse is locked).

//EDIT:
My previous statement about the bug was a bug. Getting tired...
#3
04/28/2008 (7:19 pm)
So how can we create and use custom ingame cursors then?
#4
04/28/2008 (9:54 pm)
So, after a bunch of (now deleted) BS-posts of a tired and confused brain...

1) There is a problem in that in stock 1.7, mouse locking is tied to cursor visibility. This makes using custom cursors ingame, i.e. when the mouse is locked, impossible as any time you call showCursor, you also end up disabling locking and thus enabling platform cursors that override your custom cursors.

2) The following solution is hackish but works:

--------------

In GuiCanvas::setCursorOn comment out the follwing line:

mPlatformWindow->setMouseLocked(!mCursorEnabled);

In Platform::setWindowLocked (currently empty) add the following code:

PlatformWindow* window = WindowManager->getFirstWindow();
   if( window )
      window->setMouseLocked( locked );

------------

Now you can use Canvas.cursorOn and Canvas.cursorOff while ingame to toggle custom cursors on and off.

PS: Don't forget to reorder the initialization in common.cs.
#5
04/29/2008 (5:04 am)
OK, thanks Rene I will try this.
#6
06/25/2008 (7:00 am)
I called Canvas.CursorOn(); , Canvas.CursorOff(); but I can't show custom cursor.
how can I show custom cursor.

I did

//this is common\gamescripts\cursor.cs
$cursorControlled = true;
function showCursor()
{
   if ($cursorControlled)
      lockMouse(false);
   Canvas.cursorOn();
}

function hideCursor()
{
   if ($cursorControlled)
      lockMouse(true);
   Canvas.cursorOff();
}

// this client\init.cs
function initClient()
{
....//ommision 

[b]     Canvas.setCursor("DefaultCursor");[/b]
[b]     showCursor(); [/b]

..//ommision
}
#7
06/25/2008 (7:32 am)
It won't work the way you did it. You have to do the whole thing dynamically. Example:

function foo()
{
    Canvas.cursorOn();
}
function bar()
{
    Canvas.cursorOff();
}

moveMap.bind( "keyboard", "i", foo );
moveMap.bind( "keyboard", "j", bar );

Now you can toggle custom cursors on and off with "i" and "j" (not very useful, but just an example).

Bit of an explanation:

cursorOn and cursorOff toggle the *current* visibility state which is a very dynamic thing. Also, which cursor handling scheme is then used depends on whether mouse-locking is on or off.

ATM TGEA uses platform cursors when mouse-locking is *off* and custom cursors when mouse-locking is *on*. Mouse-locking is switched on for menus and most GUI stuff.
#8
06/25/2008 (7:37 am)
Ah, and BTW, you need TGEA >= 1.7.1 or the engine changes above for this to work.
#9
06/25/2008 (9:12 am)
I want custom cursor in MainMenuGui.

I did in 1.7.1 T3D demo

common\unifiedshell\MainmenuGui.gui

function UnifiedMainMenuGui::onWake(%this)
{
lockMouse(true);
Canvas.cursorOn();
}

this is not work. but it is working in Gui Editor
what's the reason?

Without Press button, Can I curstom cursor visible from beginning?
#10
06/25/2008 (3:38 pm)
Would have to look into this. Suppose some code that's executed later on simply overrides your mouse settings.

Here's an engine modification that allows you to toggle off platform cursors altogether and simply go with custom cursors.

In gui/core/guiCanvas.h add the following to the interface of GuiCanvas:

protected:
   bool mOverridePlatformCursor;
public:
   void overridePlatformCursor( bool state = true )
   {
      mOverridePlatformCursor = state;
   }

And in gui/core/guiCanvas.cpp@63 change

mPlatformWindow(NULL)

to

mPlatformWindow(NULL),
                        mOverridePlatformCursor( false )

And to GuiCanvas::renderFrame at gui/core/guiCanvas.cpp@1527 add:

if( mOverridePlatformCursor && mPlatformWindow->getCursorController() )
         mPlatformWindow->getCursorController()->setCursorVisible( false );


Also add the following console method to the file

ConsoleMethod( GuiCanvas, overridePlatformCursor, void, 2, 3, "(value=true)" )
{
   bool value = true;
   if( argc > 2 )
      value = dAtob( argv[ 2 ] );
   object->overridePlatformCursor( value );
}

Not the most elegant solution, but it works. You can now toggle platform cursors using

Canvas.overridePlatformCursor( true );
#11
06/25/2008 (8:47 pm)
Thank you Rene Damm
#12
08/06/2008 (8:50 am)
How have you found the performance of the cursor after making these changes?
#13
08/08/2008 (12:24 am)
Platform cursors are a lot faster. Torque-rendered cursors are fairly slow and hardly usable when running in combination with a tablet.
#14
08/08/2008 (12:51 am)
@Rene: Thanks ... unfortunately I have to use Torqe-rendered cursors for my game as it is integral to the user experience in the game. Basically the cursor changes when you highlight an enemy or an NPC who you can chat to ... without this the game might not be playable.

The other option I have is to go with some type of indicator above the player that could indicate wether the person is an enemy or wether they can be talked to.

Thanks again for your time.
#15
08/08/2008 (2:53 am)
Ok, understand. The only out-of-the-box option to you currently is to go with Torque's software-rendered cursors. Torque definitely should use hardware-rendering of mouse cursors where available. With DX9 at least, this is trivial. Will give this a look when I find the time. Shouldn't be too much work and should make for an all-around better alternative to Win32 API cursors, though solving it for all GFX APIs is a little more intricate.

PS: Just noticed that I had been posting Torque source code stuff into public forums again. Need to learn to behave.
#16
08/20/2008 (5:38 pm)
Is there a private continuation of this thread? or did anyone get this to work with tgea? for my game i need a movable crosshair with a costum image. is there any way of doing this since the above tricks or has noone looked into this anymore?
#17
08/21/2008 (5:28 am)
@Tom - I got it working with TGEA using this thread. On a plus note the slow cursor response is not noticeable on a gaming machine.
#18
09/23/2008 (6:19 am)
I needed this and wanted to preserve hardware cursors for performance, so I implemented it and made it a resource:

Linky