randrew / uxn32

Uxn emulator for Windows and Wine
169 stars 7 forks source link

Mouse updates are only provided if the mouse vector is set #14

Open hikari-no-yume opened 1 year ago

hikari-no-yume commented 1 year ago

Or at least, I think that's what's going on? oneko-uxn's first release doesn't work for this reason: I only check the mouse inputs in the screen vector, and never set the mouse vector. Should I not be doing that? I guess it'd be easy to change my code to be compatible with uxn32, but I'm kinda worried about this being a potential compatibility issue in general.

hikari-no-yume commented 1 year ago

/cc @neauoire: the varvara docs don't seem to say anything about whether this is correct or not.

neauoire commented 1 year ago

The keyboard and mouse should still be accessible even if vectors are not set. Inversely, you should still be able to get a valid screen size from within the mouse event, even if there are no screen vector set.

I'll add a note on the docs to make this explicit.

randrew commented 1 year ago

The keyboard and mouse should still be accessible even if vectors are not set. Inversely, you should still be able to get a valid screen size from within the mouse event, even if there are no screen vector set.

When I implemented the mouse handling in Uxn32, I'm pretty sure I talked to you on IRC and we agreed that the behavior of Uxn32 is fine. The emulator doesn't need to provide mouse position if the mouse vector isn't set. Uxn32 is designed around this, and if the mouse vector isn't set, the mouse cursor operates in an alternate mouse mode where the host cursor isn't hidden and doesn't invoke input events to the emulator and executing ROM code.

If your game needs to use the mouse, you need to at least set a dummy routine to the mouse vector to instruct the emulator to track and capture or hide the host mouse cursor. If you set a routine that just returns, you will be able to get the mouse cursor position in the screen update routine from the mouse device, even if you don't handle the mouse input in the mouse routine/vector.

I can't easily change this code in Uxn32.

hikari-no-yume commented 1 year ago

Hmm… I mean, I doubt I'm the first or the last person to write code that works this way. Wouldn't it be possible to detect use of DEI on the mouse values and enable mouse input anyway?

randrew commented 1 year ago

That seems even weirder, doesn't it?

randrew commented 1 year ago

You probably are the first person to run into this problem, though. You need to at least set a routine to the mouse vector, even if all it does is BRK. Otherwise, Uxn32 doesn't know to hide the standard Windows mouse cursor and do the work for dealing with the mouse.

neauoire commented 1 year ago

I've done a quick look around and it's true that I never made a project where I don't handle the mouse events, but still request them as part of another vector. But I did found one project where all the button handling is done during screen events, I hadn't tried it on uxn32 before so I would have caught this.

I'll think about this, I remember we talked about registering devices by settings vectors, I hadn't thought about this case. I can tell people to set vectors to devices that are in use in the meantime. My plan was to originally use that as a way to do some device compatibility erroring, like setting a mouse vector on an emulator without a mouse could be throwing a warning on vector setting.

On 7/2/23, Andrew Richards @.***> wrote:

You probably are the first person to run into this problem, though. You need to at least set a routine to the mouse vector, even if all it does is BRK. Otherwise, Uxn32 doesn't know to hide the standard Windows mouse cursor and do the work for dealing with the mouse.

-- Reply to this email directly or view it on GitHub: https://github.com/randrew/uxn32/issues/14#issuecomment-1616820219 You are receiving this because you were mentioned.

Message ID: @.***>

randrew commented 1 year ago

I think those two things are compatible. It might even be the best way to do it. Set mouse vector to try to use it -> get a an error flag set somewhere, now the ROM knows it can't use the mouse and uses some other input method.

hikari-no-yume commented 1 year ago

A few thoughts.

Speaking about programming in general, rather than just uxn, I think it is common, or at least not rare, that people write programs that poll for events during drawing, rather than actually using event handlers. I have a few reasons to think this:

Considering all that, suppose you're writing an uxn app and you feel like using polling. You write a screen vector that draws something, and now you want to add input handling. Since varvara lets you directly read the mouse and controller values outside their vectors with DEI/DEI2, you just add those to your screen vector, and it works fine in uxnemu, the original and most popular emulator. Since you don't have a need for the other vectors, and there is no specific guidance in the documentation, you don't even think about setting them. That's exactly the trap I fell into, and I can only assume many other people could stumble into it also.

At the very least, I think this kind of requirement should be documented. But considering people will often miss that something is de jure wrong if it de facto works when they try it, it would be better if the emulator behaviour would prevent you from making a program that accidentally works in some emulators. Some options:

A more radical solution would be to not use DEI at all for inputs that require vectors: what if the mouse X and Y (etc) were pushed onto the stack before calling the mouse vector? But that would break all the existing software…


