Feature Request: Kernal Mouse VX/VY

Chat about anything CX16 related that doesn't fit elsewhere
Post Reply
ZeroByte
Posts: 714
Joined: Wed Feb 10, 2021 2:40 pm

Feature Request: Kernal Mouse VX/VY

Post by ZeroByte »


TL;DR:

The Kernal should also store and report raw mouse delta-X/delta-Y movement, and have a mode e.g. MOUSE 2, that polls the mouse dX/dY but hides the mouse pointer and does not update X and Y.

The Problem:

Currently, the Kernal only polls the mouse if it is enabled (visible), and the Kernal drives sprite 0 as the pointer and only considers it as being "on screen" at all times. It computes and stores the pointer's X and Y coordinates, and clamps them to always be on-screen. This is fantastic for a GUI or something where you're pointing at stuff on the screen, but that's not all a mouse gets used for. If you'd like to do spiffy things with a UI such as click-and-drag to interact with a widget, you may want to hide the mouse pointer and start updating the widget as the mouse drags, and when released, have the mouse pointer reappear at the same location as it was when it was hidden.

Also, what about games that want to use the mouse as an analog input? They may not even want a pointer. They may pan the screen or steer a car or whatever, and this action has nothing to do with an on-screen pointer's X/Y location. What's worse is if the pointer makes it to the edge of the screen, you can't keep sliding that way - you're boxed in.

Basically, if you do want mouse polling, but you DON'T want a pointer, you're SOL.

It's been a long time since I ever did anything with a mouse in code, but when I did, I remember the API returning dX, and dY; not X and Y. In other words, you get the raw delta-X and delta-Y since last poll. The Kernal could offer these for next to no overhead, as that's the format the mouse actually sends to the host anyway.

The solution:

I've read the kernal's mouse code, and it would be trivial to add 2 more bytes to the KVARSB0 segment - storing the raw VX / VY values as they're read in from the mouse. The kernal also stores the sign bits and overflow bits for these deltas because they're the high nybble of the "buttons" byte.

The kernal could have another API function mouse_get_velocity which works in the identical fashion as mouse_get: pass a value in X for the desired ZP address of the 4 bytes to write out. These should be signed 16-bit values, and leave the button state in A.

Worst case, the Kernal would also need to accumulate the dx/dy values and zero them out whenever mouse_get_velocity is called.

ZeroByte
Posts: 714
Joined: Wed Feb 10, 2021 2:40 pm

Feature Request: Kernal Mouse VX/VY

Post by ZeroByte »


After some thought, another option might be to just provide a new kernal API function MOUSE_GET_RAW which immediately polls the mouse and returns buttons+signbits in A, dX in X, and dY in Y but only for mouse mode 0. If the MOUSE mode is currently non-zero (i.e. the kernal is controlling the mouse) then just return all zeros.

If the kernal were to keep DX and DY while in control of mouse X and Y, it would need to keep accumulating dX and dY until such time as mouse_get_velocity (as proposed above) is called, so that apps polling less often wouldn't miss motion.

This is a kind of "middle" solution where the user gets to choose whether the kernal is controlling the mouse or not, and if not, may still request dX/dY mouse status and use it however desired, and this wouldn't put any extra strain / changes on the existing kernal mouse routines.

 

Another option for programmers would be to use the kernal's internal function ps2_receive_byte routine directly and roll-your-own mouse code, but obviously, using non-published functions is discouraged right now while the kernal is in flux. I strongly suspect that this would possibly lead to the ability to create mouse wheel support. (not sure how that might work on the emu - I haven't looked at how it translates mouse inputs to PS2 requests but it should be perfectly doable on real HW.)

Ed Minchau
Posts: 503
Joined: Sat Jul 11, 2020 3:30 pm

Feature Request: Kernal Mouse VX/VY

Post by Ed Minchau »


One solution for the click-and-drag is to substitute a "drag" image for the default mouse pointer image.  You only need to change the bytes at 1FC00, 1FC01, 1FC06, and 1FC07 to point to a new image address and other attributes.  Then when the drag is done, revert to the original image, or change the mouse pointer to some other image you design.  It's the same as any other sprite, only you don't need to control the X and Y directly.

Ender
Posts: 220
Joined: Sat May 09, 2020 9:32 pm

Feature Request: Kernal Mouse VX/VY

Post by Ender »


This would probably be a good thing to create an issue for on the kernal github repo.  Michael's probably more likely to see it that way, and they can track it in github.

ZeroByte
Posts: 714
Joined: Wed Feb 10, 2021 2:40 pm

Feature Request: Kernal Mouse VX/VY

Post by ZeroByte »


I'm currently going down the rabbit hole of the mouse communication protocol.

This is because I see no reason that the X16 should not be able to support mouse wheel. It only requires a slightly different initialization exchange with the mouse in order to place it in "Intellimouse mode" at which point it returns 4 bytes per query instead of 3, with the 3rd byte being the Z axis movement (mouse wheel). This would not work on the current emulator or on box16, as they do not implement full mouse emulation - just enough to send standard 3-byte movement packets and the ACK bytes when data is received from the X16 host.

I'm considering whether I'd like to experiment with this. The biggest issue I see is that I really couldn't validate any results, as I'd be writing X16 code that talks to emulator code that I also wrote - thus if I've made any mistakes in my interpretation of the hardware behavior / protocol, my tests wouldn't show this. They would only show that I can talk to myself. ?

A real Commander X16 would not have such an issue - if you have the proper conversation with the mouse, then it will go into Intellimouse mode. Why wouldn't it? It doesn't know it's not connected to a PC running Windows.... In this case, even if the Kernal doesn't support it, there's nothing stopping you from writing your own mouse driver and disabling the kernal mouse driver (MOUSE 0)

Here's the document I'm currently referencing

Of note: Intellimouse mode would cause mouse polling to be 33% slower, as the CPU would have to shift in an additional 11 bits per query, so that's one reason you may not wish to use mouse wheel mode.

kelli217
Posts: 535
Joined: Sun Jul 05, 2020 11:27 pm

Feature Request: Kernal Mouse VX/VY

Post by kelli217 »


I guess the way things work out with proto#3 will determine whether the mouse routines will be rewritten; if they are, then perhaps this opens the door for your request. If not, then you might have a steeper hill to climb.

Post Reply