Hardware Mouse Cursor

BlitzMax Forums/BlitzMax Programming/Hardware Mouse Cursor

therevills(Posted 2012) [#1]
Here's how to do it (currently only for Windows):

mouse.cpp:
#include "windows.h"
#include "stdio.h"

HCURSOR cursors[15]; 

extern "C" __declspec( dllexport ) void InitializeCursor(int cursorId, char* standardPath)
{
	wchar_t newPath[1024];
	MultiByteToWideChar(CP_UTF8, 0, standardPath, -1, newPath, 1024);
	HCURSOR cursor = ::LoadCursorFromFileW(newPath);
	cursors[cursorId] = cursor;
}

extern "C" __declspec( dllexport ) void SetCurrentCursor(int cursorId)
{
	HWND result = GetForegroundWindow();
	SetClassLongA(result, -12, (long)cursors[cursorId]);
	SetCursor(cursors[cursorId]);
	InvalidateRect(result, NULL, TRUE);
}


mouse.bmx:
SuperStrict

?win32
Import "mouse.cpp"

Extern
	Function InitializeCursor(cursorId:Int, path$z)
	Function SetCurrentCursor(cursorId:Int)
EndExtern
?

Graphics 800, 600

InitCursor(0, "pointer.cur")
SetCursor(0)

Repeat
	Cls
	Flip
Until AppTerminate()

Function InitCursor(id:Int, path:String)
	?win32
		InitializeCursor(id, path)
	?
End Function

Function SetCursor(id:Int)
	?win32
		SetCurrentCursor(id)
	?
End Function


Please note that Windows will impose a standard size of 32x32 for your mouse cursor, so if it is any larger than that Windows will resize it.

http://support.microsoft.com/kb/307213

Original code from here (which includes Mac code too):
http://forum.unity3d.com/threads/70163-Hardware-Cursor-Plugin

Last edited 2012


therevills(Posted 2012) [#2]
Small update... I've found a way to get around the 32x32 limit.

Change the c++ InitializeCursor method:

extern "C" __declspec( dllexport ) void InitializeCursor(int cursorId, char* standardPath)
{
	HCURSOR cursor = (HCURSOR)LoadImage(NULL, standardPath, IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE|LR_SHARED);
	cursors[cursorId] = cursor;
}


Now my 64x64 mouse cursor is displayed fine :)


therevills(Posted 2012) [#3]
Okay, need to help with the Mac version...

CursorPlugin.h
#import <Cocoa/Cocoa.h>
#include <AppKit/AppKit.h>


CursorPlugin.m


And using it like this in BlitzMax:

mouse.bmx


But when I run it, the app works but I dont get my new cursor sometimes get my new cursor (its really buggy) and when it quits I get:


Compile Error
52.565 mouse.debug[1555:60b] InitialzeCursor called



Does anyone have any ideas?

Last edited 2012

Last edited 2012


xlsior(Posted 2012) [#4]
What is the benefit of this over the standard mouse commands


therevills(Posted 2012) [#5]
No input mouse lag when using vsync and full screen ;)

Also instead of hiding the mouse and using DrawImage img, MouseX(), MouseY() for a custom mouse cursor, you can use this...


Grey Alien(Posted 2012) [#6]
To clarify it fixes movement lag but not click lag or dragging stuff lag. There's no way round that due to the nature of the problem being DX9 display lag (which means all input appears delayed).

Hope you get the Mac stuff sorted (is it needed, did you test?).


therevills(Posted 2012) [#7]
Hope you get the Mac stuff sorted (is it needed, did you test?).


Nope, I havent tested yet - I'm hoping its not needed as OpenGL lag is so much less than DirectXs.


Grey Alien(Posted 2012) [#8]
You know when the lagfix dropped the FPS to 30 was that just with DX or GL too?


therevills(Posted 2012) [#9]
Just DX, GL was fine.

Ahhh... so I wonder if its worth doing the lagfix just for OpenGL...


Grey Alien(Posted 2012) [#10]
could be!


dmaz(Posted 2012) [#11]
why don't you guys just stop using vwait?


therevills(Posted 2012) [#12]
just stop using vwait?


NEVER!! >:D

Vsync is so much smoother overall and no tearing... but you get the input lag.

I've also been researching "triple buffering"/"render ahead" as a possible workaround (as we can't fix vsync and lag):

http://www.anandtech.com/show/2794


Grey Alien(Posted 2012) [#13]
When I first made my framework the options page had a VSync on/off option and you know the framework totally supports it. It's just that VSync looks so much smoother and it made my games stand out as looking polished compared to a) non vsynced casual games with jerky anims and b) just poor framerate games. However I've yet to see a casual game with the VSync option on the options page. Perhaps though I could add it again on future games so customers can at least turn it off if they are getting mouse lag.


therevills(Posted 2012) [#14]
Perhaps though I could add it again on future games so customers can at least turn it off if they are getting mouse lag.


For an proper "indie" game yeah add it... but for a casual game do you think the user will actually know what it means? (Unless you rename from Vsync to Turn Mouse Lag Off) ;)


Grey Alien(Posted 2012) [#15]
Yeah I know it practically needs some name like "If you feel the mouse is being slow or experience any problems, try clicking this". Still lots of casual players probably never go into options when they get problems, they just quit out. Gamers are more likely to explore and look for solutions. This is why casual games need to work "straight out the box" as much as possible and have the most common settings that will work for most people and do a bit of auto-detection if need be. (I know you know this).

It's a shame this is such a minefield. When I first made the framework, half of it was creating common components, and the other half was working all this stuff out and getting BlitzMax bugs fixed and improvements made to make it suitable for commercial casual games. It's pretty good now but I still hate to think of lost sales due to some system incompatibilities (and I don't mean like 128MB Win 98 systems, I mean with half-decent modern systems and netbooks etc).

Last edited 2012


dmaz(Posted 2012) [#16]
Vsync is so much smoother overall and no tearing...
not in my experience... check out my Rocks game... perfectly smooth and no lag. not meaning to boast but all my stuff is that way and I've testing on a lot computers and have been doing it that way years.

http://www.blitzmax.com/codearcs/codearcs.php?code=2783

Last edited 2012


therevills(Posted 2012) [#17]
Nice game BTW :)

Thats a totally different way to handle the update, I will have to have a look at it more.

With your example (with the bouncing balls), how would you add a mouse cursor to the "world" without lag?

I've tried this:


But the lag is still there...

Last edited 2012

Last edited 2012


dmaz(Posted 2012) [#18]
I thought you guys were talking about the DX -input- lag problem that was fixed ages ago and it somehow popped back up. but know this is mouse pointer lag... ok... the mouse cursor has to be realtime to reduce pointer lag...



Nice game BTW :)

thanks.

Last edited 2012


therevills(Posted 2012) [#19]
Over in the The Big BlitzMax Lag Test thread we are talking about DX9 or OpenGL input lag problem with vsync on.

This thread is about how to enable a hardware mouse cursor, which eliminates the mouse lag, but of course you will still have keyboard/joystick input lag.

I've just tried your update code and the input lag is still there with vsync :/


dmaz(Posted 2012) [#20]
right but it wasn't there without vsync. so it's perfectly smooth, there is no tearing and no real lag... that was my point for why not to use it... just saying ;)


therevills(Posted 2012) [#21]
Opps... yeah of course - D'oh!

I will have to create a more complete example to see about tearing though.

I've had a good look at your timing methods and it looks really good... do you have to add everything to TObject, is there away around that? I like objects to have their own lists etc.


dmaz(Posted 2012) [#22]
you can have multiple lists or many base objects or whatever. you just need to capture the old position of all the objects that you will be tweening. so for stage.Update in my games I don't call TObject.CaptureAll, I call somthing like "GameCapture" which is a function that then calls a CaptureAll function for each object list that's in the game. sort of like the GameUpdate function in the example.

one note that's missed sometimes... on creation or if you are recycling objects or wrapping motion from one side to the other you need to set the old x/y to the current x/y. this then won't perform any tween as there is nothing in be"tween".

Last edited 2012


skn3(Posted 2012) [#23]
Pssst: custom cursors in windows and osx
http://blitzbasic.com/Community/posts.php?topic=96527


Grey Alien(Posted 2012) [#24]
There will always be tearing with vsync off. Just draw a tall vertical object and move it sideways and you'll see it. Tearing doesn't show up as much on some game types, like with small sprites.


therevills(Posted 2012) [#25]
@Jake, yep your right - quick example using dmaz's code:


Without vsync you can see tearing... :(

@skn3 - Thanks for that I'll have a proper look tonight :)

Last edited 2012


Grey Alien(Posted 2012) [#26]
Me too, it's super obvious in full-screen mode.


Rixarn(Posted 2012) [#27]
Can the problem be solved using threads? One thread for the input, and the other thread for everything else (update & render with vsync on)?

I dont't know much about threads in Bmax so forgive me if I'm suggesting nonesense..


dmaz(Posted 2012) [#28]
Without vsync you can see tearing... :(
hmmm... well... you did not tween the player. try this:

this takes away the super obvious tear... there is still *very* slight tear but a full height white on black rect is the most extreme example. do you see any tearing my game rocks?.. or here's another old more real example ... no fullscreen though so maybe it's not the best but the point is smooth games right?

Last edited 2012


therevills(Posted 2012) [#29]
D'oh... thanks again Dmaz... no I didn't see any tearing in your Rocks game, but in that game you don't use any big images. Yep tearing is most visible when using full screen. I've seen it when displaying a scrolling background image (or even a static image).