fix jitter and mouse cursor accuracy
This commit is contained in:
parent
5a1d279b0a
commit
e3054bdb79
3 changed files with 257 additions and 300 deletions
147
pixler.bas
147
pixler.bas
|
|
@ -4,7 +4,7 @@ type statetype
|
|||
bcolor as long
|
||||
offsetx as long
|
||||
offsety as long
|
||||
zoom as single
|
||||
zoom as long
|
||||
brushsize as integer
|
||||
startx as long
|
||||
starty as long
|
||||
|
|
@ -55,7 +55,7 @@ for y=0 to _height-16 step 16
|
|||
next
|
||||
_dest 0
|
||||
state.tool=1
|
||||
state.zoom=1.0
|
||||
state.zoom=1
|
||||
state.offsetx=70+20
|
||||
state.offsety=20
|
||||
state. brushsize=1
|
||||
|
|
@ -66,8 +66,8 @@ addcommand"bcolor ("+hex$(state.bcolor)+")"
|
|||
|
||||
dim lastmx,lastmy
|
||||
dim keyin as string
|
||||
dim mouseworldy as integer
|
||||
dim mouseworldx as integer
|
||||
dim mouseworldy as long
|
||||
dim mouseworldx as long
|
||||
|
||||
dim diffx as integer
|
||||
dim diffy as integer
|
||||
|
|
@ -76,6 +76,7 @@ dim oldheight as integer
|
|||
oldwidth=_width
|
||||
oldheight=_height
|
||||
do
|
||||
' 1. Check for window resizing first
|
||||
if checkresize(_source)=-1 then
|
||||
diffx=_width-oldwidth
|
||||
diffy=_height-oldheight
|
||||
|
|
@ -85,12 +86,10 @@ do
|
|||
oldheight=_height
|
||||
end if
|
||||
|
||||
canvas
|
||||
if showtoolbox then toolbox
|
||||
if showcolorpicker then colorpicker
|
||||
if showcommands then commandlist
|
||||
' 2. Clear the screen BEFORE drawing anything for this frame
|
||||
line (0,0)-(_width-1,_height-1),backgroundcolor1,bf
|
||||
|
||||
'Mouse Handling
|
||||
' 3. Process all inputs and update offsets FIRST
|
||||
while _mouseinput:mw=mw+_mousewheel:wend
|
||||
mouseclicked=0
|
||||
rmouseclicked=0
|
||||
|
|
@ -101,63 +100,43 @@ do
|
|||
|
||||
' Panning (Middle Mouse)
|
||||
if _mousebutton(3) then
|
||||
state.offsetx=int(state.offsetx+(_mousex-lastmx))
|
||||
state.offsety=int(state.offsety+(_mousey-lastmy))
|
||||
state.offsetx=state.offsetx+(_mousex-lastmx)
|
||||
state.offsety=state.offsety+(_mousey-lastmy)
|
||||
end if
|
||||
lastmx=_mousex:lastmy=_mousey
|
||||
|
||||
' Zooming
|
||||
if mw<>0 then
|
||||
' 1. Capture current world position
|
||||
mouseworldx=(_mousex-state.offsetx)/state.zoom
|
||||
mouseworldy=(_mousey-state.offsety)/state.zoom
|
||||
|
||||
' 2. Calculate the new zoom level (Snap to whole numbers)
|
||||
if mw>0 then
|
||||
state.zoom=state.zoom+1
|
||||
else
|
||||
state.zoom=state.zoom-1
|
||||
end if
|
||||
|
||||
' 3. Constrain zoom (Min 1, Max 20)
|
||||
if mw>0 then state.zoom=state.zoom+1 else state.zoom=state.zoom-1
|
||||
if state.zoom<1 then state.zoom=1
|
||||
if state.zoom>20 then state.zoom=20
|
||||
|
||||
' 4. Adjust offsets
|
||||
state.offsetx=_mousex-(mouseworldx*state.zoom)
|
||||
state.offsety=_mousey-(mouseworldy*state.zoom)
|
||||
|
||||
mw=0
|
||||
end if
|
||||
|
||||
' Keyboarding
|
||||
keyin=inkey$
|
||||
select case keyin
|
||||
case "+"
|
||||
state.brushsize=state.brushsize+1
|
||||
addcommand"brushsize ("+tst(state.brushsize)+")"
|
||||
case "-"
|
||||
if state.brushsize>1 then state.brushsize=state.brushsize-1
|
||||
addcommand"brushsize ("+tst(state.brushsize)+")"
|
||||
case chr$(19) ' ctrl+s
|
||||
'TODO: save logic
|
||||
case chr$(27) ' esc
|
||||
menu
|
||||
case "h"
|
||||
state.zoom=1.0
|
||||
state.offsetx=(_width/2)-(_width(layers(0).ihandle)/2)
|
||||
state.offsety=(_height/2)-(_height(layers(0).ihandle)/2)
|
||||
case "t"
|
||||
showtoolbox=not showtoolbox
|
||||
case "c"
|
||||
showcolorpicker=not showcolorpicker
|
||||
case "l"
|
||||
showcommands=not showcommands
|
||||
case "+": state.brushsize=state.brushsize+1: addcommand"brushsize ("+tst(state.brushsize)+")"
|
||||
case "-": if state.brushsize>1 then state.brushsize=state.brushsize-1: addcommand"brushsize ("+tst(state.brushsize)+")"
|
||||
case "h": state.zoom=1: state.offsetx=(_width/2)-(_width(layers(0).ihandle)/2): state.offsety=(_height/2)-(_height(layers(0).ihandle)/2)
|
||||
case "t": showtoolbox=not showtoolbox
|
||||
case "c": showcolorpicker=not showcolorpicker
|
||||
case "l": showcommands=not showcommands
|
||||
end select
|
||||
|
||||
' 4. Draw everything using the freshly updated math
|
||||
canvas
|
||||
if showtoolbox then toolbox
|
||||
if showcolorpicker then colorpicker
|
||||
if showcommands then commandlist
|
||||
|
||||
' 5. Flip the buffer to the monitor cleanly
|
||||
_limit 30
|
||||
_display
|
||||
line (0,0)-(_width-1,_height-1),backgroundcolor1,bf
|
||||
loop
|
||||
|
||||
sub commandlist
|
||||
|
|
@ -366,50 +345,30 @@ sub canvas
|
|||
if showcolorpicker then viewy2=_height-20 else viewy2=_height-1
|
||||
_dest 0
|
||||
|
||||
' 2. Render Layers with Clipping
|
||||
dim srcx1 as long
|
||||
dim srcy1 as long
|
||||
dim srcx2 as long
|
||||
dim srcy2 as long
|
||||
dim drawx1 as long
|
||||
dim drawy1 as long
|
||||
dim drawx2 as long
|
||||
dim drawy2 as long
|
||||
|
||||
dim i as integer
|
||||
for i=0 to ubound(layers)
|
||||
dim img as long:img=layers(i).ihandle
|
||||
dim imgw as integer:imgw=_width(img)
|
||||
dim imgh as integer:imgh=_height(img)
|
||||
|
||||
' Current scaled dimensions
|
||||
dim fullscaledw as single:fullscaledw=imgw*state.zoom
|
||||
dim fullscaledh as single:fullscaledh=imgh*state.zoom
|
||||
|
||||
' Calculate visible area in screen coordinates (Overlap of image and viewport)
|
||||
drawx1=state.offsetx
|
||||
drawy1=state.offsety
|
||||
drawx2=state.offsetx+fullscaledw
|
||||
drawy2=state.offsety+fullscaledh
|
||||
|
||||
' Clip the destination to the Viewport
|
||||
if drawx1<viewx1 then drawx1=viewx1
|
||||
if drawy1<viewy1 then drawy1=viewy1
|
||||
if drawx2>viewx2 then drawx2=viewx2
|
||||
if drawy2>viewy2 then drawy2=viewy2
|
||||
|
||||
' Only draw if the image is actually inside the viewport
|
||||
if drawx2>drawx1 and drawy2>drawy1 then
|
||||
' Map screen-clipped coordinates back to the source image coordinates
|
||||
srcx1=int((drawx1-state.offsetx)/state.zoom)
|
||||
srcy1=int((drawy1-state.offsety)/state.zoom)
|
||||
srcx2=int((drawx2-state.offsetx)/state.zoom)
|
||||
srcy2=int((drawy2-state.offsety)/state.zoom)
|
||||
|
||||
' Syntax: _PUTIMAGE (destX1, destY1)-(destX2, destY2), sourceHandle, 0, (srcX1, srcY1)-(srcX2, srcY2)
|
||||
_putimage (drawx1,drawy1)-(drawx2,drawy2),img,0,(srcx1,srcy1)-(srcx2,srcy2)
|
||||
end if
|
||||
next
|
||||
' 2. Render Layers (Let QB64 handle the viewport clipping natively)
|
||||
dim i as integer
|
||||
for i = 0 to ubound(layers)
|
||||
dim img as long: img = layers(i).ihandle
|
||||
dim imgw as integer: imgw = _width(img)
|
||||
dim imgh as integer: imgh = _height(img)
|
||||
|
||||
' Calculate the absolute unclipped destination positions
|
||||
drawx1 = state.offsetx
|
||||
drawy1 = state.offsety
|
||||
drawx2 = state.offsetx + (imgw * state.zoom)
|
||||
drawy2 = state.offsety + (imgh * state.zoom)
|
||||
|
||||
' Direct 1:1 mapping of the entire source asset
|
||||
srcx1 = 0
|
||||
srcy1 = 0
|
||||
srcx2 = imgw
|
||||
srcy2 = imgh
|
||||
|
||||
' Only draw if the asset is within the general view window range
|
||||
if drawx2 > viewx1 and drawx1 < viewx2 and drawy2 > viewy1 and drawy1 < viewy2 then
|
||||
_putimage (drawx1, drawy1)-(drawx2, drawy2), img, 0, (srcx1, srcy1)-(srcx2, srcy2)
|
||||
end if
|
||||
next
|
||||
_dest layers(2).ihandle:cls,0:_dest 0
|
||||
' 2.5 if the mouse is in ui thats all we need
|
||||
if showtoolbox then
|
||||
|
|
@ -428,12 +387,14 @@ sub canvas
|
|||
end if
|
||||
end if
|
||||
|
||||
' 3. Calculate Canvas Coordinates
|
||||
' 3. Calculate Canvas Coordinates (Center-aligned to the zoom block)
|
||||
dim canx as long
|
||||
dim cany as long
|
||||
canx=int((_mousex-state.offsetx)/state.zoom)
|
||||
cany=int((_mousey-state.offsety)/state.zoom)
|
||||
|
||||
|
||||
' Add half a zoomed pixel block to align the mouse tip to the block center
|
||||
canx = int((_mousex - state.offsetx + (state.zoom \ 2)) / state.zoom)
|
||||
cany = int((_mousey - state.offsety + (state.zoom \ 2)) / state.zoom)
|
||||
|
||||
static drawcol
|
||||
if _mousebutton(1) then drawcol=state.fcolor
|
||||
if _mousebutton(2) then drawcol=state.bcolor
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue