1
0
Fork 0
mirror of https://github.com/notwa/mm synced 2024-11-04 22:39:02 -08:00

implement greedy menu input handler

This commit is contained in:
Connor Olding 2015-11-14 16:30:04 -08:00
parent 2436eee982
commit b169d1d11e
7 changed files with 134 additions and 45 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
lua chest test
lua movement test
cheat menu.save.lua
* - Copy*

View file

@ -3,6 +3,7 @@ require "boilerplate"
require "addrs.init"
require "classes"
require "menu classes"
require "menu input handlers"
require "messages"
require "flag manager"
@ -17,15 +18,24 @@ alternate: (alt_input = true; eat_input = false)
L+R opens/closes the menu
L goes back a menu (or closes)
R selects menu items
L+Z hides menu without closing (FIXME: interferes with back)
L+Z hides the menu without closing (FIXME: interferes with back button)
D-Pad navigates
greedy: (alt_input = false; eat_input = true)
L opens the menu
while the menu is open, the game receives no inputs
D-Pad/Joystick/C-Buttons navigate through items and pages
A/L select menu items
B/R go back a menu (or closes)
Z hides the menu without closing
TODO: joystick, a/b button etc
greedy alt: (alt_input = true; eat_input = true)
same as greedy but pauses the game while in menu
(enables run_while_paused)
--]]
local run_while_paused = true
local alt_input = true
local eat_input = false
local eat_input = true
local fn = 'cheat menu.save.lua'
local saved = deserialize('cheat menu.save.lua') or {}
@ -277,51 +287,32 @@ local main_menu = Menu{
},
}
local input = InputHandler{
L = "P1 L",
R = "P1 R",
Z = "P1 Z",
up = "P1 DPad U",
down = "P1 DPad D",
left = "P1 DPad L",
right = "P1 DPad R",
}
local input = InputHandler()
input = JoyWrapper(input)
local handle = MenuHandler(main_menu, T_TL)
function handle_alt_input(handle, ctrl, pressed)
pressed.enter = false
ctrl.enter = false
local open_close = ctrl.L and ctrl.R and (pressed.L or pressed.R)
local hide = ctrl.L and ctrl.Z and (pressed.L or pressed.Z)
if open_close then
if handle.menu then -- if menu is open
handle:navigate('close')
else
pressed.enter = true
ctrl.enter = true
end
else
if hide then
handle:navigate('hide')
elseif pressed.L then
handle:navigate('back')
elseif handle.menu then
pressed.enter = pressed.R
ctrl.enter = ctrl.R
end
end
end
while mm or oot do
local ctrl, pressed = input:update()
if alt_input then
if eat_input then
local old_menu = handle.menu
handle_eat_input(handle, ctrl, pressed)
if alt_input and handle.menu ~= old_menu then
run_while_paused = true
if handle.menu then client.pause() else client.unpause() end
end
elseif alt_input then
handle_alt_input(handle, ctrl, pressed)
else
for _, v in ipairs{'left', 'right', 'up', 'down'} do
ctrl[v] = ctrl['d_'..v]
pressed[v] = pressed['d_'..v]
end
ctrl.enter = ctrl.L
pressed.enter = pressed.L
end
handle:update(ctrl, pressed)
end
for i, passive in ipairs(passives) do
passive:tick()

View file

@ -11,6 +11,7 @@ local classes = {
"SceneFlagMonitor",
"ActorLister",
"InputHandler",
"JoyWrapper",
}
for _, class in ipairs(classes) do

View file

@ -1,6 +1,25 @@
local InputHandler = Class()
function InputHandler:init(binds)
self.binds = binds
self.binds = binds or {
A = "P1 A",
B = "P1 B",
L = "P1 L",
R = "P1 R",
Z = "P1 Z",
d_up = "P1 DPad U",
d_down = "P1 DPad D",
d_left = "P1 DPad L",
d_right = "P1 DPad R",
j_up = "P1 Joy U",
j_down = "P1 Joy D",
j_left = "P1 Joy L",
j_right = "P1 Joy R",
c_up = "P1 C Up",
c_down = "P1 C Down",
c_left = "P1 C Left",
c_right = "P1 C Right",
start = "P1 Start",
}
self.old_ctrl = {}
end

