nesbox / TIC-80

TIC-80 is a fantasy computer for making, playing and sharing tiny games.
https://tic80.com
MIT License
5.05k stars 491 forks source link

Suggestion: add a mouse capture functionality #986

Closed MarcusPeixe closed 3 years ago

MarcusPeixe commented 4 years ago

Hello! I am here to suggest an enhancement.

I'd be great if we had some sort of way to capture the mouse inside the TIC-80 window, and a function that returns its offset relative to its previous location or something similar. Useful for 3D games or visualisation tools.

I know that the focus of TIC-80 is to mimic a retro console, and some people may find that such advanced functions do not fit the style, but we already have functions for interacting with the mouse and entire keyboard, as well as rendering textured triangles (textri), so you might as well consider my humble suggestion.

Regardless of the final decision, thanks for your precious time. :D

paul59 commented 4 years ago

What do you mean by 'capture the mouse' - keep it inside the window?

Getting the relative movement is simple enough to do, here's a quick example (sorry it it's obvious and you just meant having the luxury of a built-in function!):

local saved={}
local mx,my,_=mouse()
saved.x=mx
saved.y=my
function TIC()
    local xd,yd=getDeltas()
    trace("Mouse deltas "..xd..','..yd,0,0)
end
function getDeltas()
    local xdelta,ydelta=0,0
    mx,my,_=mouse()
    if mx~=saved.x then
        xdelta=mx-saved.x
        saved.x=mx
    end 
    if my~=saved.y then
        ydelta=my-saved.y
        saved.y=my
    end 
    return xdelta,ydelta
end
MarcusPeixe commented 4 years ago

The only problem would be when the mouse goes outside the window, because then your cart would be no longer able to track its movements. This makes it impossible for you to achieve a 360 degree view in any game or tool, controlled by the mouse. Perhaps it would be easier to implement a function which sets the cursor position, and call it on every frame to move the mouse back to the centre of the screen, but anyway, i hope you got the idea.

RobLoach commented 4 years ago

Forcing the mouse to not leave the window would be a nice feature. It is capable in RetroArch with the tic80 libretro core, but I think having it in the TIC-80 main application would be a great feature.

saranvdev commented 4 years ago

agreed bump

BraininaBowl commented 4 years ago

I'm using a system comparable to the suggestion by @paul59, but that stops working once the mouse hits the border of the screen. A way to set the mouse position to the center of the screen every frame would make my raycaster engine a lot more usable.

nesbox commented 3 years ago

Relative mouse mode added here 860dd0e. Please set relative bit in the mouse state (0x0FF84) to enable it, and you have to poke it every TIC() to keep it enabled. Here is an example, how to enable/disable it and print absolute/relative mouse coordinates:

rel=0
function flip(val)return val>0 and 0 or 1 end

function TIC()
    if btnp(4)then rel=flip(rel)end

    -- here we enable relative mode bit 0x0FF84*8+7=0x7FC3F
    poke(0x7FC3F,rel,1)

    cls()
    local x,y=mouse()
    print(x..":"..y)    
end

Enjoy!

joshgoebel commented 3 years ago

and you have to poke it every TIC() to keep it enabled.

This seems to make it different than every other stateful thing you poke into RAM (that I can think of)... most other states are persistent... why the inconsistency?

nesbox commented 3 years ago

why the inconsistency?

It was easier for me to handle this state, but you are right, it's inconsistency and I made a better fix here 94f76c6. The new example could look like

function flip(val)return val>0 and 0 or 1 end

function TIC()
    if btnp(4)then 
        -- here we enable/disable relative mode bit 0x0FF84*8+7=0x7FC3F
        poke(0x7FC3F,flip(peek(0x7FC3F,1)),1)
    end 

    cls()
    local x,y=mouse()
    print(x..":"..y)
end

Thank you for pointing this out to me.