Posts: 2,700
Threads: 328
Joined: Apr 2022
Reputation:
219
02-25-2024, 05:37 PM
(This post was last modified: 02-25-2024, 07:43 PM by SMcNeill.)
There's been several discussions here recently about _MouseMovementX and _MouseMovementY, and how they don't work 100% as expected in Linux and Mac. Unfortunately, the problem here is an underlying issue with glut itself not reporting that relative movement back to us.
The only real solution at the moment is for one to write their own routine to handle this type of situation, so I thought I'd take a few minutes and write up a quick example of how to do that for someone:
Code: (Select All)
DIM SHARED AS LONG MouseMoveX, MouseMoveY, MouseX, MouseY
SCREEN _NEWIMAGE(800, 600, 32)
_SCREENMOVE _MIDDLE
DO
CLS
Mouse
TMMX = TMMX + MouseMoveX: TMMY = TMMY + MouseMoveY
PRINT "Mouse x:"; MouseX
PRINT "Mouse y:"; MouseY
PRINT "MouseMoveX:"; MouseMoveX
PRINT "MouseMoveY:"; MouseMoveY
PRINT "Total MouseMoveX:"; TMMX
PRINT "TOtal MouseMoveY:"; TMMY
_LIMIT 30
_DISPLAY
LOOP UNTIL _MOUSEBUTTON(2)
SYSTEM
SUB Mouse
STATIC AS LONG CurrentX, CurrentY
STATIC AS LONG Pointer 'We need a pointer of some sort for a manual pointer. Here's a cheesy one by default.
STATIC AS INTEGER Init
WHILE _MOUSEINPUT: WEND 'catch up to the current mouse's position so we sync properly
X = _MOUSEX: Y = _MOUSEY
MouseMoveX = 0: MouseMoveY = 0
IF Init = 0 THEN
Init = -1
CurrentX = _WIDTH \ 2: CurrentY = _HEIGHT \ 2
_MOUSEHIDE
_MOUSEMOVE _WIDTH \ 2, _HEIGHT \ 2
Pointer = _NEWIMAGE(16, 8, 32)
COLOR -1, 0
_PRINTSTRING (0, 0), CHR$(24), Pointer
ELSE
IF X <> _WIDTH \ 2 OR Y <> _HEIGHT \ 2 THEN
MouseMoveX = X - _WIDTH \ 2: MouseMoveY = Y - _HEIGHT \ 2
CurrentX = CurrentX + MouseMoveX
CurrentY = CurrentY + MouseMoveY
IF CurrentX < 0 THEN CurrentX = 0
IF CurrentX >= _WIDTH THEN CurrentX = _WIDTH - 1
IF CurrentY < 0 THEN CurrentY = 0
IF CurrentY >= _HEIGHT THEN CurrentY = _HEIGHT - 1
END IF
END IF
_PUTIMAGE (CurrentX - 8, CurrentY - 8)-STEP(32, 32), Pointer
_MOUSEMOVE _WIDTH / 2, _HEIGHT / 2
MouseX = CurrentX: MouseY = CurrentY
END SUB
Test that out and see if it doesn't keep track of the current mouse position, while also allowing for mouse movement to take place regardless of the edge of the screen.
Feel free to ask/add any questions, comments, or insights into the process here, but I'm thinking this should work on all OSes without any issues. (As long as _MouseHide works on all OSes... I didn't think to check to see if it does or doesn't, to be honest.)
Posts: 189
Threads: 22
Joined: Mar 2023
Reputation:
12
Thanks vm for this, Steve, but it doesn't run on MacOS. I've previously found you've gotta put the MOUSEX and Y polling inside the WHILE _MOUSEINPUT: WEND loop, which I did, but that wasn't enough. For some reason your pointer doesn't show up. The Total MouseMovementX & Y readouts show quickly rising negative numbers while the MOUSEMOVEMENTX & Y get stuck at -400, -300. MouseX & Y show zeros. Remming out the _MOUSEHIDE shows the system pointer angrily stuck in the middle of the screen...
What are you trying to pull here, Mr. McNeill?
Posts: 2,700
Threads: 328
Joined: Apr 2022
Reputation:
219
It doesn't work on Mac?
Mac mouse commands must be broken more than I'd ever thought they were!
What we're doing here is hiding our mouse, while creating an image of one which we track and display manually. The system mouse is always jumping back to the center of the screen, so we're always reading the relative movement on it...
And that leads to me wondering just WHICH of these commands is glitching out on Mac!
Gah! One of these days, I'm going to breakdown and buy an old second hand one from somewhere just for testing purposes.
Posts: 2,700
Threads: 328
Joined: Apr 2022
Reputation:
219
02-26-2024, 03:45 AM
(This post was last modified: 02-26-2024, 04:25 AM by SMcNeill.)
Give this version a test run, if you get a chance. IF you can't see a cursor with _PUTIMAGE, then maybe it's a color -1 issue? Or something else odd?
Code: (Select All)
DIM SHARED AS LONG MouseMoveX, MouseMoveY, MouseX, MouseY
SCREEN _NEWIMAGE(800, 600, 32)
_SCREENMOVE _MIDDLE
DO
CLS
Mouse
TMMX = TMMX + MouseMoveX: TMMY = TMMY + MouseMoveY
PRINT "Mouse x:"; MouseX
PRINT "Mouse y:"; MouseY
PRINT "MouseMoveX:"; MouseMoveX
PRINT "MouseMoveY:"; MouseMoveY
PRINT "Total MouseMoveX:"; TMMX
PRINT "TOtal MouseMoveY:"; TMMY
_LIMIT 30
_PRINTSTRING (MouseX, MouseY), CHR$(24)
_DISPLAY
LOOP UNTIL _MOUSEBUTTON(2)
SYSTEM
SUB Mouse
STATIC AS LONG CurrentX, CurrentY
STATIC AS INTEGER Init
WHILE _MOUSEINPUT
Xjunk = _MOUSEX: Yjunk = _MOUSEY
WEND 'catch up to the current mouse's position so we sync properly
X = _MOUSEX: Y = _MOUSEY
MouseMoveX = 0: MouseMoveY = 0
IF Init = 0 THEN
Init = -1
CurrentX = _WIDTH \ 2: CurrentY = _HEIGHT \ 2
_MOUSEHIDE
_MOUSEMOVE _WIDTH \ 2, _HEIGHT \ 2
ELSE
IF X <> _WIDTH \ 2 OR Y <> _HEIGHT \ 2 THEN
MouseMoveX = X - _WIDTH \ 2: MouseMoveY = Y - _HEIGHT \ 2
CurrentX = CurrentX + MouseMoveX
CurrentY = CurrentY + MouseMoveY
IF CurrentX < 0 THEN CurrentX = 0
IF CurrentX >= _WIDTH THEN CurrentX = _WIDTH - 1
IF CurrentY < 0 THEN CurrentY = 0
IF CurrentY >= _HEIGHT THEN CurrentY = _HEIGHT - 1
END IF
END IF
_MOUSEMOVE _WIDTH \ 2, _HEIGHT \ 2
WHILE _MOUSEINPUT
Xjunk = _MOUSEX: Yjunk = _MOUSEY
WEND 'clear the manual reset to the center so we don't read it in the next pass
MouseX = CurrentX: MouseY = CurrentY
END SUB
Even if the values do something odd (which I don't know why they should), you should still be able to see the arrow on the screen and move it around. In this case, it's only going to be a text sized character of an arrow (CHR$(24)), so you might need to strain your eyes to find it, but it should definitely be there.
Once a cursor is available and moving, then we can sort out what the heck is going on with the return values. Work on one thing at a time.
Posts: 189
Threads: 22
Joined: Mar 2023
Reputation:
12
I gave it a shot. The numbers don't change, though I do see the pointer stuck at 0, 0. You put that junkX/Y = _MOUSEX/Y inside the WHILE/WEND, but no info is transferred from those variables to the rest of your sub as written. I do get basic mouse x and y values and pointer movement from the below, but nothing from your sub...
Code: (Select All)
DIM SHARED AS LONG MouseX, MouseY
SCREEN _NEWIMAGE(800, 600, 32)
_SCREENMOVE _MIDDLE
DO
CLS
Mouse
TMMX = TMMX + MouseMoveX: TMMY = TMMY + MouseMoveY
PRINT "Mouse x:"; MouseX
PRINT "Mouse y:"; MouseY
PRINT "MouseMoveX:"; MouseMoveX
PRINT "MouseMoveY:"; MouseMoveY
PRINT "Total MouseMoveX:"; TMMX
PRINT "TOtal MouseMoveY:"; TMMY
_LIMIT 30
_PRINTSTRING (MouseX, MouseY), CHR$(24)
_DISPLAY
LOOP UNTIL _MOUSEBUTTON(2)
SYSTEM
SUB Mouse
WHILE _MOUSEINPUT
MouseX = _MOUSEX: MouseY = _MOUSEY
WEND '
_MOUSEHIDE
END SUB
Posts: 189
Threads: 22
Joined: Mar 2023
Reputation:
12
UPDATE: You got me thinking . . . Your idea here of resetting the mouse to middle of screen works to overcome the _mousemovementX issue pretty darned well! There's a slight pause in mouse control when the mouse position is reset, but that sure beats having to "unwind" the mouse to get more movement out of it. Thanks again, Sir Steve.
Posts: 2,700
Threads: 328
Joined: Apr 2022
Reputation:
219
@NakedApe The problem on Mac, it turns out, is the glutWarpPointer function that we call to move the mouse. For whatever reason, once it's called, it invokes a 250ms lockout of all keyboard and mouse events.
Move the mouse, we stop reading keyboard input and mouse events for a quarter of a second...
The loop is on a _LIMIT 30, so it's ran 7.5 times more often than that... So the vast majority of mouse movements and keypresses and such just get blocked by the system, by moving the mouse back to the center so often.
https://stackoverflow.com/questions/1019...deprecated <-- This may have a solution to that issue, as we've did some prelimary digging into it. All we need now is for our Mac guru's to have some free time so they can see about implementing the fix for us.
Posts: 98
Threads: 1
Joined: Jun 2023
Reputation:
3
SMcNeill,
No problem that I can tell on linux. The first on with a big pointer, all numbers shows up no delays in display. The same with the second one with a small pointer. I hope this helps in some way.
Posts: 2,700
Threads: 328
Joined: Apr 2022
Reputation:
219
Linux and Windows work as expected. Mac has the issue with glutWarpPointer that I mentioned above. We'll need to find a fix to it, and then this should work on all platforms in a consistant manner.
Posts: 2,700
Threads: 328
Joined: Apr 2022
Reputation:
219
One of our Mac users could test this out, if they'd be so kind, and tell us how it performs for them:
Code: (Select All)
DIM SHARED AS LONG MouseMoveX, MouseMoveY, MouseX, MouseY
SCREEN _NEWIMAGE(800, 600, 32)
_SCREENMOVE _MIDDLE
Pointer = _NEWIMAGE(16, 8, 32)
COLOR -1, 0
_PRINTSTRING (0, 0), CHR$(24), Pointer
DO
CLS
Mouse
TMMX = TMMX + MouseMoveX: TMMY = TMMY + MouseMoveY
PRINT "Mouse x:"; MouseX
PRINT "Mouse y:"; MouseY
PRINT "MouseMoveX:"; MouseMoveX
PRINT "MouseMoveY:"; MouseMoveY
PRINT "Total MouseMoveX:"; TMMX
PRINT "TOtal MouseMoveY:"; TMMY
_LIMIT 30
_PUTIMAGE (MouseX - 8, MouseY - 8)-STEP(32, 32), Pointer
_DISPLAY
LOOP UNTIL _MOUSEBUTTON(2)
SYSTEM
SUB Mouse
STATIC AS LONG CurrentX, CurrentY
STATIC AS INTEGER Init, counter
counter = (counter + 1) MOD 10
WHILE _MOUSEINPUT: WEND 'catch up to the current mouse's position so we sync properly
X = _MOUSEX: Y = _MOUSEY
MouseMoveX = 0: MouseMoveY = 0
IF Init = 0 THEN
Init = -1
CurrentX = _WIDTH \ 2: CurrentY = _HEIGHT \ 2
_MOUSEHIDE
_MOUSEMOVE _WIDTH \ 2, _HEIGHT \ 2
ELSE
IF X <> _WIDTH \ 2 OR Y <> _HEIGHT \ 2 THEN
MouseMoveX = X - _WIDTH \ 2: MouseMoveY = Y - _HEIGHT \ 2
CurrentX = CurrentX + MouseMoveX
CurrentY = CurrentY + MouseMoveY
IF CurrentX < 0 THEN CurrentX = 0
IF CurrentX >= _WIDTH THEN CurrentX = _WIDTH - 1
IF CurrentY < 0 THEN CurrentY = 0
IF CurrentY >= _HEIGHT THEN CurrentY = _HEIGHT - 1
END IF
END IF
IF counter = 0 THEN _MOUSEMOVE _WIDTH \ 2, _HEIGHT \ 2
MouseX = CurrentX: MouseY = CurrentY
END SUB
This seems hyper-sensitive to me on Windows for some reason, but the idea here is that this _MouseMove statement *only* occcurs on every 10th pass. (1/3rd of a second, while the _mousemove blocks input for 1/4th of a second.) I'm thinking that with a longer delay than the lock, Mac should still be able to read mouse events and report them for us. I'm not entriely certain how laggy/skippy it might be, and I wouldn't want to try and implement any actual program on Mac that uses _MouseMove right now. Have a program move the mouse and lock out keyboard and mouse input?? No thanks! What the heck type of glitch is that for glut?? And if it's not a glitch, then what the heck is its intended purpose?
This should just give some testable example of this glitch in action. Lower the mod on the counter to decrease delay between mousemove calls ( counter = (counter + 1) MOD 10); increase it to increase the delay between mousemove calls. Feel free to change it and see how it performs with various alterations to how fast mousemove is called.
I don't have a Mac for testing, so I'm kind of curious what type of results this will actually generate for us. My mind is telling me what I'd *expect* to happen. Now, whether or not that's actually happens, remains up to the OS to decide I guess. LOL! In the end, this still might not make any change to things with Mac, though I'd *think* that it should.
|