mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-22 21:46:51 +02:00
This commit is contained in:
+1
-10
@@ -919,16 +919,7 @@ function Game:gamepadaxis(joystick, axis, value)
|
||||
Input:gamepadaxis(joystick, axis, value)
|
||||
end
|
||||
|
||||
-- conf.lua turns the mobile accelerometer-joystick off (#468), but guard the
|
||||
-- generic joystick path anyway: any sensor-style device that still reaches us
|
||||
-- has gravity pinning an axis past the deadzone, which would hide the touch
|
||||
-- overlay every instant and steer the player by tilt through the axis-1/2
|
||||
-- mapping (#459). Real controllers arrive as SDL gamepads or named sticks,
|
||||
-- never as "* Accelerometer".
|
||||
local function isAccelerometer(joystick)
|
||||
local name = joystick and joystick.getName and joystick:getName()
|
||||
return name ~= nil and name:lower():find("accelerometer", 1, true) ~= nil
|
||||
end
|
||||
local isAccelerometer = GamepadMap.isAccelerometer
|
||||
|
||||
-- BindingsMenu's raw-stick capture rides the same top-state routing as the
|
||||
-- keyboard and gamepad paths (#632). Only a stick SDL does not recognize
|
||||
|
||||
@@ -106,6 +106,17 @@ function GamepadMap.ignoreRawForJoystick(joystick)
|
||||
return ok and isPad == true
|
||||
end
|
||||
|
||||
-- conf.lua turns the mobile accelerometer-joystick off (#468), but guard the
|
||||
-- generic joystick path anyway: any sensor-style device that still reaches us
|
||||
-- has gravity pinning an axis past the deadzone, which would hide the touch
|
||||
-- overlay every instant and steer the player by tilt through the axis-1/2
|
||||
-- mapping (#459). Real controllers arrive as SDL gamepads or named sticks,
|
||||
-- never as "* Accelerometer".
|
||||
function GamepadMap.isAccelerometer(joystick)
|
||||
local name = joystick and joystick.getName and joystick:getName()
|
||||
return name ~= nil and name:lower():find("accelerometer", 1, true) ~= nil
|
||||
end
|
||||
|
||||
function GamepadMap.mapRawButton(index)
|
||||
if nxActive() then
|
||||
local nx = GamepadMap.NX_RAW_BUTTON_BINDINGS[index]
|
||||
|
||||
+6
-1
@@ -281,6 +281,7 @@ end
|
||||
|
||||
function Input:joystickpressed(joystick, button)
|
||||
if GamepadMap.ignoreRawForJoystick(joystick) then return end
|
||||
if GamepadMap.isAccelerometer(joystick) then return end
|
||||
noteCapture(self, "joy", "pressed", button)
|
||||
local btn = self.joyBindings[button]
|
||||
if btn then press(self, btn, "joy:" .. button) end
|
||||
@@ -288,6 +289,7 @@ end
|
||||
|
||||
function Input:joystickreleased(joystick, button)
|
||||
if GamepadMap.ignoreRawForJoystick(joystick) then return end
|
||||
if GamepadMap.isAccelerometer(joystick) then return end
|
||||
noteCapture(self, "joy", "released", button)
|
||||
local btn = self.joyBindings[button]
|
||||
if btn then release(self, btn, "joy:" .. button) end
|
||||
@@ -330,6 +332,7 @@ end
|
||||
|
||||
function Input:joystickaxis(joystick, axis, value)
|
||||
if GamepadMap.ignoreRawForJoystick(joystick) then return end
|
||||
if GamepadMap.isAccelerometer(joystick) then return end
|
||||
if axis == 1 then
|
||||
self:gamepadaxis(joystick, "leftx", value)
|
||||
elseif axis == 2 then
|
||||
@@ -343,6 +346,7 @@ end
|
||||
-- directions on top of a direction rebind.
|
||||
function Input:joystickhat(joystick, hat, direction)
|
||||
if GamepadMap.ignoreRawForJoystick(joystick) then return end
|
||||
if GamepadMap.isAccelerometer(joystick) then return end
|
||||
local source = "hat:" .. hat
|
||||
for _, btn in ipairs(self.hatDirs[hat] or {}) do
|
||||
release(self, btn, source)
|
||||
@@ -380,7 +384,8 @@ function Input:reconcile()
|
||||
local ok, joysticks = pcall(js.getJoysticks)
|
||||
if not ok or type(joysticks) ~= "table" then return end
|
||||
for _, j in ipairs(joysticks) do
|
||||
if GamepadMap.ignoreRawForJoystick(j) then
|
||||
if GamepadMap.isAccelerometer(j) then
|
||||
elseif GamepadMap.ignoreRawForJoystick(j) then
|
||||
-- SDL-recognized pad: buttons + left stick, the gamepad surfaces
|
||||
if j.isGamepadDown then
|
||||
for button, btn in pairs(self.padBindings) do
|
||||
|
||||
+79
-23
@@ -1,4 +1,4 @@
|
||||
-- Screen orientation lock, Android only (#592, #716).
|
||||
-- Screen orientation lock, Android and iOS (#592, #716, #1638).
|
||||
--
|
||||
-- Persisted as options.orientation: "auto" | "portrait" | "landscape" |
|
||||
-- "reverseLandscape". The lock travels through SDL_HINT_ORIENTATIONS:
|
||||
@@ -10,16 +10,12 @@
|
||||
-- rotation lock"; LANDSCAPE allows both landscapes (SENSOR_LANDSCAPE ->
|
||||
-- USER_LANDSCAPE); REVERSE LANDSCAPE is SDL's LandscapeRight alone.
|
||||
--
|
||||
-- SDL only re-reads the hint when the window is created or its resizable
|
||||
-- flag changes (SDL_androidwindow.c: Android_CreateWindow /
|
||||
-- Android_SetWindowResizable both call Android_JNI_SetOrientation). LOVE
|
||||
-- 11.5 exposes neither hints nor a resizable setter, so apply() goes through
|
||||
-- the FFI to SDL's C API: set the hint, then pulse the window's resizable
|
||||
-- flag off and back on -- each edge makes the Android backend recompute the
|
||||
-- requested orientation, so a change from the launcher or the OPTION menu
|
||||
-- takes hold immediately, and the flag ends where it started (conf.lua sets
|
||||
-- resizable on mobile). Everything is pcall-guarded: desktop, iOS (the
|
||||
-- Info.plist governs there) and headless stubs make this a no-op.
|
||||
-- Android only re-reads the hint at window creation or on a resizable-flag
|
||||
-- change (SDL_androidwindow.c), and SDL_SetWindowResizable early-returns on
|
||||
-- a fullscreen window (SDL_video.c:2237) -- which LOVE's Android window
|
||||
-- always is -- so the hint never reached a running activity (#1638).
|
||||
-- apply() sets the hint for a later window, then goes over JNI for the live
|
||||
-- one. iOS needs only the hint. Desktop and headless stubs no-op.
|
||||
|
||||
local Orientation = {}
|
||||
|
||||
@@ -58,6 +54,11 @@ function Orientation.isAndroid()
|
||||
return love.system.getOS() == "Android"
|
||||
end
|
||||
|
||||
function Orientation.isIOS()
|
||||
if not love or not love.system or not love.system.getOS then return false end
|
||||
return love.system.getOS() == "iOS"
|
||||
end
|
||||
|
||||
function Orientation.cycle(mode, dir)
|
||||
local cur, idx = Orientation.normalize(mode), 1
|
||||
for i, m in ipairs(Orientation.MODES) do
|
||||
@@ -67,6 +68,15 @@ function Orientation.cycle(mode, dir)
|
||||
return Orientation.MODES[(idx - 1 + (dir or 1)) % n + 1]
|
||||
end
|
||||
|
||||
-- ActivityInfo constants, what setOrientationBis lands on per hint after
|
||||
-- GameActivity's *_SENSOR -> *_USER remap (#716).
|
||||
local REQUESTED = {
|
||||
auto = 13,
|
||||
portrait = 1,
|
||||
landscape = 11,
|
||||
reverseLandscape = 8,
|
||||
}
|
||||
|
||||
-- The SDL2 C API this module needs. cdef errors on redefinition, so run it
|
||||
-- once and remember whether it took; ffi itself may be absent (plain Lua
|
||||
-- test interpreters), hence the pcall'd require.
|
||||
@@ -77,33 +87,79 @@ local function sdlFfi()
|
||||
if cdefOk == nil then
|
||||
cdefOk = pcall(ffi.cdef, [[
|
||||
typedef struct SDL_Window SDL_Window;
|
||||
typedef union { int32_t i; int64_t pad; } love_jvalue;
|
||||
int SDL_SetHint(const char *name, const char *value);
|
||||
SDL_Window *SDL_GL_GetCurrentWindow(void);
|
||||
void SDL_SetWindowResizable(SDL_Window *window, int resizable);
|
||||
void *SDL_AndroidGetJNIEnv(void);
|
||||
void *SDL_AndroidGetActivity(void);
|
||||
]])
|
||||
end
|
||||
if not cdefOk then return nil end
|
||||
return ffi
|
||||
end
|
||||
|
||||
-- Push the mode into the live activity. Returns true when the hint reached
|
||||
-- SDL (the symbols resolved), false on any non-Android / stubbed platform.
|
||||
-- Slot numbers in JNINativeInterface (jni.h).
|
||||
local JNI_EXCEPTION_CLEAR = 17
|
||||
local JNI_DELETE_LOCAL_REF = 23
|
||||
local JNI_GET_OBJECT_CLASS = 31
|
||||
local JNI_GET_METHOD_ID = 33
|
||||
local JNI_CALL_VOID_METHOD_A = 63
|
||||
|
||||
-- What Android_JNI_SetOrientation reaches, called directly: the hint path
|
||||
-- cannot re-run on a live fullscreen window (SDL_video.c:2237).
|
||||
local function setRequestedOrientation(ffi, requested)
|
||||
local env = ffi.C.SDL_AndroidGetJNIEnv()
|
||||
if env == nil then return false end
|
||||
local activity = ffi.C.SDL_AndroidGetActivity()
|
||||
if activity == nil then return false end
|
||||
local fns = ffi.cast("void***", env)[0]
|
||||
local getObjectClass = ffi.cast("void *(*)(void *, void *)", fns[JNI_GET_OBJECT_CLASS])
|
||||
local getMethodID = ffi.cast(
|
||||
"void *(*)(void *, void *, const char *, const char *)", fns[JNI_GET_METHOD_ID])
|
||||
local callVoidMethodA = ffi.cast(
|
||||
"void (*)(void *, void *, void *, love_jvalue *)", fns[JNI_CALL_VOID_METHOD_A])
|
||||
local deleteLocalRef = ffi.cast("void (*)(void *, void *)", fns[JNI_DELETE_LOCAL_REF])
|
||||
local exceptionClear = ffi.cast("void (*)(void *)", fns[JNI_EXCEPTION_CLEAR])
|
||||
|
||||
local ok = false
|
||||
local cls = getObjectClass(env, activity)
|
||||
if cls ~= nil then
|
||||
local mid = getMethodID(env, cls, "setRequestedOrientation", "(I)V")
|
||||
if mid ~= nil then
|
||||
local args = ffi.new("love_jvalue[1]")
|
||||
args[0].pad = 0
|
||||
args[0].i = requested
|
||||
callVoidMethodA(env, activity, mid, args)
|
||||
ok = true
|
||||
end
|
||||
exceptionClear(env)
|
||||
deleteLocalRef(env, cls)
|
||||
end
|
||||
deleteLocalRef(env, activity)
|
||||
return ok
|
||||
end
|
||||
|
||||
-- Returns true only when the request actually landed, never unconditionally
|
||||
-- as it once did (#1638).
|
||||
function Orientation.apply(mode)
|
||||
if not Orientation.isAndroid() then return false end
|
||||
local android = Orientation.isAndroid()
|
||||
if not (android or Orientation.isIOS()) then return false end
|
||||
local ffi = sdlFfi()
|
||||
if not ffi then return false end
|
||||
mode = Orientation.normalize(mode)
|
||||
local ok = pcall(function()
|
||||
-- "SDL_IOS_ORIENTATIONS" is SDL_HINT_ORIENTATIONS's name (SDL_hints.h);
|
||||
-- despite the IOS in the string, the Android backend reads it too.
|
||||
local ok, reached = pcall(function()
|
||||
-- SDL_HINT_ORIENTATIONS is "SDL_IOS_ORIENTATIONS" in the SDL2 Android
|
||||
-- ships and "SDL_ORIENTATIONS" in the SDL3 the iOS app links; each
|
||||
-- engine ignores the other's key.
|
||||
ffi.C.SDL_SetHint("SDL_IOS_ORIENTATIONS", HINTS[mode])
|
||||
local win = ffi.C.SDL_GL_GetCurrentWindow()
|
||||
if win ~= nil then
|
||||
ffi.C.SDL_SetWindowResizable(win, 0)
|
||||
ffi.C.SDL_SetWindowResizable(win, 1)
|
||||
end
|
||||
ffi.C.SDL_SetHint("SDL_ORIENTATIONS", HINTS[mode])
|
||||
-- On iOS the hint is the lock: UIKit re-asks on every rotation
|
||||
-- (SDL_uikitviewcontroller.m supportedInterfaceOrientations).
|
||||
if not android then return true end
|
||||
return setRequestedOrientation(ffi, REQUESTED[mode])
|
||||
end)
|
||||
return ok
|
||||
return ok and reached == true
|
||||
end
|
||||
|
||||
function Orientation.applyOptions(opts)
|
||||
|
||||
@@ -154,8 +154,14 @@ local function newSfxSource(data, key, def, pitch, tempo, plain)
|
||||
return newFileSource(def)
|
||||
end
|
||||
|
||||
local function deviceSuspended()
|
||||
local ChipAudio = package.loaded["src.core.ChipAudio"]
|
||||
return ChipAudio ~= nil and ChipAudio.isSuspended()
|
||||
end
|
||||
|
||||
local function playPath(data, key, def, pitch, tempo, plain)
|
||||
if not love.audio or not def then return nil end
|
||||
if deviceSuspended() then return nil end
|
||||
local src = cache[key]
|
||||
if src == false then return nil end -- known bad, already logged
|
||||
if not src then
|
||||
@@ -602,6 +608,7 @@ end
|
||||
-- cache carries no clips (Red/Blue) or headless.
|
||||
function Sound.playPikaCry(data, n)
|
||||
if not love.audio then return nil end
|
||||
if deviceSuspended() then return nil end
|
||||
local count = data.audio and data.audio.pikaCries
|
||||
if not count then return nil end
|
||||
n = math.max(1, math.min(count, n or 1))
|
||||
@@ -633,6 +640,7 @@ end
|
||||
-- like the original's PlayCry -> WaitForSoundToFinish can poll it
|
||||
function Sound.playCry(data, species, pikaClip)
|
||||
if not love.audio then return nil end
|
||||
if deviceSuspended() then return nil end
|
||||
-- Yellow voices every Pikachu cry with the PCM clips (the chip cry is
|
||||
-- never used for the species there). Which clip is a property of the
|
||||
-- call site in the original -- every caller of PlayPikachuSoundClip sets
|
||||
|
||||
@@ -303,15 +303,12 @@ local function coreRows(opts, hooks)
|
||||
end)
|
||||
end
|
||||
|
||||
-- ORIENTATION (#592): Android only -- the lock rides SDL's orientation
|
||||
-- hint, which iOS reads only at startup (the Info.plist governs there) and
|
||||
-- desktop ignores. Unlike the other launcher rows this one live-applies:
|
||||
-- the window exists here too, and rotating under the player's finger is
|
||||
-- the only feedback that reads.
|
||||
-- ORIENTATION (#592, #1638): mobile only. Unlike the other launcher rows
|
||||
-- this one live-applies: the window exists here too, and rotating under
|
||||
-- the player's finger is the only feedback that reads.
|
||||
do
|
||||
local osName = love.system and love.system.getOS and love.system.getOS()
|
||||
local okOr, Orientation = pcall(require, "src.core.Orientation")
|
||||
if okOr and osName == "Android" then
|
||||
if okOr and (Orientation.isAndroid() or Orientation.isIOS()) then
|
||||
add(Strings("ORIENTATION"),
|
||||
function() return Strings(Orientation.modeLabel(opts.orientation)) end,
|
||||
function(dir)
|
||||
|
||||
@@ -3017,9 +3017,13 @@ local function buildTextModal(imp, m, key, title, body, closeFn)
|
||||
local h = math.floor(math.min(m.H - 2 * m.pad, 460 * m.s))
|
||||
local px, py, pw, ph = modalPanel(m, w, h)
|
||||
local cy = py + pad
|
||||
Kit.text("button", Kit.ellipsize("button", title, pw - 2 * pad),
|
||||
local xW = math.max(Kit.tapMin(), math.floor(30 * m.s))
|
||||
Kit.text("button", Kit.ellipsize("button", title,
|
||||
pw - 2 * pad - xW - math.floor(8 * m.s)),
|
||||
px + pad, cy, PAL.heading)
|
||||
cy = cy + Kit.textHeight("button") + math.floor(10 * m.s)
|
||||
btn(imp, px + pw - pad - xW, cy, xW, xW, key .. "-x", "X",
|
||||
{ font = "small", action = closeFn })
|
||||
cy = cy + math.max(Kit.textHeight("button"), xW) + math.floor(10 * m.s)
|
||||
|
||||
local pagerH = math.max(Kit.tapMin(), math.floor(30 * m.s))
|
||||
local bodyH = (py + ph - pad) - cy - m.btnH - math.floor(10 * m.s)
|
||||
@@ -5071,6 +5075,7 @@ function LauncherView.draw(imp)
|
||||
-- whole stage draws shielded (no clicks, no hover, no focus ring) while
|
||||
-- one is up; buildModals lowers the shield for the modal's own controls.
|
||||
imp._modalUpNow = modalUp(imp)
|
||||
if imp._modalUpNow then imp:_blurPanelFields() end
|
||||
Kit.blockClicks = imp._modalUpNow
|
||||
|
||||
local step = Kit.scrollStep(m.s)
|
||||
|
||||
@@ -2854,6 +2854,7 @@ function RomImporter:_updatePadCursor(dt)
|
||||
local overY = 0
|
||||
if ny > oy + h then overY = ny - (oy + h)
|
||||
elseif ny < oy then overY = ny - oy end
|
||||
if math.abs(ay) > PAD_DEAD and not self._padStickCentered then overY = 0 end
|
||||
if overY ~= 0 and self._flex then
|
||||
require("src.import.LauncherView").wheelmoved(self, 0, -overY / 48)
|
||||
end
|
||||
@@ -2913,7 +2914,11 @@ end
|
||||
function RomImporter:gamepadaxis(_, axis, value)
|
||||
if axis == "leftx" or axis == "lefty" or axis == "righty" then
|
||||
self._padAxis[axis] = value
|
||||
if math.abs(value) > PAD_DEAD then self:_activatePadCursor() end
|
||||
if math.abs(value) > PAD_DEAD then
|
||||
self:_activatePadCursor()
|
||||
elseif axis == "lefty" then
|
||||
self._padStickCentered = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2922,18 +2927,21 @@ end
|
||||
-- fire the virtual cursor's click twice off one A press (#620).
|
||||
function RomImporter:joystickpressed(joystick, button)
|
||||
if GamepadMap.ignoreRawForJoystick(joystick) then return end
|
||||
if GamepadMap.isAccelerometer(joystick) then return end
|
||||
local padButton = GamepadMap.mapRawToGamepadButton(button)
|
||||
if padButton then self:gamepadpressed(joystick, padButton) end
|
||||
end
|
||||
|
||||
function RomImporter:joystickreleased(joystick, button)
|
||||
if GamepadMap.ignoreRawForJoystick(joystick) then return end
|
||||
if GamepadMap.isAccelerometer(joystick) then return end
|
||||
local padButton = GamepadMap.mapRawToGamepadButton(button)
|
||||
if padButton then self:gamepadreleased(joystick, padButton) end
|
||||
end
|
||||
|
||||
function RomImporter:joystickaxis(joystick, axis, value)
|
||||
if GamepadMap.ignoreRawForJoystick(joystick) then return end
|
||||
if GamepadMap.isAccelerometer(joystick) then return end
|
||||
if axis == 1 then
|
||||
self:gamepadaxis(joystick, "leftx", value)
|
||||
elseif axis == 2 then
|
||||
@@ -2943,6 +2951,7 @@ end
|
||||
|
||||
function RomImporter:joystickhat(joystick, hat, direction)
|
||||
if GamepadMap.ignoreRawForJoystick(joystick) then return end
|
||||
if GamepadMap.isAccelerometer(joystick) then return end
|
||||
for _, dir in ipairs(self._rawHatDirs[hat] or {}) do
|
||||
self._padDir[dir] = nil
|
||||
end
|
||||
@@ -4003,6 +4012,18 @@ function RomImporter:_disarmTextInput()
|
||||
end
|
||||
end
|
||||
|
||||
function RomImporter:_blurPanelFields()
|
||||
if not (self._findSearchFocus or self._skinUrlFocus) then return end
|
||||
if self._indexPrompt or self._rename or self._settingsText
|
||||
or self._profileSavePrompt or self._profileRenamePrompt
|
||||
or (self._syncModal and self._syncFocus) then
|
||||
return
|
||||
end
|
||||
self._findSearchFocus = false
|
||||
self._skinUrlFocus = false
|
||||
self:_disarmTextInput()
|
||||
end
|
||||
|
||||
function RomImporter:_beginRename(version, id)
|
||||
local label
|
||||
for _, slot in ipairs(self.slots[version] or {}) do
|
||||
|
||||
@@ -580,8 +580,8 @@ local function buildRows(game)
|
||||
end
|
||||
rows = filtered
|
||||
end
|
||||
-- ORIENTATION only on Android, the one platform Orientation.apply reaches.
|
||||
if not Orientation.isAndroid() then
|
||||
-- ORIENTATION only on the platforms Orientation.apply reaches (#1638).
|
||||
if not (Orientation.isAndroid() or Orientation.isIOS()) then
|
||||
local filtered = {}
|
||||
for _, row in ipairs(rows) do
|
||||
if row.id ~= "orientation" then filtered[#filtered + 1] = row end
|
||||
|
||||
@@ -151,6 +151,7 @@ end
|
||||
|
||||
function PadCursor.joystickpressed(joystick, button)
|
||||
if GamepadMap.ignoreRawForJoystick(joystick) then return nil end
|
||||
if GamepadMap.isAccelerometer(joystick) then return nil end
|
||||
local padButton = GamepadMap.mapRawToGamepadButton(button)
|
||||
if padButton then return PadCursor.gamepadpressed(joystick, padButton) end
|
||||
return nil
|
||||
@@ -158,12 +159,14 @@ end
|
||||
|
||||
function PadCursor.joystickreleased(joystick, button)
|
||||
if GamepadMap.ignoreRawForJoystick(joystick) then return end
|
||||
if GamepadMap.isAccelerometer(joystick) then return end
|
||||
local padButton = GamepadMap.mapRawToGamepadButton(button)
|
||||
if padButton then PadCursor.gamepadreleased(joystick, padButton) end
|
||||
end
|
||||
|
||||
function PadCursor.joystickaxis(joystick, axisIndex, value)
|
||||
if GamepadMap.ignoreRawForJoystick(joystick) then return end
|
||||
if GamepadMap.isAccelerometer(joystick) then return end
|
||||
if axisIndex == 1 then
|
||||
PadCursor.gamepadaxis(joystick, "leftx", value)
|
||||
elseif axisIndex == 2 then
|
||||
@@ -173,6 +176,7 @@ end
|
||||
|
||||
function PadCursor.joystickhat(joystick, hat, direction)
|
||||
if GamepadMap.ignoreRawForJoystick(joystick) then return end
|
||||
if GamepadMap.isAccelerometer(joystick) then return end
|
||||
for _, d in ipairs(rawHatDirs[hat] or {}) do
|
||||
dir[d] = nil
|
||||
end
|
||||
|
||||
@@ -252,6 +252,8 @@ function EvolutionAnim:setPhase(phase)
|
||||
full = self.full,
|
||||
})
|
||||
end
|
||||
local stack = self.game and self.game.stack
|
||||
if stack and stack.top and stack:top() == self then stack:pop() end
|
||||
return
|
||||
end
|
||||
end
|
||||
@@ -321,8 +323,18 @@ end
|
||||
function EvolutionAnim:update(_dt)
|
||||
local input = self.game and self.game.input
|
||||
local phase = self.phase
|
||||
-- onDone has already fired; the caller pops this state on its own beat.
|
||||
if phase == "done" then return end
|
||||
-- onDone has already fired.
|
||||
if phase == "done" then
|
||||
local stack = self.game and self.game.stack
|
||||
if stack and stack.top and stack:top() == self then stack:pop() end
|
||||
return
|
||||
end
|
||||
|
||||
if phase == "waitingLearn" then
|
||||
local stack = self.game and self.game.stack
|
||||
if stack and stack.top and stack:top() == self then self:nextLearn() end
|
||||
return
|
||||
end
|
||||
|
||||
if phase == "flash" then
|
||||
return self:updateFlash(input)
|
||||
|
||||
Reference in New Issue
Block a user