@@ -10,6 +10,7 @@ assert(type(core) == 'table' and core.version >= 1.0, 'InputManager works only w
1010local log = core .import ' class.logger'
1111local helper = core .import ' helper'
1212
13+ local pairs = _G .pairs
1314local min = math.min
1415local max = math.max
1516local ceil = math.ceil
@@ -18,7 +19,7 @@ local setKeyRepeat = love.keyboard.setKeyRepeat
1819local inputs = { }
1920
2021local function bit (p )
21- return 2 ^ (p - 1 )
22+ return 2 ^ (p - 1 )
2223end
2324
2425local function bitor (x , y )
@@ -48,15 +49,15 @@ local function bitxor(x, y)
4849end
4950
5051local function hasbit (x , p )
51- return x % (p + p ) >= p
52+ return x % (p + p ) >= p
5253end
5354
5455local function setbit (x , p )
55- return hasbit (x , p ) and x or x + p
56+ return hasbit (x , p ) and x or x + p
5657end
5758
5859local function clearbit (x , p )
59- return hasbit (x , p ) and x - p or x
60+ return hasbit (x , p ) and x - p or x
6061end
6162
6263local function newInput ()
@@ -80,10 +81,12 @@ local Manager = { frame = 0, delay = 0, timer = 0, buttons = { }, mapping = { },
8081 self .remoteplayers = 0
8182 self .keys = { }
8283 self .keymap = { }
84+ self .consumed = { }
8385 self :reset ()
8486 local keys = kwargs .keys or { }
8587 for i = 1 , # keys do
8688 self .keys [i ] = { keys [i ], bit (i ) }
89+ self .consumed [i ] = { }
8790 self .keymap [keys [i ]] = i
8891 end
8992 if kwargs .mappings then
@@ -106,6 +109,9 @@ local Manager = { frame = 0, delay = 0, timer = 0, buttons = { }, mapping = { },
106109 self .buttons [p ] = { }
107110 inputs [p ] = newInput ()
108111 end
112+ for p = self .localplayers + 1 , self .localplayers + self .remoteplayers do
113+ inputs [p ] = newInput ()
114+ end
109115 end
110116
111117 --- Advance timer and frame.
@@ -116,16 +122,21 @@ local Manager = { frame = 0, delay = 0, timer = 0, buttons = { }, mapping = { },
116122
117123 --- Update inputs.
118124 function Manager :update ()
119- for i = 1 , self .localplayers + self .remoteplayers do
120- local it = inputs [i ]
125+ for p = 1 , self .localplayers + self .remoteplayers do
126+ local it = inputs [p ]
121127 while it .prev and it .frame >= self .frame do
122128 it = it .prev
123129 end
124130 while it .next and it .next .frame <= self .frame do
125131 it = it .next
126132 end
133+ if it ~= inputs [p ] then
134+ for k = 1 , # self .consumed do
135+ self .consumed [k ][p ] = nil
136+ end
137+ end
127138 -- log:info('B%02d F%02d [%04x|%05d] -> [%04x|%05d] -> [%04x|%05d]', b, f, it.prev.data, it.prev.frame, it.data, it.frame, it.next.data, it.next.frame)
128- inputs [i ] = it
139+ inputs [p ] = it
129140 end
130141 end
131142
@@ -159,13 +170,42 @@ local Manager = { frame = 0, delay = 0, timer = 0, buttons = { }, mapping = { },
159170 -- @return boolean
160171 -- @return number
161172 function Manager :hitted (button , player )
162- local index = self .keymap [button ]
163- if index then
164- index = self .keys [index ][2 ]
173+ local keycode = self .keymap [button ]
174+ if keycode then
175+ keycode = self .keys [keycode ][2 ]
176+ local input = nil
177+ for p = player or 1 , player or self .localplayers do
178+ input = inputs [p ]
179+ local ishitted = input and input .frame == self .frame and hasbit (input .data , keycode )
180+ local prev = input and input .prev
181+ if ishitted and (not prev or prev .frame ~= self .frame and not hasbit (prev .data , keycode )) then
182+ return true , p
183+ end
184+ end
185+ end
186+ return false
187+ end
188+
189+ --- Check if button was pressed at this frame and consume it for next call.
190+ -- @param string button Hitted button.
191+ -- @param number player Player to check or nil to check any local player.
192+ -- @return boolean
193+ -- @return number
194+ function Manager :consume (button , player )
195+ local keycode = self .keymap [button ]
196+ if keycode then
197+ local consumed = self .consumed [keycode ]
165198 local input = nil
199+ keycode = self .keys [keycode ][2 ]
166200 for p = player or 1 , player or self .localplayers do
201+ if consumed [p ] then
202+ return false
203+ end
167204 input = inputs [p ]
168- if input and input .frame == self .frame and hasbit (input .data , index ) then
205+ local ishitted = input and input .frame == self .frame and hasbit (input .data , keycode )
206+ local prev = input and input .prev
207+ if ishitted and (not prev or prev .frame ~= self .frame and not hasbit (prev .data , keycode )) then
208+ consumed [p ] = true
169209 return true , p
170210 end
171211 end
@@ -276,7 +316,7 @@ local Manager = { frame = 0, delay = 0, timer = 0, buttons = { }, mapping = { },
276316 left , right = right , right .next
277317 end
278318 if left and left .frame == timer then
279- local xor = bitxor ( left . data , input )
319+ -- TODO: fix this input merger
280320 local changes = bitxor (xor , left .changes )
281321 if bitor (xor , changes ) == changes then
282322 left .data = input
0 commit comments