mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-15 07:41:21 +02:00
better hover
This commit is contained in:
+105
-4
@@ -370,6 +370,7 @@ local function cartProject(cx, cy, yaw, pitch, x, y, z)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function cartPolygon(points, color, alpha)
|
local function cartPolygon(points, color, alpha)
|
||||||
|
if not love.graphics.polygon then return end
|
||||||
local flat = {}
|
local flat = {}
|
||||||
for i = 1, #points do
|
for i = 1, #points do
|
||||||
flat[#flat + 1], flat[#flat + 2] = points[i][1], points[i][2]
|
flat[#flat + 1], flat[#flat + 2] = points[i][1], points[i][2]
|
||||||
@@ -423,6 +424,55 @@ local function cartLabelMesh(imp, version, label, points)
|
|||||||
return mesh
|
return mesh
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local CART_HOVER_SHADER = [[
|
||||||
|
extern vec2 mouse_screen_pos;
|
||||||
|
extern float hovering;
|
||||||
|
extern float screen_scale;
|
||||||
|
|
||||||
|
#ifdef VERTEX
|
||||||
|
vec4 position(mat4 transform_projection, vec4 vertex_position) {
|
||||||
|
if (hovering <= 0.) {
|
||||||
|
return transform_projection * vertex_position;
|
||||||
|
}
|
||||||
|
float mid_dist = length(vertex_position.xy - 0.5 * love_ScreenSize.xy)
|
||||||
|
/ length(love_ScreenSize.xy);
|
||||||
|
vec2 mouse_offset = (vertex_position.xy - mouse_screen_pos.xy) / screen_scale;
|
||||||
|
float scale = 0.2 * (-0.03 - 0.3 * max(0., 0.3 - mid_dist))
|
||||||
|
* hovering * (length(mouse_offset) * length(mouse_offset)) / (2. - mid_dist);
|
||||||
|
return transform_projection * vertex_position + vec4(0.0, 0.0, 0.0, scale);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PIXEL
|
||||||
|
vec4 effect(vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords) {
|
||||||
|
return Texel(tex, texture_coords) * color;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
]]
|
||||||
|
|
||||||
|
local function cartHoverShader(imp)
|
||||||
|
if imp._cartHoverShader ~= nil then
|
||||||
|
return imp._cartHoverShader or nil
|
||||||
|
end
|
||||||
|
if not (love.graphics and love.graphics.newShader) then
|
||||||
|
imp._cartHoverShader = false
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local ok, sh = pcall(love.graphics.newShader, CART_HOVER_SHADER)
|
||||||
|
imp._cartHoverShader = ok and sh or false
|
||||||
|
return imp._cartHoverShader or nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local function cartSendHover(shader, mx, my, hovering, screenScale)
|
||||||
|
if not shader or not shader.send then return false end
|
||||||
|
local ok = pcall(function()
|
||||||
|
shader:send("mouse_screen_pos", { mx, my })
|
||||||
|
shader:send("hovering", hovering)
|
||||||
|
shader:send("screen_scale", screenScale)
|
||||||
|
end)
|
||||||
|
return ok
|
||||||
|
end
|
||||||
|
|
||||||
local function cartridgeButton(imp, x, y, w, h, key, version, gameName, action)
|
local function cartridgeButton(imp, x, y, w, h, key, version, gameName, action)
|
||||||
local state = cartridgeState(imp, version)
|
local state = cartridgeState(imp, version)
|
||||||
local focused = Kit.focusable(key, x, y, w, h)
|
local focused = Kit.focusable(key, x, y, w, h)
|
||||||
@@ -474,13 +524,50 @@ local function cartridgeButton(imp, x, y, w, h, key, version, gameName, action)
|
|||||||
end
|
end
|
||||||
local pointerX = clamp((Kit.mouseX - cx) / math.max(1, w / 2), -1, 1)
|
local pointerX = clamp((Kit.mouseX - cx) / math.max(1, w / 2), -1, 1)
|
||||||
local pointerY = clamp((Kit.mouseY - cy) / math.max(1, h / 2), -1, 1)
|
local pointerY = clamp((Kit.mouseY - cy) / math.max(1, h / 2), -1, 1)
|
||||||
local hoverTilt = hot and pointerX * 0.12 or math.sin(Kit.time * 0.75) * 0.035
|
local hoverFx = hot or focused
|
||||||
|
if hoverFx and not state.wasHot then
|
||||||
|
state.juiceStart = Kit.time
|
||||||
|
state.juiceScaleAmt = 0.02
|
||||||
|
state.juiceRAmt = (math.random() > 0.5 and 1 or -1) * 0.012
|
||||||
|
state.visScale = 1 - 0.6 * 0.02
|
||||||
|
end
|
||||||
|
state.wasHot = hoverFx
|
||||||
|
local juiceScale, juiceR = 0, 0
|
||||||
|
if state.juiceStart then
|
||||||
|
local juiceT = Kit.time - state.juiceStart
|
||||||
|
if juiceT >= 0.4 then
|
||||||
|
state.juiceStart = nil
|
||||||
|
else
|
||||||
|
local remain = (0.4 - juiceT) / 0.4
|
||||||
|
juiceScale = state.juiceScaleAmt * math.sin(50.8 * juiceT) * remain ^ 3
|
||||||
|
juiceR = state.juiceRAmt * math.sin(40.8 * juiceT) * remain ^ 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
state.visScale = state.visScale or 1
|
||||||
|
local desScale = (hoverFx and 1.05 or 1) + juiceScale
|
||||||
|
local ease = math.exp(-60 * dt)
|
||||||
|
state.visScale = ease * state.visScale + (1 - ease) * desScale
|
||||||
|
if not state.animId then
|
||||||
|
local n, s = 0, tostring(version)
|
||||||
|
for i = 1, #s do n = n + s:byte(i) * i end
|
||||||
|
state.animId = n
|
||||||
|
end
|
||||||
|
local hoverMx, hoverMy
|
||||||
|
if hot then
|
||||||
|
hoverMx, hoverMy = Kit.mouseX, Kit.mouseY
|
||||||
|
elseif focused then
|
||||||
|
hoverMx, hoverMy = cx, cy
|
||||||
|
else
|
||||||
|
local tiltAngle = Kit.time * (1.56 + (state.animId / 1.14212) % 1)
|
||||||
|
+ state.animId / 1.35122
|
||||||
|
hoverMx = x + (0.5 + 0.1 * math.cos(tiltAngle)) * w
|
||||||
|
hoverMy = y + (0.5 + 0.1 * math.sin(tiltAngle)) * h
|
||||||
|
end
|
||||||
local pressX = active and pointerX * w * 0.025 or 0
|
local pressX = active and pointerX * w * 0.025 or 0
|
||||||
local pressY = active and pointerY * h * 0.018 or 0
|
local pressY = active and pointerY * h * 0.018 or 0
|
||||||
local yaw = -0.42 + state.spin + hoverTilt
|
local yaw = -0.42 + state.spin
|
||||||
local pitch = 0.14 + (state.pitchDrag or 0)
|
local pitch = 0.14 + (state.pitchDrag or 0)
|
||||||
+ (hot and pointerY * 0.08 or math.sin(Kit.time * 0.6) * 0.018)
|
local pressedScale = (active and 0.965 or 1) * state.visScale
|
||||||
local pressedScale = active and 0.965 or 1
|
|
||||||
|
|
||||||
Kit._audit("control", x, y, w, h, key)
|
Kit._audit("control", x, y, w, h, key)
|
||||||
if focused then
|
if focused then
|
||||||
@@ -494,6 +581,19 @@ local function cartridgeButton(imp, x, y, w, h, key, version, gameName, action)
|
|||||||
return cartProject(cx + pressX, cy + pressY, yaw, pitch,
|
return cartProject(cx + pressX, cy + pressY, yaw, pitch,
|
||||||
px * pressedScale, py * pressedScale, pz * pressedScale)
|
px * pressedScale, py * pressedScale, pz * pressedScale)
|
||||||
end
|
end
|
||||||
|
local shader = cartHoverShader(imp)
|
||||||
|
local useHover = shader
|
||||||
|
and cartSendHover(shader, hoverMx, hoverMy, 1,
|
||||||
|
math.max(1, 0.4 * math.min(w, h)))
|
||||||
|
if not useHover then
|
||||||
|
yaw = yaw + (hoverMx - cx) / math.max(1, w / 2) * 0.08
|
||||||
|
pitch = pitch + (hoverMy - cy) / math.max(1, h / 2) * 0.05
|
||||||
|
end
|
||||||
|
love.graphics.push("all")
|
||||||
|
love.graphics.translate(cx, cy)
|
||||||
|
love.graphics.rotate(juiceR * 2)
|
||||||
|
love.graphics.translate(-cx, -cy)
|
||||||
|
if useHover then love.graphics.setShader(shader) end
|
||||||
|
|
||||||
local capH = h * 3 / 65
|
local capH = h * 3 / 65
|
||||||
local mainTop = -halfH + capH
|
local mainTop = -halfH + capH
|
||||||
@@ -553,6 +653,7 @@ local function cartridgeButton(imp, x, y, w, h, key, version, gameName, action)
|
|||||||
{ project(w * 0.07, h * 0.37, faceZ + 1) },
|
{ project(w * 0.07, h * 0.37, faceZ + 1) },
|
||||||
{ project(0, h * 0.43, faceZ + 1) },
|
{ project(0, h * 0.43, faceZ + 1) },
|
||||||
}, side, 0.70)
|
}, side, 0.70)
|
||||||
|
love.graphics.pop()
|
||||||
|
|
||||||
if not state.active and (Kit._activateId == key) then
|
if not state.active and (Kit._activateId == key) then
|
||||||
queueAction(imp, key, action)
|
queueAction(imp, key, action)
|
||||||
|
|||||||
Reference in New Issue
Block a user