View file

@ -0,0 +1,20 @@
local JoyWrapper = Class()
function JoyWrapper:init(handler, threshold)
self.handler = handler
self.old_ctrl = {}
self.threshold = threshold or 80
end
function JoyWrapper:update(inputs)
local j = inputs or joypad.getimmediate()
local jj = joypad.get()
local jx = jj['P1 X Axis']
local jy = jj['P1 Y Axis']
j["P1 Joy R"] = jx >= self.threshold or jj['P1 A Right']
j["P1 Joy L"] = jx <= -self.threshold or jj['P1 A Left']
j["P1 Joy U"] = jy >= self.threshold or jj['P1 A Up']
j["P1 Joy D"] = jy <= -self.threshold or jj['P1 A Down']
return self.handler:update(j)
end
return JoyWrapper

View file

@ -275,7 +275,7 @@ function MenuHandler:init(main_menu, brush)
self.backstack = {}
self.brush = brush
self.menu = nil
self.hidden = false
self.hidden = nil
end
function MenuHandler:push(menu)
@ -286,7 +286,14 @@ function MenuHandler:pop()
return table.remove(self.backstack)
end
function MenuHandler:unhide()
if not self.hidden then return end
self.menu = self.hidden
self.hidden = nil
end
function MenuHandler:navigate(new_menu)
self:unhide()
if new_menu ~= self.menu then
if new_menu == 'back' then
new_menu = self:pop()
@ -294,8 +301,8 @@ function MenuHandler:navigate(new_menu)
self.backstack = {}
new_menu = nil
elseif new_menu == 'hide' then
self.hidden = true
return
self.hidden = self.menu
new_menu = nil
elseif self.menu and new_menu ~= self.menu then
self:push(self.menu)
self.menu:unfocus()
@ -308,9 +315,8 @@ end
function MenuHandler:update(ctrl, pressed)
if self.hidden then
if not pressed.enter then return end
self.hidden = false
end
if not self.menu and pressed.enter then
self:unhide()
elseif not self.menu and pressed.enter then
self:navigate(self.main_menu)
elseif self.menu then
local new_menu = self.menu:navigate(ctrl, pressed)

View file

@ -0,0 +1,51 @@
function handle_alt_input(handle, ctrl, pressed)
for _, v in ipairs{'left', 'right', 'up', 'down'} do
ctrl[v] = ctrl['d_'..v]
pressed[v] = pressed['d_'..v]
end
pressed.enter = false
ctrl.enter = false
local open_close = ctrl.L and ctrl.R and (pressed.L or pressed.R)
local hide = ctrl.L and ctrl.Z and (pressed.L or pressed.Z)
if open_close then
if handle.menu then -- if menu is open
handle:navigate('close')
else
pressed.enter = true
ctrl.enter = true
end
else
if hide then
handle:navigate('hide')
elseif pressed.L then
handle:navigate('back')
elseif handle.menu then
pressed.enter = pressed.R
ctrl.enter = ctrl.R
end
end
handle:update(ctrl, pressed)
end
function handle_eat_input(handle, ctrl, pressed)
for _, v in ipairs{'left', 'right', 'up', 'down'} do
ctrl[v] = ctrl['d_'..v] or ctrl['j_'..v] or ctrl['c_'..v]
pressed[v] = pressed['d_'..v] or pressed['j_'..v] or pressed['c_'..v]
end
if not handle.menu then
pressed.enter = pressed.L
else
if pressed.Z then
handle:navigate('hide')
elseif pressed.R or pressed.B then
handle:navigate('back')
end
pressed.enter = pressed.A or pressed.L
ctrl.enter = ctrl.A or ctrl.L
joypad.set({}, 1)
joypad.setanalog({["X Axis"]=false, ["Y Axis"]=false}, 1)
end
handle:update(ctrl, pressed)
end