Re: being able to check if setting the mouse vector worked, I can see that being useful. I think a reasonable way to allow that would be to return 0000 if the vector is read back.

neauoire commented 1 year ago

After sleeping on this, I think devices supported by the emulator shouldn't require a vector to be set at all. Devices should write the values in memory either way, the pattern of setting a vector to test for a device's support wouldn't be equal across all devices. Reading the Screen width should always work, even if there isn't a vector set for the Screen device.

I'll make it explicit in the docs. Uxn32 will have to be modified to support this, in the meantime you can set a BRK vector in xneko to the devices needed during the Screen vector?

On 7/3/23, hikari_no_yume @.***> wrote:

A few thoughts.

Speaking about programming in general, rather than just uxn, I think it is common, or at least not rare, that people write programs that poll for events during drawing, rather than actually using event handlers. I have a few reasons to think this:

  • I've done this in several of my own games for systems other than uxn.
  • The way it lets you put everything in one function (drawing, input handling and game logic) is very convenient and natural in my opinion.
  • It is the straightforward way to do things when implementing an immediate-mode GUI system, which is a popular approach in game development.

Considering all that, suppose you're writing an uxn app and you feel like using polling. You write a screen vector that draws something, and now you want to add input handling. Since varvara lets you directly read the mouse and controller values outside their vectors with DEI/DEI2, you just add those to your screen vector, and it works fine in uxnemu, the original and most popular emulator. Since you don't have a need for the other vectors, and there is no specific guidance in the documentation, you don't even think about setting them. That's exactly the trap I fell into, and I can only assume many other people could stumble into it also.

At the very least, I think this kind of requirement should be documented. But considering people will often miss that something is de jure wrong if it de facto works when they try it, it would be better if the emulator behaviour would prevent you from making a program that accidentally works in some emulators. Some options:

  • If we want to allow this pattern, then Uxn32 can accommodate it by detecting use of DEI to read the mouse/controller device.
  • If we want to disallow this pattern, then either:
    • emulators should be required to return 0 for use of DEI on the mouse/controller state unless their respective vectors are set
    • emulators should be required to return 0 for the use of DEI on the mouse/controller state when this happens outside the respective vector

A more radical solution would be to not use DEI at all for inputs that require vectors: what if the mouse X and Y (etc) were pushed onto the stack before calling the mouse vector? But that would break all the existing software…


Re: being able to check if setting the mouse vector worked, I can see that being useful. I think a reasonable way to allow that would be to return 0000 if the vector is read back.

-- Reply to this email directly or view it on GitHub: https://github.com/randrew/uxn32/issues/14#issuecomment-1617928880 You are receiving this because you were mentioned.

Message ID: @.***>

hikari-no-yume commented 1 year ago

For oneko-uxn I'll probably implement an actual mouse vector anyway, because it's more efficient (no unnecessary “has the mouse moved” check every frame), it can give more responsive movement in emulators like Uxn32 that support >60Hz mouse updates, and it will be easier to support a gamepad this way. That it fixes Uxn32 in the process is a nice bonus.

randrew commented 1 year ago

Uxn32 will have to be modified to support this

It will have to be redesigned to support this. And there will need to be some way to recognize if the Uxn ROM program is drawing a mouse cursor or not, somehow. Because losing the mouse cursor when the user mouses over the window isn't a desirable behavior for a desktop program. At least not in Windows.

randrew commented 1 year ago

Well, maybe it's OK to just lose the mouse cursor? I don't know. Maybe it's fine.

neauoire commented 1 year ago

On uxnemu I always hide the mouse cursor, even for programs like tetris which doesn't make use of the mouse, it might be better off without. The issue I can think of, is that you'd still want to see the cursor when beetbug is visible.

On 7/3/23, Andrew Richards @.***> wrote:

Well, maybe it's OK to just lose the mouse cursor? I don't know. Maybe it's fine.

-- Reply to this email directly or view it on GitHub: https://github.com/randrew/uxn32/issues/14#issuecomment-1619250360 You are receiving this because you were mentioned.

Message ID: @.***>

randrew commented 1 year ago

The mouse cursor is already handled correctly for Beetbug, even when the Uxn ROM program has the mouse vector set.

hikari-no-yume commented 1 year ago

Is there any reason detecting DEI/DEI2 use on the mouse ports wouldn't work? I suppose you could make a ROM that does read the mouse co-ords but doesn't draw its own cursor, but considering uxnemu's behaviour I don't think that needs to be worried about.

randrew commented 1 year ago

It would work, but it's a bit weird. I wouldn't expect reading from an apparently read-only location to have such large external effects as hiding the mouse cursor for the end user.