--*********************************************************** --** THE INDIE STONE ** --*********************************************************** if isServer() then return end JoypadState = {} JoypadState.controllers = {} JoypadState.players = {} JoypadState.joypads = {} JoypadState.forceActivate = nil; Joypad = {} Joypad.AButton = 0; Joypad.BButton = 1; Joypad.XButton = 2; Joypad.YButton = 3; Joypad.LBumper = 4; Joypad.RBumper = 5; Joypad.Back = 6 Joypad.Start = 7 Joypad.LStickButton = 8 Joypad.RStickButton = 9 Joypad.Other = 10 Joypad.DPadLeft = 100 Joypad.DPadRight = 101 Joypad.DPadUp = 102 Joypad.DPadDown = 103 Joypad.Texture = {} Joypad.Texture.AButton = getTexture("media/ui/xbox/XBOX_A.png") Joypad.Texture.BButton = getTexture("media/ui/xbox/XBOX_B.png") Joypad.Texture.XButton = getTexture("media/ui/xbox/XBOX_X.png") Joypad.Texture.YButton = getTexture("media/ui/xbox/XBOX_Y.png") Joypad.Texture.LBumper = getTexture("media/ui/xbox/xbox_lb.png") Joypad.Texture.RBumper = getTexture("media/ui/xbox/xbox_rb.png") Joypad.Texture.DPadLeft = getTexture("media/ui/xbox/XBOX_dpad_left.png") Joypad.Texture.DPadRight = getTexture("media/ui/xbox/XBOX_dpad_right.png") Joypad.Texture.DPadUp = getTexture("media/ui/xbox/XBOX_dpad_up.png") Joypad.Texture.DPadDown = getTexture("media/ui/xbox/XBOX_dpad_down.png") Joypad.Texture.DPad = getTexture("media/ui/xbox/XBOX_dpad.png") Joypad.Texture.LStick = getTexture("media/ui/leftstick.png") Joypad.Texture.RStick = getTexture("media/ui/rightstick.png") Joypad.Texture.LTrigger = getTexture("media/ui/xbox/xbox_lefttrigger.png") Joypad.Texture.RTrigger = getTexture("media/ui/xbox/xbox_righttrigger.png") Joypad.Texture.Menu = getTexture("media/ui/xbox/XBOX_Menu.png") Joypad.Texture.View = getTexture("media/ui/xbox/XBOX_View.png") Joypad.Texture.Back = Joypad.Texture.View Joypad.Texture.Start = Joypad.Texture.Menu joypad = {} joypad.wantNoise = getDebug() local noise = function(fmt, arg1, arg2, arg3, arg4) if not joypad.wantNoise then return end local msg = string.format(fmt, arg1, arg2, arg3, arg4) print('joypad: '..tostring(msg)) end local function uiToString(ui) return ui and ui:toString() or "nil" end ----- JoypadControllerData = ISBaseObject:derive("JoypadControllerData") function JoypadControllerData:setJoypad(joypadData) if joypadData.controller then joypadData.controller:clearJoypad() end self.joypad = joypadData joypadData.id = self.id joypadData.controller = self end function JoypadControllerData:clearJoypad() local joypad = self.joypad self.joypad = nil if joypad then joypad:clearController() end end function JoypadControllerData:new(id) local o = ISBaseObject.new(self) o.id = id o.pressed = {} o.wasPressed = {} for n = 1,getButtonCount(id) do o.pressed[n-1] = isJoypadPressed(id, n-1) end o.connected = isJoypadConnected(id) o.joypad = nil return o end ----- JoypadData = ISBaseObject:derive("JoypadData") function JoypadData:setController(controller) if controller.joypad then controller.joypad:clearController() end self.id = controller.id self.controller = controller controller.joypad = self end function JoypadData:clearController() local controller = self.controller self.id = -1 self.controller = nil if controller then controller:clearJoypad() end end function JoypadData:isConnected() return self.controller and self.controller.connected end function JoypadData:setActive(isActive) self.isActive = isActive end function JoypadData:new() local o = ISBaseObject.new(self) o.id = -1 -- same as controller.id o.player = nil o.controller = nil o.focus = nil o.lastfocus = nil o.prevfocus = nil o.prevprevfocus = nil o.isActive = false o.inMainMenu = false o.listBox = nil return o end ----- -- GLFW supports 16 controllers. for i=1,16 do JoypadState.controllers[i-1] = JoypadControllerData:new(i-1) end for i=1,getMaxActivePlayers() do JoypadState.joypads[i] = JoypadData:new() end ----- function getFocusForPlayer(playerNum) local joypadData = JoypadState.players[playerNum+1] return joypadData and joypadData.focus or nil; end function JoypadControllerData:onPauseButtonPressed() local joypadData = self.joypad if UIManager.getSpeedControls() and not isClient() then if UIManager.getSpeedControls():getCurrentGameSpeed() == 0 or getGameTime():getTrueMultiplier() > 1 then if MainScreen.instance and MainScreen.instance.inGame and MainScreen.instance:isReallyVisible() then -- return to game below --[[ elseif joypadData.pauseKeyTime and (joypadData.pauseKeyTime + 750 > getTimestampMs()) then -- double-tap, go to main menu below --]] else UIManager.getSpeedControls():ButtonClicked("Play") return end --[[ else joypadData.pauseKeyTime = getTimestampMs() UIManager.getSpeedControls():ButtonClicked("Pause") return --]] end end if MainScreen.instance and MainScreen.instance.inGame then ISUIHandler.setVisibleAllUI(MainScreen.instance:isVisible()) if MainScreen.instance:isVisible() then MainScreen.instance:setVisible(false) MainScreen.instance:removeFromUIManager() else MainScreen.instance:setVisible(true) MainScreen.instance:addToUIManager() end if MainScreen.instance:isVisible() then getCell():setDrag(nil, 0) setGameSpeed(0) setShowPausedMessage(false) JoypadState.saveAllFocus() joypadData.focus = MainScreen.instance joypadData.inMainMenu = true MainScreen.instance:onEnterFromGame() else MainScreen.instance:onReturnToGame() setGameSpeed(1); setShowPausedMessage(true) joypadData.inMainMenu = false JoypadState.restoreAllFocus() end end end function JoypadControllerData:onPressButtonNoFocus(button) local joypadData = self.joypad local activeWhilePaused = joypadData.activeWhilePaused local displayListBox = button == Joypad.AButton and not joypadData.player and not IsoPlayer.allPlayersDead() if displayListBox then activeWhilePaused = true end if not activeWhilePaused and isGamePaused() and button ~= Joypad.Start and button ~= Joypad.Back then return end if ISTermsOfServiceUI and ISTermsOfServiceUI.instance and ISTermsOfServiceUI.instance:isReallyVisible() then if button == Joypad.AButton then local focus = ISTermsOfServiceUI.instance joypadData.focus = focus updateJoypadFocus(joypadData) end return end ----- -- Case 1: In the main menu. ----- if MainScreen.instance and MainScreen.instance:isReallyVisible() then -- Activating a controller in the main menu does not display the JoypadListBox. -- Also, the controller is not assigned to any player. if button == Joypad.AButton then local focus = MainScreen.instance:getCurrentFocusForController() if focus == nil then return end joypadData.inMainMenu = true joypadData.focus = focus updateJoypadFocus(joypadData) return end return end ----- -- Case 2: In game. ----- if joypadData.player and getCell() and getCell():getDrag(joypadData.player) then getCell():getDrag(joypadData.player):onJoypadPressButton(joypadIndex, joypadData, button); return; end if displayListBox then local playerNum if joypadData == JoypadState.joypads[1] then playerNum = 0 elseif joypadData == JoypadState.joypads[2] then playerNum = 1 elseif joypadData == JoypadState.joypads[3] then playerNum = 2 else playerNum = 3 end joypadData.listBox = ISJoypadListBox.Create(playerNum, joypadData) joypadData.listBox:fill() joypadData.listBox:setVisible(true) joypadData.listBox:addToUIManager() joypadData.focus = joypadData.listBox joypadData.activeWhilePaused = true return end if button == Joypad.Back and joypadData.player and getSpecificPlayer(joypadData.player) then local wheel = getPlayerBackButtonWheel(joypadData.player) wheel:addCommands() wheel:addToUIManager(true) wheel:setVisible(true) setJoypadFocus(joypadData.player, wheel) getSpecificPlayer(joypadData.player):setJoypadIgnoreAimUntilCentered(true) return end if button == Joypad.Start and joypadData.player and getSpecificPlayer(joypadData.player) then self:onPauseButtonPressed() return end if joypadData.player and getPlayerData(joypadData.player) then local buts = getButtonPrompts(joypadData.player) if button == Joypad.AButton then buts:onAPress() end if button == Joypad.BButton then buts:onBPress() end if button == Joypad.XButton then buts:onXPress() end if button == Joypad.YButton then buts:onYPress() end if button == Joypad.LBumper then buts:onLBPress() end if button == Joypad.RBumper then buts:onRBPress() end end if button == Joypad.LStickButton or button == Joypad.RStickButton then ISJoystickButtonRadialMenu.onJoypadDown(button, joypadData) end end function JoypadControllerData:onPressButton(button) local joypadData = self.joypad if not joypadData then return end if not joypadData.focus then self:onPressButtonNoFocus(button) return end if MainScreen.instance and MainScreen.instance.inGame and MainScreen.instance:isReallyVisible() then if button == Joypad.Start and joypadData.focus == MainScreen.instance then self:onPauseButtonPressed() else joypadData.focus:onJoypadDown(button, joypadData) end return end if not joypadData.activeWhilePaused and isGamePaused() then return; end joypadData.focus:onJoypadDown(button, joypadData); end function JoypadControllerData:onReleaseButton(button) local joypadData = self.joypad -- This controller isn't assigned to any player or the main menu. if not joypadData then return end if not joypadData.player then return end if getPlayerData(joypadData.player) then local buts = getButtonPrompts(joypadData.player) buts:onJoypadButtonReleased(button) local wheel = getPlayerBackButtonWheel(joypadData.player) if joypadData.focus == wheel then wheel:onJoypadButtonReleased(button, joypadData) return end wheel = getPlayerRadialMenu(joypadData.player) if joypadData.focus == wheel then wheel:onJoypadButtonReleased(button, joypadData) if button == Joypad.LStickButton or button == Joypad.RStickButton then ISJoystickButtonRadialMenu.onJoypadButtonReleased(button, joypadData) end return end end if button == Joypad.XButton then ISVehicleRegulator.onJoypadReleaseX(joypadData) end if button == Joypad.LStickButton or button == Joypad.RStickButton then ISJoystickButtonRadialMenu.onJoypadButtonReleased(button, joypadData) end end function getJoypadFocus(playerID) local joypadData = JoypadState.players[playerID+1]; return joypadData and joypadData.focus or nil; end function setJoypadFocus(playerID, control) local joypadData = JoypadState.players[playerID+1]; if not joypadData then return end noise("set focus to %s for player %d", uiToString(control), playerID) if control ~= nil and control ~= joypadData.focus then noise("focus changed - bumping down prevs"); noise("current: %s", uiToString(joypadData.focus)); noise("prev: %s", uiToString(joypadData.prevfocus)); joypadData.prevprevfocus = joypadData.prevfocus; joypadData.prevfocus = joypadData.focus; end if control then noise("new: %s", uiToString(control)); end joypadData.focus = control; -- updateJoypadFocus(joypadData); end function setPrevFocusForPlayer(playerID) local joypadData = JoypadState.players[playerID+1]; if not joypadData then return end noise("set focus to previous for player %d", playerID); noise("current: %s", uiToString(joypadData.focus)); noise("prev: %s", uiToString(joypadData.prevfocus)); joypadData.focus = joypadData.prevfocus; joypadData.prevfocus = joypadData.prevprevfocus; joypadData.prevprevfocus = nil; -- joypadData.lastfocus = nil; -- updateJoypadFocus(joypadData); end function setPrevPrevFocusForPlayer(playerID) local joypadData = JoypadState.players[playerID+1]; if not joypadData then return end noise("set focus to previous-previous for player %d", playerID); noise("current: %s", uiToString(joypadData.focus)); noise("prev: %s", uiToString(joypadData.prevfocus)); joypadData.focus = joypadData.prevprevfocus; joypadData.prevfocus = nil; joypadData.prevprevfocus = nil; -- joypadData.lastfocus = nil; -- updateJoypadFocus(joypadData); end function updateJoypadFocus(joypadData) if joypadData.lastfocus ~= joypadData.focus then noise("change focus from %s to %s", uiToString(joypadData.lastfocus), uiToString(joypadData.focus)) local lastfocus = joypadData.lastfocus joypadData.lastfocus = nil if joypadData.focus ~= nil then noise("focus in %s", uiToString(joypadData.focus)) joypadData.focus:onGainJoypadFocus(joypadData); end if lastfocus ~= nil then noise("focus out %s", uiToString(lastfocus)) lastfocus:onLoseJoypadFocus(joypadData); end end if joypadData.player ~= nil and getSpecificPlayer(joypadData.player) then if joypadData.focus ~= nil then joypadData.lastactualfocus = joypadData.focus; setPlayerMovementActive(joypadData.player, false); else setPlayerMovementActive(joypadData.player, true); end joypadData.lastfocus = joypadData.focus; if joypadData.focus == nil and getPlayerData(joypadData.player) then if JoypadState.disableControllerPrompt then joypadData.lastfocus = joypadData.focus; return; end local buts = getButtonPrompts(joypadData.player); if buts ~= nil then buts:getBestAButtonAction(nil); buts:getBestBButtonAction(nil); buts:getBestYButtonAction(nil); buts:getBestXButtonAction(nil); buts:getBestLBButtonAction(nil); buts:getBestRBButtonAction(nil); end end else joypadData.lastfocus = joypadData.focus; end if JoypadState.disableMovement then setPlayerMovementActive(joypadData.player, false); end end function JoypadControllerData:onPressUp() if not self.joypad then return end local joypadData = self.joypad if joypadData.focus ~= nil then if joypadData.focus:isVisible() then joypadData.focus:onJoypadDirUp(joypadData); end return end if not joypadData.player then return end if getCell():getDrag(joypadData.player) then getCell():getDrag(joypadData.player):onJoypadDirUp(joypadData); elseif ISVehicleRegulator.onJoypadPressUp(joypadData) then -- increase regulator speed else ISDPadWheels.onDisplayUp(joypadData) -- local playerObj = getSpecificPlayer(joypadData.player) -- ItemBindingHandler.equipBestWeapon(playerObj, "Firearm") end end function JoypadControllerData:onReleaseUp() if not self.joypad then return end local joypadData = self.joypad if not joypadData.player then return end local wheel = getPlayerRadialMenu(joypadData.player) if joypadData.focus == wheel and wheel:isVisible() then wheel:onJoypadButtonReleased(Joypad.DPadUp, joypadData) end end function JoypadControllerData:onPressDown() if not self.joypad then return end local joypadData = self.joypad if joypadData.focus ~= nil then if joypadData.focus:isVisible() then joypadData.focus:onJoypadDirDown(joypadData); end return end if not joypadData.player then return end if getCell():getDrag(joypadData.player) then getCell():getDrag(joypadData.player):onJoypadDirDown(joypadData); elseif ISVehicleRegulator.onJoypadPressDown(joypadData) then -- decrease regulator speed else ISDPadWheels.onDisplayDown(joypadData) end end function JoypadControllerData:onReleaseDown() if not self.joypad then return end local joypadData = self.joypad if not joypadData.player then return end local wheel = getPlayerRadialMenu(joypadData.player) if joypadData.focus == wheel and wheel:isVisible() then wheel:onJoypadButtonReleased(Joypad.DPadDown, joypadData) end end function JoypadControllerData:onPressLeft() if not self.joypad then return end local joypadData = self.joypad if joypadData.focus ~= nil then if joypadData.focus:isVisible() then joypadData.focus:onJoypadDirLeft(joypadData); end return end if not joypadData.player then return end if getCell():getDrag(joypadData.player) then getCell():getDrag(joypadData.player):onJoypadDirLeft(joypadData); else ISDPadWheels.onDisplayLeft(joypadData) -- local playerObj = getSpecificPlayer(joypadData.player) -- ItemBindingHandler.equipBestWeapon(playerObj, "Swinging") end end function JoypadControllerData:onReleaseLeft() if not self.joypad then return end local joypadData = self.joypad if not joypadData.player then return end local wheel = getPlayerRadialMenu(joypadData.player) if joypadData.focus == wheel and wheel:isVisible() then wheel:onJoypadButtonReleased(Joypad.DPadLeft, joypadData) end end function JoypadControllerData:onPressRight() if not self.joypad then return end local joypadData = self.joypad if joypadData.focus ~= nil then if joypadData.focus:isVisible() then joypadData.focus:onJoypadDirRight(joypadData); end return end if not joypadData.player then return end if getCell():getDrag(joypadData.player) then getCell():getDrag(joypadData.player):onJoypadDirRight(joypadData); else ISDPadWheels.onDisplayRight(joypadData) -- local playerObj = getSpecificPlayer(joypadData.player) -- ItemBindingHandler.equipBestWeapon(playerObj, "Stab") end end function JoypadControllerData:onReleaseRight() if not self.joypad then return end local joypadData = self.joypad if not joypadData.player then return end local wheel = getPlayerRadialMenu(joypadData.player) if joypadData.focus == wheel and wheel:isVisible() then wheel:onJoypadButtonReleased(Joypad.DPadRight, joypadData) end end local function translateButton(joypad, button) if button == getJoypadAButton(joypad) then return Joypad.AButton end if button == getJoypadBButton(joypad) then return Joypad.BButton end if button == getJoypadXButton(joypad) then return Joypad.XButton end if button == getJoypadYButton(joypad) then return Joypad.YButton end if button == getJoypadLBumper(joypad) then return Joypad.LBumper end if button == getJoypadRBumper(joypad) then return Joypad.RBumper end if button == getJoypadBackButton(joypad) then return Joypad.Back end if button == getJoypadStartButton(joypad) then return Joypad.Start end if button == getJoypadLeftStickButton(joypad) then return Joypad.LStickButton end if button == getJoypadRightStickButton(joypad) then return Joypad.RStickButton end return Joypad.Other end function JoypadControllerData:update(time) if not self.connected then return end local i = self.id local v = self local t = time if isJoypadDown(i) then if not v.down then v.timedown = t; v.timedownproc = 0 end v.down = true v.dtdown = t - v.timedown v.dtprocdown = t - v.timedownproc else v.timedown = 0 v.down = false end if isJoypadUp(i) then if not v.up then v.timeup = t; v.timeupproc = 0 end v.up = true v.dtup = t - v.timeup v.dtprocup = t - v.timeupproc else v.timeup = 0 v.up = false end if isJoypadLeft(i) then if not v.left then v.timeleft = t v.timeleftproc = 0 end v.left = true v.dtleft = t - v.timeleft v.dtprocleft = t - v.timeleftproc else v.timeleft = 0 v.left = false end if isJoypadRight(i) then if not v.right then v.timeright = t v.timerightproc = 0 end v.right = true v.dtright = t - v.timeright v.dtprocright = t - v.timerightproc else v.timeright = 0 v.right = false end --print("DEBUG: v.down="..tostring(v.down).." v.dtdown="..tostring(v.dtdown).." v.timedown="..tostring(v.timedown).." v.dtprocdown="..tostring(v.dtprocdown)) --print("DEBUG: v.up="..tostring(v.up).." v.dtup="..tostring(v.dtup).." v.timeup="..tostring(v.timeup).." v.dtprocup="..tostring(v.dtprocup)) if v.down and v.dtprocdown>300 then v:onPressDown(); v.timedownproc = t elseif v.down and v.dtdown>900 and v.dtprocdown>110 then v:onPressDown(); v.timedownproc = t elseif v.down and v.dtdown>3000 and v.dtprocdown>50 then v:onPressDown(); v.timedownproc = t elseif not v.down and v.timedownproc ~= 0 then v:onReleaseDown() v.timedownproc = 0 end if v.up and v.dtprocup>300 then v:onPressUp(); v.timeupproc = t elseif v.up and v.dtup>900 and v.dtprocup>110 then v:onPressUp(); v.timeupproc = t elseif v.up and v.dtup>3000 and v.dtprocup>50 then v:onPressUp(); v.timeupproc = t elseif not v.up and v.timeupproc ~= 0 then v:onReleaseUp() v.timeupproc = 0 end if v.left and v.dtprocleft > 300 then v:onPressLeft() v.timeleftproc = t elseif v.left and v.dtleft > 900 and v.dtprocleft > 110 then v:onPressLeft() v.timeleftproc = t elseif v.left and v.dtleft > 3000 and v.dtprocleft > 50 then v:onPressLeft() v.timeleftproc = t elseif not v.left and v.timeleftproc ~= 0 then v:onReleaseLeft() v.timeleftproc = 0 end if v.right and v.dtprocright > 300 then v:onPressRight() v.timerightproc = t elseif v.right and v.dtright > 900 and v.dtprocright > 110 then v:onPressRight() v.timerightproc = t elseif v.right and v.dtright > 3000 and v.dtprocright > 50 then v:onPressRight() v.timerightproc = t elseif not v.right and v.timerightproc ~= 0 then v:onReleaseRight() v.timerightproc = 0 end for n = 0,getButtonCount(i)-1 do if v.pressed[n] == nil then v.pressed[n] = true; end v.wasPressed[n] = v.pressed[n]; v.pressed[n] = isJoypadPressed(i, n); if v.pressed[n] and not v.wasPressed[n] then local button = translateButton(v.id, n) v:onPressButton(button) elseif v.wasPressed[n] and not v.pressed[n] then local button = translateButton(v.id, n) v:onReleaseButton(button) end end if v.joypad then updateJoypadFocus(v.joypad) end end function onJoypadRenderTick(ticks) if JoypadState.controllerTest then return end local t = getTimestampMs() for i=1,16 do local controller = JoypadState.controllers[i-1] controller:update(t) end end function JoypadState.onGamepadConnect(id) JoypadState.controllers[id].connected = true end function JoypadState.onGamepadDisconnect(id) JoypadState.controllers[id].connected = false end function onJoypadActivate(id) if JoypadState.controllerTest then return end -- if getCore():getGameMode() == "Tutorial" then return end local controller = JoypadState.controllers[id] if controller.joypad ~= nil then return end noise("activate %d", id) if MainScreen.instance and MainScreenInstance.inGame then local numPlayers = getNumActivePlayers() + 1 local maxPlayer = math.min(numPlayers, getMaxActivePlayers()) for i=1,maxPlayer do if not JoypadState.players[i] then joypadData = JoypadState.joypads[i] break end end if not joypadData then -- All player slots have controllers. return end else joypadData = JoypadState.joypads[1] end joypadData:setActive(true) controller:setJoypad(joypadData) end function onJoypadActivateUI(id) onJoypadActivate(id) end function onJoypadBeforeDeactivate(id) local joypadData = JoypadState.controllers[id].joypad if joypadData == nil then return end if joypadData.focus and joypadData.focus.onJoypadBeforeDeactivate then joypadData.focus:onJoypadBeforeDeactivate(joypadData) end end function onJoypadDeactivate(id) local controller = JoypadState.controllers[id] local joypadData = controller.joypad if joypadData == nil then return end joypadData:setActive(false) if joypadData.inMainMenu and joypadData.focus ~= nil and MainScreen.instance and MainScreen.instance:isReallyVisible() then joypadData.focus:onLoseJoypadFocus(joypadData) joypadData.focus = nil joypadData.lastfocus = nil end if joypadData.listBox then if joypadData.focus == joypadData.listBox then joypadData.focus = nil joypadData.lastfocus = nil end joypadData.listBox:removeFromUIManager() joypadData.listBox = nil end if joypadData.player == nil then return end local ui = ISJoypadDisconnectedUI:new(joypadData.player) ui:setAlwaysOnTop(true) ui:addToUIManager() joypadData.disconnectedUI = ui end function onJoypadBeforeReactivate(id) local joypadData = JoypadState.controllers[id].joypad if joypadData == nil then return end if joypadData.focus and joypadData.focus.onJoypadBeforeReactivate then joypadData.focus:onJoypadBeforeReactivate(joypadData) end end function onJoypadReactivate(id) local controller = JoypadState.controllers[id] local joypadData = controller.joypad if joypadData == nil then return end joypadData:setActive(true) if joypadData.disconnectedUI then joypadData.disconnectedUI:removeFromUIManager() joypadData.disconnectedUI = nil end if joypadData.focus and joypadData.focus.onJoypadReactivate then joypadData.focus:onJoypadReactivate(joypadData) end if joypadData.inMainMenu then if MainScreen.instance and MainScreen.instance:isReallyVisible() then local focus = MainScreen.instance:getCurrentFocusForController() if focus == nil then return end joypadData.focus = focus updateJoypadFocus(joypadData) return end end end -- Player 0 controller was disconnected, and they chose to use keyboard and mouse. function JoypadState.useKeyboardMouse() local playerNum = 0 local joypadData = JoypadState.players[playerNum+1] JoypadState.players[playerNum+1] = nil joypadData.player = nil if joypadData.focus ~= nil then joypadData.focus:onLoseJoypadFocus(joypadData) joypadData.focus = nil end local playerObj = getSpecificPlayer(playerNum) if playerObj then -- See inventory handling in JoypadControllerData:onPressButton(). playerObj:setBannedAttacking(false) end if joypadData.listBox then joypadData.listBox:removeFromUIManager() joypadData.listBox = nil end revertToKeyboardAndMouse() end function JoypadState.getMainMenuJoypad() for _,joypadData in ipairs(JoypadState.joypads) do if joypadData.inMainMenu then return joypadData end end return nil end function JoypadState.saveAllFocus() JoypadState.saveFocus = {} for i,joypadData in pairs(JoypadState.joypads) do JoypadState.saveFocus[i] = joypadData.focus end end function JoypadState.restoreAllFocus() if not JoypadState.saveFocus then return end for i,joypadData in pairs(JoypadState.joypads) do if JoypadState.saveFocus[i] and JoypadState.saveFocus[i]:isVisible() then joypadData.focus = JoypadState.saveFocus[i] else joypadData.focus = nil end end table.wipe(JoypadState.saveFocus) end function JoypadState.onPlayerDeath(playerObj) local playerNum = playerObj:getPlayerNum() local joypadData = JoypadState.players[playerNum+1] if joypadData then noise('removing joypad player %d', playerNum) joypadData.player = nil joypadData.focus = nil joypadData.lastfocus = nil joypadData.prevfocus = nil joypadData.prevprevfocus = nil end end function JoypadState.onCoopJoinFailed(playerNum) local joypadData = JoypadState.players[playerNum+1] if joypadData then joypadData.focus = nil if joypadData.player then error "joypadData.player ~= nil" end end end JoypadState.onGameStart = function() local playerNum = 0 local joypadData = JoypadState.joypads[playerNum+1] local controller = joypadData.controller if controller then noise("force activate") joypadData.inMainMenu = false joypadData.focus = nil joypadData.lastfocus = nil joypadData.prevfocus = nil joypadData.prevprevfocus = nil joypadData.player = playerNum JoypadState.players[playerNum+1] = joypadData local playerObj = getSpecificPlayer(playerNum) setPlayerJoypad(playerNum, joypadData.id, playerObj, nil) createPlayerData(playerNum) -- FIXME: obsolete? getPlayerInventory(playerNum):setController(joypadData.id) getPlayerLoot(playerNum):setController(joypadData.id) --[[ -- Display JoypadListBox. controller:onPressButton(Joypad.AButton) updateJoypadFocus(joypadData) -- Take over player 1. controller:onPressButton(Joypad.AButton) --]] end end function JoypadState.onRenderUI() if JoypadState.debugUI == nil then JoypadState.debugUI = ISJoypadDebugUI:new() JoypadState.debugUI:initialise() JoypadState.debugUI:instantiate() end JoypadState.debugUI:render() end Events.OnGamepadConnect.Add(JoypadState.onGamepadConnect) Events.OnGamepadDisconnect.Add(JoypadState.onGamepadDisconnect) Events.OnJoypadActivate.Add(onJoypadActivate); Events.OnJoypadActivateUI.Add(onJoypadActivateUI); Events.OnJoypadBeforeDeactivate.Add(onJoypadBeforeDeactivate); Events.OnJoypadDeactivate.Add(onJoypadDeactivate); Events.OnJoypadBeforeReactivate.Add(onJoypadBeforeReactivate); Events.OnJoypadReactivate.Add(onJoypadReactivate); Events.OnRenderTick.Add(onJoypadRenderTick); Events.OnGameStart.Add(JoypadState.onGameStart); --Events.OnPlayerDeath.Add(JoypadState.onPlayerDeath); Events.OnCoopJoinFailed.Add(JoypadState.onCoopJoinFailed) Events.OnJoypadRenderUI.Add(JoypadState.onRenderUI)